[FFmpeg-devel] [PATCH] correct MPEG video parser not to return incomplete frames
Ivan Schreter
schreter
Sun Aug 2 17:11:55 CEST 2009
Hi,
Michael Niedermayer wrote:
> On Sun, Aug 02, 2009 at 03:58:59PM +0200, Ivan Schreter wrote:
> [...]
>
>> @@ -146,7 +153,12 @@
>> /* we have a full frame : we just parse the first few MPEG headers
>> to have the full timing information. The time take by this
>> function should be negligible for uncorrupted streams */
>> - mpegvideo_extract_headers(s, avctx, buf, buf_size);
>> + if (mpegvideo_extract_headers(s, avctx, buf, buf_size) < 0) {
>> + /* garbled frame, ignore (possibly first read after seek) */
>> + *poutbuf = NULL;
>> + *poutbuf_size = 0;
>> + return next;
>> + }
>> #if 0
>> printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
>> s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict);
>>
>
> as already said elsewhere, its not the job of parsers to discard data
> it would break decoders that are capable to decode damaged frames, like
> our decoder.
>
The problem is not in the decoder, but rather parser. Namely, associated
data (PTS, DTS, position, etc.) are passed incorrectly.
> in addition to this your patch is VERY broken in a subtile and hard to
> debug way, that is it will detect 99% of the incomplete frames but not
> all from what it doesnt detect again most but not all would be fine,
> that would be a nightmare to debug as it would occur so rarely and
> require exact seeking to the problematic spot to reproduce ...
> the issue and that might not be the only one is that there can be
> things prior to the picture start code that can matter ...
>
It is also not the intention to detect 100% of incomplete frames. The
intention is only to detect partial frame after the seek, so we don't
return nonsense back (which breaks seeking).
Possibly, the check could be made in a "fresh" parser only, so that we
at most lose very first broken frame of a stream and it would still
correct the seeking...
Otherwise, how would you do it? The problem:
After the seek, you are positioned to a packet containing some video
stream data. There is a bit from the previous frame, but PTS/DTS are
related to the new frame. You don't know whether the first part of the
packet belongs to a previous frame or whether it is a complete frame
(access unit). But you do know, it can only be a complete frame, if it
contains picture start code _and_ a slice.
Current code will simply take the rest of previous frame as a complete
frame and return it back, thus associating PTS/DTS of the packet with
this broken frame. Then, parser will read the next frame (correct one),
but associate AV_NOPTS_VALUE for PTS/DTS of that frame, since it is the
second frame starting in the same packet (and thus timestamps have to be
calculated). Wrong timestamps will be calculated for this frame. This
breaks seeking and CANNOT be addressed in the decoder (it's not the
proper place).
Regards,
Ivan
More information about the ffmpeg-devel
mailing list