[FFmpeg-devel] [PATCH] lavfi: use ceil right shift for chroma width/height.
Stefano Sabatini
stefasab at gmail.com
Fri May 10 15:41:19 CEST 2013
On date Thursday 2013-05-09 18:14:34 +0200, Clément Bœsch encoded:
> This should fix several issues with odd dimensions inputs.
>
> ---
> Note: this is mostly untested
> ---
> libavfilter/vf_blend.c | 4 ++--
> libavfilter/vf_boxblur.c | 2 +-
> libavfilter/vf_decimate.c | 4 ++--
> libavfilter/vf_delogo.c | 6 ++++--
> libavfilter/vf_extractplanes.c | 4 ++--
> libavfilter/vf_fade.c | 3 ++-
> libavfilter/vf_fieldmatch.c | 8 ++++----
> libavfilter/vf_geq.c | 8 ++++----
> libavfilter/vf_hflip.c | 20 ++++++++++----------
> libavfilter/vf_hqdn3d.c | 4 ++--
> libavfilter/vf_hue.c | 3 ++-
> libavfilter/vf_il.c | 2 +-
> libavfilter/vf_interlace.c | 2 +-
> libavfilter/vf_kerndeint.c | 2 +-
> libavfilter/vf_mpdecimate.c | 3 ++-
> libavfilter/vf_noise.c | 2 +-
> libavfilter/vf_showinfo.c | 2 +-
> libavfilter/vf_smartblur.c | 7 ++++---
> libavfilter/vf_telecine.c | 2 +-
> libavfilter/vf_tinterlace.c | 2 +-
> libavfilter/vf_transpose.c | 4 ++--
> 21 files changed, 50 insertions(+), 44 deletions(-)
>
> diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c
> index b4c62ba..a0022cd 100644
> --- a/libavfilter/vf_blend.c
> +++ b/libavfilter/vf_blend.c
> @@ -372,8 +372,8 @@ static void blend_frame(AVFilterContext *ctx,
> for (plane = 0; plane < b->nb_planes; plane++) {
> int hsub = plane == 1 || plane == 2 ? b->hsub : 0;
> int vsub = plane == 1 || plane == 2 ? b->vsub : 0;
> - int outw = dst_buf->width >> hsub;
> - int outh = dst_buf->height >> vsub;
> + int outw = FF_CEIL_RSHIFT(dst_buf->width, hsub);
> + int outh = FF_CEIL_RSHIFT(dst_buf->height, vsub);
> uint8_t *dst = dst_buf->data[plane];
> uint8_t *top = top_buf->data[plane];
> uint8_t *bottom = bottom_buf->data[plane];
> diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
> index b010670..a8a2014 100644
> --- a/libavfilter/vf_boxblur.c
> +++ b/libavfilter/vf_boxblur.c
> @@ -302,7 +302,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> AVFilterLink *outlink = inlink->dst->outputs[0];
> AVFrame *out;
> int plane;
> - int cw = inlink->w >> boxblur->hsub, ch = in->height >> boxblur->vsub;
> + int cw = FF_CEIL_RSHIFT(inlink->w, boxblur->hsub), ch = FF_CEIL_RSHIFT(in->height, boxblur->vsub);
> int w[4] = { inlink->w, cw, cw, inlink->w };
> int h[4] = { in->height, ch, ch, in->height };
>
> diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c
> index 9548531..8767d5f 100644
> --- a/libavfilter/vf_decimate.c
> +++ b/libavfilter/vf_decimate.c
> @@ -92,8 +92,8 @@ static void calc_diffs(const DecimateContext *dm, struct qitem *q,
> const int linesize2 = f2->linesize[plane];
> const uint8_t *f1p = f1->data[plane];
> const uint8_t *f2p = f2->data[plane];
> - int width = plane ? f1->width >> dm->hsub : f1->width;
> - int height = plane ? f1->height >> dm->vsub : f1->height;
> + int width = plane ? FF_CEIL_RSHIFT(f1->width, dm->hsub) : f1->width;
> + int height = plane ? FF_CEIL_RSHIFT(f1->height, dm->vsub) : f1->height;
> int hblockx = dm->blockx / 2;
> int hblocky = dm->blocky / 2;
>
> diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
> index c747b02..b644190 100644
> --- a/libavfilter/vf_delogo.c
> +++ b/libavfilter/vf_delogo.c
> @@ -228,9 +228,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
>
> apply_delogo(out->data[plane], out->linesize[plane],
> in ->data[plane], in ->linesize[plane],
> - inlink->w>>hsub, inlink->h>>vsub,
> + FF_CEIL_RSHIFT(inlink->w, hsub),
> + FF_CEIL_RSHIFT(inlink->h, vsub),
> delogo->x>>hsub, delogo->y>>vsub,
> - delogo->w>>hsub, delogo->h>>vsub,
> + FF_CEIL_RSHIFT(delogo->w, hsub),
> + FF_CEIL_RSHIFT(delogo->h, vsub),
> delogo->band>>FFMIN(hsub, vsub),
> delogo->show, direct);
> }
> diff --git a/libavfilter/vf_extractplanes.c b/libavfilter/vf_extractplanes.c
> index 229e3d5..9844ed5 100644
> --- a/libavfilter/vf_extractplanes.c
> +++ b/libavfilter/vf_extractplanes.c
> @@ -171,8 +171,8 @@ static int config_output(AVFilterLink *outlink)
> const int output = outlink->srcpad - ctx->output_pads;
>
> if (e->map[output] == 1 || e->map[output] == 2) {
> - outlink->h = inlink->h >> desc->log2_chroma_h;
> - outlink->w = inlink->w >> desc->log2_chroma_w;
> + outlink->h = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
> + outlink->w = FF_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
> }
>
> return 0;
> diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
> index 4dbd4c7..4f7039e 100644
> --- a/libavfilter/vf_fade.c
> +++ b/libavfilter/vf_fade.c
> @@ -233,8 +233,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
> /* chroma planes */
> for (plane = 1; plane < 3; plane++) {
> for (i = 0; i < frame->height; i++) {
> + const int width = FF_CEIL_RSHIFT(inlink->w, fade->hsub);
> p = frame->data[plane] + (i >> fade->vsub) * frame->linesize[plane];
> - for (j = 0; j < inlink->w >> fade->hsub; j++) {
> + for (j = 0; j < width; j++) {
> /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
> * representation of 128.5. The .5 is for rounding
> * purposes. */
> diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c
> index 3495895..3a6f806 100644
> --- a/libavfilter/vf_fieldmatch.c
> +++ b/libavfilter/vf_fieldmatch.c
> @@ -153,12 +153,12 @@ AVFILTER_DEFINE_CLASS(fieldmatch);
>
> static int get_width(const FieldMatchContext *fm, const AVFrame *f, int plane)
> {
> - return plane ? f->width >> fm->hsub : f->width;
> + return plane ? FF_CEIL_RSHIFT(f->width, fm->hsub) : f->width;
> }
>
> static int get_height(const FieldMatchContext *fm, const AVFrame *f, int plane)
> {
> - return plane ? f->height >> fm->vsub : f->height;
> + return plane ? FF_CEIL_RSHIFT(f->height, fm->vsub) : f->height;
> }
>
> static int64_t luma_abs_diff(const AVFrame *f1, const AVFrame *f2)
> @@ -270,8 +270,8 @@ static int calc_combed_score(const FieldMatchContext *fm, const AVFrame *src)
> uint8_t *cmkp = fm->cmask_data[0];
> uint8_t *cmkpU = fm->cmask_data[1];
> uint8_t *cmkpV = fm->cmask_data[2];
> - const int width = src->width >> fm->hsub;
> - const int height = src->height >> fm->vsub;
> + const int width = FF_CEIL_RSHIFT(src->width, fm->hsub);
> + const int height = FF_CEIL_RSHIFT(src->height, fm->vsub);
> const int cmk_linesize = fm->cmask_linesize[0] << 1;
> const int cmk_linesizeUV = fm->cmask_linesize[2];
> uint8_t *cmkpp = cmkp - (cmk_linesize>>1);
> diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
> index a5396f8..5ee75d1 100644
> --- a/libavfilter/vf_geq.c
> +++ b/libavfilter/vf_geq.c
> @@ -66,8 +66,8 @@ static inline double getpix(void *priv, double x, double y, int plane)
> AVFrame *picref = geq->picref;
> const uint8_t *src = picref->data[plane];
> const int linesize = picref->linesize[plane];
> - const int w = picref->width >> ((plane == 1 || plane == 2) ? geq->hsub : 0);
> - const int h = picref->height >> ((plane == 1 || plane == 2) ? geq->vsub : 0);
> + const int w = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(picref->width, geq->hsub) : picref->width;
> + const int h = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(picref->height, geq->vsub) : picref->height;
>
> if (!src)
> return 0;
> @@ -209,8 +209,8 @@ static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in)
> int x, y;
> uint8_t *dst = out->data[plane];
> const int linesize = out->linesize[plane];
> - const int w = inlink->w >> ((plane == 1 || plane == 2) ? geq->hsub : 0);
> - const int h = inlink->h >> ((plane == 1 || plane == 2) ? geq->vsub : 0);
> + const int w = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->w, geq->hsub) : inlink->w;
> + const int h = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, geq->vsub) : inlink->h;
>
> values[VAR_W] = w;
> values[VAR_H] = h;
> diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
> index cb51981..0250b43 100644
> --- a/libavfilter/vf_hflip.c
> +++ b/libavfilter/vf_hflip.c
> @@ -77,7 +77,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> AVFilterLink *outlink = ctx->outputs[0];
> AVFrame *out;
> uint8_t *inrow, *outrow;
> - int i, j, plane, step, hsub, vsub;
> + int i, j, plane, step;
>
> out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
> if (!out) {
> @@ -91,16 +91,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> memcpy(out->data[1], in->data[1], AVPALETTE_SIZE);
>
> for (plane = 0; plane < 4 && in->data[plane]; plane++) {
> + const int width = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->w, flip->hsub) : inlink->w;
> + const int height = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, flip->vsub) : inlink->h;
> step = flip->max_step[plane];
> - hsub = (plane == 1 || plane == 2) ? flip->hsub : 0;
> - vsub = (plane == 1 || plane == 2) ? flip->vsub : 0;
>
> outrow = out->data[plane];
> - inrow = in ->data[plane] + ((inlink->w >> hsub) - 1) * step;
> - for (i = 0; i < in->height >> vsub; i++) {
> + inrow = in ->data[plane] + (width - 1) * step;
> + for (i = 0; i < height; i++) {
> switch (step) {
> case 1:
> - for (j = 0; j < (inlink->w >> hsub); j++)
> + for (j = 0; j < width; j++)
> outrow[j] = inrow[-j];
> break;
>
> @@ -108,7 +108,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> {
> uint16_t *outrow16 = (uint16_t *)outrow;
> uint16_t * inrow16 = (uint16_t *) inrow;
> - for (j = 0; j < (inlink->w >> hsub); j++)
> + for (j = 0; j < width; j++)
> outrow16[j] = inrow16[-j];
> }
> break;
> @@ -117,7 +117,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> {
> uint8_t *in = inrow;
> uint8_t *out = outrow;
> - for (j = 0; j < (inlink->w >> hsub); j++, out += 3, in -= 3) {
> + for (j = 0; j < width; j++, out += 3, in -= 3) {
> int32_t v = AV_RB24(in);
> AV_WB24(out, v);
> }
> @@ -128,13 +128,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> {
> uint32_t *outrow32 = (uint32_t *)outrow;
> uint32_t * inrow32 = (uint32_t *) inrow;
> - for (j = 0; j < (inlink->w >> hsub); j++)
> + for (j = 0; j < width; j++)
> outrow32[j] = inrow32[-j];
> }
> break;
>
> default:
> - for (j = 0; j < (inlink->w >> hsub); j++)
> + for (j = 0; j < width; j++)
> memcpy(outrow + j*step, inrow - j*step, step);
> }
>
> diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
> index 51adeb8..8e8f553 100644
> --- a/libavfilter/vf_hqdn3d.c
> +++ b/libavfilter/vf_hqdn3d.c
> @@ -297,8 +297,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> for (c = 0; c < 3; c++) {
> denoise(hqdn3d, in->data[c], out->data[c],
> hqdn3d->line, &hqdn3d->frame_prev[c],
> - in->width >> (!!c * hqdn3d->hsub),
> - in->height >> (!!c * hqdn3d->vsub),
> + FF_CEIL_RSHIFT(in->width, (!!c * hqdn3d->hsub)),
> + FF_CEIL_RSHIFT(in->height, (!!c * hqdn3d->vsub)),
> in->linesize[c], out->linesize[c],
> hqdn3d->coefs[c?2:0], hqdn3d->coefs[c?3:1]);
> }
> diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
> index c62cba8..cba39d0 100644
> --- a/libavfilter/vf_hue.c
> +++ b/libavfilter/vf_hue.c
> @@ -305,7 +305,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
>
> process_chrominance(outpic->data[1], outpic->data[2], outpic->linesize[1],
> inpic->data[1], inpic->data[2], inpic->linesize[1],
> - inlink->w >> hue->hsub, inlink->h >> hue->vsub,
> + FF_CEIL_RSHIFT(inlink->w, hue->hsub),
> + FF_CEIL_RSHIFT(inlink->h, hue->vsub),
> hue->hue_cos, hue->hue_sin);
>
> if (!direct)
> diff --git a/libavfilter/vf_il.c b/libavfilter/vf_il.c
> index 7edd042..783b91a 100644
> --- a/libavfilter/vf_il.c
> +++ b/libavfilter/vf_il.c
> @@ -110,7 +110,7 @@ static int config_input(AVFilterLink *inlink)
> if ((ret = av_image_fill_linesizes(il->linesize, inlink->format, inlink->w)) < 0)
> return ret;
>
> - il->chroma_height = inlink->h >> desc->log2_chroma_h;
> + il->chroma_height = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
>
> return 0;
> }
> diff --git a/libavfilter/vf_interlace.c b/libavfilter/vf_interlace.c
> index 3e787ab..3315fb0 100644
> --- a/libavfilter/vf_interlace.c
> +++ b/libavfilter/vf_interlace.c
> @@ -131,7 +131,7 @@ static void copy_picture_field(AVFrame *src_frame, AVFrame *dst_frame,
> int plane, i, j;
>
> for (plane = 0; plane < desc->nb_components; plane++) {
> - int lines = (plane == 1 || plane == 2) ? inlink->h >> vsub : inlink->h;
> + int lines = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
> int linesize = av_image_get_linesize(inlink->format, inlink->w, plane);
> uint8_t *dstp = dst_frame->data[plane];
> const uint8_t *srcp = src_frame->data[plane];
> diff --git a/libavfilter/vf_kerndeint.c b/libavfilter/vf_kerndeint.c
> index 8a44868..431a0a9 100644
> --- a/libavfilter/vf_kerndeint.c
> +++ b/libavfilter/vf_kerndeint.c
> @@ -151,7 +151,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
> outpic->interlaced_frame = 0;
>
> for (plane = 0; inpic->data[plane] && plane < 4; plane++) {
> - h = plane == 0 ? inlink->h : inlink->h >> kerndeint->vsub;
> + h = plane == 0 ? inlink->h : FF_CEIL_RSHIFT(inlink->h, kerndeint->vsub);
> bwidth = kerndeint->tmp_bwidth[plane];
>
> srcp = srcp_saved = inpic->data[plane];
> diff --git a/libavfilter/vf_mpdecimate.c b/libavfilter/vf_mpdecimate.c
> index 2e386f7..45d510b 100644
> --- a/libavfilter/vf_mpdecimate.c
> +++ b/libavfilter/vf_mpdecimate.c
> @@ -122,7 +122,8 @@ static int decimate_frame(AVFilterContext *ctx,
> int hsub = plane == 1 || plane == 2 ? decimate->hsub : 0;
> if (diff_planes(ctx,
> cur->data[plane], ref->data[plane], ref->linesize[plane],
> - ref->width>>hsub, ref->height>>vsub))
> + FF_CEIL_RSHIFT(ref->width, hsub),
> + FF_CEIL_RSHIFT(ref->height, vsub)))
> return 0;
> }
>
> diff --git a/libavfilter/vf_noise.c b/libavfilter/vf_noise.c
> index c965cbf..da418fe 100644
> --- a/libavfilter/vf_noise.c
> +++ b/libavfilter/vf_noise.c
> @@ -193,7 +193,7 @@ static int config_input(AVFilterLink *inlink)
> if ((ret = av_image_fill_linesizes(n->linesize, inlink->format, inlink->w)) < 0)
> return ret;
>
> - n->height[1] = n->height[2] = inlink->h >> desc->log2_chroma_h;
> + n->height[1] = n->height[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
> n->height[0] = n->height[3] = inlink->h;
>
> return 0;
> diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
> index dd97843..9acadcf 100644
> --- a/libavfilter/vf_showinfo.c
> +++ b/libavfilter/vf_showinfo.c
> @@ -46,7 +46,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
> for (plane = 0; plane < 4 && frame->data[plane]; plane++) {
> int64_t linesize = av_image_get_linesize(frame->format, frame->width, plane);
> uint8_t *data = frame->data[plane];
> - int h = plane == 1 || plane == 2 ? inlink->h >> vsub : inlink->h;
> + int h = plane == 1 || plane == 2 ? FF_CEIL_RSHIFT(inlink->h, vsub) : inlink->h;
>
> if (linesize < 0)
> return linesize;
> diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c
> index 4dd1664..daf7451 100644
> --- a/libavfilter/vf_smartblur.c
> +++ b/libavfilter/vf_smartblur.c
> @@ -166,7 +166,8 @@ static int config_props(AVFilterLink *inlink)
>
> alloc_sws_context(&sblur->luma, inlink->w, inlink->h, sblur->sws_flags);
> alloc_sws_context(&sblur->chroma,
> - inlink->w >> sblur->hsub, inlink->h >> sblur->vsub,
> + FF_CEIL_RSHIFT(inlink->w, sblur->hsub),
> + FF_CEIL_RSHIFT(inlink->h, sblur->vsub),
> sblur->sws_flags);
>
> return 0;
> @@ -241,8 +242,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
> SmartblurContext *sblur = inlink->dst->priv;
> AVFilterLink *outlink = inlink->dst->outputs[0];
> AVFrame *outpic;
> - int cw = inlink->w >> sblur->hsub;
> - int ch = inlink->h >> sblur->vsub;
> + int cw = FF_CEIL_RSHIFT(inlink->w, sblur->hsub);
> + int ch = FF_CEIL_RSHIFT(inlink->h, sblur->vsub);
>
> outpic = ff_get_video_buffer(outlink, outlink->w, outlink->h);
> if (!outpic) {
> diff --git a/libavfilter/vf_telecine.c b/libavfilter/vf_telecine.c
> index e30f357..ba47da1 100644
> --- a/libavfilter/vf_telecine.c
> +++ b/libavfilter/vf_telecine.c
> @@ -129,7 +129,7 @@ static int config_input(AVFilterLink *inlink)
> if ((ret = av_image_fill_linesizes(tc->stride, inlink->format, inlink->w)) < 0)
> return ret;
>
> - tc->planeheight[1] = tc->planeheight[2] = inlink->h >> desc->log2_chroma_h;
> + tc->planeheight[1] = tc->planeheight[2] = FF_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
> tc->planeheight[0] = tc->planeheight[3] = inlink->h;
>
> tc->nb_planes = av_pix_fmt_count_planes(inlink->format);
> diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
> index f6bf054..5e89162 100644
> --- a/libavfilter/vf_tinterlace.c
> +++ b/libavfilter/vf_tinterlace.c
> @@ -130,7 +130,7 @@ static int config_out_props(AVFilterLink *outlink)
>
> /* fill black picture with black */
> for (i = 0; i < 4 && tinterlace->black_data[i]; i++) {
> - int h = i == 1 || i == 2 ? outlink->h >> desc->log2_chroma_h : outlink->h;
> + int h = i == 1 || i == 2 ? FF_CEIL_RSHIFT(outlink->h, desc->log2_chroma_h) : outlink->h;
> memset(tinterlace->black_data[i], black[i],
> tinterlace->black_linesize[i] * h);
> }
> diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
> index bd66a61..c949e07 100644
> --- a/libavfilter/vf_transpose.c
> +++ b/libavfilter/vf_transpose.c
> @@ -163,8 +163,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> int vsub = plane == 1 || plane == 2 ? trans->vsub : 0;
> int pixstep = trans->pixsteps[plane];
> int inh = in->height >> vsub;
> - int outw = out->width >> hsub;
> - int outh = out->height >> vsub;
> + int outw = FF_CEIL_RSHIFT(out->width, hsub);
> + int outh = FF_CEIL_RSHIFT(out->height, vsub);
> uint8_t *dst, *src;
> int dstlinesize, srclinesize;
> int x, y;
Should be fine, assuming that FATE passes.
--
FFmpeg = Furious and Fast Martial Powered Elitist Gadget
More information about the ffmpeg-devel
mailing list