mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 20:42:30 +00:00
dvbsuboverlay: remove unnecessary RGB -> YUV conversion by using YUV palettes
the default CLUTs still use RGB -> YUV conversions since the standard defines them as RGBA values.
This commit is contained in:
parent
f63a67ebfb
commit
994156c1b8
2 changed files with 75 additions and 137 deletions
|
@ -33,7 +33,6 @@
|
||||||
#include <string.h> /* memset */
|
#include <string.h> /* memset */
|
||||||
#include <gst/gstutils.h> /* GST_READ_UINT16_BE */
|
#include <gst/gstutils.h> /* GST_READ_UINT16_BE */
|
||||||
#include <gst/base/gstbitreader.h> /* GstBitReader */
|
#include <gst/base/gstbitreader.h> /* GstBitReader */
|
||||||
#include "ffmpeg-colorspace.h" /* YUV_TO_RGB1_CCIR */ /* FIXME: Just give YUV data to gstreamer then? */
|
|
||||||
|
|
||||||
#include "dvb-sub.h"
|
#include "dvb-sub.h"
|
||||||
|
|
||||||
|
@ -55,13 +54,10 @@ static void dvb_sub_init (void);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_NEG_CROP 1024
|
#define MAX_NEG_CROP 1024
|
||||||
static guint8 ff_cropTbl[256 + 2 * MAX_NEG_CROP] = { 0, };
|
|
||||||
|
|
||||||
#define cm (ff_cropTbl + MAX_NEG_CROP)
|
#define AYUV(y,u,v,a) (((a) << 24) | ((y) << 16) | ((u) << 8) | (v))
|
||||||
|
#define RGBA_TO_AYUV(r,g,b,a) (((a) << 24) | ((rgb_to_y(r,g,b)) << 16) | ((rgb_to_u(r,g,b)) << 8) | (rgb_to_v(r,g,b)))
|
||||||
|
|
||||||
/* FIXME: This is really ARGB... We might need this configurable for performant
|
|
||||||
* FIXME: use in GStreamer as well if that likes RGBA more (Qt prefers ARGB) */
|
|
||||||
#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
|
|
||||||
|
|
||||||
typedef struct DVBSubCLUT
|
typedef struct DVBSubCLUT
|
||||||
{
|
{
|
||||||
|
@ -156,6 +152,40 @@ typedef enum
|
||||||
BOTTOM_FIELD = 1
|
BOTTOM_FIELD = 1
|
||||||
} DvbSubPixelDataSubBlockFieldType;
|
} DvbSubPixelDataSubBlockFieldType;
|
||||||
|
|
||||||
|
static inline gint
|
||||||
|
rgb_to_y (gint r, gint g, gint b)
|
||||||
|
{
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
ret = (gint) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16));
|
||||||
|
ret = CLAMP (ret, 0, 255);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gint
|
||||||
|
rgb_to_u (gint r, gint g, gint b)
|
||||||
|
{
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
ret =
|
||||||
|
(gint) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) +
|
||||||
|
128);
|
||||||
|
ret = CLAMP (ret, 0, 255);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gint
|
||||||
|
rgb_to_v (gint r, gint g, gint b)
|
||||||
|
{
|
||||||
|
gint ret;
|
||||||
|
|
||||||
|
ret =
|
||||||
|
(gint) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) +
|
||||||
|
128);
|
||||||
|
ret = CLAMP (ret, 0, 255);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static DVBSubObject *
|
static DVBSubObject *
|
||||||
get_object (DvbSub * dvb_sub, guint16 object_id)
|
get_object (DvbSub * dvb_sub, guint16 object_id)
|
||||||
{
|
{
|
||||||
|
@ -263,20 +293,6 @@ delete_state (DvbSub * dvb_sub)
|
||||||
g_warn_if_fail (dvb_sub->object_list == NULL);
|
g_warn_if_fail (dvb_sub->object_list == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init static data necessary for ffmpeg-colorspace conversion */
|
|
||||||
static void
|
|
||||||
dsputil_static_init (void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
ff_cropTbl[i + MAX_NEG_CROP] = i;
|
|
||||||
for (i = 0; i < MAX_NEG_CROP; i++) {
|
|
||||||
ff_cropTbl[i] = 0;
|
|
||||||
ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dvb_sub_init (void)
|
dvb_sub_init (void)
|
||||||
{
|
{
|
||||||
|
@ -284,19 +300,17 @@ dvb_sub_init (void)
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (dvbsub_debug, "dvbsub", 0, "dvbsuboverlay parser");
|
GST_DEBUG_CATEGORY_INIT (dvbsub_debug, "dvbsub", 0, "dvbsuboverlay parser");
|
||||||
|
|
||||||
dsputil_static_init (); /* Initializes ff_cropTbl table, used in YUV_TO_RGB conversion */
|
|
||||||
|
|
||||||
/* Initialize the static default_clut structure, from which other clut
|
/* Initialize the static default_clut structure, from which other clut
|
||||||
* structures are initialized from (to start off with default CLUTs
|
* structures are initialized from (to start off with default CLUTs
|
||||||
* as defined in the specification). */
|
* as defined in the specification). */
|
||||||
default_clut.id = -1;
|
default_clut.id = -1;
|
||||||
|
|
||||||
default_clut.clut4[0] = RGBA (0, 0, 0, 0);
|
default_clut.clut4[0] = RGBA_TO_AYUV (0, 0, 0, 0);
|
||||||
default_clut.clut4[1] = RGBA (255, 255, 255, 255);
|
default_clut.clut4[1] = RGBA_TO_AYUV (255, 255, 255, 255);
|
||||||
default_clut.clut4[2] = RGBA (0, 0, 0, 255);
|
default_clut.clut4[2] = RGBA_TO_AYUV (0, 0, 0, 255);
|
||||||
default_clut.clut4[3] = RGBA (127, 127, 127, 255);
|
default_clut.clut4[3] = RGBA_TO_AYUV (127, 127, 127, 255);
|
||||||
|
|
||||||
default_clut.clut16[0] = RGBA (0, 0, 0, 0);
|
default_clut.clut16[0] = RGBA_TO_AYUV (0, 0, 0, 0);
|
||||||
for (i = 1; i < 16; i++) {
|
for (i = 1; i < 16; i++) {
|
||||||
if (i < 8) {
|
if (i < 8) {
|
||||||
r = (i & 1) ? 255 : 0;
|
r = (i & 1) ? 255 : 0;
|
||||||
|
@ -307,10 +321,10 @@ dvb_sub_init (void)
|
||||||
g = (i & 2) ? 127 : 0;
|
g = (i & 2) ? 127 : 0;
|
||||||
b = (i & 4) ? 127 : 0;
|
b = (i & 4) ? 127 : 0;
|
||||||
}
|
}
|
||||||
default_clut.clut16[i] = RGBA (r, g, b, 255);
|
default_clut.clut16[i] = RGBA_TO_AYUV (r, g, b, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
default_clut.clut256[0] = RGBA (0, 0, 0, 0);
|
default_clut.clut256[0] = RGBA_TO_AYUV (0, 0, 0, 0);
|
||||||
for (i = 1; i < 256; i++) {
|
for (i = 1; i < 256; i++) {
|
||||||
if (i < 8) {
|
if (i < 8) {
|
||||||
r = (i & 1) ? 255 : 0;
|
r = (i & 1) ? 255 : 0;
|
||||||
|
@ -345,7 +359,7 @@ dvb_sub_init (void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default_clut.clut256[i] = RGBA (r, g, b, a);
|
default_clut.clut256[i] = RGBA_TO_AYUV (r, g, b, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,7 +578,6 @@ _dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||||
DVBSubCLUT *clut;
|
DVBSubCLUT *clut;
|
||||||
int entry_id, depth, full_range;
|
int entry_id, depth, full_range;
|
||||||
int y, cr, cb, alpha;
|
int y, cr, cb, alpha;
|
||||||
int r, g, b, r_add, g_add, b_add;
|
|
||||||
|
|
||||||
GST_MEMDUMP ("DVB clut packet", buf, buf_size);
|
GST_MEMDUMP ("DVB clut packet", buf, buf_size);
|
||||||
|
|
||||||
|
@ -613,18 +626,15 @@ _dvb_sub_parse_clut_segment (DvbSub * dvb_sub, guint16 page_id, guint8 * buf,
|
||||||
if (y == 0)
|
if (y == 0)
|
||||||
alpha = 0xff;
|
alpha = 0xff;
|
||||||
|
|
||||||
YUV_TO_RGB1_CCIR (cb, cr);
|
GST_DEBUG ("CLUT DEFINITION: clut %d := (%d,%d,%d,%d)", entry_id, y, cb, cr,
|
||||||
YUV_TO_RGB2_CCIR (r, g, b, y);
|
|
||||||
|
|
||||||
GST_DEBUG ("CLUT DEFINITION: clut %d := (%d,%d,%d,%d)", entry_id, r, g, b,
|
|
||||||
alpha);
|
alpha);
|
||||||
|
|
||||||
if (depth & 0x80)
|
if (depth & 0x80)
|
||||||
clut->clut4[entry_id] = RGBA (r, g, b, 255 - alpha);
|
clut->clut4[entry_id] = AYUV (y, cb, cr, 255 - alpha);
|
||||||
if (depth & 0x40)
|
if (depth & 0x40)
|
||||||
clut->clut16[entry_id] = RGBA (r, g, b, 255 - alpha);
|
clut->clut16[entry_id] = AYUV (y, cb, cr, 255 - alpha);
|
||||||
if (depth & 0x20)
|
if (depth & 0x20)
|
||||||
clut->clut256[entry_id] = RGBA (r, g, b, 255 - alpha);
|
clut->clut256[entry_id] = AYUV (y, cb, cr, 255 - alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -423,47 +423,11 @@ gst_dvbsub_overlay_getcaps (GstPad * pad)
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline gint
|
|
||||||
rgb_to_y (gint r, gint g, gint b)
|
|
||||||
{
|
|
||||||
gint ret;
|
|
||||||
|
|
||||||
ret = (gint) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16));
|
|
||||||
ret = CLAMP (ret, 0, 255);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gint
|
|
||||||
rgb_to_u (gint r, gint g, gint b)
|
|
||||||
{
|
|
||||||
gint ret;
|
|
||||||
|
|
||||||
ret =
|
|
||||||
(gint) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) +
|
|
||||||
128);
|
|
||||||
ret = CLAMP (ret, 0, 255);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline gint
|
|
||||||
rgb_to_v (gint r, gint g, gint b)
|
|
||||||
{
|
|
||||||
gint ret;
|
|
||||||
|
|
||||||
ret =
|
|
||||||
(gint) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) +
|
|
||||||
128);
|
|
||||||
ret = CLAMP (ret, 0, 255);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: DVB-SUB actually provides us AYUV from CLUT, but libdvbsub used to convert it to ARGB */
|
|
||||||
static void
|
static void
|
||||||
blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer)
|
blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
guint counter;
|
guint counter;
|
||||||
DVBSubtitleRect *sub_region;
|
DVBSubtitleRect *sub_region;
|
||||||
gint r, g, b;
|
|
||||||
gint a1, a2, a3, a4;
|
gint a1, a2, a3, a4;
|
||||||
gint y1, y2, y3, y4;
|
gint y1, y2, y3, y4;
|
||||||
gint u1, u2, u3, u4;
|
gint u1, u2, u3, u4;
|
||||||
|
@ -574,49 +538,33 @@ blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer)
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]];
|
sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]];
|
||||||
a1 = (color >> 24) & 0xff;
|
a1 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y1 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u1 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v1 = color & 0xff;
|
||||||
|
|
||||||
y1 = rgb_to_y (r, g, b);
|
|
||||||
u1 = rgb_to_u (r, g, b);
|
|
||||||
v1 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[(sy >> 16) * src_stride + ((sx +
|
sub_region->pict.palette[src[(sy >> 16) * src_stride + ((sx +
|
||||||
xstep) >> 16)]];
|
xstep) >> 16)]];
|
||||||
a2 = (color >> 24) & 0xff;
|
a2 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y2 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u2 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v2 = color & 0xff;
|
||||||
|
|
||||||
y2 = rgb_to_y (r, g, b);
|
|
||||||
u2 = rgb_to_u (r, g, b);
|
|
||||||
v2 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride +
|
sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride +
|
||||||
(sx >> 16)]];
|
(sx >> 16)]];
|
||||||
a3 = (color >> 24) & 0xff;
|
a3 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y3 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u3 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v3 = color & 0xff;
|
||||||
|
|
||||||
y3 = rgb_to_y (r, g, b);
|
|
||||||
u3 = rgb_to_u (r, g, b);
|
|
||||||
v3 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride +
|
sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride +
|
||||||
((sx + xstep) >> 16)]];
|
((sx + xstep) >> 16)]];
|
||||||
a4 = (color >> 24) & 0xff;
|
a4 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y4 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u4 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v4 = color & 0xff;
|
||||||
|
|
||||||
y4 = rgb_to_y (r, g, b);
|
|
||||||
u4 = rgb_to_u (r, g, b);
|
|
||||||
v4 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255;
|
dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255;
|
||||||
dst_y[1] = (a2 * y2 + (255 - a2) * dst_y[1]) / 255;
|
dst_y[1] = (a2 * y2 + (255 - a2) * dst_y[1]) / 255;
|
||||||
|
@ -641,25 +589,17 @@ blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer)
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]];
|
sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]];
|
||||||
a1 = (color >> 24) & 0xff;
|
a1 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y1 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u1 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v1 = color & 0xff;
|
||||||
|
|
||||||
y1 = rgb_to_y (r, g, b);
|
|
||||||
u1 = rgb_to_u (r, g, b);
|
|
||||||
v1 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride +
|
sub_region->pict.palette[src[((sy + ystep) >> 16) * src_stride +
|
||||||
(sx >> 16)]];
|
(sx >> 16)]];
|
||||||
a3 = (color >> 24) & 0xff;
|
a3 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y3 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u3 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v3 = color & 0xff;
|
||||||
|
|
||||||
y3 = rgb_to_y (r, g, b);
|
|
||||||
u3 = rgb_to_u (r, g, b);
|
|
||||||
v3 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255;
|
dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255;
|
||||||
dst_y2[0] = (a3 * y3 + (255 - a3) * dst_y2[0]) / 255;
|
dst_y2[0] = (a3 * y3 + (255 - a3) * dst_y2[0]) / 255;
|
||||||
|
@ -690,25 +630,17 @@ blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer)
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]];
|
sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]];
|
||||||
a1 = (color >> 24) & 0xff;
|
a1 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y1 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u1 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v1 = color & 0xff;
|
||||||
|
|
||||||
y1 = rgb_to_y (r, g, b);
|
|
||||||
u1 = rgb_to_u (r, g, b);
|
|
||||||
v1 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[(sy >> 16) * src_stride + ((sx +
|
sub_region->pict.palette[src[(sy >> 16) * src_stride + ((sx +
|
||||||
xstep) >> 16)]];
|
xstep) >> 16)]];
|
||||||
a2 = (color >> 24) & 0xff;
|
a2 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y2 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u2 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v2 = color & 0xff;
|
||||||
|
|
||||||
y2 = rgb_to_y (r, g, b);
|
|
||||||
u2 = rgb_to_u (r, g, b);
|
|
||||||
v2 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255;
|
dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255;
|
||||||
dst_y[1] = (a2 * y2 + (255 - a2) * dst_y[1]) / 255;
|
dst_y[1] = (a2 * y2 + (255 - a2) * dst_y[1]) / 255;
|
||||||
|
@ -728,13 +660,9 @@ blit_i420 (GstDVBSubOverlay * overlay, DVBSubtitles * subs, GstBuffer * buffer)
|
||||||
color =
|
color =
|
||||||
sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]];
|
sub_region->pict.palette[src[(sy >> 16) * src_stride + (sx >> 16)]];
|
||||||
a1 = (color >> 24) & 0xff;
|
a1 = (color >> 24) & 0xff;
|
||||||
r = (color >> 16) & 0xff;
|
y1 = (color >> 16) & 0xff;
|
||||||
g = (color >> 8) & 0xff;
|
u1 = (color >> 8) & 0xff;
|
||||||
b = color & 0xff;
|
v1 = color & 0xff;
|
||||||
|
|
||||||
y1 = rgb_to_y (r, g, b);
|
|
||||||
u1 = rgb_to_u (r, g, b);
|
|
||||||
v1 = rgb_to_v (r, g, b);
|
|
||||||
|
|
||||||
dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255;
|
dst_y[0] = (a1 * y1 + (255 - a1) * dst_y[0]) / 255;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue