Search code examples
ffmpegvideo-streaminglibavmpeg2-ts

libav MPEGTS demuxing - handle loop/discontinuity


I'm writing a video/audio player that uses libav/ffmpeg for demuxing and decoding MPEGTS streams over UDP. One problem that I'm dealing with is that sometimes the stream is looping and when it loops, my player breaks down.

The issue is that once the stream loops, the new packets have widely different dts/pts. My player is relying on pts for video - audio synchronisation so it's important that I can handle pts properly.

Whenever the server loops the stream, it sends a discontinuity flag, which I can confirm is being correctly received by libav mpegts demuxer (I did some digging in the code and inspected the debug logs). However, it seems to me that the demuxer doesn't act on the discontinuity flag much. In other words, from the point of view of the user I can't tell that there's a discontinuity, apart from the dramatic jump in dts/pts.

Is there a way I can reliably tell that there was a discontinuty so I can recalculate my timestamps and continue playback smoothly?


Solution

  • Eventually I came up with a solution. Not sure it's the best way to deal with this, but it works for me.

    It's true that packets demuxed by libav don't contain any specific information about discontinuity occuring. However, if discontinuity occurs, that means that there will be a sudden change in dts/pts between the 2 packets.

    In other words, discontinuity means the content changed. Since it changed, the timestamps are gonna be very different.

    The timestamp can only change in 2 ways:

    1. It's gonna be lower than the previous one, which is not allowed in a continuous stream
    2. it's gonna be much greater than the previous one

    Case 1. is pretty straight forward. Case 2. works if you pick high enough threshold. I picked 1 minute. So if I receive a packet and the timestamp difference between it and the previous packet is more than 1 minute, I consider that a discontinuity.

    This decision process is based around a "timestamp", but what timestamp am I talking about? The packets contain 2 timestamps - dts and pts. However, it seems that pts is usually out of order. But dts is always increasing so I based my logic around dts.