lavfi: use ceil right shift for chroma width/height.

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.
This commit is contained in:
Clément Bœsch 2013-05-09 17:59:38 +02:00
parent d751a2526f
commit 50e66726a2
21 changed files with 50 additions and 44 deletions

View 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];

View 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 };

View 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;

View 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);
}

View 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;

View 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. */

View 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);

View 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;

View 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);
}

View 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]);
}

View 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)

View 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;
}

View 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];

View 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];

View 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;
}

View 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;

View 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;

View 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) {

View 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);

View 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);
}

View 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;