fix videoscale stride bugs

Original commit message from CVS:
fix videoscale stride bugs
This commit is contained in:
Thomas Vander Stichele 2004-07-26 16:49:19 +00:00
parent 20ed00a9a0
commit bf81a3702a
2 changed files with 94 additions and 55 deletions

View file

@ -1,3 +1,19 @@
2004-07-26 Thomas Vander Stichele <thomas at apestaart dot org>
* gst/videoscale/videoscale.c: (gst_videoscale_setup),
(gst_videoscale_planar411), (gst_videoscale_planar400),
(gst_videoscale_packed422), (gst_videoscale_packed422rev),
(gst_videoscale_scale_nearest_str1),
(gst_videoscale_scale_nearest_str2),
(gst_videoscale_scale_nearest_str4),
(gst_videoscale_scale_nearest_16bit),
(gst_videoscale_scale_nearest_24bit):
fixed stride issues
tested with 320x240 -> 321, 322, 324 x240
tested with YV12, I420, YUY2, UYVY
fixed packed422rev (don't think it could have worked before)
by testing with UYVY
2004-07-26 Benjamin Otte <otte@gnome.org> 2004-07-26 Benjamin Otte <otte@gnome.org>
* ext/lame/gstlame.c: (gst_lame_sink_link), (gst_lame_init), * ext/lame/gstlame.c: (gst_lame_sink_link), (gst_lame_init),

View file

@ -67,11 +67,14 @@ static void gst_videoscale_16bit (GstVideoscale * scale, unsigned char *dest,
unsigned char *src); unsigned char *src);
static void gst_videoscale_scale_nearest_str1 (GstVideoscale * scale, static void gst_videoscale_scale_nearest_str1 (GstVideoscale * scale,
unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh); unsigned char *dest, unsigned char *src, int sw, int sh, int ss, int dw,
int dh, int ds);
static void gst_videoscale_scale_nearest_str2 (GstVideoscale * scale, static void gst_videoscale_scale_nearest_str2 (GstVideoscale * scale,
unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh); unsigned char *dest, unsigned char *src, int sw, int sh, int ss, int dw,
int dh, int ds);
static void gst_videoscale_scale_nearest_str4 (GstVideoscale * scale, static void gst_videoscale_scale_nearest_str4 (GstVideoscale * scale,
unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh); unsigned char *dest, unsigned char *src, int sw, int sh, int ss, int dw,
int dh, int ds);
static void gst_videoscale_scale_nearest_16bit (GstVideoscale * scale, static void gst_videoscale_scale_nearest_16bit (GstVideoscale * scale,
unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh); unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh);
static void gst_videoscale_scale_nearest_24bit (GstVideoscale * scale, static void gst_videoscale_scale_nearest_24bit (GstVideoscale * scale,
@ -289,25 +292,37 @@ gst_videoscale_planar411 (GstVideoscale * scale, unsigned char *dest,
int sh = scale->from_height; int sh = scale->from_height;
int dw = scale->to_width; int dw = scale->to_width;
int dh = scale->to_height; int dh = scale->to_height;
int ss, ds; /* strides */
GST_LOG_OBJECT (scale, "scaling planar 4:1:1 %dx%d to %dx%d", sw, sh, dw, dh); GST_LOG_OBJECT (scale, "scaling planar 4:1:1 %dx%d to %dx%d", sw, sh, dw, dh);
gst_videoscale_scale_nearest_str1 (scale, dest, src, sw, sh, dw, dh); /* Y */
src += sw * sh; ss = ROUND_UP_4 (sw);
dest += dw * dh; ds = ROUND_UP_4 (dw);
dh = dh >> 1; gst_videoscale_scale_nearest_str1 (scale, dest, src, sw, sh, ss, dw, dh, ds);
dw = dw >> 1;
sh = sh >> 1;
sw = sw >> 1;
gst_videoscale_scale_nearest_str1 (scale, dest, src, sw, sh, dw, dh); src += ss * sh;
dest += ds * dh;
src += sw * sh; /* Cb and Cr are 2x2, so divide widths and heights in half */
dest += dw * dh;
gst_videoscale_scale_nearest_str1 (scale, dest, src, sw, sh, dw, dh); /* we want to round up, so we add 1 before shifting */
dh = (dh + 1) >> 1;
dw = (dw + 1) >> 1;
sh = (sh + 1) >> 1;
sw = (sw + 1) >> 1;
ss = ROUND_UP_4 (sw);
ds = ROUND_UP_4 (dw);
gst_videoscale_scale_nearest_str1 (scale, dest, src, sw, sh, ss, dw, dh, ds);
src += ss * sh;
dest += ds * dh;
gst_videoscale_scale_nearest_str1 (scale, dest, src, sw, sh, ss, dw, dh, ds);
} }
static void static void
@ -318,10 +333,13 @@ gst_videoscale_planar400 (GstVideoscale * scale, unsigned char *dest,
int sh = scale->from_height; int sh = scale->from_height;
int dw = scale->to_width; int dw = scale->to_width;
int dh = scale->to_height; int dh = scale->to_height;
int ss, ds; /* strides */
GST_LOG_OBJECT (scale, "scaling Y-only %dx%d to %dx%d", sw, sh, dw, dh); GST_LOG_OBJECT (scale, "scaling Y-only %dx%d to %dx%d", sw, sh, dw, dh);
gst_videoscale_scale_nearest_str1 (scale, dest, src, sw, sh, dw, dh); ss = ROUND_UP_4 (sw);
ds = ROUND_UP_4 (dw);
gst_videoscale_scale_nearest_str1 (scale, dest, src, sw, sh, ss, dw, dh, ds);
} }
static void static void
@ -332,15 +350,20 @@ gst_videoscale_packed422 (GstVideoscale * scale, unsigned char *dest,
int sh = scale->from_height; int sh = scale->from_height;
int dw = scale->to_width; int dw = scale->to_width;
int dh = scale->to_height; int dh = scale->to_height;
int ss, ds; /* strides */
GST_LOG_OBJECT (scale, "scaling 4:2:2 %dx%d to %dx%d", sw, sh, dw, dh); GST_LOG_OBJECT (scale, "scaling 4:2:2 %dx%d to %dx%d", sw, sh, dw, dh);
gst_videoscale_scale_nearest_str2 (scale, dest, src, sw, sh, dw, dh); /* Y */
gst_videoscale_scale_nearest_str4 (scale, dest + 1, src + 1, sw / 2, sh, ss = ROUND_UP_4 (sw * 2);
dw / 2, dh); ds = ROUND_UP_4 (dw * 2);
gst_videoscale_scale_nearest_str4 (scale, dest + 3, src + 3, sw / 2, sh, gst_videoscale_scale_nearest_str2 (scale, dest, src, sw, sh, ss, dw, dh, ds);
dw / 2, dh);
/* Cb and Cr */
gst_videoscale_scale_nearest_str4 (scale, dest + 1, src + 1, sw / 2, sh, ss,
dw / 2, dh, ds);
gst_videoscale_scale_nearest_str4 (scale, dest + 3, src + 3, sw / 2, sh, ss,
dw / 2, dh, ds);
} }
static void static void
@ -351,15 +374,21 @@ gst_videoscale_packed422rev (GstVideoscale * scale, unsigned char *dest,
int sh = scale->from_height; int sh = scale->from_height;
int dw = scale->to_width; int dw = scale->to_width;
int dh = scale->to_height; int dh = scale->to_height;
int ss, ds; /* strides */
GST_LOG_OBJECT (scale, "scaling 4:2:2 %dx%d to %dx%d", sw, sh, dw, dh); GST_LOG_OBJECT (scale, "scaling 4:2:2 %dx%d to %dx%d", sw, sh, dw, dh);
gst_videoscale_scale_nearest_str2 (scale, dest + 1, src, sw, sh, dw, dh); /* Y */
gst_videoscale_scale_nearest_str4 (scale, dest, src + 1, sw / 2, sh, dw / 2, ss = ROUND_UP_4 (sw * 2);
dh); ds = ROUND_UP_4 (dw * 2);
gst_videoscale_scale_nearest_str4 (scale, dest + 2, src + 3, sw / 2, sh, gst_videoscale_scale_nearest_str2 (scale, dest + 1, src + 1, sw, sh, ss, dw,
dw / 2, dh); dh, ds);
/* Cb and Cr */
gst_videoscale_scale_nearest_str4 (scale, dest, src, sw / 2, sh, ss,
dw / 2, dh, ds);
gst_videoscale_scale_nearest_str4 (scale, dest + 2, src + 2, sw / 2, sh, ss,
dw / 2, dh, ds);
} }
static void static void
@ -567,13 +596,13 @@ gst_videoscale_scale_point_sample (GstVideoscale * scale, unsigned char *src,
static void static void
gst_videoscale_scale_nearest_str1 (GstVideoscale * scale, gst_videoscale_scale_nearest_str1 (GstVideoscale * scale,
unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh) unsigned char *dest, unsigned char *src, int sw, int sh, int ss,
int dw, int dh, int ds)
{ {
int ypos, yinc, y; int ypos, yinc, y;
int xpos, xinc, x; int xpos, xinc, x;
guchar *destp; guchar *destp;
guchar *srcp; guchar *srcp;
int sstride, dstride;
GST_LOG_OBJECT (scale, "scaling nearest from %p to %p with dest width %d", GST_LOG_OBJECT (scale, "scaling nearest from %p to %p with dest width %d",
src, dest, dw); src, dest, dw);
@ -581,12 +610,10 @@ gst_videoscale_scale_nearest_str1 (GstVideoscale * scale,
ypos = 0; ypos = 0;
yinc = (sh << 16) / dh; yinc = (sh << 16) / dh;
xinc = (sw << 16) / dw; xinc = (sw << 16) / dw;
sstride = sw;
dstride = dw;
for (y = dh; y; y--) { for (y = dh; y; y--) {
if (ypos >= 0x10000) { if (ypos >= 0x10000) {
src += (ypos >> 16) * sstride; src += (ypos >> 16) * ss;
ypos &= 0xffff; ypos &= 0xffff;
} }
@ -603,7 +630,7 @@ gst_videoscale_scale_nearest_str1 (GstVideoscale * scale,
*destp++ = *srcp; *destp++ = *srcp;
xpos += xinc; xpos += xinc;
} }
dest += dstride; dest += ds;
ypos += yinc; ypos += yinc;
} }
@ -611,13 +638,13 @@ gst_videoscale_scale_nearest_str1 (GstVideoscale * scale,
static void static void
gst_videoscale_scale_nearest_str2 (GstVideoscale * scale, gst_videoscale_scale_nearest_str2 (GstVideoscale * scale,
unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh) unsigned char *dest, unsigned char *src, int sw, int sh, int ss,
int dw, int dh, int ds)
{ {
int ypos, yinc, y; int ypos, yinc, y;
int xpos, xinc, x; int xpos, xinc, x;
guchar *destp; guchar *destp;
guchar *srcp; guchar *srcp;
int sstride, dstride;
GST_LOG_OBJECT (scale, "scaling nearest from %p to %p with dest width %d", GST_LOG_OBJECT (scale, "scaling nearest from %p to %p with dest width %d",
src, dest, dw); src, dest, dw);
@ -625,13 +652,11 @@ gst_videoscale_scale_nearest_str2 (GstVideoscale * scale,
ypos = 0; ypos = 0;
yinc = (sh << 16) / dh; yinc = (sh << 16) / dh;
xinc = (sw << 16) / dw; xinc = (sw << 16) / dw;
sstride = sw * 2;
dstride = dw * 2;
for (y = dh; y; y--) { for (y = dh; y; y--) {
if (ypos >= 0x10000) { if (ypos >= 0x10000) {
src += (ypos >> 16) * sstride; src += (ypos >> 16) * ss;
ypos &= 0xffff; ypos &= 0xffff;
} }
@ -649,7 +674,7 @@ gst_videoscale_scale_nearest_str2 (GstVideoscale * scale,
destp += 2; destp += 2;
xpos += xinc; xpos += xinc;
} }
dest += dstride; dest += ds;
ypos += yinc; ypos += yinc;
} }
@ -657,13 +682,13 @@ gst_videoscale_scale_nearest_str2 (GstVideoscale * scale,
static void static void
gst_videoscale_scale_nearest_str4 (GstVideoscale * scale, gst_videoscale_scale_nearest_str4 (GstVideoscale * scale,
unsigned char *dest, unsigned char *src, int sw, int sh, int dw, int dh) unsigned char *dest, unsigned char *src, int sw, int sh, int ss,
int dw, int dh, int ds)
{ {
int ypos, yinc, y; int ypos, yinc, y;
int xpos, xinc, x; int xpos, xinc, x;
guchar *destp; guchar *destp;
guchar *srcp; guchar *srcp;
int sstride, dstride;
GST_LOG_OBJECT (scale, "scaling nearest from %p to %p with dest width %d", GST_LOG_OBJECT (scale, "scaling nearest from %p to %p with dest width %d",
src, dest, dw); src, dest, dw);
@ -671,13 +696,11 @@ gst_videoscale_scale_nearest_str4 (GstVideoscale * scale,
ypos = 0; ypos = 0;
yinc = (sh << 16) / dh; yinc = (sh << 16) / dh;
xinc = (sw << 16) / dw; xinc = (sw << 16) / dw;
sstride = sw * 4;
dstride = dw * 4;
for (y = dh; y; y--) { for (y = dh; y; y--) {
if (ypos >= 0x10000) { if (ypos >= 0x10000) {
src += (ypos >> 16) * sstride; src += (ypos >> 16) * ss;
ypos &= 0xffff; ypos &= 0xffff;
} }
@ -695,7 +718,7 @@ gst_videoscale_scale_nearest_str4 (GstVideoscale * scale,
destp += 4; destp += 4;
xpos += xinc; xpos += xinc;
} }
dest += dstride; dest += ds;
ypos += yinc; ypos += yinc;
} }
@ -709,19 +732,19 @@ gst_videoscale_scale_nearest_16bit (GstVideoscale * scale,
int xpos, xinc, x; int xpos, xinc, x;
guchar *destp; guchar *destp;
guchar *srcp; guchar *srcp;
int sstride, dstride; /* row strides in bytes */ int ss, ds; /* row strides in bytes */
GST_LOG_OBJECT (scale, "scaling nearest from %p to %p, destination width %d", GST_LOG_OBJECT (scale, "scaling nearest from %p to %p, destination width %d",
src, dest, dw); src, dest, dw);
/* FIXME: strides should be gotten from caps; for now we do it Just Like /* FIXME: strides should be gotten from caps; for now we do it Just Like
videotestsrc, which means round off to next multiple of 4 bytes */ videotestsrc, which means round off to next multiple of 4 bytes */
sstride = sw * 2; ss = sw * 2;
if (sw % 2 == 1) if (sw % 2 == 1)
sstride += 2; ss += 2;
dstride = dw * 2; ds = dw * 2;
if (dw % 2 == 1) if (dw % 2 == 1)
dstride += 2; ds += 2;
ypos = 0; ypos = 0;
yinc = (sh << 16) / dh; /* 16 bit fixed point arithmetic */ yinc = (sh << 16) / dh; /* 16 bit fixed point arithmetic */
@ -731,7 +754,7 @@ gst_videoscale_scale_nearest_16bit (GstVideoscale * scale,
for (y = dh; y; y--) { /* faster than 0 .. dh */ for (y = dh; y; y--) { /* faster than 0 .. dh */
if (ypos >= 0x10000) { /* ypos >= 1 ? */ if (ypos >= 0x10000) { /* ypos >= 1 ? */
src += (ypos >> 16) * sstride; /* go down round(ypos) src lines */ src += (ypos >> 16) * ss; /* go down round(ypos) src lines */
ypos &= 0xffff; /* ypos %= 1 */ ypos &= 0xffff; /* ypos %= 1 */
} }
@ -751,7 +774,7 @@ gst_videoscale_scale_nearest_16bit (GstVideoscale * scale,
destp += 2; /* go right one destination pixel */ destp += 2; /* go right one destination pixel */
xpos += xinc; xpos += xinc;
} }
dest += dstride; /* go down one destination line */ dest += ds; /* go down one destination line */
ypos += yinc; ypos += yinc;
} }
@ -765,14 +788,14 @@ gst_videoscale_scale_nearest_24bit (GstVideoscale * scale,
int xpos, xinc, x; int xpos, xinc, x;
guchar *destp; guchar *destp;
guchar *srcp; guchar *srcp;
int sstride, dstride; /* row strides in bytes */ int ss, ds; /* row strides in bytes */
GST_LOG_OBJECT (scale, "scaling nearest %p %p %d", src, dest, dw); GST_LOG_OBJECT (scale, "scaling nearest %p %p %d", src, dest, dw);
/* FIXME: strides should be gotten from caps; for now we do it Just Like /* FIXME: strides should be gotten from caps; for now we do it Just Like
videotestsrc, which means round off to next multiple of 4 bytes */ videotestsrc, which means round off to next multiple of 4 bytes */
sstride = ROUND_UP_4 (sw * 3); ss = ROUND_UP_4 (sw * 3);
dstride = ROUND_UP_4 (dw * 3); ds = ROUND_UP_4 (dw * 3);
ypos = 0; ypos = 0;
yinc = (sh << 16) / dh; yinc = (sh << 16) / dh;
@ -781,7 +804,7 @@ gst_videoscale_scale_nearest_24bit (GstVideoscale * scale,
for (y = dh; y; y--) { for (y = dh; y; y--) {
if (ypos >= 0x10000) { if (ypos >= 0x10000) {
src += (ypos >> 16) * sstride; src += (ypos >> 16) * ss;
ypos &= 0xffff; ypos &= 0xffff;
} }
@ -801,7 +824,7 @@ gst_videoscale_scale_nearest_24bit (GstVideoscale * scale,
destp += 3; destp += 3;
xpos += xinc; xpos += xinc;
} }
dest += dstride; dest += ds;
ypos += yinc; ypos += yinc;
} }