On 12/4/2020 7:57 PM, Andreas Rheinhardt wrote:
A reference to an AV1RawFrameHeader and consequently the
AV1RawFrameHeader itself and everything it has a reference to leak
if the hardware has no AV1 decoding capabilities.

It looks like it can happen if get_buffer() fails even with hardware support.

It happens e.g.
in the cbs-av1-av1-1-b8-02-allintra FATE-test; it has just been masked
because the return value of ffmpeg (which indicates failure when using
Valgrind or ASAN) is ignored when doing tests of type md5.

Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@gmail.com>
---
I switched the av_buffer_ref() and update_context_with_frame_header()
because the latter does not need any cleanup on failure.

Also notice that actual decoding with this patch applied is completely
untested.

  libavcodec/av1dec.c | 20 +++++++++++---------
  1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index 1589b8f0c0..d7b2ac9d46 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -674,20 +674,20 @@ static int av1_frame_alloc(AVCodecContext *avctx, 
AV1Frame *f)
      AVFrame *frame;
      int ret;
- f->header_ref = av_buffer_ref(s->header_ref);
-    if (!f->header_ref)
-        return AVERROR(ENOMEM);
-
-    f->raw_frame_header = s->raw_frame_header;
-
      ret = update_context_with_frame_header(avctx, header);
      if (ret < 0) {
          av_log(avctx, AV_LOG_ERROR, "Failed to update context with frame 
header\n");
          return ret;
      }
+ f->header_ref = av_buffer_ref(s->header_ref);
+    if (!f->header_ref)
+        return AVERROR(ENOMEM);
+
+    f->raw_frame_header = s->raw_frame_header;
+
      if ((ret = ff_thread_get_buffer(avctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 
0)
-        return ret;
+        goto fail;
frame = f->tf.f;
      frame->key_frame = header->frame_type == AV1_FRAME_KEY;
@@ -710,8 +710,10 @@ static int av1_frame_alloc(AVCodecContext *avctx, AV1Frame 
*f)
          if (hwaccel->frame_priv_data_size) {
              f->hwaccel_priv_buf =
                  av_buffer_allocz(hwaccel->frame_priv_data_size);
-            if (!f->hwaccel_priv_buf)
+            if (!f->hwaccel_priv_buf) {
+                ret = AVERROR(ENOMEM);
                  goto fail;
+            }
              f->hwaccel_picture_private = f->hwaccel_priv_buf->data;
          }
      }
@@ -719,7 +721,7 @@ static int av1_frame_alloc(AVCodecContext *avctx, AV1Frame 
*f)
fail:

Just to be safe, add a ret = 0 above this line.

      av1_frame_unref(avctx, f);
-    return AVERROR(ENOMEM);
+    return ret;
  }
static int set_output_frame(AVCodecContext *avctx, AVFrame *frame,

LGTM, and while unrelated to this fix, this also reveals that in some scenarios, decoding without hardware support reaches this point, when it's meant to abort when parsing the sequence header and being unable to set up a hardware pixel format in avctx.

Looks like when parsing a second sequence header (Like in the second keyframe) where s->pix_fmt is already set to a software format, get_pixel_format() is not called, and so decoding proceeds to deal with frames.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to