[FFmpeg-devel] [PATCH]ffplay 2/2: Fix subtitle rendering for special cases
Björn Axelsson
gecko
Sun Feb 1 23:19:37 CET 2009
Second subtitle-related patch.
The ffplay.c subtitle renderer (blend_subrect) fails to handle some of the
special cases with odd widths, odd heights and/or odd positions. For
example it could insert an empty line, wraparound the subrect one pixel
vertically, misalign the UV components and generally make a mess of things.
This fix could have been smaller, since I didn't care to track down the
original error in the offset calculations. Instead I replaced the
calculations with an arguably simpler and seemingly more correct
implementation.
A sample that works better with this patch is
http://samples.mplayerhq.hu/MPEG-VOB/ClosedCaptions/Starship_Troopers.vob
--
Bj?rn Axelsson
-------------- next part --------------
Index: ffplay.c
===================================================================
--- ffplay.c.orig 2009-02-01 21:23:05.000000000 +0100
+++ ffplay.c 2009-02-01 21:23:11.000000000 +0100
@@ -434,8 +434,9 @@
static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
{
- int wrap, wrap3, width2, skip2;
int y, u, v, a, u1, v1, a1, w, h;
+ uint8_t *lum0, *cb0, *cr0;
+ const uint8_t *p0;
uint8_t *lum, *cb, *cr;
const uint8_t *p;
const uint32_t *pal;
@@ -445,22 +446,13 @@
dsth = av_clip(rect->h, 0, imgh);
dstx = av_clip(rect->x, 0, imgw - dstw);
dsty = av_clip(rect->y, 0, imgh - dsth);
- lum = dst->data[0] + dsty * dst->linesize[0];
- cb = dst->data[1] + (dsty >> 1) * dst->linesize[1];
- cr = dst->data[2] + (dsty >> 1) * dst->linesize[2];
-
- width2 = (dstw + 1) >> 1;
- skip2 = dstx >> 1;
- wrap = dst->linesize[0];
- wrap3 = rect->pict.linesize[0];
- p = rect->pict.data[0];
+ lum = lum0 = dst->data[0] + dsty * dst->linesize[0] + dstx;
+ cb = cb0 = dst->data[1] + (dsty >> 1) * dst->linesize[1] + (dstx >> 1);
+ cr = cr0 = dst->data[2] + (dsty >> 1) * dst->linesize[2] + (dstx >> 1);
+ p = p0 = rect->pict.data[0];
pal = (const uint32_t *)rect->pict.data[1]; /* Now in YCrCb! */
if (dsty & 1) {
- lum += dstx;
- cb += skip2;
- cr += skip2;
-
if (dstx & 1) {
YUVA_IN(y, u, v, a, p, pal);
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
@@ -496,35 +488,33 @@
cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
}
- p += wrap3 + (wrap3 - dstw * BPP);
- lum += wrap + (wrap - dstw - dstx);
- cb += dst->linesize[1] - width2 - skip2;
- cr += dst->linesize[2] - width2 - skip2;
+ p0 += rect->pict.linesize[0];
+ lum0 += dst->linesize[0];
+ cb0 += dst->linesize[1];
+ cr0 += dst->linesize[2];
}
for(h = dsth - (dsty & 1); h >= 2; h -= 2) {
- lum += dstx;
- cb += skip2;
- cr += skip2;
-
+ lum = lum0;
+ cb = cb0;
+ cr = cr0;
+ p = p0;
if (dstx & 1) {
YUVA_IN(y, u, v, a, p, pal);
u1 = u;
v1 = v;
a1 = a;
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- p += wrap3;
- lum += wrap;
- YUVA_IN(y, u, v, a, p, pal);
+ YUVA_IN(y, u, v, a, p + rect->pict.linesize[0], pal);
u1 += u;
v1 += v;
a1 += a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ lum[dst->linesize[0]] = ALPHA_BLEND(a, lum[dst->linesize[0]], y, 0);
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
cb++;
cr++;
- p += -wrap3 + BPP;
- lum += -wrap + 1;
+ p += BPP;
+ lum++;
}
for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
YUVA_IN(y, u, v, a, p, pal);
@@ -538,28 +528,25 @@
v1 += v;
a1 += a;
lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
- p += wrap3;
- lum += wrap;
- YUVA_IN(y, u, v, a, p, pal);
+ YUVA_IN(y, u, v, a, p + rect->pict.linesize[0], pal);
u1 += u;
v1 += v;
a1 += a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ lum[dst->linesize[0]] = ALPHA_BLEND(a, lum[dst->linesize[0]], y, 0);
- YUVA_IN(y, u, v, a, p + BPP, pal);
+ YUVA_IN(y, u, v, a, p + BPP + rect->pict.linesize[0], pal);
u1 += u;
v1 += v;
a1 += a;
- lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
-
+ lum[dst->linesize[0] + 1] = ALPHA_BLEND(a, lum[dst->linesize[0] + 1], y, 0);
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
cb++;
cr++;
- p += -wrap3 + 2 * BPP;
- lum += -wrap + 2;
+ p += 2 * BPP;
+ lum += 2;
}
if (w) {
YUVA_IN(y, u, v, a, p, pal);
@@ -567,65 +554,59 @@
v1 = v;
a1 = a;
lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- p += wrap3;
- lum += wrap;
- YUVA_IN(y, u, v, a, p, pal);
+ YUVA_IN(y, u, v, a, p + rect->pict.linesize[0], pal);
u1 += u;
v1 += v;
a1 += a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ lum[dst->linesize[0]] = ALPHA_BLEND(a, lum[dst->linesize[0]], y, 0);
cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
cb++;
cr++;
- p += -wrap3 + BPP;
- lum += -wrap + 1;
+ p += BPP;
+ lum++;
}
- p += wrap3 + (wrap3 - dstw * BPP);
- lum += wrap + (wrap - dstw - dstx);
- cb += dst->linesize[1] - width2 - skip2;
- cr += dst->linesize[2] - width2 - skip2;
+ p0 += rect->pict.linesize[0] << 1;
+ lum0 += dst->linesize[0] << 1;
+ cb0 += dst->linesize[1];
+ cr0 += dst->linesize[2];
}
/* handle odd height */
if (h) {
- lum += dstx;
- cb += skip2;
- cr += skip2;
-
if (dstx & 1) {
- YUVA_IN(y, u, v, a, p, pal);
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
- cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
- cb++;
- cr++;
- lum++;
- p += BPP;
+ YUVA_IN(y, u, v, a, p0, pal);
+ lum0[0] = ALPHA_BLEND(a, lum0[0], y, 0);
+ cb0[0] = ALPHA_BLEND(a >> 2, cb0[0], u, 0);
+ cr0[0] = ALPHA_BLEND(a >> 2, cr0[0], v, 0);
+ cb0++;
+ cr0++;
+ lum0++;
+ p0 += BPP;
}
for(w = dstw - (dstx & 1); w >= 2; w -= 2) {
- YUVA_IN(y, u, v, a, p, pal);
+ YUVA_IN(y, u, v, a, p0, pal);
u1 = u;
v1 = v;
a1 = a;
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+ lum0[0] = ALPHA_BLEND(a, lum0[0], y, 0);
- YUVA_IN(y, u, v, a, p + BPP, pal);
+ YUVA_IN(y, u, v, a, p0 + BPP, pal);
u1 += u;
v1 += v;
a1 += a;
- lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
- cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
- cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
- cb++;
- cr++;
- p += 2 * BPP;
- lum += 2;
+ lum0[1] = ALPHA_BLEND(a, lum0[1], y, 0);
+ cb0[0] = ALPHA_BLEND(a1 >> 2, cb0[0], u, 1);
+ cr0[0] = ALPHA_BLEND(a1 >> 2, cr0[0], v, 1);
+ cb0++;
+ cr0++;
+ p0 += 2 * BPP;
+ lum0 += 2;
}
if (w) {
- YUVA_IN(y, u, v, a, p, pal);
- lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
- cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
- cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+ YUVA_IN(y, u, v, a, p0, pal);
+ lum0[0] = ALPHA_BLEND(a, lum0[0], y, 0);
+ cb0[0] = ALPHA_BLEND(a >> 2, cb0[0], u, 0);
+ cr0[0] = ALPHA_BLEND(a >> 2, cr0[0], v, 0);
}
}
}
More information about the ffmpeg-devel
mailing list