h264 decoder decodes complete GOP wrong / skips one GOP if stream does not start with SPS/PPS
|Reported by:||Marco Munderloh||Owned by:|
|Blocking:||Reproduced by developer:||yes|
|Analyzed by developer:||no|
Summary of the bug:
I recorded a DVB TS stream. It contains an H264 video stream which first NALU is a B slice, followed by the SPS, PPS NALUs and an IDR frame.
If this stream is played with ffplay (either the TS or the demuxed elementary stream), the decoder seems to get so much confused by the leading B slice that the following valid GOP is completely decoded erroneous until the next GOP arrives. ffplay skips the broken frames and starts playing at the second GOP by default. One has to specify -flags2 +showall to see the GOP of broken frames.
If the B slice is removed from the stream, playing starts fine from the first frame/GOP on.
I see that it is intended that ffmpeg tries to decode and conceal every frame coming in, but that should effect only one frame (the B slice) and not the following GOP.
However, I'm not so sure why the B slice is concealed as there is no valid SPS/PPS yet which is mandatory to decode the slice. But that might be a different problem.
Take a h264 stream starting with a B slice, followed by the SPS/PPS/IDR. I uploaded a sample TS file to ftp://upload.ffmpeg.org/MPlayer/incoming/ called DVB_testvideo.ts. One can either play that file or extract the H264 elementary stream and use it directly.
The stream is using PAFF/MBAFF, but I don't know if this is related.
How to reproduce:
% ffplay DVB_testvideo.ts skips the first valid GOP completely and starts playing from frame 16 onwards. % ffplay DVB_testvideo.ts -flags2 +showall starts playing 16 broken frames, then recovers and plays fine. Now remove the first B slice (skip 17756 from the H264 bitstream or 20304 bytes from the whole TS file). % ffplay DVB_testvideo.ts plays fine from the first frame on (15 frames valid frames more then before) % ffplay DVB_testvideo.ts -flags2 +showall shows no broken frames anymore ffmpeg version N-42015-g64e4bd7 built on openSUSE 13.1 (gcc 4.8.1)