Browse Source

avcodec/v4l2_m2m: adapt to call close() on init fail

This fixes several mem leaks when init of encoder/decoder failed.

Fixes ticket #8285

Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com>
tags/n4.4
Andriy Gelman 5 years ago
parent
commit
7c32e9cf93
3 changed files with 9 additions and 8 deletions
  1. +6
    -0
      libavcodec/v4l2_m2m.c
  2. +2
    -8
      libavcodec/v4l2_m2m_dec.c
  3. +1
    -0
      libavcodec/v4l2_m2m_enc.c

+ 6
- 0
libavcodec/v4l2_m2m.c View File

@@ -330,6 +330,7 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context)


close(s->fd); close(s->fd);
av_frame_free(&s->frame); av_frame_free(&s->frame);
av_packet_unref(&s->buf_pkt);


av_free(s); av_free(s);
} }
@@ -339,6 +340,10 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
V4L2m2mContext *s = priv->context; V4L2m2mContext *s = priv->context;
int ret; int ret;


if (!s)
return 0;

if (s->fd >= 0) {
ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF);
if (ret) if (ret)
av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->output.name); 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); ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF);
if (ret) if (ret)
av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name); av_log(s->avctx, AV_LOG_ERROR, "VIDIOC_STREAMOFF %s\n", s->capture.name);
}


ff_v4l2_context_release(&s->output); ff_v4l2_context_release(&s->output);




+ 2
- 8
libavcodec/v4l2_m2m_dec.c View File

@@ -205,9 +205,6 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)
ret = ff_v4l2_m2m_codec_init(priv); ret = ff_v4l2_m2m_codec_init(priv);
if (ret) { if (ret) {
av_log(avctx, AV_LOG_ERROR, "can't configure decoder\n"); av_log(avctx, AV_LOG_ERROR, "can't configure decoder\n");
s->self_ref = NULL;
av_buffer_unref(&priv->context_ref);

return ret; return ret;
} }


@@ -216,10 +213,7 @@ static av_cold int v4l2_decode_init(AVCodecContext *avctx)


static av_cold int v4l2_decode_close(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) #define OFFSET(x) offsetof(V4L2m2mPriv, x)
@@ -254,7 +248,7 @@ static const AVOption options[] = {
.close = v4l2_decode_close, \ .close = v4l2_decode_close, \
.bsfs = bsf_name, \ .bsfs = bsf_name, \
.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \ .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", \ .wrapper_name = "v4l2m2m", \
} }




+ 1
- 0
libavcodec/v4l2_m2m_enc.c View File

@@ -429,6 +429,7 @@ static const AVCodecDefault v4l2_m2m_defaults[] = {
.close = v4l2_encode_close, \ .close = v4l2_encode_close, \
.defaults = v4l2_m2m_defaults, \ .defaults = v4l2_m2m_defaults, \
.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
.wrapper_name = "v4l2m2m", \ .wrapper_name = "v4l2m2m", \
} }




Loading…
Cancel
Save