av_read_frame() returns packet with duration 0, makes my life annoying
#1
Hi all,

I'm debugging a small issue that is annoying me as hell. I have mpegts files that are created by ArgusTV when recording from a DVB-T source.
When I try to play them, probing the input file is OK. I can see that avformat_find_stream_info returns the proper duration, etc.
(called from DVDDemuxFFMpeg::Open)

After a few seconds of play, the duration spikes from the initial (correct) 43 minutes to about 18 hours, 21 minutes. After some digging I found that the
info is taken from DVDDemuxFFMpeg::GetStreamLength which takes it from the format context.

I can see that there are several frames that return with duration 0 after av_read_frame in the Read() method. Actually, the packet returns with duration 0
and very large pts/dts values that after conversion using timebase they become the 18h:21m. Later on there is some processing of the duration values
and in this case the format context duration is updated using those large values.

I suspect there is a problem with the file itself, maybe some bad frames that cause ffmpeg's parser to bail out without giving proper values. I'm trying to debug
ffmpeg now with some log prints but I'd like to know -

Is it enough to detect such a scenario by checking if the packet duration is 0? Currently there is no such check in the code. The code will check for invalid
pts/dts values (NOPTS or 0 set) but doesn't check the duration.

I'm currently digging deeper and will see if detecting duration=0 is helping any... If so, are you even interested in adding such a check?
Reply
#2
is it a complete frame ?
Reply
#3
How do I find out? Still learning this stuff..
Reply
#4
FYI - I added a check for m_pkt.pkt.duration == 0 and if it's set to 0 I set the pts and dts values to AV_NOPTS_VALUE.
This seems to fix the issue with the duration - it is no longer spiking to 18h+.

I'm still investigating inside ffmpeg.

Edit - Looking deeper with some debug logs, ffmpeg returns the following values for the packet:
IN delayed:0 pts:5945594642, dts:5945594642 cur_dts:NOPTS st:3 pc:00C42E00 duration:0
15:29:39 T:13688 DEBUG: ffmpeg[3578]: [mpegts] read_frame_internal stream=3, pts=5945594642, dts=5945594642, size=14, duration=0, flags=1

The stream index is 3. Apparently the file has 6 streams: video, 2x audio and 3 dvb_subtitle streams. I get duration 0 for any packet that originates from a subtitle stream
(the small length is also a good indicator of subtitles) and very high dts/pts.

The code in DVDDemuxFFmpeg::Read takes a packet and processes it without checking if the packet is from a subtitle stream. On line 793 it will see a dts value that is very
large but still not AV_NOPTS_VALUE and will process it. In that if clause the format context's duration will be overridden with something that shouldn't affect the video duration.

I think that entire code shouldn't be doing anything for subtitle streams. This can easily be detected by checking the stream codec which seems a better fix.
Reply
#5
The same happens with recordings from tvheadend from time to time. The duration usually ends up being 22-23 hours. A possibly related bug is that the duration is sometimes not determined at all so the recording has 00:00 duration, making skipping a pain and resume points not working.
Reply
#6
Proper handling for all types of subtitles like Teletext, DVB subtitles etc would probably fix this problem too..
 
Intel Core i5 2320 8GB 500GB HDD - Tvheadend + Kodi, Raspberry Pi 3 - LibreELEC, HDHomeRun HDHR3-4DC, Epson TW3200, Pioneer VSX-1123
Reply
#7
You're right, of course. I've seen some commits done to FFmpeg very recently that improve handling of subtitle streams but even with those I found a bug in the latest code regarding handling of decompression timestamp for non-monotonic streams. It's a trivial fix but if it helps I'll submit it to the
FFmpeg mailing list. Hopefully the guys here will merge the PR :-)

BTW - I started with a TS file that was generated by ArgusTV during recording. I'm "glad" to hear that tvheadend saves mpegts and the same problem
is reproduced by it. This makes me believe my case is not an isolated case.
Reply
#8
Hi all, latest update -

It seems that DVB subtitle streams / teletext streams are what they call "private streams" with stream type 0xBD. These can have their own timebase which can many times be very different than the video stream's timebase (I admit I have no clue how their timebase works). Also, apparently sometimes the PTS fields are not properly set by the broadcaster which may lead to trouble.

Side note - I verified the values are "weird" with TS packet analyzer and project X. FFmpeg is not doing anything special here.

In GStreamer there's special code to handle this case. In FFmpeg I saw very recently patches submitted to the FFmpeg mailing list that help deal with this case. Regardless, XBMC in my opinion should not extend the format context's duration due to private streams, or any stream type that is not strictly real content.

The progress bar and play duration is used to control timeshifting/rewind/etc. for video and audio.

I've opened a PR https://github.com/xbmc/xbmc/pull/4337 to fix this. It's a small fix but should at least protect us from such weird cases. Hopefully it gets accepted :-)
Reply

Logout Mark Read Team Forum Stats Members Help
av_read_frame() returns packet with duration 0, makes my life annoying0