]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/v4l2_m2m: adapt to call close() on init fail
authorAndriy Gelman <andriy.gelman@gmail.com>
Sun, 2 Aug 2020 18:31:22 +0000 (14:31 -0400)
committerAndriy Gelman <andriy.gelman@gmail.com>
Sun, 2 Aug 2020 18:31:22 +0000 (14:31 -0400)
This fixes several mem leaks when init of encoder/decoder failed.

Fixes ticket #8285

Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com>
libavcodec/v4l2_m2m.c
libavcodec/v4l2_m2m_dec.c
libavcodec/v4l2_m2m_enc.c

index d8d872ea099d488b58046e9f4d47c191fdd1a125..944c1a2823016e06bf46b4161d2e4bf2590c28fb 100644 (file)
@@ -330,6 +330,7 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context)
 
     close(s->fd);
     av_frame_free(&s->frame);
+    av_packet_unref(&s->buf_pkt);
 
     av_free(s);
 }
@@ -339,6 +340,10 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
     V4L2m2mContext *s = priv->context;
     int ret;
 
+    if (!s)
+        return 0;
+
+    if (s->fd >= 0) {
     ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF);
     if (ret)
         av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name);
@@ -346,6 +351,7 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
     ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF);
     if (ret)
         av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name);
+    }
 
     ff_v4l2_context_release(&s->output);
 
index b038efed9c8781d55a8bc8fc0686c7b461d44240..ab07c0a24a2b8ca554d1d3459f3855cb88bc559e 100644 (file)
@@ -205,9 +205,6 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
     ret = ff_v4l2_m2m_codec_init(priv);
     if (ret) {
         av_log(avctx, AV_LOG_ERROR, "can't configure decoder\n");
-        s->self_ref = NULL;
-        av_buffer_unref(&priv->context_ref);
-
         return ret;
     }
 
@@ -216,10 +213,7 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
 
 static av_cold int v4l2_decode_close(AVCodecContext *avctx)
 {
-    V4L2m2mPriv *priv = avctx->priv_data;
-    V4L2m2mContext *s = priv->context;
-    av_packet_unref(&s->buf_pkt);
-    return ff_v4l2_m2m_codec_end(priv);
+    return ff_v4l2_m2m_codec_end(avctx->priv_data);
 }
 
 #define OFFSET(x) offsetof(V4L2m2mPriv, x)
@@ -254,7 +248,7 @@ static const AVOption options[] = {
         .close          = v4l2_decode_close, \
         .bsfs           = bsf_name, \
         .capabilities   = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
-        .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS, \
+        .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_INIT_CLEANUP, \
         .wrapper_name   = "v4l2m2m", \
     }
 
index 56df4286adde5a25163677649f94c6a6effb087f..af0ed1e306623afb8b1f6f79bac8295043bd9007 100644 (file)
@@ -429,6 +429,7 @@ static const AVCodecDefault v4l2_m2m_defaults[] = {
         .close          = v4l2_encode_close, \
         .defaults       = v4l2_m2m_defaults, \
         .capabilities   = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
+        .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP, \
         .wrapper_name   = "v4l2m2m", \
     }