lavf/qsv: clone the frame which may be managed by framework
authorRuiling Song <ruiling.song@intel.com>
Tue, 3 Apr 2018 01:50:20 +0000 (09:50 +0800)
committerMark Thompson <sw@jkqxz.net>
Sat, 21 Apr 2018 18:00:43 +0000 (19:00 +0100)
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 <ruiling.song@intel.com>
libavfilter/qsvvpp.c
libavfilter/vf_vpp_qsv.c

index 732cf56..2c01295 100644 (file)
@@ -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) {
index 6be7098..41a9f38 100644 (file)
@@ -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);