mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-08 18:39:54 +00:00
assrender: Fix I420 mode and enable it
This commit is contained in:
parent
5076cdc6f9
commit
77d0ded9ed
1 changed files with 134 additions and 97 deletions
|
@ -48,7 +48,8 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
|
||||||
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
|
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
|
||||||
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx)
|
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";"
|
||||||
|
GST_VIDEO_CAPS_YUV ("I420"))
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate video_sink_factory =
|
static GstStaticPadTemplate video_sink_factory =
|
||||||
|
@ -57,7 +58,8 @@ static GstStaticPadTemplate video_sink_factory =
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
|
||||||
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
|
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
|
||||||
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx)
|
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";"
|
||||||
|
GST_VIDEO_CAPS_YUV ("I420"))
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate text_sink_factory =
|
static GstStaticPadTemplate text_sink_factory =
|
||||||
|
@ -372,7 +374,7 @@ static void \
|
||||||
blit_##name (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer) \
|
blit_##name (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer) \
|
||||||
{ \
|
{ \
|
||||||
guint counter = 0; \
|
guint counter = 0; \
|
||||||
guint8 alpha, r, g, b, k; \
|
gint alpha, r, g, b, k; \
|
||||||
const guint8 *src; \
|
const guint8 *src; \
|
||||||
guint8 *dst; \
|
guint8 *dst; \
|
||||||
gint x, y, w, h; \
|
gint x, y, w, h; \
|
||||||
|
@ -402,7 +404,7 @@ blit_##name (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer) \
|
||||||
\
|
\
|
||||||
for (y = 0; y < h; y++) { \
|
for (y = 0; y < h; y++) { \
|
||||||
for (x = 0; x < w; x++) { \
|
for (x = 0; x < w; x++) { \
|
||||||
k = ((guint8) src[0]) * alpha / 255; \
|
k = src[0] * alpha / 255; \
|
||||||
dst[R] = (k * r + (255 - k) * dst[R]) / 255; \
|
dst[R] = (k * r + (255 - k) * dst[R]) / 255; \
|
||||||
dst[G] = (k * g + (255 - k) * dst[G]) / 255; \
|
dst[G] = (k * g + (255 - k) * dst[G]) / 255; \
|
||||||
dst[B] = (k * b + (255 - k) * dst[B]) / 255; \
|
dst[B] = (k * b + (255 - k) * dst[B]) / 255; \
|
||||||
|
@ -428,33 +430,48 @@ CREATE_RGB_BLIT_FUNCTION (bgrx, 4, 2, 1, 0);
|
||||||
|
|
||||||
#undef CREATE_RGB_BLIT_FUNCTION
|
#undef CREATE_RGB_BLIT_FUNCTION
|
||||||
|
|
||||||
#if 0
|
static inline gint
|
||||||
#define COMP_Y(ret, r, g, b) \
|
rgb_to_y (gint r, gint g, gint b)
|
||||||
{ \
|
{
|
||||||
ret = (int) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16)); \
|
gint ret;
|
||||||
ret = CLAMP (ret, 0, 255); \
|
|
||||||
|
ret = (gint) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16));
|
||||||
|
ret = CLAMP (ret, 0, 255);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COMP_U(ret, r, g, b) \
|
static inline gint
|
||||||
{ \
|
rgb_to_u (gint r, gint g, gint b)
|
||||||
ret = (int) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) + 128); \
|
{
|
||||||
ret = CLAMP (ret, 0, 255); \
|
gint ret;
|
||||||
|
|
||||||
|
ret =
|
||||||
|
(gint) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) +
|
||||||
|
128);
|
||||||
|
ret = CLAMP (ret, 0, 255);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COMP_V(ret, r, g, b) \
|
static inline gint
|
||||||
{ \
|
rgb_to_v (gint r, gint g, gint b)
|
||||||
ret = (int) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) + 128); \
|
{
|
||||||
ret = CLAMP (ret, 0, 255); \
|
gint ret;
|
||||||
|
|
||||||
|
ret =
|
||||||
|
(gint) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) +
|
||||||
|
128);
|
||||||
|
ret = CLAMP (ret, 0, 255);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
|
blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
guint counter = 0;
|
guint counter = 0;
|
||||||
guint8 alpha, r, g, b, k;
|
gint alpha, r, g, b, k, k2;
|
||||||
guint8 Y, U, V;
|
gint Y, U, V;
|
||||||
const guint8 *src;
|
const guint8 *src;
|
||||||
guint8 *dst;
|
guint8 *dst_y, *dst_u, *dst_v;
|
||||||
gint x, y, w, h;
|
gint x, y, w, h;
|
||||||
gint w2, h2;
|
gint w2, h2;
|
||||||
gint width = render->width;
|
gint width = render->width;
|
||||||
|
@ -463,7 +480,6 @@ blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
|
||||||
gint y_offset, y_height, y_width, y_stride;
|
gint y_offset, y_height, y_width, y_stride;
|
||||||
gint u_offset, u_height, u_width, u_stride;
|
gint u_offset, u_height, u_width, u_stride;
|
||||||
gint v_offset, v_height, v_width, v_stride;
|
gint v_offset, v_height, v_width, v_stride;
|
||||||
gint div;
|
|
||||||
|
|
||||||
y_offset =
|
y_offset =
|
||||||
gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 0, width,
|
gst_video_format_get_component_offset (GST_VIDEO_FORMAT_I420, 0, width,
|
||||||
|
@ -503,102 +519,125 @@ blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
|
||||||
g = ((ass_image->color) >> 16) & 0xff;
|
g = ((ass_image->color) >> 16) & 0xff;
|
||||||
b = ((ass_image->color) >> 8) & 0xff;
|
b = ((ass_image->color) >> 8) & 0xff;
|
||||||
|
|
||||||
COMP_Y (Y, r, g, b);
|
Y = rgb_to_y (r, g, b);
|
||||||
COMP_U (U, r, g, b);
|
U = rgb_to_u (r, g, b);
|
||||||
COMP_V (V, r, g, b);
|
V = rgb_to_v (r, g, b);
|
||||||
|
|
||||||
w = MIN (ass_image->w, width - ass_image->dst_x);
|
w = MIN (ass_image->w, width - ass_image->dst_x);
|
||||||
h = MIN (ass_image->h, height - ass_image->dst_y);
|
h = MIN (ass_image->h, height - ass_image->dst_y);
|
||||||
|
|
||||||
src_stride = ass_image->stride;
|
|
||||||
|
|
||||||
/* Y */
|
|
||||||
src = ass_image->bitmap;
|
|
||||||
dst =
|
|
||||||
buffer->data + y_offset + ass_image->dst_y * y_stride +
|
|
||||||
ass_image->dst_x;
|
|
||||||
for (y = 0; y < h; y++) {
|
|
||||||
for (x = 0; x < w; x++) {
|
|
||||||
k = ((guint8) src[0]) * alpha / 255;
|
|
||||||
dst[0] = (k * Y + (255 - k) * dst[0]) / 255;
|
|
||||||
src++;
|
|
||||||
dst++;
|
|
||||||
}
|
|
||||||
src += src_stride - w;
|
|
||||||
dst += y_stride - w;
|
|
||||||
}
|
|
||||||
|
|
||||||
w2 = (w + 1) / 2;
|
w2 = (w + 1) / 2;
|
||||||
h2 = (h + 1) / 2;
|
h2 = (h + 1) / 2;
|
||||||
|
|
||||||
/* U */
|
src_stride = ass_image->stride;
|
||||||
|
|
||||||
src = ass_image->bitmap;
|
src = ass_image->bitmap;
|
||||||
dst =
|
dst_y =
|
||||||
|
buffer->data + y_offset + ass_image->dst_y * y_stride +
|
||||||
|
ass_image->dst_x;
|
||||||
|
dst_u =
|
||||||
buffer->data + u_offset + ((ass_image->dst_y + 1) / 2) * u_stride +
|
buffer->data + u_offset + ((ass_image->dst_y + 1) / 2) * u_stride +
|
||||||
(ass_image->dst_x + 1) / 2;
|
(ass_image->dst_x + 1) / 2;
|
||||||
for (y = 0; y < h2; y++) {
|
dst_v =
|
||||||
for (x = 0; x < w2; x++) {
|
|
||||||
k = src[0] * alpha / 255;
|
|
||||||
div = 1;
|
|
||||||
if (x * 2 + 1 < w) {
|
|
||||||
k += src[1] * alpha / 255;
|
|
||||||
div++;
|
|
||||||
}
|
|
||||||
if (y * 2 + 1 < h) {
|
|
||||||
k += src[src_stride] * alpha / 255;
|
|
||||||
div++;
|
|
||||||
}
|
|
||||||
if (y * 2 + 1 < h && x * 2 + 1 < w) {
|
|
||||||
k += src[src_stride + 1] * alpha / 255;
|
|
||||||
div++;
|
|
||||||
}
|
|
||||||
k /= div;
|
|
||||||
|
|
||||||
dst[0] = (k * U + (255 - k) * dst[0]) / 255;
|
|
||||||
dst++;
|
|
||||||
src += 2;
|
|
||||||
}
|
|
||||||
dst += u_stride - w2;
|
|
||||||
src += src_stride - w2 * 2;
|
|
||||||
}
|
|
||||||
/* V */
|
|
||||||
src = ass_image->bitmap;
|
|
||||||
dst =
|
|
||||||
buffer->data + v_offset + ((ass_image->dst_y + 1) / 2) * v_stride +
|
buffer->data + v_offset + ((ass_image->dst_y + 1) / 2) * v_stride +
|
||||||
(ass_image->dst_x + 1) / 2;
|
(ass_image->dst_x + 1) / 2;
|
||||||
for (y = 0; y < h2; y++) {
|
|
||||||
for (x = 0; x < w2; x++) {
|
|
||||||
k = src[0] * alpha / 255;
|
|
||||||
div = 1;
|
|
||||||
if (x * 2 + 1 < w) {
|
|
||||||
k += src[1] * alpha / 255;
|
|
||||||
div++;
|
|
||||||
}
|
|
||||||
if (y * 2 + 1 < h) {
|
|
||||||
k += src[src_stride] * alpha / 255;
|
|
||||||
div++;
|
|
||||||
}
|
|
||||||
if (y * 2 + 1 < h && x * 2 + 1 < w) {
|
|
||||||
k += src[src_stride + 1] * alpha / 255;
|
|
||||||
div++;
|
|
||||||
}
|
|
||||||
k /= div;
|
|
||||||
|
|
||||||
dst[0] = (k * V + (255 - k) * dst[0]) / 255;
|
for (y = 0; y < h - 1; y += 2) {
|
||||||
dst++;
|
for (x = 0; x < w - 1; x += 2) {
|
||||||
src += 2;
|
k = src[0] * alpha / 255;
|
||||||
|
k2 = k;
|
||||||
|
dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
|
||||||
|
|
||||||
|
k = src[1] * alpha / 255;
|
||||||
|
k2 += k;
|
||||||
|
dst_y[1] = (k * Y + (255 - k) * dst_y[1]) / 255;
|
||||||
|
|
||||||
|
src += src_stride;
|
||||||
|
dst_y += y_stride;
|
||||||
|
|
||||||
|
k = src[0] * alpha / 255;
|
||||||
|
k2 += k;
|
||||||
|
dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
|
||||||
|
|
||||||
|
k = src[1] * alpha / 255;
|
||||||
|
k2 += k;
|
||||||
|
dst_y[1] = (k * Y + (255 - k) * dst_y[1]) / 255;
|
||||||
|
|
||||||
|
k2 /= 4;
|
||||||
|
dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
|
||||||
|
dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
|
||||||
|
dst_u++;
|
||||||
|
dst_v++;
|
||||||
|
|
||||||
|
src += -src_stride + 2;
|
||||||
|
dst_y += -y_stride + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < w) {
|
||||||
|
k = src[0] * alpha / 255;
|
||||||
|
k2 = k;
|
||||||
|
dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
|
||||||
|
|
||||||
|
src += src_stride;
|
||||||
|
dst_y += y_stride;
|
||||||
|
|
||||||
|
k = src[0] * alpha / 255;
|
||||||
|
k2 += k;
|
||||||
|
dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
|
||||||
|
|
||||||
|
k2 /= 2;
|
||||||
|
dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
|
||||||
|
dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
|
||||||
|
dst_u++;
|
||||||
|
dst_v++;
|
||||||
|
|
||||||
|
src += -src_stride + 1;
|
||||||
|
dst_y += -y_stride + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
src += src_stride + (src_stride - w);
|
||||||
|
dst_y += y_stride + (y_stride - w);
|
||||||
|
dst_u += u_stride - w2;
|
||||||
|
dst_v += v_stride - w2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < h) {
|
||||||
|
for (x = 0; x < w - 1; x += 2) {
|
||||||
|
k = src[0] * alpha / 255;
|
||||||
|
k2 = k;
|
||||||
|
dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
|
||||||
|
|
||||||
|
k = src[1] * alpha / 255;
|
||||||
|
k2 += k;
|
||||||
|
dst_y[1] = (k * Y + (255 - k) * dst_y[1]) / 255;
|
||||||
|
|
||||||
|
k2 /= 2;
|
||||||
|
dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
|
||||||
|
dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
|
||||||
|
dst_u++;
|
||||||
|
dst_v++;
|
||||||
|
|
||||||
|
src += 2;
|
||||||
|
dst_y += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < w) {
|
||||||
|
k = src[0] * alpha / 255;
|
||||||
|
k2 = k;
|
||||||
|
dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
|
||||||
|
|
||||||
|
dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
|
||||||
|
dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
|
||||||
}
|
}
|
||||||
dst += v_stride - w2;
|
|
||||||
src += src_stride - w2 * 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
counter++;
|
counter++;
|
||||||
ass_image = ass_image->next;
|
ass_image = ass_image->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (render, "amount of rendered ass_image: %u", counter);
|
GST_LOG_OBJECT (render, "amount of rendered ass_image: %u", counter);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_ass_render_setcaps_video (GstPad * pad, GstCaps * caps)
|
gst_ass_render_setcaps_video (GstPad * pad, GstCaps * caps)
|
||||||
|
@ -643,11 +682,9 @@ gst_ass_render_setcaps_video (GstPad * pad, GstCaps * caps)
|
||||||
case GST_VIDEO_FORMAT_BGRx:
|
case GST_VIDEO_FORMAT_BGRx:
|
||||||
render->blit = blit_bgrx;
|
render->blit = blit_bgrx;
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
case GST_VIDEO_FORMAT_I420:
|
case GST_VIDEO_FORMAT_I420:
|
||||||
render->blit = blit_i420;
|
render->blit = blit_i420;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
Loading…
Reference in a new issue