[PATCH 02/18] avcodec/h264dec: do not await a field that was never decoded

Dom Cobley via ffmpeg-devel <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <[email protected]>
The frame num gap concealment awaits the previous short term reference before
copying it into the dummy picture it just allocated, both fields of it when
that picture is field coded. Nothing guarantees either field was ever decoded.

A field pair whose second field never arrived reports only the field it has,
and the end of decode_nal_units() reports one field of ::cur_pic_ptr and none
at all of a picture that is not a reference. Corrupt input reaches both, and
the wait is then for a field that no thread will ever produce -- often the
awaiting thread's own, so it deadlocks against itself. A decoder that hangs on
damaged input is worse than one that conceals it badly.

::reference collects the field bits as ff_h264_execute_ref_pic_marking() marks
each field, so requiring a whole frame there admits exactly the pictures whose
every field has been decoded and reported. Anything else falls through to the
colour fill below, which is what the concealment does already when there is no
previous picture to copy from.

Found by fuzzing 00004.MTS with the noise bitstream filter under frame
threading; it reproduces on an unmodified tree, without any multiview
involvement, and roughly five times more often once a view is selected with
-map 0:v:0:view:1.

Signed-off-by: Dom Cobley <[email protected]>
---
 libavcodec/h264_slice.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index a042616f7b..c96d99d242 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1551,7 +1551,15 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl,
                 -1
             };
 
-            if (prev &&
+            /* Only conceal from a picture that is certain to be reported.
+             * ::reference collects the field bits as each field is marked, so
+             * anything short of a whole frame is either a field pair whose
+             * second field never arrived or a picture that is no reference at
+             * all -- and the end of decode_nal_units() reports neither. Corrupt
+             * input reaches both, and awaiting one waits for a field that will
+             * never be decoded. Fall through to the colour fill instead.
+             * Masked, as ::reference also carries DELAYED_PIC_REF. */
+            if (prev && (prev->reference & PICT_FRAME) == PICT_FRAME &&
                 h->short_ref[0]->f->width == prev->f->width &&
                 h->short_ref[0]->f->height == prev->f->height &&
                 h->short_ref[0]->f->format == prev->f->format) {
-- 
2.53.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.