lavfi: use ceil right shift for chroma width/height.
authorClément Bœsch <ubitux@gmail.com>
Thu, 9 May 2013 15:59:38 +0000 (17:59 +0200)
committerClément Bœsch <ubitux@gmail.com>
Fri, 10 May 2013 15:20:06 +0000 (17:20 +0200)
This should fix several issues with odd dimensions inputs.

lut, vflip, pad and crop video filters also need to be checked for such
issues. It's possible sws is also affected.

21 files changed:
libavfilter/vf_blend.c
libavfilter/vf_boxblur.c
libavfilter/vf_decimate.c
libavfilter/vf_delogo.c
libavfilter/vf_extractplanes.c
libavfilter/vf_fade.c
libavfilter/vf_fieldmatch.c
libavfilter/vf_geq.c
libavfilter/vf_hflip.c
libavfilter/vf_hqdn3d.c
libavfilter/vf_hue.c
libavfilter/vf_il.c
libavfilter/vf_interlace.c
libavfilter/vf_kerndeint.c
libavfilter/vf_mpdecimate.c
libavfilter/vf_noise.c
libavfilter/vf_showinfo.c
libavfilter/vf_smartblur.c
libavfilter/vf_telecine.c
libavfilter/vf_tinterlace.c
libavfilter/vf_transpose.c

index b4c62ba..a0022cd 100644 (file)
@@ -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];
index b010670..a8a2014 100644 (file)
@@ -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 };
 
index 9548531..8767d5f 100644 (file)
@@ -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;
 
index c747b02..b644190 100644 (file)
@@ -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);
     }
index 229e3d5..9844ed5 100644 (file)
@@ -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;
index 4dbd4c7..4f7039e 100644 (file)
@@ -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. */
index 3495895..3a6f806 100644 (file)
@@ -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);
index a5396f8..5ee75d1 100644 (file)
@@ -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;
index cb51981..0250b43 100644 (file)
@@ -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);
             }
 
index 51adeb8..8e8f553 100644 (file)
@@ -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]);
     }
index c62cba8..cba39d0 100644 (file)
@@ -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)
index 7edd042..783b91a 100644 (file)
@@ -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;
 }
index 3e787ab..3315fb0 100644 (file)
@@ -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];
index 8a44868..431a0a9 100644 (file)
@@ -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];
index 2e386f7..45d510b 100644 (file)
@@ -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;
     }
 
index c965cbf..da418fe 100644 (file)
@@ -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;
index dd97843..9acadcf 100644 (file)
@@ -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;
index 4dd1664..daf7451 100644 (file)
@@ -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) {
index e30f357..ba47da1 100644 (file)
@@ -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);
index f6bf054..5e89162 100644 (file)
@@ -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);
         }
index bd66a61..c949e07 100644 (file)
@@ -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;