[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