diff options
author | Arnaud Vrac <avrac@freebox.fr> | 2015-04-07 14:38:08 +0200 |
---|---|---|
committer | Jan Schmidt <jan@centricular.com> | 2015-09-26 23:17:58 +1000 |
commit | dd3e9deb2aa695a391b58f24d86a3c00bbc1258a (patch) | |
tree | bb7670a36347452f8645e7f5e57d2be5949ebc04 /gst/dvdspu | |
parent | 5016a73190595505dc38b54f8f9a08c4f180f3a6 (diff) |
dvdspu: render to ARGB overlay instead of AYUV
https://bugzilla.gnome.org/show_bug.cgi?id=663750
Diffstat (limited to 'gst/dvdspu')
-rw-r--r-- | gst/dvdspu/gstdvdspu.c | 2 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-common.h | 15 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-pgs.c | 28 | ||||
-rw-r--r-- | gst/dvdspu/gstspu-vobsub-render.c | 43 |
4 files changed, 53 insertions, 35 deletions
diff --git a/gst/dvdspu/gstdvdspu.c b/gst/dvdspu/gstdvdspu.c index dd02d1c88..4fe1ac10b 100644 --- a/gst/dvdspu/gstdvdspu.c +++ b/gst/dvdspu/gstdvdspu.c @@ -716,7 +716,7 @@ gstspu_render_composition (GstDVDSpu * dvdspu) gint spu_w, spu_h; gsize size; - format = GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_YUV; + format = GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB; switch (dvdspu->spu_input_type) { case SPU_INPUT_TYPE_PGS: diff --git a/gst/dvdspu/gstspu-common.h b/gst/dvdspu/gstspu-common.h index 3107f29fc..1618384d0 100644 --- a/gst/dvdspu/gstspu-common.h +++ b/gst/dvdspu/gstspu-common.h @@ -39,19 +39,12 @@ struct SpuRect { gint16 bottom; }; -/* Store a pre-multiplied YUV colour value */ +/* Store a pre-multiplied ARGB colour value */ struct SpuColour { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN + guint8 B; + guint8 G; + guint8 R; guint8 A; - guint8 Y; - guint8 U; - guint8 V; -#else - guint8 V; - guint8 U; - guint8 Y; - guint8 A; -#endif }; G_END_DECLS diff --git a/gst/dvdspu/gstspu-pgs.c b/gst/dvdspu/gstspu-pgs.c index d727535ad..6a54e461b 100644 --- a/gst/dvdspu/gstspu-pgs.c +++ b/gst/dvdspu/gstspu-pgs.c @@ -319,9 +319,9 @@ pgs_composition_object_render (PgsCompositionObject * obj, SpuState * state, memcpy (pix, colour, sizeof (*pix)); } else { pix->A = colour->A; - pix->Y = colour->Y + pix->Y * inv_A / 255; - pix->U = colour->U + pix->U * inv_A / 255; - pix->V = colour->V + pix->V * inv_A / 255; + pix->R = colour->R + pix->R * inv_A / 255; + pix->G = colour->G + pix->G * inv_A / 255; + pix->B = colour->B + pix->B * inv_A / 255; } } } else { @@ -511,6 +511,7 @@ parse_set_palette (GstDVDSpu * dvdspu, guint8 type, guint8 * payload, state->pgs.palette[i].A = 0; for (i = 0; i < n_entries; i++) { guint8 n, Y, U, V, A; + gint R, G, B; n = payload[0]; Y = payload[1]; U = payload[2]; @@ -519,15 +520,26 @@ parse_set_palette (GstDVDSpu * dvdspu, guint8 type, guint8 * payload, #if DUMP_FULL_PALETTE PGS_DUMP ("Entry %3d: Y %3d U %3d V %3d A %3d ", n, Y, U, V, A); - if (((i + 1) % 2) == 0) - PGS_DUMP ("\n"); +#endif + + /* Convert to ARGB */ + R = (298 * Y + 459 * V - 63514) >> 8; + G = (298 * Y - 55 * U - 136 * V + 19681) >> 8; + B = (298 * Y + 541 * U - 73988) >> 8; + + R = CLAMP (R, 0, 255); + G = CLAMP (G, 0, 255); + B = CLAMP (B, 0, 255); + +#if DUMP_FULL_PALETTE + PGS_DUMP ("Entry %3d: A %3d R %3d G %3d B %3d\n", n, A, R, G, B); #endif /* Premultiply the palette entries by the alpha */ state->pgs.palette[n].A = A; - state->pgs.palette[n].Y = Y * A / 255; - state->pgs.palette[n].U = U * A / 255; - state->pgs.palette[n].V = V * A / 255; + state->pgs.palette[n].R = R * A / 255; + state->pgs.palette[n].G = G * A / 255; + state->pgs.palette[n].B = B * A / 255; payload += PGS_PALETTE_ENTRY_SIZE; } diff --git a/gst/dvdspu/gstspu-vobsub-render.c b/gst/dvdspu/gstspu-vobsub-render.c index 45dcabb20..583fd32e7 100644 --- a/gst/dvdspu/gstspu-vobsub-render.c +++ b/gst/dvdspu/gstspu-vobsub-render.c @@ -40,29 +40,42 @@ gstspu_vobsub_recalc_palette (GstDVDSpu * dvdspu, if (state->vobsub.current_clut[idx[0]] != 0) { for (i = 0; i < 4; i++, dest++) { guint32 col = state->vobsub.current_clut[idx[i]]; + gint A, Y, U, V; + gint R, G, B; /* Convert incoming 4-bit alpha to 8 bit for blending */ - dest->A = (alpha[i] << 4) | alpha[i]; - dest->Y = ((col >> 16) & 0xff) * dest->A / 255; + A = (alpha[i] << 4) | alpha[i]; + Y = ((col >> 16) & 0xff); /* U/V are stored as V/U in the clut words, so switch them */ - dest->V = ((col >> 8) & 0xff) * dest->A / 255; - dest->U = (col & 0xff) * dest->A / 255; + V = ((col >> 8) & 0xff); + U = (col & 0xff); + + R = (298 * Y + 459 * V - 63514) >> 8; + G = (298 * Y - 55 * U - 136 * V + 19681) >> 8; + B = (298 * Y + 541 * U - 73988) >> 8; + + R = CLAMP (R, 0, 255); + G = CLAMP (G, 0, 255); + B = CLAMP (B, 0, 255); + + dest->A = A; + dest->R = R * A / 255; + dest->G = G * A / 255; + dest->B = B * A / 255; } } else { - int y = 240; + int c = 255; /* The CLUT presumably hasn't been set, so we'll just guess some * values for the non-transparent colors (white, grey, black) */ for (i = 0; i < 4; i++, dest++) { dest->A = (alpha[i] << 4) | alpha[i]; if (alpha[i] != 0) { - dest[0].Y = y * dest[0].A / 255; - y -= 112; - if (y < 0) - y = 0; + dest->R = dest->G = dest->B = c * dest->A / 255; + c -= 128; + if (c < 0) + c = 0; } - dest[0].U = 128 * dest[0].A / 255; - dest[0].V = 128 * dest[0].A / 255; } } } @@ -173,7 +186,7 @@ gstspu_vobsub_draw_rle_run (SpuState * state, GstVideoFrame * frame, gint16 x, gint16 end, SpuColour * colour) { GST_TRACE ("Y: %d x: %d end %d %d %d %d %d", - state->vobsub.cur_Y, x, end, colour->Y, colour->U, colour->V, colour->A); + state->vobsub.cur_Y, x, end, colour->R, colour->G, colour->B, colour->A); if (colour->A > 0) { gint i; @@ -194,9 +207,9 @@ gstspu_vobsub_draw_rle_run (SpuState * state, GstVideoFrame * frame, memcpy (pix, colour, sizeof (*pix)); } else { pix->A = colour->A; - pix->Y = colour->Y + pix->Y * inv_A / 255; - pix->U = colour->U + pix->U * inv_A / 255; - pix->V = colour->V + pix->V * inv_A / 255; + pix->R = colour->R + pix->R * inv_A / 255; + pix->G = colour->G + pix->G * inv_A / 255; + pix->B = colour->B + pix->B * inv_A / 255; } } |