[FFmpeg-devel] [RFC]Remove panscan side data in filters that change the resolution

Carl Eugen Hoyos cehoyos at ag.or.at
Wed Jul 2 10:34:42 CEST 2014


Hi!

Attached is a work-around for ticket #3750.

Please comment, Carl Eugen
-------------- next part --------------
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index 84dbee9..cdf86b4 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -95,6 +95,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
     AspectContext *s = link->dst->priv;
 
     frame->sample_aspect_ratio = s->sar;
+    av_frame_remove_side_data(frame, AV_FRAME_DATA_PANSCAN);
     return ff_filter_frame(link->dst->outputs[0], frame);
 }
 
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index a2f029a..6b782bb 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -88,6 +88,7 @@ typedef struct CropContext {
     char *x_expr, *y_expr, *w_expr, *h_expr;
     AVExpr *x_pexpr, *y_pexpr;  /* parsed expressions for x and y */
     double var_values[VAR_VARS_NB];
+    int rm_panscan;
 } CropContext;
 
 static int query_formats(AVFilterContext *ctx)
@@ -215,6 +216,8 @@ static int config_input(AVFilterLink *link)
                s->w, s->h);
         return AVERROR(EINVAL);
     }
+    if (s->w != link->w || s->h != link->h)
+        s->rm_panscan = 1;
 
     /* set default, required in the case the first computed value for x/y is NAN */
     s->x = (link->w - s->w) / 2;
@@ -248,6 +251,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
 
     frame->width  = s->w;
     frame->height = s->h;
+    if (s->rm_panscan)
+        av_frame_remove_side_data(frame, AV_FRAME_DATA_PANSCAN);
 
     s->var_values[VAR_N] = link->frame_count;
     s->var_values[VAR_T] = frame->pts == AV_NOPTS_VALUE ?
diff --git a/libavfilter/vf_field.c b/libavfilter/vf_field.c
index ed12379..1ef37fb 100644
--- a/libavfilter/vf_field.c
+++ b/libavfilter/vf_field.c
@@ -74,6 +74,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
 
     inpicref->height = outlink->h;
     inpicref->interlaced_frame = 0;
+    av_frame_remove_side_data(inpicref, AV_FRAME_DATA_PANSCAN);
 
     for (i = 0; i < field->nb_planes; i++) {
         if (field->type == FIELD_TYPE_BOTTOM)
diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c
index 8a7d4e8..efbb6a8 100644
--- a/libavfilter/vf_framepack.c
+++ b/libavfilter/vf_framepack.c
@@ -295,6 +295,7 @@ static int request_frame(AVFilterLink *outlink)
             return AVERROR(ENOMEM);
         }
         stereo->type = s->format;
+        av_frame_remove_side_data(dst, AV_FRAME_DATA_PANSCAN);
 
         return ff_filter_frame(outlink, dst);
     }
diff --git a/libavfilter/vf_hqx.c b/libavfilter/vf_hqx.c
index 4783381..8d331fc 100644
--- a/libavfilter/vf_hqx.c
+++ b/libavfilter/vf_hqx.c
@@ -501,6 +501,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     ctx->internal->execute(ctx, hqx->func, &td, NULL, FFMIN(inlink->h, ctx->graph->nb_threads));
 
     av_frame_free(&in);
+    av_frame_remove_side_data(out, AV_FRAME_DATA_PANSCAN);
     return ff_filter_frame(outlink, out);
 }
 
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index 2d9b9d0..5b9fa83 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -88,6 +88,7 @@ typedef struct PadContext {
     char *x_expr;           ///< width  expression string
     char *y_expr;           ///< height expression string
     uint8_t rgba_color[4];  ///< color for the padding area
+    int rm_panscan;
     FFDrawContext draw;
     FFDrawColor color;
 } PadContext;
@@ -180,6 +181,9 @@ static int config_input(AVFilterLink *inlink)
         return AVERROR(EINVAL);
     }
 
+    if (s->w != inlink->w || s->h != inlink->h)
+        s->rm_panscan = 1;
+
     return 0;
 
 eval_fail:
@@ -349,6 +353,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 
     out->width  = s->w;
     out->height = s->h;
+    if (s->rm_panscan)
+        av_frame_remove_side_data(out, AV_FRAME_DATA_PANSCAN);
 
     if (in != out)
         av_frame_free(&in);
diff --git a/libavfilter/vf_rotate.c b/libavfilter/vf_rotate.c
index 7e5b12b..d31c4271 100644
--- a/libavfilter/vf_rotate.c
+++ b/libavfilter/vf_rotate.c
@@ -75,6 +75,7 @@ typedef struct {
     int use_bilinear;
     float sinx, cosx;
     double var_values[VAR_VARS_NB];
+    int rm_panscan;
     FFDrawContext draw;
     FFDrawColor color;
 } RotContext;
@@ -250,6 +251,8 @@ static int config_props(AVFilterLink *outlink)
     rot->nb_planes = av_pix_fmt_count_planes(inlink->format);
     outlink->w = rot->outw;
     outlink->h = rot->outh;
+    if (outlink->w != inlink->w || outlink->h != inlink->h)
+        rot->rm_panscan = 1;
     return 0;
 }
 
@@ -507,6 +510,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
         ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outh, ctx->graph->nb_threads));
     }
 
+    av_frame_remove_side_data(out, AV_FRAME_DATA_PANSCAN);
     av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index c4605c7..c693fb0 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -109,6 +109,7 @@ typedef struct ScaleContext {
     int in_v_chr_pos;
 
     int force_original_aspect_ratio;
+    int rm_panscan;
 } ScaleContext;
 
 static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts)
@@ -327,6 +328,8 @@ static int config_props(AVFilterLink *outlink)
 
     outlink->w = w;
     outlink->h = h;
+    if (inlink->w != outlink->w || inlink->h != outlink->h)
+        scale->rm_panscan = 1;
 
     /* TODO: make algorithm configurable */
 
@@ -471,6 +474,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     av_frame_copy_props(out, in);
     out->width  = outlink->w;
     out->height = outlink->h;
+    if (scale->rm_panscan)
+        av_frame_remove_side_data(out, AV_FRAME_DATA_PANSCAN);
 
     if(scale->output_is_pal)
         avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format);
diff --git a/libavfilter/vf_separatefields.c b/libavfilter/vf_separatefields.c
index 42ce682..b03f11c 100644
--- a/libavfilter/vf_separatefields.c
+++ b/libavfilter/vf_separatefields.c
@@ -59,6 +59,7 @@ static void extract_field(AVFrame *frame, int nb_planes, int type)
             frame->data[i] = frame->data[i] + frame->linesize[i];
         frame->linesize[i] *= 2;
     }
+    av_frame_remove_side_data(frame, AV_FRAME_DATA_PANSCAN);
 }
 
 static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
diff --git a/libavfilter/vf_stereo3d.c b/libavfilter/vf_stereo3d.c
index 2140120..44d1112 100644
--- a/libavfilter/vf_stereo3d.c
+++ b/libavfilter/vf_stereo3d.c
@@ -142,6 +142,7 @@ typedef struct Stereo3DContext {
     int pixstep[4];
     AVFrame *prev;
     double ts_unit;
+    int rm_panscan;
 } Stereo3DContext;
 
 #define OFFSET(x) offsetof(Stereo3DContext, x)
@@ -372,6 +373,8 @@ static int config_output(AVFilterLink *outlink)
 
     s->out.width     = s->width;
     s->out.height    = s->height;
+    if (s->out.width != inlink->w || s->out.height != inlink->h)
+        s->rm_panscan = 1;
     s->out.off_lstep =
     s->out.off_rstep =
     s->out.off_left  =
@@ -624,6 +627,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
                s->in.format == ALTERNATING_RL) {
         out->pts = outlink->frame_count * s->ts_unit;
     }
+    av_frame_remove_side_data(out, AV_FRAME_DATA_PANSCAN);
     return ff_filter_frame(outlink, out);
 }
 
diff --git a/libavfilter/vf_super2xsai.c b/libavfilter/vf_super2xsai.c
index 686dac1..c26ead8 100644
--- a/libavfilter/vf_super2xsai.c
+++ b/libavfilter/vf_super2xsai.c
@@ -314,6 +314,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)
     av_frame_copy_props(outpicref, inpicref);
     outpicref->width  = outlink->w;
     outpicref->height = outlink->h;
+    av_frame_remove_side_data(outpicref, AV_FRAME_DATA_PANSCAN);
 
     super2xsai(inlink->dst, inpicref->data[0], inpicref->linesize[0],
                outpicref->data[0], outpicref->linesize[0],
diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c
index 459ae46..a56cbf5 100644
--- a/libavfilter/vf_tile.c
+++ b/libavfilter/vf_tile.c
@@ -177,6 +177,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
             return AVERROR(ENOMEM);
         }
         av_frame_copy_props(tile->out_ref, picref);
+        av_frame_remove_side_data(tile->out_ref, AV_FRAME_DATA_PANSCAN);
         tile->out_ref->width  = outlink->w;
         tile->out_ref->height = outlink->h;
 
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index d9b165c..64bc2b8 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -251,6 +251,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 
     td.in = in, td.out = out;
     ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outlink->h, ctx->graph->nb_threads));
+    av_frame_remove_side_data(out, AV_FRAME_DATA_PANSCAN);
     av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }


More information about the ffmpeg-devel mailing list