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

Michael Niedermayer michaelni at gmx.at
Wed Jul 2 13:44:58 CEST 2014


On Wed, Jul 02, 2014 at 10:34:42AM +0200, Carl Eugen Hoyos wrote:
> Hi!
> 
> Attached is a work-around for ticket #3750.
> 
> Please comment, Carl Eugen

>  vf_aspect.c         |    1 +
>  vf_crop.c           |    5 +++++
>  vf_field.c          |    1 +
>  vf_framepack.c      |    1 +
>  vf_hqx.c            |    1 +
>  vf_pad.c            |    6 ++++++
>  vf_rotate.c         |    4 ++++
>  vf_scale.c          |    5 +++++
>  vf_separatefields.c |    1 +
>  vf_stereo3d.c       |    4 ++++
>  vf_super2xsai.c     |    1 +
>  vf_tile.c           |    1 +
>  vf_transpose.c      |    1 +
>  13 files changed, 32 insertions(+)
> b004bda156eaf174aa335ff21f001d496252c999  patchpanscan.diff
> 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);

you shouldnt need the rm_panscan variable, the link dimensions or
frame and link dimensions could be checked directly

though i wonder if it wouldnt work to drop panscan in
av_frame_copy_props() if dimensions mismatched or better update
panscan there

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

DNS cache poisoning attacks, popular search engine, Google internet authority
dont be evil, please
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140702/b1adef99/attachment.asc>


More information about the ffmpeg-devel mailing list