From a768c0a3e1fa29eddc7dd348012b3093e476c94e Mon Sep 17 00:00:00 2001 From: Ruiling Song Date: Tue, 3 Apr 2018 09:50:20 +0800 Subject: [PATCH] lavf/qsv: clone the frame which may be managed by framework For filters based on framesync, the input frame was managed by framesync, so we should not directly keep and destroy it, instead we make a clone of it here, or else double-free will occur. But for other filters not based on framesync, we still need to free the input frame inside filter_frame. Signed-off-by: Ruiling Song (cherry picked from commit d865783b6c8d4f96f5094ed72eff0f5a4a4908af) --- libavfilter/qsvvpp.c | 4 ++-- libavfilter/vf_vpp_qsv.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 732cf56a6a..2c01295628 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -296,7 +296,7 @@ static QSVFrame *submit_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *p av_log(ctx, AV_LOG_ERROR, "QSVVPP gets a wrong frame.\n"); return NULL; } - qsv_frame->frame = picref; + qsv_frame->frame = av_frame_clone(picref); qsv_frame->surface = (mfxFrameSurface1 *)qsv_frame->frame->data[3]; } else { /* make a copy if the input is not padded as libmfx requires */ @@ -318,7 +318,7 @@ static QSVFrame *submit_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *p av_frame_copy_props(qsv_frame->frame, picref); av_frame_free(&picref); } else - qsv_frame->frame = picref; + qsv_frame->frame = av_frame_clone(picref); if (map_frame_to_surface(qsv_frame->frame, &qsv_frame->surface_internal) < 0) { diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index 6be7098ae9..41a9f38962 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -341,9 +341,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) VPPContext *vpp = inlink->dst->priv; AVFilterLink *outlink = ctx->outputs[0]; - if (vpp->qsv) + if (vpp->qsv) { ret = ff_qsvvpp_filter_frame(vpp->qsv, inlink, picref); - else { + av_frame_free(&picref); + } else { if (picref->pts != AV_NOPTS_VALUE) picref->pts = av_rescale_q(picref->pts, inlink->time_base, outlink->time_base); ret = ff_filter_frame(outlink, picref);