summaryrefslogtreecommitdiff
path: root/ext/assrender/gstassrender.c
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2009-12-08 11:26:02 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2009-12-08 14:00:25 +0100
commit77d0ded9edab410e27d33aa1c185461cd7482f62 (patch)
tree5c92370cdba02974ccdd2b6c03b0920d49ea91a0 /ext/assrender/gstassrender.c
parent5076cdc6f95b0a73c1f40909e7b96a6052fcea66 (diff)
assrender: Fix I420 mode and enable it
Diffstat (limited to 'ext/assrender/gstassrender.c')
-rw-r--r--ext/assrender/gstassrender.c219
1 files changed, 128 insertions, 91 deletions
diff --git a/ext/assrender/gstassrender.c b/ext/assrender/gstassrender.c
index 241214cd3..bd02e3480 100644
--- a/ext/assrender/gstassrender.c
+++ b/ext/assrender/gstassrender.c
@@ -48,7 +48,8 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
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 =
@@ -57,7 +58,8 @@ static GstStaticPadTemplate video_sink_factory =
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR ";"
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 =
@@ -372,7 +374,7 @@ static void \
blit_##name (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer) \
{ \
guint counter = 0; \
- guint8 alpha, r, g, b, k; \
+ gint alpha, r, g, b, k; \
const guint8 *src; \
guint8 *dst; \
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 (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[G] = (k * g + (255 - k) * dst[G]) / 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
-#if 0
-#define COMP_Y(ret, r, g, b) \
-{ \
- ret = (int) (((19595 * r) >> 16) + ((38470 * g) >> 16) + ((7471 * b) >> 16)); \
- ret = CLAMP (ret, 0, 255); \
+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;
}
-#define COMP_U(ret, r, g, b) \
-{ \
- ret = (int) (-((11059 * r) >> 16) - ((21709 * g) >> 16) + ((32768 * b) >> 16) + 128); \
- ret = CLAMP (ret, 0, 255); \
+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;
}
-#define COMP_V(ret, r, g, b) \
-{ \
- ret = (int) (((32768 * r) >> 16) - ((27439 * g) >> 16) - ((5329 * b) >> 16) + 128); \
- ret = CLAMP (ret, 0, 255); \
+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 void
blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
{
guint counter = 0;
- guint8 alpha, r, g, b, k;
- guint8 Y, U, V;
+ gint alpha, r, g, b, k, k2;
+ gint Y, U, V;
const guint8 *src;
- guint8 *dst;
+ guint8 *dst_y, *dst_u, *dst_v;
gint x, y, w, h;
gint w2, h2;
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 u_offset, u_height, u_width, u_stride;
gint v_offset, v_height, v_width, v_stride;
- gint div;
y_offset =
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;
b = ((ass_image->color) >> 8) & 0xff;
- COMP_Y (Y, r, g, b);
- COMP_U (U, r, g, b);
- COMP_V (V, r, g, b);
+ Y = rgb_to_y (r, g, b);
+ U = rgb_to_u (r, g, b);
+ V = rgb_to_v (r, g, b);
w = MIN (ass_image->w, width - ass_image->dst_x);
h = MIN (ass_image->h, height - ass_image->dst_y);
+ w2 = (w + 1) / 2;
+ h2 = (h + 1) / 2;
+
src_stride = ass_image->stride;
- /* Y */
src = ass_image->bitmap;
- dst =
+ dst_y =
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++;
+ dst_u =
+ buffer->data + u_offset + ((ass_image->dst_y + 1) / 2) * u_stride +
+ (ass_image->dst_x + 1) / 2;
+ dst_v =
+ buffer->data + v_offset + ((ass_image->dst_y + 1) / 2) * v_stride +
+ (ass_image->dst_x + 1) / 2;
+
+ for (y = 0; y < h - 1; y += 2) {
+ 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;
+
+ 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;
}
- src += src_stride - w;
- dst += y_stride - w;
- }
- w2 = (w + 1) / 2;
- h2 = (h + 1) / 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;
- /* U */
- src = ass_image->bitmap;
- dst =
- buffer->data + u_offset + ((ass_image->dst_y + 1) / 2) * u_stride +
- (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;
+ k2 += k;
+ dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
- dst[0] = (k * U + (255 - k) * dst[0]) / 255;
- dst++;
- src += 2;
+ 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;
}
- dst += u_stride - w2;
- src += src_stride - w2 * 2;
+
+ src += src_stride + (src_stride - w);
+ dst_y += y_stride + (y_stride - w);
+ dst_u += u_stride - w2;
+ dst_v += v_stride - w2;
}
- /* V */
- src = ass_image->bitmap;
- dst =
- buffer->data + v_offset + ((ass_image->dst_y + 1) / 2) * v_stride +
- (ass_image->dst_x + 1) / 2;
- for (y = 0; y < h2; y++) {
- for (x = 0; x < w2; x++) {
+
+ if (y < h) {
+ for (x = 0; x < w - 1; x += 2) {
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;
+ 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++;
- dst[0] = (k * V + (255 - k) * dst[0]) / 255;
- dst++;
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:
counter++;
ass_image = ass_image->next;
}
+
GST_LOG_OBJECT (render, "amount of rendered ass_image: %u", counter);
}
-#endif
static gboolean
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:
render->blit = blit_bgrx;
break;
-#if 0
case GST_VIDEO_FORMAT_I420:
render->blit = blit_i420;
break;
-#endif
default:
ret = FALSE;
goto out;