Message ID | 20200429025421.9270-1-andriy.gelman@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | [FFmpeg-devel,v2] avcodec/v4l2_m2m: Adapt to call close() on init fail | expand |
Context | Check | Description |
---|---|---|
andriy/default | pending | |
andriy/make | success | Make finished |
andriy/make_fate | success | Make fate finished |
On Tue, 28. Apr 22:54, Andriy Gelman wrote: > From: Andriy Gelman <andriy.gelman@gmail.com> > > This fixes several mem leaks when init of encoder/decoder failed. > > Fixes ticket #8285 > > Signed-off-by: Andriy Gelman <andriy.gelman@gmail.com> > --- > > Changes in v2: > - Use FF_CODEC_CAP_INIT_CLEANUP > > This patch supersedes: > https://patchwork.ffmpeg.org/project/ffmpeg/patch/20200310045541.13048-1-andriy.gelman@gmail.com/ > https://patchwork.ffmpeg.org/project/ffmpeg/patch/20200310045541.13048-2-andriy.gelman@gmail.com/ > > libavcodec/v4l2_m2m.c | 8 ++++++++ > libavcodec/v4l2_m2m_dec.c | 10 ++-------- > libavcodec/v4l2_m2m_enc.c | 2 ++ > 3 files changed, 12 insertions(+), 8 deletions(-) > > diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c > index e48b3a8ccf..bfea70ff0c 100644 > --- a/libavcodec/v4l2_m2m.c > +++ b/libavcodec/v4l2_m2m.c > @@ -338,6 +338,13 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) > V4L2m2mContext *s = priv->context; > int ret; > > + if (!s) > + return 0; > + > + if (av_codec_is_decoder(s->avctx->codec)) > + av_packet_unref(&s->buf_pkt); > + > + 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); > @@ -345,6 +352,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); > > diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c > index 3e17e0fcac..a2ea0ff73a 100644 > --- a/libavcodec/v4l2_m2m_dec.c > +++ b/libavcodec/v4l2_m2m_dec.c > @@ -212,9 +212,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; > } > > @@ -223,10 +220,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) > @@ -261,7 +255,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", \ > } > > diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c > index 8454e2326c..97c937fdf9 100644 > --- a/libavcodec/v4l2_m2m_enc.c > +++ b/libavcodec/v4l2_m2m_enc.c > @@ -25,6 +25,7 @@ > #include <sys/ioctl.h> > #include <search.h> > #include "libavcodec/avcodec.h" > +#include "libavcodec/internal.h" > #include "libavutil/pixdesc.h" > #include "libavutil/pixfmt.h" > #include "libavutil/opt.h" > @@ -391,6 +392,7 @@ static const AVOption options[] = { > .receive_packet = v4l2_receive_packet, \ > .close = v4l2_encode_close, \ > .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \ > + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \ > .wrapper_name = "v4l2m2m", \ > }; > ping
diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c index e48b3a8ccf..bfea70ff0c 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c @@ -338,6 +338,13 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) V4L2m2mContext *s = priv->context; int ret; + if (!s) + return 0; + + if (av_codec_is_decoder(s->avctx->codec)) + av_packet_unref(&s->buf_pkt); + + 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); @@ -345,6 +352,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); diff --git a/libavcodec/v4l2_m2m_dec.c b/libavcodec/v4l2_m2m_dec.c index 3e17e0fcac..a2ea0ff73a 100644 --- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c @@ -212,9 +212,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; } @@ -223,10 +220,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) @@ -261,7 +255,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", \ } diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 8454e2326c..97c937fdf9 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -25,6 +25,7 @@ #include <sys/ioctl.h> #include <search.h> #include "libavcodec/avcodec.h" +#include "libavcodec/internal.h" #include "libavutil/pixdesc.h" #include "libavutil/pixfmt.h" #include "libavutil/opt.h" @@ -391,6 +392,7 @@ static const AVOption options[] = { .receive_packet = v4l2_receive_packet, \ .close = v4l2_encode_close, \ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \ + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \ .wrapper_name = "v4l2m2m", \ };