summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRavi Kiran K N <ravi.kiran@samsung.com>2015-03-05 11:00:30 +0530
committerWim Taymans <wtaymans@redhat.com>2015-03-06 11:40:54 +0100
commit24f6329acaf5239d1a74da0f26f05a015e441bac (patch)
tree38023d1d80fc43775bce62183afa3afaf850b9bc
parent13804eab7d1361c5c8496613ff3e2a26ceac5238 (diff)
videobox: use video-converter APIs for format conversionwork
Use video-converter library APIs for format conversions instead of duplicating the conversion code in videobox. Add conversion configuration structure for crop/borders and alpha. https://bugzilla.gnome.org/show_bug.cgi?id=737401
-rw-r--r--gst/videobox/gstvideobox.c2601
-rw-r--r--gst/videobox/gstvideobox.h5
2 files changed, 113 insertions, 2493 deletions
diff --git a/gst/videobox/gstvideobox.c b/gst/videobox/gstvideobox.c
index 4c0ed36e1..7511c3d04 100644
--- a/gst/videobox/gstvideobox.c
+++ b/gst/videobox/gstvideobox.c
@@ -68,19 +68,6 @@ GST_DEBUG_CATEGORY_STATIC (videobox_debug);
#define GST_CAT_DEFAULT videobox_debug
/* From videotestsrc.c */
-static const guint8 yuv_sdtv_colors_Y[VIDEO_BOX_FILL_LAST] =
- { 16, 145, 41, 81, 210, 235 };
-static const guint8 yuv_sdtv_colors_U[VIDEO_BOX_FILL_LAST] =
- { 128, 54, 240, 90, 16, 128 };
-static const guint8 yuv_sdtv_colors_V[VIDEO_BOX_FILL_LAST] =
- { 128, 34, 110, 240, 146, 128 };
-
-static const guint8 yuv_hdtv_colors_Y[VIDEO_BOX_FILL_LAST] =
- { 16, 173, 32, 63, 219, 235 };
-static const guint8 yuv_hdtv_colors_U[VIDEO_BOX_FILL_LAST] =
- { 128, 42, 240, 102, 16, 128 };
-static const guint8 yuv_hdtv_colors_V[VIDEO_BOX_FILL_LAST] =
- { 128, 26, 118, 240, 138, 128 };
static const guint8 rgb_colors_R[VIDEO_BOX_FILL_LAST] =
{ 0, 0, 0, 255, 255, 255 };
@@ -89,2281 +76,6 @@ static const guint8 rgb_colors_G[VIDEO_BOX_FILL_LAST] =
static const guint8 rgb_colors_B[VIDEO_BOX_FILL_LAST] =
{ 0, 0, 255, 0, 0, 255 };
-/* Generated by -bad/ext/cog/generate_tables */
-static const int cog_ycbcr_to_rgb_matrix_8bit_hdtv[] = {
- 298, 0, 459, -63514,
- 298, -55, -136, 19681,
- 298, 541, 0, -73988,
-};
-
-static const int cog_ycbcr_to_rgb_matrix_8bit_sdtv[] = {
- 298, 0, 409, -57068,
- 298, -100, -208, 34707,
- 298, 516, 0, -70870,
-};
-
-static const gint cog_rgb_to_ycbcr_matrix_8bit_hdtv[] = {
- 47, 157, 16, 4096,
- -26, -87, 112, 32768,
- 112, -102, -10, 32768,
-};
-
-static const gint cog_rgb_to_ycbcr_matrix_8bit_sdtv[] = {
- 66, 129, 25, 4096,
- -38, -74, 112, 32768,
- 112, -94, -18, 32768,
-};
-
-static const gint cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit[] = {
- 256, -30, -53, 10600,
- 0, 261, 29, -4367,
- 0, 19, 262, -3289,
-};
-
-static const gint cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit[] = {
- 256, 25, 49, -9536,
- 0, 253, -28, 3958,
- 0, -19, 252, 2918,
-};
-
-static const gint cog_identity_matrix_8bit[] = {
- 256, 0, 0, 0,
- 0, 256, 0, 0,
- 0, 0, 256, 0,
-};
-
-#define APPLY_MATRIX(m,o,v1,v2,v3) ((m[o*4] * v1 + m[o*4+1] * v2 + m[o*4+2] * v3 + m[o*4+3]) >> 8)
-
-static void
-fill_ayuv (GstVideoBoxFill fill_type, guint b_alpha,
- GstVideoFrame * frame, gboolean sdtv)
-{
- guint32 empty_pixel;
- guint8 *dest;
- gint width, height;
- gint stride;
-
- width = GST_VIDEO_FRAME_WIDTH (frame);
- height = GST_VIDEO_FRAME_HEIGHT (frame);
-
- b_alpha = CLAMP (b_alpha, 0, 255);
-
- if (sdtv)
- empty_pixel = GUINT32_FROM_BE ((b_alpha << 24) |
- (yuv_sdtv_colors_Y[fill_type] << 16) |
- (yuv_sdtv_colors_U[fill_type] << 8) | yuv_sdtv_colors_V[fill_type]);
- else
- empty_pixel = GUINT32_FROM_BE ((b_alpha << 24) |
- (yuv_hdtv_colors_Y[fill_type] << 16) |
- (yuv_hdtv_colors_U[fill_type] << 8) | yuv_hdtv_colors_V[fill_type]);
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
- stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
-
- if (G_LIKELY (stride == 4 * width))
- video_box_orc_splat_u32 ((guint32 *) dest, empty_pixel, width * height);
- else if (height) {
- for (; height; --height) {
- video_box_orc_splat_u32 ((guint32 *) dest, empty_pixel, width);
- dest += stride;
- }
- }
-}
-
-static void
-copy_ayuv_ayuv (guint i_alpha, GstVideoFrame * dest_frame,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src_frame,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- gint src_stride;
- gint dest_stride;
- guint8 *dest, *src;
-
- src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src_frame, 0);
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest_frame, 0);
-
- src = GST_VIDEO_FRAME_PLANE_DATA (src_frame, 0);
- dest = GST_VIDEO_FRAME_PLANE_DATA (dest_frame, 0);
-
- dest = dest + dest_y * dest_stride + dest_x * 4;
- src = src + src_y * src_stride + src_x * 4;
-
- w *= 4;
-
- if (dest_sdtv != src_sdtv) {
- gint matrix[12];
- gint y, u, v;
-
- memcpy (matrix,
- dest_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
- cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- /* ORC FIXME */
- dest[j] = (src[j] * i_alpha) >> 8;
- y = src[j + 1];
- u = src[j + 2];
- v = src[j + 3];
- dest[j + 1] = APPLY_MATRIX (matrix, 0, y, u, v);
- dest[j + 2] = APPLY_MATRIX (matrix, 1, y, u, v);
- dest[j + 3] = APPLY_MATRIX (matrix, 2, y, u, v);
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else {
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- /* ORC FIXME */
- dest[j] = (src[j] * i_alpha) >> 8;
- dest[j + 1] = src[j + 1];
- dest[j + 2] = src[j + 2];
- dest[j + 3] = src[j + 3];
- }
- dest += dest_stride;
- src += src_stride;
- }
- }
-}
-
-static void
-copy_ayuv_i420 (guint i_alpha, GstVideoFrame * dest_frame,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src_frame,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- guint8 *destY, *destY2, *destU, *destV;
- gint dest_strideY, dest_strideU, dest_strideV;
- const guint8 *src2;
- gint src_stride;
- gint y_idx, uv_idx;
- gint y1, y2, y3, y4;
- gint u1, u2, u3, u4;
- gint v1, v2, v3, v4;
- gint matrix[12];
- guint8 *src;
- gint dest_height, src_height, dest_width;
-
- dest_height = GST_VIDEO_FRAME_HEIGHT (dest_frame);
- dest_width = GST_VIDEO_FRAME_WIDTH (dest_frame);
- src_height = GST_VIDEO_FRAME_HEIGHT (src_frame);
-
- dest_strideY = GST_VIDEO_FRAME_COMP_STRIDE (dest_frame, 0);
- dest_strideU = GST_VIDEO_FRAME_COMP_STRIDE (dest_frame, 1);
- dest_strideV = GST_VIDEO_FRAME_COMP_STRIDE (dest_frame, 2);
-
- src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src_frame, 0);
-
- destY = GST_VIDEO_FRAME_COMP_DATA (dest_frame, 0);
- destU = GST_VIDEO_FRAME_COMP_DATA (dest_frame, 1);
- destV = GST_VIDEO_FRAME_COMP_DATA (dest_frame, 2);
-
- destY = destY + dest_y * dest_strideY + dest_x;
- destY2 = (dest_y < dest_height) ? destY + dest_strideY : destY;
- destU = destU + (dest_y / 2) * dest_strideU + dest_x / 2;
- destV = destV + (dest_y / 2) * dest_strideV + dest_x / 2;
-
- src = GST_VIDEO_FRAME_PLANE_DATA (src_frame, 0);
- src = src + src_y * src_stride + src_x * 4;
- src2 = (src_y < src_height) ? src + src_stride : src;
-
- h = dest_y + h;
- w = dest_x + w;
-
- if (src_sdtv != dest_sdtv)
- memcpy (matrix,
- dest_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
- cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
- else
- memcpy (matrix, cog_identity_matrix_8bit, 12 * sizeof (gint));
-
- /* 1. Handle the first destination scanline specially if it
- * doesn't start at the macro pixel boundary, i.e. blend
- * with the background! */
- if (dest_y % 2 == 1) {
- /* 1.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 2 == 1) {
- y1 = src[4 * 0 + 1];
- u1 = src[4 * 0 + 2];
- v1 = src[4 * 0 + 3];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[0] =
- CLAMP ((3 * destU[0] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4, 0,
- 255);
- destV[0] =
- CLAMP ((3 * destV[0] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 4, 0,
- 255);
-
- j = dest_x + 1;
- y_idx = uv_idx = 1;
- } else {
- j = dest_x;
- y_idx = uv_idx = 0;
- }
-
- /* 1.2. Copy all macro pixels from the source to the destination
- * but blend with the background because we're only filling
- * the lower part of the macro pixels. */
- for (; j < w - 1; j += 2) {
- y1 = src[4 * y_idx + 1];
- y2 = src[4 * y_idx + 4 + 1];
-
- u1 = src[4 * y_idx + 2];
- u2 = src[4 * y_idx + 4 + 2];
-
- v1 = src[4 * y_idx + 3];
- v2 = src[4 * y_idx + 4 + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[y_idx + 1] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destU[uv_idx] = CLAMP (
- (2 * destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u2, v2)) / 4, 0, 255);
- destV[uv_idx] = CLAMP (
- (2 * destV[uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
-
- y_idx += 2;
- uv_idx++;
- }
-
- /* 1.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = src[4 * y_idx + 1];
- u1 = src[4 * y_idx + 2];
- v1 = src[4 * y_idx + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[uv_idx] = CLAMP (
- (destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0, 255);
- destV[uv_idx] = CLAMP (
- (destV[uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 2, 0, 255);
- } else if (j == w - 1) {
- y1 = src[4 * y_idx + 1];
- u1 = src[4 * y_idx + 2];
- v1 = src[4 * y_idx + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[uv_idx] = CLAMP (
- (3 * destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4, 0,
- 255);
- destV[uv_idx] =
- CLAMP ((3 * destV[uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 4,
- 0, 255);
- }
-
- destY += dest_strideY;
- destY2 += dest_strideY;
- destU += dest_strideU;
- destV += dest_strideV;
- src += src_stride;
- src2 += src_stride;
- i = dest_y + 1;
- } else {
- i = dest_y;
- }
-
- /* 2. Copy all macro pixel scanlines, the destination scanline
- * now starts at macro pixel boundary. */
- for (; i < h - 1; i += 2) {
- /* 2.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 2 == 1) {
- y1 = src[4 * 0 + 1];
- y2 = src2[4 * 0 + 1];
- u1 = src[4 * 0 + 2];
- u2 = src2[4 * 0 + 2];
- v1 = src[4 * 0 + 3];
- v2 = src2[4 * 0 + 3];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY2[0] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destU[0] = CLAMP (
- (2 * destU[0] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u2, v2)) / 4, 0, 255);
- destV[0] = CLAMP (
- (2 * destV[0] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
- j = dest_x + 1;
- y_idx = uv_idx = 1;
- } else {
- j = dest_x;
- y_idx = uv_idx = 0;
- }
-
- /* 2.2. Copy all macro pixels from the source to the destination.
- * All pixels now start at macro pixel boundary, i.e. no
- * blending with the background is necessary. */
- for (; j < w - 1; j += 2) {
- y1 = src[4 * y_idx + 1];
- y2 = src[4 * y_idx + 4 + 1];
- y3 = src2[4 * y_idx + 1];
- y4 = src2[4 * y_idx + 4 + 1];
-
- u1 = src[4 * y_idx + 2];
- u2 = src[4 * y_idx + 4 + 2];
- u3 = src2[4 * y_idx + 2];
- u4 = src2[4 * y_idx + 4 + 2];
-
- v1 = src[4 * y_idx + 3];
- v2 = src[4 * y_idx + 4 + 3];
- v3 = src2[4 * y_idx + 3];
- v4 = src2[4 * y_idx + 4 + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[y_idx + 1] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destY2[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y3, u3, v3), 0, 255);
- destY2[y_idx + 1] = CLAMP (APPLY_MATRIX (matrix, 0, y4, u4, v4), 0, 255);
-
- destU[uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 1, y1, u1, v1) + APPLY_MATRIX (matrix, 1, y2,
- u2, v2) + APPLY_MATRIX (matrix, 1, y3, u3,
- v3) + APPLY_MATRIX (matrix, 1, y4, u4, v4)) / 4, 0, 255);
- destV[uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 2, y1, u1, v1) + APPLY_MATRIX (matrix, 2, y2,
- u2, v2) + APPLY_MATRIX (matrix, 2, y3, u3,
- v3) + APPLY_MATRIX (matrix, 2, y4, u4, v4)) / 4, 0, 255);
-
- y_idx += 2;
- uv_idx++;
- }
-
- /* 2.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = src[4 * y_idx + 1];
- y2 = src2[4 * y_idx + 1];
-
- u1 = src[4 * y_idx + 2];
- u2 = src2[4 * y_idx + 2];
-
- v1 = src[4 * y_idx + 3];
- v2 = src2[4 * y_idx + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY2[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destU[uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 1, y1, u1, v1) + APPLY_MATRIX (matrix, 2, y2,
- u2, v2)) / 2, 0, 255);
- destV[uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 1, y1, u1, v1) + APPLY_MATRIX (matrix, 2, y2,
- u2, v2)) / 2, 0, 255);
- } else if (j == w - 1) {
- y1 = src[4 * y_idx + 1];
- y2 = src2[4 * y_idx + 1];
-
- u1 = src[4 * y_idx + 2];
- u2 = src2[4 * y_idx + 2];
-
- v1 = src[4 * y_idx + 3];
- v2 = src2[4 * y_idx + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY2[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destU[uv_idx] = CLAMP (
- (2 * destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
- destV[uv_idx] = CLAMP (
- (2 * destV[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
- }
-
- destY += 2 * dest_strideY;
- destY2 += 2 * dest_strideY;
- destU += dest_strideU;
- destV += dest_strideV;
- src += 2 * src_stride;
- src2 += 2 * src_stride;
- }
-
- /* 3. Handle the last scanline if one exists. This again
- * doesn't start at macro pixel boundary but should
- * only fill the upper part of the macro pixels. */
- if (i == h - 1 && i == dest_height - 1) {
- /* 3.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 2 == 1) {
- y1 = src[4 * 0 + 1];
- u1 = src[4 * 0 + 2];
- v1 = src[4 * 0 + 3];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[0] =
- CLAMP ((destU[0] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0, 255);
- destV[0] =
- CLAMP ((destV[0] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 2, 0, 255);
-
- j = dest_x + 1;
- y_idx = uv_idx = 1;
- } else {
- j = dest_x;
- y_idx = uv_idx = 0;
- }
-
- /* 3.2. Copy all macro pixels from the source to the destination
- * but blend with the background because we're only filling
- * the upper part of the macro pixels. */
- for (; j < w - 1; j += 2) {
- y1 = src[4 * y_idx + 1];
- y2 = src[4 * y_idx + 4 + 1];
-
- u1 = src[4 * y_idx + 2];
- u2 = src[4 * y_idx + 4 + 2];
-
- v1 = src[4 * y_idx + 3];
- v2 = src[4 * y_idx + 4 + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[y_idx + 1] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
-
- destU[uv_idx] = CLAMP (
- (2 * destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u2, v2)) / 4, 0, 255);
- destV[uv_idx] = CLAMP (
- (2 * destV[uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
-
- y_idx += 2;
- uv_idx++;
- }
-
- /* 3.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = src[4 * y_idx + 1];
- u1 = src[4 * y_idx + 2];
- v1 = src[4 * y_idx + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[uv_idx] = CLAMP (
- (destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0, 255);
- destV[uv_idx] = CLAMP (
- (destV[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0, 255);
- } else if (j == w - 1) {
- y1 = src[4 * y_idx + 1];
- u1 = src[4 * y_idx + 2];
- v1 = src[4 * y_idx + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[uv_idx] = CLAMP (
- (3 * destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4, 0,
- 255);
- destV[uv_idx] =
- CLAMP ((3 * destV[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4,
- 0, 255);
- }
- } else if (i == h - 1) {
- /* 3.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 2 == 1) {
- y1 = src[4 * 0 + 1];
- u1 = src[4 * 0 + 2];
- v1 = src[4 * 0 + 3];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[0] =
- CLAMP ((3 * destU[0] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4, 0,
- 255);
- destV[0] =
- CLAMP ((3 * destV[0] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 4, 0,
- 255);
-
- j = dest_x + 1;
- y_idx = uv_idx = 1;
- } else {
- j = dest_x;
- y_idx = uv_idx = 0;
- }
-
- /* 3.2. Copy all macro pixels from the source to the destination
- * but blend with the background because we're only filling
- * the upper part of the macro pixels. */
- for (; j < w - 1; j += 2) {
- y1 = src[4 * y_idx + 1];
- y2 = src[4 * y_idx + 4 + 1];
-
- u1 = src[4 * y_idx + 2];
- u2 = src[4 * y_idx + 4 + 2];
-
- v1 = src[4 * y_idx + 3];
- v2 = src[4 * y_idx + 4 + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[y_idx + 1] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
-
- destU[uv_idx] = CLAMP (
- (2 * destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u2, v2)) / 4, 0, 255);
- destV[uv_idx] = CLAMP (
- (2 * destV[uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
-
- y_idx += 2;
- uv_idx++;
- }
-
- /* 3.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = src[4 * y_idx + 1];
- u1 = src[4 * y_idx + 2];
- v1 = src[4 * y_idx + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[uv_idx] = CLAMP (
- (destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0, 255);
- destV[uv_idx] = CLAMP (
- (destV[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0, 255);
- } else if (j == w - 1) {
- y1 = src[4 * y_idx + 1];
- u1 = src[4 * y_idx + 2];
- v1 = src[4 * y_idx + 3];
-
- destY[y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[uv_idx] = CLAMP (
- (3 * destU[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4, 0,
- 255);
- destV[uv_idx] =
- CLAMP ((3 * destV[uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4,
- 0, 255);
- }
- }
-}
-
-static void
-fill_planar_yuv (GstVideoBoxFill fill_type, guint b_alpha,
- GstVideoFrame * frame, gboolean sdtv)
-{
- guint8 empty_pixel[3];
- guint8 *destY, *destU, *destV;
- gint strideY, strideU, strideV;
- gint heightY, heightU, heightV;
- gint widthY, widthU, widthV;
-
- if (sdtv) {
- empty_pixel[0] = yuv_sdtv_colors_Y[fill_type];
- empty_pixel[1] = yuv_sdtv_colors_U[fill_type];
- empty_pixel[2] = yuv_sdtv_colors_V[fill_type];
- } else {
- empty_pixel[0] = yuv_hdtv_colors_Y[fill_type];
- empty_pixel[1] = yuv_hdtv_colors_U[fill_type];
- empty_pixel[2] = yuv_hdtv_colors_V[fill_type];
- }
-
- strideY = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
- strideU = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
- strideV = GST_VIDEO_FRAME_COMP_STRIDE (frame, 2);
-
- destY = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
- destU = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
- destV = GST_VIDEO_FRAME_COMP_DATA (frame, 2);
-
- widthY = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0);
- widthU = GST_VIDEO_FRAME_COMP_WIDTH (frame, 1);
- widthV = GST_VIDEO_FRAME_COMP_WIDTH (frame, 2);
-
- heightY = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0);
- heightU = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1);
- heightV = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 2);
-
- if (strideY == widthY) {
- memset (destY, empty_pixel[0], strideY * heightY);
- } else if (heightY) {
- for (; heightY; --heightY) {
- memset (destY, empty_pixel[0], widthY);
- destY += strideY;
- }
- }
- if (strideU == widthU) {
- memset (destU, empty_pixel[1], strideU * heightU);
- } else if (heightU) {
- for (; heightU; --heightU) {
- memset (destU, empty_pixel[1], widthU);
- destU += strideU;
- }
- }
- if (strideV == widthV) {
- memset (destV, empty_pixel[2], strideV * heightV);
- } else if (heightV) {
- for (; heightV; --heightV) {
- memset (destV, empty_pixel[2], widthV);
- destV += strideV;
- }
- }
-}
-
-static void
-copy_y444_y444 (guint i_alpha, GstVideoFrame * dest,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- guint8 *destY, *destU, *destV;
- const guint8 *srcY, *srcU, *srcV;
- gint dest_strideY, dest_strideU, dest_strideV;
- gint src_strideY, src_strideU, src_strideV;
-
- dest_strideY = GST_VIDEO_FRAME_COMP_STRIDE (dest, 0);
- dest_strideU = GST_VIDEO_FRAME_COMP_STRIDE (dest, 1);
- dest_strideV = GST_VIDEO_FRAME_COMP_STRIDE (dest, 2);
-
- src_strideY = GST_VIDEO_FRAME_COMP_STRIDE (src, 0);
- src_strideU = GST_VIDEO_FRAME_COMP_STRIDE (src, 1);
- src_strideV = GST_VIDEO_FRAME_COMP_STRIDE (src, 2);
-
- destY = GST_VIDEO_FRAME_COMP_DATA (dest, 0);
- destU = GST_VIDEO_FRAME_COMP_DATA (dest, 1);
- destV = GST_VIDEO_FRAME_COMP_DATA (dest, 2);
-
- srcY = GST_VIDEO_FRAME_COMP_DATA (src, 0);
- srcU = GST_VIDEO_FRAME_COMP_DATA (src, 1);
- srcV = GST_VIDEO_FRAME_COMP_DATA (src, 2);
-
- destY = destY + dest_y * dest_strideY + dest_x;
- destU = destU + dest_y * dest_strideU + dest_x;
- destV = destV + dest_y * dest_strideV + dest_x;
-
- srcY = srcY + src_y * src_strideY + src_x;
- srcU = srcU + src_y * src_strideU + src_x;
- srcV = srcV + src_y * src_strideV + src_x;
-
- if (src_sdtv != dest_sdtv) {
- gint matrix[12];
- gint y, u, v;
-
- memcpy (matrix,
- dest_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
- cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- y = APPLY_MATRIX (matrix, 0, srcY[j], srcU[j], srcV[j]);
- u = APPLY_MATRIX (matrix, 1, srcY[j], srcU[j], srcV[j]);
- v = APPLY_MATRIX (matrix, 2, srcY[j], srcU[j], srcV[j]);
-
- destY[j] = y;
- destU[j] = u;
- destV[j] = v;
- }
- destY += dest_strideY;
- destU += dest_strideU;
- destV += dest_strideV;
-
- srcY += src_strideY;
- srcU += src_strideU;
- srcV += src_strideV;
- }
- } else {
- for (i = 0; i < h; i++) {
- memcpy (destY, srcY, w);
- memcpy (destU, srcU, w);
- memcpy (destV, srcV, w);
-
- destY += dest_strideY;
- destU += dest_strideU;
- destV += dest_strideV;
-
- srcY += src_strideY;
- srcU += src_strideU;
- srcV += src_strideV;
- }
- }
-}
-
-static void
-copy_y42b_y42b (guint i_alpha, GstVideoFrame * dest,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- guint8 *destY, *destU, *destV;
- const guint8 *srcY, *srcU, *srcV;
- gint dest_strideY, dest_strideU, dest_strideV;
- gint src_strideY, src_strideU, src_strideV;
- gint src_y_idx, src_uv_idx;
- gint dest_y_idx, dest_uv_idx;
- gint matrix[12];
- gint y1, y2;
- gint u1, u2;
- gint v1, v2;
- gint dest_width;
-
- dest_width = GST_VIDEO_FRAME_WIDTH (dest);
-
- dest_strideY = GST_VIDEO_FRAME_COMP_STRIDE (dest, 0);
- dest_strideU = GST_VIDEO_FRAME_COMP_STRIDE (dest, 1);
- dest_strideV = GST_VIDEO_FRAME_COMP_STRIDE (dest, 2);
-
- src_strideY = GST_VIDEO_FRAME_COMP_STRIDE (src, 0);
- src_strideU = GST_VIDEO_FRAME_COMP_STRIDE (src, 1);
- src_strideV = GST_VIDEO_FRAME_COMP_STRIDE (src, 2);
-
- destY = GST_VIDEO_FRAME_COMP_DATA (dest, 0);
- destU = GST_VIDEO_FRAME_COMP_DATA (dest, 1);
- destV = GST_VIDEO_FRAME_COMP_DATA (dest, 2);
-
- srcY = GST_VIDEO_FRAME_COMP_DATA (src, 0);
- srcU = GST_VIDEO_FRAME_COMP_DATA (src, 1);
- srcV = GST_VIDEO_FRAME_COMP_DATA (src, 2);
-
- destY = destY + dest_y * dest_strideY + dest_x;
- destU = destU + dest_y * dest_strideU + dest_x / 2;
- destV = destV + dest_y * dest_strideV + dest_x / 2;
-
- srcY = srcY + src_y * src_strideY + src_x;
- srcU = srcU + src_y * src_strideU + src_x / 2;
- srcV = srcV + src_y * src_strideV + src_x / 2;
-
- h = dest_y + h;
- w = dest_x + w;
-
- if (src_sdtv != dest_sdtv)
- memcpy (matrix,
- dest_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
- cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
- else
- memcpy (matrix, cog_identity_matrix_8bit, 12 * sizeof (gint));
-
- /* 1. Copy all macro pixel scanlines, the destination scanline
- * now starts at macro pixel boundary. */
- for (i = dest_y; i < h; i++) {
- /* 1.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 2 == 1) {
- y1 = srcY[0];
- u1 = srcU[0];
- v1 = srcV[0];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[0] = CLAMP (
- (destU[0] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0, 255);
- destV[0] = CLAMP (
- (destV[0] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 2, 0, 255);
- j = dest_x + 1;
- src_y_idx = dest_y_idx = dest_uv_idx = 1;
- src_uv_idx = (src_x % 2) + 1;
- } else {
- j = dest_x;
- src_y_idx = dest_y_idx = dest_uv_idx = 0;
- src_uv_idx = (src_x % 2);
- }
-
- /* 1.2. Copy all macro pixels from the source to the destination.
- * All pixels now start at macro pixel boundary, i.e. no
- * blending with the background is necessary. */
- for (; j < w - 1; j += 2) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
-
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
- src_uv_idx++;
- u2 = srcU[src_uv_idx / 2];
- v2 = srcV[src_uv_idx / 2];
- src_uv_idx++;
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
-
- destU[dest_uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 1, y1, u1, v1) + APPLY_MATRIX (matrix, 1, y2,
- u2, v2)) / 2, 0, 255);
- destV[dest_uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 2, y1, u1, v1) + APPLY_MATRIX (matrix, 2, y2,
- u2, v2)) / 2, 0, 255);
-
- dest_y_idx += 2;
- src_y_idx += 2;
- dest_uv_idx++;
- }
-
- /* 1.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (APPLY_MATRIX (matrix, 1, y1, u1, v1), 0, 255);
- destV[dest_uv_idx] = CLAMP (APPLY_MATRIX (matrix, 1, y1, u1, v1), 0, 255);
- } else if (j == w - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 2, 0, 255);
- destV[dest_uv_idx] = CLAMP (
- (destV[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 2, 0, 255);
- }
-
- destY += dest_strideY;
- destU += dest_strideU;
- destV += dest_strideV;
- srcY += src_strideY;
-
- srcU += src_strideU;
- srcV += src_strideV;
- }
-}
-
-static void
-copy_y41b_y41b (guint i_alpha, GstVideoFrame * dest,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- guint8 *destY, *destU, *destV;
- const guint8 *srcY, *srcU, *srcV;
- gint dest_strideY, dest_strideU, dest_strideV;
- gint src_strideY, src_strideU, src_strideV;
- gint src_y_idx, src_uv_idx;
- gint dest_y_idx, dest_uv_idx;
- gint matrix[12];
- gint y1, y2, y3, y4;
- gint u1, u2, u3, u4;
- gint v1, v2, v3, v4;
- gint dest_width;
-
- dest_width = GST_VIDEO_FRAME_WIDTH (dest);
-
- dest_strideY = GST_VIDEO_FRAME_COMP_STRIDE (dest, 0);
- dest_strideU = GST_VIDEO_FRAME_COMP_STRIDE (dest, 1);
- dest_strideV = GST_VIDEO_FRAME_COMP_STRIDE (dest, 2);
-
- src_strideY = GST_VIDEO_FRAME_COMP_STRIDE (src, 0);
- src_strideU = GST_VIDEO_FRAME_COMP_STRIDE (src, 1);
- src_strideV = GST_VIDEO_FRAME_COMP_STRIDE (src, 2);
-
- destY = GST_VIDEO_FRAME_COMP_DATA (dest, 0);
- destU = GST_VIDEO_FRAME_COMP_DATA (dest, 1);
- destV = GST_VIDEO_FRAME_COMP_DATA (dest, 2);
-
- srcY = GST_VIDEO_FRAME_COMP_DATA (src, 0);
- srcU = GST_VIDEO_FRAME_COMP_DATA (src, 1);
- srcV = GST_VIDEO_FRAME_COMP_DATA (src, 2);
-
- destY = destY + dest_y * dest_strideY + dest_x;
- destU = destU + dest_y * dest_strideU + dest_x / 4;
- destV = destV + dest_y * dest_strideV + dest_x / 4;
-
- srcY = srcY + src_y * src_strideY + src_x;
- srcU = srcU + src_y * src_strideU + src_x / 4;
- srcV = srcV + src_y * src_strideV + src_x / 4;
-
- h = dest_y + h;
- w = dest_x + w;
-
- if (src_sdtv != dest_sdtv)
- memcpy (matrix,
- dest_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
- cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
- else
- memcpy (matrix, cog_identity_matrix_8bit, 12 * sizeof (gint));
-
- /* 1. Copy all macro pixel scanlines, the destination scanline
- * now starts at macro pixel boundary. */
- for (i = dest_y; i < h; i++) {
- /* 1.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 4 == 1) {
- y1 = srcY[0];
- y2 = srcY[1];
- y3 = srcY[2];
- u1 = srcU[0];
- v1 = srcV[0];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[1] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u1, v1), 0, 255);
- destY[2] = CLAMP (APPLY_MATRIX (matrix, 0, y3, u1, v1), 0, 255);
-
- destU[0] = CLAMP (
- (destU[0] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u1,
- v1) + APPLY_MATRIX (matrix, 1, y3, u1, v1)) / 4, 0, 255);
- destV[0] =
- CLAMP ((destV[0] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u1,
- v1) + APPLY_MATRIX (matrix, 2, y3, u1, v1)) / 4, 0, 255);
-
- j = dest_x + 3;
- src_y_idx = dest_y_idx = 3;
- dest_uv_idx = 1;
- src_uv_idx = (src_x % 4) + 3;
- } else if (dest_x % 4 == 2) {
- y1 = srcY[0];
- y2 = srcY[1];
- u1 = srcU[0];
- v1 = srcV[0];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[1] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u1, v1), 0, 255);
-
- destU[0] = CLAMP (
- (2 * destU[0] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u1, v1)) / 4, 0, 255);
- destV[0] =
- CLAMP ((2 * destV[0] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u1, v1)) / 4, 0, 255);
-
- j = dest_x + 2;
- src_y_idx = dest_y_idx = 2;
- dest_uv_idx = 1;
- src_uv_idx = (src_x % 4) + 2;
- } else if (dest_x % 4 == 3) {
- y1 = srcY[0];
- u1 = srcU[0];
- v1 = srcV[0];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
-
- destU[0] = CLAMP (
- (3 * destU[0] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4, 0, 255);
- destV[0] = CLAMP (
- (3 * destV[0] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 4, 0, 255);
-
- j = dest_x + 1;
- src_y_idx = dest_y_idx = 1;
- dest_uv_idx = 1;
- src_uv_idx = (src_x % 4) + 1;
- } else {
- j = dest_x;
- src_y_idx = dest_y_idx = dest_uv_idx = 0;
- src_uv_idx = (src_x % 4);
- }
-
- /* 1.2. Copy all macro pixels from the source to the destination.
- * All pixels now start at macro pixel boundary, i.e. no
- * blending with the background is necessary. */
- for (; j < w - 3; j += 4) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
- y3 = srcY[src_y_idx + 2];
- y4 = srcY[src_y_idx + 3];
-
- u1 = srcU[src_uv_idx / 4];
- v1 = srcV[src_uv_idx / 4];
- src_uv_idx++;
- u2 = srcU[src_uv_idx / 4];
- v2 = srcV[src_uv_idx / 4];
- src_uv_idx++;
- u3 = srcU[src_uv_idx / 4];
- v3 = srcV[src_uv_idx / 4];
- src_uv_idx++;
- u4 = srcU[src_uv_idx / 4];
- v4 = srcV[src_uv_idx / 4];
- src_uv_idx++;
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destY[dest_y_idx + 2] =
- CLAMP (APPLY_MATRIX (matrix, 0, y3, u3, v3), 0, 255);
- destY[dest_y_idx + 3] =
- CLAMP (APPLY_MATRIX (matrix, 0, y4, u4, v4), 0, 255);
-
- destU[dest_uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 1, y1, u1, v1) + APPLY_MATRIX (matrix, 1, y2,
- u2, v2) + APPLY_MATRIX (matrix, 1, y3, u3,
- v3) + APPLY_MATRIX (matrix, 1, y4, u4, v4)) / 4, 0, 255);
- destV[dest_uv_idx] =
- CLAMP ((APPLY_MATRIX (matrix, 2, y1, u1, v1) + APPLY_MATRIX (matrix,
- 2, y2, u2, v2) + APPLY_MATRIX (matrix, 2, y3, u3,
- v3) + APPLY_MATRIX (matrix, 2, y4, u4, v4)) / 4, 0, 255);
-
- dest_y_idx += 4;
- src_y_idx += 4;
- dest_uv_idx++;
- }
-
- /* 1.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 4];
- v1 = srcV[src_uv_idx / 4];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (APPLY_MATRIX (matrix, 1, y1, u1, v1), 0, 255);
- destV[dest_uv_idx] = CLAMP (APPLY_MATRIX (matrix, 1, y1, u1, v1), 0, 255);
- } else if (j == w - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 4];
- v1 = srcV[src_uv_idx / 4];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (destU[dest_uv_idx] + 3 * APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 4, 0, 255);
- destV[dest_uv_idx] = CLAMP (
- (destV[dest_uv_idx] + 3 * APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 4, 0, 255);
- } else if (j == w - 2 && j == dest_width - 2) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
- u1 = srcU[src_uv_idx / 4];
- v1 = srcV[src_uv_idx / 4];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (APPLY_MATRIX (matrix, 1, y1, u1, v1), 0, 255);
- destV[dest_uv_idx] = CLAMP (APPLY_MATRIX (matrix, 1, y1, u1, v1), 0, 255);
- } else if (j == w - 2) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
- u1 = srcU[src_uv_idx / 4];
- v1 = srcV[src_uv_idx / 4];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u1, v1), 0, 255);
- destU[dest_uv_idx] =
- CLAMP ((destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 2, 0, 255);
- destV[dest_uv_idx] =
- CLAMP ((destV[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 2, 0, 255);
- } else if (j == w - 3 && j == dest_width - 3) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
- y3 = srcY[src_y_idx + 2];
- u1 = srcU[src_uv_idx / 4];
- v1 = srcV[src_uv_idx / 4];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u1, v1), 0, 255);
- destY[dest_y_idx + 2] =
- CLAMP (APPLY_MATRIX (matrix, 0, y3, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (APPLY_MATRIX (matrix, 1, y1, u1, v1), 0, 255);
- destV[dest_uv_idx] = CLAMP (APPLY_MATRIX (matrix, 1, y1, u1, v1), 0, 255);
- } else if (j == w - 3) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
- y3 = srcY[src_y_idx + 2];
- u1 = srcU[src_uv_idx / 4];
- v1 = srcV[src_uv_idx / 4];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u1, v1), 0, 255);
- destY[dest_y_idx + 2] =
- CLAMP (APPLY_MATRIX (matrix, 0, y3, u1, v1), 0, 255);
- destU[dest_uv_idx] =
- CLAMP ((3 * destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 4, 0, 255);
- destV[dest_uv_idx] =
- CLAMP ((3 * destV[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 4, 0, 255);
- }
-
- destY += dest_strideY;
- destU += dest_strideU;
- destV += dest_strideV;
- srcY += src_strideY;
- srcU += src_strideU;
- srcV += src_strideV;
- }
-}
-
-static void
-copy_i420_i420 (guint i_alpha, GstVideoFrame * dest,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- guint8 *destY, *destU, *destV;
- const guint8 *srcY, *srcU, *srcV;
- guint8 *destY2;
- const guint8 *srcY2, *srcU2, *srcV2;
- gint dest_strideY, dest_strideU, dest_strideV;
- gint src_strideY, src_strideU, src_strideV;
- gint src_y_idx, src_uv_idx;
- gint dest_y_idx, dest_uv_idx;
- gint matrix[12];
- gint y1, y2, y3, y4;
- gint u1, u2, u3, u4;
- gint v1, v2, v3, v4;
- gint dest_width, dest_height;
-
- dest_width = GST_VIDEO_FRAME_WIDTH (dest);
- dest_height = GST_VIDEO_FRAME_HEIGHT (dest);
-
- dest_strideY = GST_VIDEO_FRAME_COMP_STRIDE (dest, 0);
- dest_strideU = GST_VIDEO_FRAME_COMP_STRIDE (dest, 1);
- dest_strideV = GST_VIDEO_FRAME_COMP_STRIDE (dest, 2);
-
- src_strideY = GST_VIDEO_FRAME_COMP_STRIDE (src, 0);
- src_strideU = GST_VIDEO_FRAME_COMP_STRIDE (src, 1);
- src_strideV = GST_VIDEO_FRAME_COMP_STRIDE (src, 2);
-
- destY = GST_VIDEO_FRAME_COMP_DATA (dest, 0);
- destU = GST_VIDEO_FRAME_COMP_DATA (dest, 1);
- destV = GST_VIDEO_FRAME_COMP_DATA (dest, 2);
-
- srcY = GST_VIDEO_FRAME_COMP_DATA (src, 0);
- srcU = GST_VIDEO_FRAME_COMP_DATA (src, 1);
- srcV = GST_VIDEO_FRAME_COMP_DATA (src, 2);
-
- destY = destY + dest_y * dest_strideY + dest_x;
- destU = destU + (dest_y / 2) * dest_strideU + dest_x / 2;
- destV = destV + (dest_y / 2) * dest_strideV + dest_x / 2;
-
- srcY = srcY + src_y * src_strideY + src_x;
- srcU = srcU + (src_y / 2) * src_strideU + src_x / 2;
- srcV = srcV + (src_y / 2) * src_strideV + src_x / 2;
-
- destY2 = destY + dest_strideY;
- srcY2 = srcY + src_strideY;
-
- h = dest_y + h;
- w = dest_x + w;
-
- if (src_sdtv != dest_sdtv)
- memcpy (matrix,
- dest_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
- cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
- else
- memcpy (matrix, cog_identity_matrix_8bit, 12 * sizeof (gint));
-
- /* 1. Handle the first destination scanline specially if it
- * doesn't start at the macro pixel boundary, i.e. blend
- * with the background! */
- if (dest_y % 2 == 1) {
- /* 1.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 2 == 1) {
- y1 = srcY[0];
- u1 = srcU[0];
- v1 = srcV[0];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[0] =
- CLAMP ((3 * destU[0] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4, 0,
- 255);
- destV[0] =
- CLAMP ((3 * destV[0] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 4, 0,
- 255);
-
- j = dest_x + 1;
- src_y_idx = dest_y_idx = dest_uv_idx = 1;
- src_uv_idx = (src_x % 2) + 1;
- } else {
- j = dest_x;
- src_y_idx = dest_y_idx = dest_uv_idx = 0;
- src_uv_idx = (src_x % 2);
- }
-
- /* 1.2. Copy all macro pixels from the source to the destination
- * but blend with the background because we're only filling
- * the lower part of the macro pixels. */
- for (; j < w - 1; j += 2) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
-
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
- src_uv_idx++;
- u2 = srcU[src_uv_idx / 2];
- v2 = srcV[src_uv_idx / 2];
- src_uv_idx++;
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destU[dest_uv_idx] =
- CLAMP ((2 * destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u2, v2)) / 4, 0, 255);
- destV[dest_uv_idx] =
- CLAMP ((2 * destV[dest_uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
-
- dest_y_idx += 2;
- src_y_idx += 2;
- dest_uv_idx++;
- }
-
- /* 1.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0,
- 255);
- destV[dest_uv_idx] =
- CLAMP ((destV[dest_uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1)) / 2, 0, 255);
- } else if (j == w - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (3 * destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4,
- 0, 255);
- destV[dest_uv_idx] =
- CLAMP ((3 * destV[dest_uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1)) / 4, 0, 255);
- }
-
- destY += dest_strideY;
- destY2 += dest_strideY;
- destU += dest_strideU;
- destV += dest_strideV;
- srcY += src_strideY;
- srcY2 += src_strideY;
- src_y++;
- if (src_y % 2 == 0) {
- srcU += src_strideU;
- srcV += src_strideV;
- }
- i = dest_y + 1;
- } else {
- i = dest_y;
- }
-
- /* 2. Copy all macro pixel scanlines, the destination scanline
- * now starts at macro pixel boundary. */
- for (; i < h - 1; i += 2) {
- /* 2.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
-
- srcU2 = srcU;
- srcV2 = srcV;
- if (src_y % 2 == 1) {
- srcU2 += src_strideU;
- srcV2 += src_strideV;
- }
-
- if (dest_x % 2 == 1) {
- y1 = srcY[0];
- y2 = srcY2[0];
- u1 = srcU[0];
- v1 = srcV[0];
- u2 = srcU2[0];
- v2 = srcV2[0];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY2[0] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destU[0] = CLAMP (
- (2 * destU[0] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u2, v2)) / 4, 0, 255);
- destV[0] = CLAMP (
- (2 * destV[0] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
- j = dest_x + 1;
- src_y_idx = dest_y_idx = dest_uv_idx = 1;
- src_uv_idx = (src_x % 2) + 1;
- } else {
- j = dest_x;
- src_y_idx = dest_y_idx = dest_uv_idx = 0;
- src_uv_idx = (src_x % 2);
- }
-
- /* 2.2. Copy all macro pixels from the source to the destination.
- * All pixels now start at macro pixel boundary, i.e. no
- * blending with the background is necessary. */
- for (; j < w - 1; j += 2) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
- y3 = srcY2[src_y_idx];
- y4 = srcY2[src_y_idx + 1];
-
- u1 = srcU[src_uv_idx / 2];
- u3 = srcU2[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
- v3 = srcV2[src_uv_idx / 2];
- src_uv_idx++;
- u2 = srcU[src_uv_idx / 2];
- u4 = srcU2[src_uv_idx / 2];
- v2 = srcV[src_uv_idx / 2];
- v4 = srcV2[src_uv_idx / 2];
- src_uv_idx++;
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destY2[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y3, u3, v3), 0, 255);
- destY2[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y4, u4, v4), 0, 255);
-
- destU[dest_uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 1, y1, u1, v1) + APPLY_MATRIX (matrix, 1, y2,
- u2, v2) + APPLY_MATRIX (matrix, 1, y3, u3,
- v3) + APPLY_MATRIX (matrix, 1, y4, u4, v4)) / 4, 0, 255);
- destV[dest_uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 2, y1, u1, v1) + APPLY_MATRIX (matrix, 2, y2,
- u2, v2) + APPLY_MATRIX (matrix, 2, y3, u3,
- v3) + APPLY_MATRIX (matrix, 2, y4, u4, v4)) / 4, 0, 255);
-
- dest_y_idx += 2;
- src_y_idx += 2;
- dest_uv_idx++;
- }
-
- /* 2.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = srcY[src_y_idx];
- y2 = srcY2[src_y_idx];
-
- u1 = srcU[src_uv_idx / 2];
- u2 = srcU2[src_uv_idx / 2];
-
- v1 = srcV[src_uv_idx / 2];
- v2 = srcV2[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY2[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 1, y1, u1, v1) + APPLY_MATRIX (matrix, 2, y2,
- u2, v2)) / 2, 0, 255);
- destV[dest_uv_idx] = CLAMP (
- (APPLY_MATRIX (matrix, 1, y1, u1, v1) + APPLY_MATRIX (matrix, 2, y2,
- u2, v2)) / 2, 0, 255);
- } else if (j == w - 1) {
- y1 = srcY[src_y_idx];
- y2 = srcY2[src_y_idx];
-
- u1 = srcU[src_uv_idx / 2];
- u2 = srcU2[src_uv_idx / 2];
-
- v1 = srcV[src_uv_idx / 2];
- v2 = srcV2[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY2[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (2 * destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
- destV[dest_uv_idx] = CLAMP (
- (2 * destV[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
- }
-
- destY += 2 * dest_strideY;
- destY2 += 2 * dest_strideY;
- destU += dest_strideU;
- destV += dest_strideV;
- srcY += 2 * src_strideY;
- srcY2 += 2 * src_strideY;
-
- src_y += 2;
- srcU += src_strideU;
- srcV += src_strideV;
- }
-
- /* 3. Handle the last scanline if one exists. This again
- * doesn't start at macro pixel boundary but should
- * only fill the upper part of the macro pixels. */
- if (i == h - 1 && i == dest_height - 1) {
- /* 3.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 2 == 1) {
- y1 = srcY[0];
- u1 = srcU[0];
- v1 = srcV[0];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[0] =
- CLAMP ((destU[0] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0, 255);
- destV[0] =
- CLAMP ((destV[0] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 2, 0, 255);
-
- j = dest_x + 1;
- src_y_idx = dest_y_idx = dest_uv_idx = 1;
- src_uv_idx = (src_x % 2) + 1;
- } else {
- j = dest_x;
- src_y_idx = dest_y_idx = dest_uv_idx = 0;
- src_uv_idx = (src_x % 2);
- }
-
- /* 3.2. Copy all macro pixels from the source to the destination
- * but blend with the background because we're only filling
- * the upper part of the macro pixels. */
- for (; j < w - 1; j += 2) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
-
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
- src_uv_idx++;
- u2 = srcU[src_uv_idx / 2];
- v2 = srcV[src_uv_idx / 2];
- src_uv_idx++;
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
-
- destU[dest_uv_idx] = CLAMP (
- (2 * destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u2, v2)) / 4, 0, 255);
- destV[dest_uv_idx] = CLAMP (
- (2 * destV[dest_uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
-
- dest_y_idx += 2;
- src_y_idx += 2;
- dest_uv_idx++;
- }
-
- /* 3.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0,
- 255);
- destV[dest_uv_idx] =
- CLAMP ((destV[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 2, 0, 255);
- } else if (j == w - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (3 * destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4,
- 0, 255);
- destV[dest_uv_idx] =
- CLAMP ((3 * destV[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 4, 0, 255);
- }
- } else if (i == h - 1) {
- /* 3.1. Handle the first destination pixel if it doesn't
- * start at the macro pixel boundary, i.e. blend with
- * the background! */
- if (dest_x % 2 == 1) {
- y1 = srcY[0];
- u1 = srcU[0];
- v1 = srcV[0];
-
- destY[0] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[0] =
- CLAMP ((3 * destU[0] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4, 0,
- 255);
- destV[0] =
- CLAMP ((3 * destV[0] + APPLY_MATRIX (matrix, 2, y1, u1, v1)) / 4, 0,
- 255);
-
- j = dest_x + 1;
- src_y_idx = dest_y_idx = dest_uv_idx = 1;
- src_uv_idx = (src_x % 2) + 1;
- } else {
- j = dest_x;
- src_y_idx = dest_y_idx = dest_uv_idx = 0;
- src_uv_idx = (src_x % 2);
- }
-
- /* 3.2. Copy all macro pixels from the source to the destination
- * but blend with the background because we're only filling
- * the upper part of the macro pixels. */
- for (; j < w - 1; j += 2) {
- y1 = srcY[src_y_idx];
- y2 = srcY[src_y_idx + 1];
-
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
- src_uv_idx++;
- u2 = srcU[src_uv_idx / 2];
- v2 = srcV[src_uv_idx / 2];
- src_uv_idx++;
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destY[dest_y_idx + 1] =
- CLAMP (APPLY_MATRIX (matrix, 0, y2, u2, v2), 0, 255);
-
- destU[dest_uv_idx] = CLAMP (
- (2 * destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1) + APPLY_MATRIX (matrix, 1, y2, u2, v2)) / 4, 0, 255);
- destV[dest_uv_idx] = CLAMP (
- (2 * destV[dest_uv_idx] + APPLY_MATRIX (matrix, 2, y1, u1,
- v1) + APPLY_MATRIX (matrix, 2, y2, u2, v2)) / 4, 0, 255);
-
- dest_y_idx += 2;
- src_y_idx += 2;
- dest_uv_idx++;
- }
-
- /* 3.3. Now copy the last pixel if one exists and blend it
- * with the background because we only fill part of
- * the macro pixel. In case this is the last pixel of
- * the destination we will a larger part. */
- if (j == w - 1 && j == dest_width - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 2, 0,
- 255);
- destV[dest_uv_idx] =
- CLAMP ((destV[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 2, 0, 255);
- } else if (j == w - 1) {
- y1 = srcY[src_y_idx];
- u1 = srcU[src_uv_idx / 2];
- v1 = srcV[src_uv_idx / 2];
-
- destY[dest_y_idx] = CLAMP (APPLY_MATRIX (matrix, 0, y1, u1, v1), 0, 255);
- destU[dest_uv_idx] = CLAMP (
- (3 * destU[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1, v1)) / 4,
- 0, 255);
- destV[dest_uv_idx] =
- CLAMP ((3 * destV[dest_uv_idx] + APPLY_MATRIX (matrix, 1, y1, u1,
- v1)) / 4, 0, 255);
- }
- }
-}
-
-static void
-copy_i420_ayuv (guint i_alpha, GstVideoFrame * dest_frame,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src_frame,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- const guint8 *srcY, *srcU, *srcV;
- gint src_strideY, src_strideU, src_strideV;
- gint dest_stride;
- guint8 *dest;
-
- src_strideY = GST_VIDEO_FRAME_COMP_STRIDE (src_frame, 0);
- src_strideU = GST_VIDEO_FRAME_COMP_STRIDE (src_frame, 1);
- src_strideV = GST_VIDEO_FRAME_COMP_STRIDE (src_frame, 2);
-
- srcY = GST_VIDEO_FRAME_COMP_DATA (src_frame, 0);
- srcU = GST_VIDEO_FRAME_COMP_DATA (src_frame, 1);
- srcV = GST_VIDEO_FRAME_COMP_DATA (src_frame, 2);
-
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest_frame, 0);
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (dest_frame, 0);
- dest = dest + dest_y * dest_stride + dest_x * 4;
-
- srcY = srcY + src_y * src_strideY + src_x;
- srcU = srcU + (src_y / 2) * src_strideU + src_x / 2;
- srcV = srcV + (src_y / 2) * src_strideV + src_x / 2;
-
- i_alpha = CLAMP (i_alpha, 0, 255);
-
- if (src_sdtv != dest_sdtv) {
- gint i, j, uv_idx;
- gint y, u, v;
- gint y1, u1, v1;
- gint matrix[12];
-
- memcpy (matrix,
- dest_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
- cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
-
- for (i = 0; i < h; i++) {
- for (j = 0, uv_idx = src_x % 2; j < w; j++, uv_idx++) {
- y = srcY[j];
- u = srcU[uv_idx / 2];
- v = srcV[uv_idx / 2];
-
- y1 = APPLY_MATRIX (matrix, 0, y, u, v);
- u1 = APPLY_MATRIX (matrix, 1, y, u, v);
- v1 = APPLY_MATRIX (matrix, 2, y, u, v);
-
- dest[4 * j + 0] = i_alpha;
- dest[4 * j + 1] = y1;
- dest[4 * j + 2] = u1;
- dest[4 * j + 3] = v1;
- }
- dest += dest_stride;
-
- src_y++;
- srcY += src_strideY;
- if (src_y % 2 == 0) {
- srcU += src_strideU;
- srcV += src_strideV;
- }
- }
- } else {
- gint i, j, uv_idx;
- gint y, u, v;
-
- for (i = 0; i < h; i++) {
- for (j = 0, uv_idx = src_x % 2; j < w; j++, uv_idx++) {
- y = srcY[j];
- u = srcU[uv_idx / 2];
- v = srcV[uv_idx / 2];
-
- dest[4 * j + 0] = i_alpha;
- dest[4 * j + 1] = y;
- dest[4 * j + 2] = u;
- dest[4 * j + 3] = v;
- }
- dest += dest_stride;
-
- src_y++;
- srcY += src_strideY;
- if (src_y % 2 == 0) {
- srcU += src_strideU;
- srcV += src_strideV;
- }
- }
- }
-}
-
-static void
-fill_rgb32 (GstVideoBoxFill fill_type, guint b_alpha,
- GstVideoFrame * frame, gboolean sdtv)
-{
- guint32 empty_pixel;
- gint p[4];
- guint8 *dest;
- guint stride;
- gint width, height;
-
- width = GST_VIDEO_FRAME_WIDTH (frame);
- height = GST_VIDEO_FRAME_HEIGHT (frame);
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
- stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
-
- p[0] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 3);
- p[1] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 0);
- p[2] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 1);
- p[3] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 2);
-
- b_alpha = CLAMP (b_alpha, 0, 255);
-
- if (GST_VIDEO_FRAME_N_COMPONENTS (frame) == 4) {
- empty_pixel = GUINT32_FROM_LE ((b_alpha << (p[0] * 8)) |
- (rgb_colors_R[fill_type] << (p[1] * 8)) |
- (rgb_colors_G[fill_type] << (p[2] * 8)) |
- (rgb_colors_B[fill_type] << (p[3] * 8)));
- } else {
- empty_pixel = GUINT32_FROM_LE (
- (rgb_colors_R[fill_type] << (p[1] * 8)) |
- (rgb_colors_G[fill_type] << (p[2] * 8)) |
- (rgb_colors_B[fill_type] << (p[3] * 8)));
- }
-
- if (stride == width * 4) {
- video_box_orc_splat_u32 ((guint32 *) dest, empty_pixel, width * height);
- } else if (height) {
- for (; height; --height) {
- video_box_orc_splat_u32 ((guint32 *) dest, empty_pixel, width);
- dest += stride;
- }
- }
-}
-
-static void
-fill_rgb24 (GstVideoBoxFill fill_type, guint b_alpha,
- GstVideoFrame * frame, gboolean sdtv)
-{
- gint dest_stride;
- gint p[4];
- gint i, j;
- guint8 *dest;
- gint width, height;
-
- width = GST_VIDEO_FRAME_WIDTH (frame);
- height = GST_VIDEO_FRAME_HEIGHT (frame);
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
-
- p[1] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 0);
- p[2] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 1);
- p[3] = GST_VIDEO_FRAME_COMP_OFFSET (frame, 2);
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- dest[3 * j + p[1]] = rgb_colors_R[fill_type];
- dest[3 * j + p[2]] = rgb_colors_G[fill_type];
- dest[3 * j + p[3]] = rgb_colors_B[fill_type];
- }
- dest += dest_stride;
- }
-}
-
-static void
-copy_rgb32 (guint i_alpha, GstVideoFrame * dest_frame,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src_frame,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- gint src_stride, dest_stride;
- gboolean in_alpha, out_alpha;
- gint in_bpp, out_bpp;
- gint p_out[4];
- gint p_in[4];
- gboolean packed_out;
- gboolean packed_in;
- guint8 *src, *dest;
-
- src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src_frame, 0);
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest_frame, 0);
- in_bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (src_frame, 0);
- out_bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (dest_frame, 0);
- packed_in = (in_bpp < 4);
- packed_out = (out_bpp < 4);
-
- out_alpha = GST_VIDEO_INFO_HAS_ALPHA (&dest_frame->info);
- p_out[0] = GST_VIDEO_FRAME_COMP_OFFSET (dest_frame, 3);
- p_out[1] = GST_VIDEO_FRAME_COMP_OFFSET (dest_frame, 0);
- p_out[2] = GST_VIDEO_FRAME_COMP_OFFSET (dest_frame, 1);
- p_out[3] = GST_VIDEO_FRAME_COMP_OFFSET (dest_frame, 2);
-
- in_alpha = GST_VIDEO_INFO_HAS_ALPHA (&src_frame->info);
- p_in[0] = GST_VIDEO_FRAME_COMP_OFFSET (src_frame, 3);
- p_in[1] = GST_VIDEO_FRAME_COMP_OFFSET (src_frame, 0);
- p_in[2] = GST_VIDEO_FRAME_COMP_OFFSET (src_frame, 1);
- p_in[3] = GST_VIDEO_FRAME_COMP_OFFSET (src_frame, 2);
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (dest_frame, 0);
- dest = dest + dest_y * dest_stride + dest_x * out_bpp;
- src = GST_VIDEO_FRAME_PLANE_DATA (src_frame, 0);
- src = src + src_y * src_stride + src_x * in_bpp;
-
- if (in_alpha && out_alpha) {
- w *= 4;
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- dest[j + p_out[0]] = (src[j + p_in[0]] * i_alpha) >> 8;
- dest[j + p_out[1]] = src[j + p_in[1]];
- dest[j + p_out[2]] = src[j + p_in[2]];
- dest[j + p_out[3]] = src[j + p_in[3]];
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else if (out_alpha && !packed_in) {
- w *= 4;
- i_alpha = CLAMP (i_alpha, 0, 255);
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- dest[j + p_out[0]] = i_alpha;
- dest[j + p_out[1]] = src[j + p_in[1]];
- dest[j + p_out[2]] = src[j + p_in[2]];
- dest[j + p_out[3]] = src[j + p_in[3]];
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else if (out_alpha && packed_in) {
- i_alpha = CLAMP (i_alpha, 0, 255);
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- dest[4 * j + p_out[0]] = i_alpha;
- dest[4 * j + p_out[1]] = src[in_bpp * j + p_in[1]];
- dest[4 * j + p_out[2]] = src[in_bpp * j + p_in[2]];
- dest[4 * j + p_out[3]] = src[in_bpp * j + p_in[3]];
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else if (!packed_out && !packed_in) {
- w *= 4;
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- dest[j + p_out[1]] = src[j + p_in[1]];
- dest[j + p_out[2]] = src[j + p_in[2]];
- dest[j + p_out[3]] = src[j + p_in[3]];
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else {
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- dest[out_bpp * j + p_out[1]] = src[in_bpp * j + p_in[1]];
- dest[out_bpp * j + p_out[2]] = src[in_bpp * j + p_in[2]];
- dest[out_bpp * j + p_out[3]] = src[in_bpp * j + p_in[3]];
- }
- dest += dest_stride;
- src += src_stride;
- }
- }
-}
-
-static void
-copy_rgb32_ayuv (guint i_alpha, GstVideoFrame * dest_frame,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src_frame,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- gint src_stride, dest_stride;
- gboolean in_alpha;
- gint in_bpp;
- gint p_in[4];
- gboolean packed_in;
- gint matrix[12];
- gint a;
- gint y, u, v;
- gint r, g, b;
- guint8 *dest, *src;
-
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest_frame, 0);
- src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src_frame, 0);
- in_bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (src_frame, 0);
- packed_in = (in_bpp < 4);
-
- in_alpha = GST_VIDEO_INFO_HAS_ALPHA (&src_frame->info);
- p_in[0] = GST_VIDEO_FRAME_COMP_OFFSET (src_frame, 3);
- p_in[1] = GST_VIDEO_FRAME_COMP_OFFSET (src_frame, 0);
- p_in[2] = GST_VIDEO_FRAME_COMP_OFFSET (src_frame, 1);
- p_in[3] = GST_VIDEO_FRAME_COMP_OFFSET (src_frame, 2);
-
- memcpy (matrix,
- (dest_sdtv) ? cog_rgb_to_ycbcr_matrix_8bit_sdtv :
- cog_rgb_to_ycbcr_matrix_8bit_hdtv, 12 * sizeof (gint));
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (dest_frame, 0);
- dest = dest + dest_y * dest_stride + dest_x * 4;
- src = GST_VIDEO_FRAME_PLANE_DATA (src_frame, 0);
- src = src + src_y * src_stride + src_x * in_bpp;
-
- if (in_alpha) {
- w *= 4;
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- a = (src[j + p_in[0]] * i_alpha) >> 8;
- r = src[j + p_in[1]];
- g = src[j + p_in[2]];
- b = src[j + p_in[3]];
-
- y = APPLY_MATRIX (matrix, 0, r, g, b);
- u = APPLY_MATRIX (matrix, 1, r, g, b);
- v = APPLY_MATRIX (matrix, 2, r, g, b);
-
- dest[j + 0] = a;
- dest[j + 1] = CLAMP (y, 0, 255);
- dest[j + 2] = CLAMP (u, 0, 255);
- dest[j + 3] = CLAMP (v, 0, 255);
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else if (!packed_in) {
- w *= 4;
- i_alpha = CLAMP (i_alpha, 0, 255);
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- a = i_alpha;
- r = src[j + p_in[1]];
- g = src[j + p_in[2]];
- b = src[j + p_in[3]];
-
- y = APPLY_MATRIX (matrix, 0, r, g, b);
- u = APPLY_MATRIX (matrix, 1, r, g, b);
- v = APPLY_MATRIX (matrix, 2, r, g, b);
-
- dest[j + 0] = a;
- dest[j + 1] = CLAMP (y, 0, 255);
- dest[j + 2] = CLAMP (u, 0, 255);
- dest[j + 3] = CLAMP (v, 0, 255);
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else {
- i_alpha = CLAMP (i_alpha, 0, 255);
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- a = i_alpha;
- r = src[in_bpp * j + p_in[1]];
- g = src[in_bpp * j + p_in[2]];
- b = src[in_bpp * j + p_in[3]];
-
- y = APPLY_MATRIX (matrix, 0, r, g, b);
- u = APPLY_MATRIX (matrix, 1, r, g, b);
- v = APPLY_MATRIX (matrix, 2, r, g, b);
-
- dest[4 * j + 0] = a;
- dest[4 * j + 1] = CLAMP (y, 0, 255);
- dest[4 * j + 2] = CLAMP (u, 0, 255);
- dest[4 * j + 3] = CLAMP (v, 0, 255);
- }
- dest += dest_stride;
- src += src_stride;
- }
- }
-}
-
-static void
-copy_ayuv_rgb32 (guint i_alpha, GstVideoFrame * dest_frame,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src_frame,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- gint src_stride, dest_stride;
- gboolean out_alpha;
- gint out_bpp;
- gint p_out[4];
- gboolean packed_out;
- gint matrix[12];
- gint a;
- gint y, u, v;
- gint r, g, b;
- guint8 *src, *dest;
-
- src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src_frame, 0);
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest_frame, 0);
- out_bpp = GST_VIDEO_FRAME_COMP_PSTRIDE (dest_frame, 0);
- packed_out = (out_bpp < 4);
-
- out_alpha = GST_VIDEO_INFO_HAS_ALPHA (&dest_frame->info);
- p_out[0] = GST_VIDEO_FRAME_COMP_OFFSET (dest_frame, 3);
- p_out[1] = GST_VIDEO_FRAME_COMP_OFFSET (dest_frame, 0);
- p_out[2] = GST_VIDEO_FRAME_COMP_OFFSET (dest_frame, 1);
- p_out[3] = GST_VIDEO_FRAME_COMP_OFFSET (dest_frame, 2);
-
- memcpy (matrix,
- (src_sdtv) ? cog_ycbcr_to_rgb_matrix_8bit_sdtv :
- cog_ycbcr_to_rgb_matrix_8bit_hdtv, 12 * sizeof (gint));
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (dest_frame, 0);
- dest = dest + dest_y * dest_stride + dest_x * out_bpp;
- src = GST_VIDEO_FRAME_PLANE_DATA (src_frame, 0);
- src = src + src_y * src_stride + src_x * 4;
-
- if (out_alpha) {
- w *= 4;
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- a = (src[j + 0] * i_alpha) >> 8;
- y = src[j + 1];
- u = src[j + 2];
- v = src[j + 3];
-
- r = APPLY_MATRIX (matrix, 0, y, u, v);
- g = APPLY_MATRIX (matrix, 1, y, u, v);
- b = APPLY_MATRIX (matrix, 2, y, u, v);
-
- dest[j + p_out[0]] = a;
- dest[j + p_out[1]] = CLAMP (r, 0, 255);
- dest[j + p_out[2]] = CLAMP (g, 0, 255);
- dest[j + p_out[3]] = CLAMP (b, 0, 255);
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else if (!packed_out) {
- w *= 4;
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 4) {
- y = src[j + 1];
- u = src[j + 2];
- v = src[j + 3];
-
- r = APPLY_MATRIX (matrix, 0, y, u, v);
- g = APPLY_MATRIX (matrix, 1, y, u, v);
- b = APPLY_MATRIX (matrix, 2, y, u, v);
-
- dest[j + p_out[1]] = CLAMP (r, 0, 255);
- dest[j + p_out[2]] = CLAMP (g, 0, 255);
- dest[j + p_out[3]] = CLAMP (b, 0, 255);
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else {
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- y = src[4 * j + 1];
- u = src[4 * j + 2];
- v = src[4 * j + 3];
-
- r = APPLY_MATRIX (matrix, 0, y, u, v);
- g = APPLY_MATRIX (matrix, 1, y, u, v);
- b = APPLY_MATRIX (matrix, 2, y, u, v);
-
- dest[out_bpp * j + p_out[1]] = CLAMP (r, 0, 255);
- dest[out_bpp * j + p_out[2]] = CLAMP (g, 0, 255);
- dest[out_bpp * j + p_out[3]] = CLAMP (b, 0, 255);
- }
- dest += dest_stride;
- src += src_stride;
- }
- }
-}
-
-static void
-fill_gray (GstVideoBoxFill fill_type, guint b_alpha,
- GstVideoFrame * frame, gboolean sdtv)
-{
- gint i, j;
- gint dest_stride;
- guint8 *dest;
- gint width, height;
- GstVideoFormat format;
-
- format = GST_VIDEO_FRAME_FORMAT (frame);
-
- width = GST_VIDEO_FRAME_WIDTH (frame);
- height = GST_VIDEO_FRAME_HEIGHT (frame);
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
-
- if (format == GST_VIDEO_FORMAT_GRAY8) {
- guint8 val = yuv_sdtv_colors_Y[fill_type];
-
- for (i = 0; i < height; i++) {
- memset (dest, val, width);
- dest += dest_stride;
- }
- } else {
- guint16 val = yuv_sdtv_colors_Y[fill_type] << 8;
-
- if (format == GST_VIDEO_FORMAT_GRAY16_BE) {
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- GST_WRITE_UINT16_BE (dest + 2 * j, val);
- }
- dest += dest_stride;
- }
- } else {
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- GST_WRITE_UINT16_LE (dest + 2 * j, val);
- }
- dest += dest_stride;
- }
- }
- }
-}
-
-static void
-copy_packed_simple (guint i_alpha, GstVideoFrame * dest_frame,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src_frame,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i;
- gint src_stride, dest_stride;
- gint pixel_stride, row_size;
- guint8 *src, *dest;
-
- src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src_frame, 0);
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest_frame, 0);
- pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (dest_frame, 0);
- row_size = w * pixel_stride;
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (dest_frame, 0);
- dest = dest + dest_y * dest_stride + dest_x * pixel_stride;
- src = GST_VIDEO_FRAME_PLANE_DATA (src_frame, 0);
- src = src + src_y * src_stride + src_x * pixel_stride;
-
- for (i = 0; i < h; i++) {
- memcpy (dest, src, row_size);
- dest += dest_stride;
- src += src_stride;
- }
-}
-
-static void
-fill_yuy2 (GstVideoBoxFill fill_type, guint b_alpha,
- GstVideoFrame * frame, gboolean sdtv)
-{
- guint8 y, u, v;
- gint i, j;
- gint stride;
- gint width, height;
- guint8 *dest;
- GstVideoFormat format;
-
- format = GST_VIDEO_FRAME_FORMAT (frame);
-
- width = GST_VIDEO_FRAME_WIDTH (frame);
- height = GST_VIDEO_FRAME_HEIGHT (frame);
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
- stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
-
- y = (sdtv) ? yuv_sdtv_colors_Y[fill_type] : yuv_hdtv_colors_Y[fill_type];
- u = (sdtv) ? yuv_sdtv_colors_U[fill_type] : yuv_hdtv_colors_U[fill_type];
- v = (sdtv) ? yuv_sdtv_colors_V[fill_type] : yuv_hdtv_colors_V[fill_type];
-
- width = width + (width % 2);
-
- if (format == GST_VIDEO_FORMAT_YUY2) {
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j += 2) {
- dest[j * 2 + 0] = y;
- dest[j * 2 + 1] = u;
- dest[j * 2 + 2] = y;
- dest[j * 2 + 3] = v;
- }
-
- dest += stride;
- }
- } else if (format == GST_VIDEO_FORMAT_YVYU) {
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j += 2) {
- dest[j * 2 + 0] = y;
- dest[j * 2 + 1] = v;
- dest[j * 2 + 2] = y;
- dest[j * 2 + 3] = u;
- }
-
- dest += stride;
- }
- } else {
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j += 2) {
- dest[j * 2 + 0] = u;
- dest[j * 2 + 1] = y;
- dest[j * 2 + 2] = v;
- dest[j * 2 + 3] = y;
- }
-
- dest += stride;
- }
- }
-}
-
-static void
-copy_yuy2_yuy2 (guint i_alpha, GstVideoFrame * dest_frame,
- gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src_frame,
- gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h)
-{
- gint i, j;
- gint src_stride, dest_stride;
- guint8 *src, *dest;
- GstVideoFormat src_format;
-
- src_format = GST_VIDEO_FRAME_FORMAT (src_frame);
-
- src_stride = GST_VIDEO_FRAME_PLANE_STRIDE (src_frame, 0);
- dest_stride = GST_VIDEO_FRAME_PLANE_STRIDE (dest_frame, 0);
-
- dest_x = (dest_x & ~1);
- src_x = (src_x & ~1);
-
- w = w + (w % 2);
-
- dest = GST_VIDEO_FRAME_PLANE_DATA (dest_frame, 0);
- dest = dest + dest_y * dest_stride + dest_x * 2;
- src = GST_VIDEO_FRAME_PLANE_DATA (src_frame, 0);
- src = src + src_y * src_stride + src_x * 2;
-
- if (src_sdtv != dest_sdtv) {
- gint y1, u1, v1;
- gint y2, u2, v2;
- gint matrix[12];
-
- memcpy (matrix,
- dest_sdtv ? cog_ycbcr_hdtv_to_ycbcr_sdtv_matrix_8bit :
- cog_ycbcr_sdtv_to_ycbcr_hdtv_matrix_8bit, 12 * sizeof (gint));
-
- if (src_format == GST_VIDEO_FORMAT_YUY2) {
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 2) {
- y1 = src[j * 2 + 0];
- y2 = src[j * 2 + 2];
- u1 = u2 = src[j * 2 + 1];
- v1 = v2 = src[j * 2 + 3];
-
- dest[j * 2 + 0] = APPLY_MATRIX (matrix, 0, y1, u1, v1);
- dest[j * 2 + 1] = APPLY_MATRIX (matrix, 1, y1, u1, v1);
- dest[j * 2 + 2] = APPLY_MATRIX (matrix, 0, y1, u2, v2);
- dest[j * 2 + 3] = APPLY_MATRIX (matrix, 2, y2, u2, v2);
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else if (src_format == GST_VIDEO_FORMAT_YVYU) {
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 2) {
- y1 = src[j * 2 + 0];
- y2 = src[j * 2 + 2];
- v1 = v2 = src[j * 2 + 1];
- u1 = u2 = src[j * 2 + 3];
-
- dest[j * 2 + 0] = APPLY_MATRIX (matrix, 0, y1, u1, v1);
- dest[j * 2 + 1] = APPLY_MATRIX (matrix, 2, y1, u1, v1);
- dest[j * 2 + 2] = APPLY_MATRIX (matrix, 0, y1, u2, v2);
- dest[j * 2 + 3] = APPLY_MATRIX (matrix, 1, y2, u2, v2);
- }
- dest += dest_stride;
- src += src_stride;
- }
- } else {
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j += 2) {
- u1 = u2 = src[j * 2 + 0];
- v1 = v2 = src[j * 2 + 2];
- y1 = src[j * 2 + 1];
- y2 = src[j * 2 + 3];
-
- dest[j * 2 + 1] = APPLY_MATRIX (matrix, 0, y1, u1, v1);
- dest[j * 2 + 0] = APPLY_MATRIX (matrix, 1, y1, u1, v1);
- dest[j * 2 + 3] = APPLY_MATRIX (matrix, 0, y1, u2, v2);
- dest[j * 2 + 2] = APPLY_MATRIX (matrix, 2, y2, u2, v2);
- }
- dest += dest_stride;
- src += src_stride;
- }
- }
- } else {
- for (i = 0; i < h; i++) {
- memcpy (dest, src, w * 2);
- dest += dest_stride;
- src += src_stride;
- }
- }
-}
-
#define DEFAULT_LEFT 0
#define DEFAULT_RIGHT 0
#define DEFAULT_TOP 0
@@ -2456,6 +168,10 @@ gst_video_box_finalize (GObject * object)
g_mutex_clear (&video_box->mutex);
+ if (video_box->converter) {
+ gst_video_converter_free (video_box->converter);
+ video_box->converter = NULL;
+ }
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -2549,6 +265,7 @@ gst_video_box_init (GstVideoBox * video_box)
video_box->alpha = DEFAULT_ALPHA;
video_box->border_alpha = DEFAULT_BORDER_ALPHA;
video_box->autocrop = FALSE;
+ video_box->converter = NULL;
g_mutex_init (&video_box->mutex);
}
@@ -2987,7 +704,7 @@ bail:
static gboolean
gst_video_box_recalc_transform (GstVideoBox * video_box)
{
- gboolean res = TRUE;
+ gboolean res;
/* if we have the same format in and out and we don't need to perform any
* cropping at all, we can just operate in passthrough mode */
@@ -2999,150 +716,27 @@ gst_video_box_recalc_transform (GstVideoBox * video_box)
GST_LOG_OBJECT (video_box, "we are using passthrough");
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM_CAST (video_box),
TRUE);
+ res = TRUE;
} else {
GST_LOG_OBJECT (video_box, "we are not using passthrough");
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM_CAST (video_box),
FALSE);
+ res = FALSE;
}
return res;
}
-static gboolean
-gst_video_box_select_processing_functions (GstVideoBox * video_box)
-{
- switch (video_box->out_format) {
- case GST_VIDEO_FORMAT_AYUV:
- video_box->fill = fill_ayuv;
- switch (video_box->in_format) {
- case GST_VIDEO_FORMAT_AYUV:
- video_box->copy = copy_ayuv_ayuv;
- break;
- case GST_VIDEO_FORMAT_I420:
- case GST_VIDEO_FORMAT_YV12:
- video_box->copy = copy_i420_ayuv;
- break;
- case GST_VIDEO_FORMAT_ARGB:
- case GST_VIDEO_FORMAT_ABGR:
- case GST_VIDEO_FORMAT_RGBA:
- case GST_VIDEO_FORMAT_BGRA:
- case GST_VIDEO_FORMAT_xRGB:
- case GST_VIDEO_FORMAT_xBGR:
- case GST_VIDEO_FORMAT_RGBx:
- case GST_VIDEO_FORMAT_BGRx:
- case GST_VIDEO_FORMAT_RGB:
- case GST_VIDEO_FORMAT_BGR:
- video_box->copy = copy_rgb32_ayuv;
- break;
- default:
- break;
- }
- break;
- case GST_VIDEO_FORMAT_I420:
- case GST_VIDEO_FORMAT_YV12:
- video_box->fill = fill_planar_yuv;
- switch (video_box->in_format) {
- case GST_VIDEO_FORMAT_AYUV:
- video_box->copy = copy_ayuv_i420;
- break;
- case GST_VIDEO_FORMAT_I420:
- case GST_VIDEO_FORMAT_YV12:
- video_box->copy = copy_i420_i420;
- break;
- default:
- break;
- }
- break;
- case GST_VIDEO_FORMAT_ARGB:
- case GST_VIDEO_FORMAT_ABGR:
- case GST_VIDEO_FORMAT_RGBA:
- case GST_VIDEO_FORMAT_BGRA:
- case GST_VIDEO_FORMAT_xRGB:
- case GST_VIDEO_FORMAT_xBGR:
- case GST_VIDEO_FORMAT_RGBx:
- case GST_VIDEO_FORMAT_BGRx:
- case GST_VIDEO_FORMAT_RGB:
- case GST_VIDEO_FORMAT_BGR:
- video_box->fill = (video_box->out_format == GST_VIDEO_FORMAT_BGR
- || video_box->out_format ==
- GST_VIDEO_FORMAT_RGB) ? fill_rgb24 : fill_rgb32;
- switch (video_box->in_format) {
- case GST_VIDEO_FORMAT_ARGB:
- case GST_VIDEO_FORMAT_ABGR:
- case GST_VIDEO_FORMAT_RGBA:
- case GST_VIDEO_FORMAT_BGRA:
- case GST_VIDEO_FORMAT_xRGB:
- case GST_VIDEO_FORMAT_xBGR:
- case GST_VIDEO_FORMAT_RGBx:
- case GST_VIDEO_FORMAT_BGRx:
- case GST_VIDEO_FORMAT_RGB:
- case GST_VIDEO_FORMAT_BGR:
- video_box->copy = copy_rgb32;
- break;
- case GST_VIDEO_FORMAT_AYUV:
- video_box->copy = copy_ayuv_rgb32;
- default:
- break;
- }
- break;
- case GST_VIDEO_FORMAT_GRAY8:
- case GST_VIDEO_FORMAT_GRAY16_BE:
- case GST_VIDEO_FORMAT_GRAY16_LE:
- video_box->fill = fill_gray;
- switch (video_box->in_format) {
- case GST_VIDEO_FORMAT_GRAY8:
- case GST_VIDEO_FORMAT_GRAY16_BE:
- case GST_VIDEO_FORMAT_GRAY16_LE:
- video_box->copy = copy_packed_simple;
- break;
- default:
- break;
- }
- break;
- case GST_VIDEO_FORMAT_YUY2:
- case GST_VIDEO_FORMAT_YVYU:
- case GST_VIDEO_FORMAT_UYVY:
- video_box->fill = fill_yuy2;
- switch (video_box->in_format) {
- case GST_VIDEO_FORMAT_YUY2:
- case GST_VIDEO_FORMAT_YVYU:
- case GST_VIDEO_FORMAT_UYVY:
- video_box->copy = copy_yuy2_yuy2;
- break;
- default:
- break;
- }
- break;
- case GST_VIDEO_FORMAT_Y444:
- case GST_VIDEO_FORMAT_Y42B:
- case GST_VIDEO_FORMAT_Y41B:
- video_box->fill = fill_planar_yuv;
- switch (video_box->in_format) {
- case GST_VIDEO_FORMAT_Y444:
- video_box->copy = copy_y444_y444;
- break;
- case GST_VIDEO_FORMAT_Y42B:
- video_box->copy = copy_y42b_y42b;
- break;
- case GST_VIDEO_FORMAT_Y41B:
- video_box->copy = copy_y41b_y41b;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- return video_box->fill != NULL && video_box->copy != NULL;
-}
static gboolean
gst_video_box_set_info (GstVideoFilter * vfilter, GstCaps * in,
GstVideoInfo * in_info, GstCaps * out, GstVideoInfo * out_info)
{
GstVideoBox *video_box = GST_VIDEO_BOX (vfilter);
- gboolean ret;
+ gboolean ret = TRUE;
+ GstStructure *videobox_conf = NULL;
+ gint br, bl, bt, bb, crop_w, crop_h;
+ guint border_fill, fill_type;
+ guint b_alpha = CLAMP (video_box->border_alpha * 256, 0, 255);
g_mutex_lock (&video_box->mutex);
@@ -3168,10 +762,99 @@ gst_video_box_set_info (GstVideoFilter * vfilter, GstCaps * in,
gst_video_box_autocrop (video_box);
/* recalc the transformation strategy */
- ret = gst_video_box_recalc_transform (video_box);
+ if (gst_video_box_recalc_transform (video_box))
+ /* passthrough enabled. No need to create converter. */
+ goto finish;
+
+ if (video_box->converter) {
+ gst_video_converter_free (video_box->converter);
+ video_box->converter = NULL;
+ }
+
+ crop_h = 0;
+ crop_w = 0;
+
+ br = video_box->box_right;
+ bl = video_box->box_left;
+ bt = video_box->box_top;
+ bb = video_box->box_bottom;
+
+ if (br >= 0 && bl >= 0) {
+ crop_w = video_box->in_width - (br + bl);
+ } else if (br >= 0 && bl < 0) {
+ crop_w = video_box->in_width - (br);
+ } else if (br < 0 && bl >= 0) {
+ crop_w = video_box->in_width - (bl);
+ } else if (br < 0 && bl < 0) {
+ crop_w = video_box->in_width;
+ }
+
+ if (bb >= 0 && bt >= 0) {
+ crop_h = video_box->in_height - (bb + bt);
+ } else if (bb >= 0 && bt < 0) {
+ crop_h = video_box->in_height - (bb);
+ } else if (bb < 0 && bt >= 0) {
+ crop_h = video_box->in_height - (bt);
+ } else if (bb < 0 && bt < 0) {
+ crop_h = video_box->in_height;
+ }
+
+ video_box->crop_h = crop_h;
+ video_box->crop_w = crop_w;
+ video_box->src_y = 0;
+ video_box->src_x = 0;
+ video_box->dest_y = 0;
+ video_box->dest_x = 0;
+
+ /* Top border */
+ if (bt < 0) {
+ video_box->dest_y += -bt;
+ } else {
+ video_box->src_y += bt;
+ }
- if (ret)
- ret = gst_video_box_select_processing_functions (video_box);
+
+ /* Left border */
+ if (bl < 0) {
+ video_box->dest_x += -bl;
+ } else {
+ video_box->src_x += bl;
+ }
+
+ /* Border fill type */
+ fill_type = video_box->fill_type;
+ border_fill =
+ (b_alpha << 24) | (rgb_colors_R[fill_type] << 16) |
+ (rgb_colors_G[fill_type] << 8) | rgb_colors_B[fill_type];
+
+ GST_DEBUG_OBJECT (video_box, "Borders are: L:%d, R:%d, T:%d, B:%d", bl, br,
+ bt, bb);
+
+ videobox_conf =
+ gst_structure_new ("videoboxconf", GST_VIDEO_CONVERTER_OPT_SRC_X,
+ G_TYPE_INT, video_box->src_x, GST_VIDEO_CONVERTER_OPT_SRC_Y, G_TYPE_INT,
+ video_box->src_y, GST_VIDEO_CONVERTER_OPT_DEST_X, G_TYPE_INT,
+ video_box->dest_x, GST_VIDEO_CONVERTER_OPT_DEST_Y, G_TYPE_INT,
+ video_box->dest_y, GST_VIDEO_CONVERTER_OPT_SRC_WIDTH, G_TYPE_INT, crop_w,
+ GST_VIDEO_CONVERTER_OPT_SRC_HEIGHT, G_TYPE_INT, crop_h,
+ GST_VIDEO_CONVERTER_OPT_DEST_WIDTH, G_TYPE_INT, crop_w,
+ GST_VIDEO_CONVERTER_OPT_DEST_HEIGHT, G_TYPE_INT, crop_h,
+ GST_VIDEO_CONVERTER_OPT_FILL_BORDER, G_TYPE_BOOLEAN, TRUE,
+ GST_VIDEO_CONVERTER_OPT_BORDER_ARGB, G_TYPE_UINT, border_fill,
+ GST_VIDEO_CONVERTER_OPT_ALPHA_MODE, G_TYPE_STRING, "mult",
+ GST_VIDEO_CONVERTER_OPT_ALPHA_VALUE, G_TYPE_DOUBLE, video_box->alpha,
+ NULL);
+
+ if (videobox_conf) {
+ video_box->converter =
+ gst_video_converter_new (in_info, out_info, videobox_conf);
+
+ if (!video_box->converter)
+ ret = FALSE;
+ } else
+ ret = FALSE;
+
+finish:
g_mutex_unlock (&video_box->mutex);
return ret;
@@ -3227,77 +910,12 @@ static void
gst_video_box_process (GstVideoBox * video_box, GstVideoFrame * in,
GstVideoFrame * out)
{
- guint b_alpha = CLAMP (video_box->border_alpha * 256, 0, 255);
- guint i_alpha = CLAMP (video_box->alpha * 256, 0, 255);
- GstVideoBoxFill fill_type = video_box->fill_type;
- gint br, bl, bt, bb, crop_w, crop_h;
-
- crop_h = 0;
- crop_w = 0;
-
- br = video_box->box_right;
- bl = video_box->box_left;
- bt = video_box->box_top;
- bb = video_box->box_bottom;
-
- if (br >= 0 && bl >= 0) {
- crop_w = video_box->in_width - (br + bl);
- } else if (br >= 0 && bl < 0) {
- crop_w = video_box->in_width - (br);
- } else if (br < 0 && bl >= 0) {
- crop_w = video_box->in_width - (bl);
- } else if (br < 0 && bl < 0) {
- crop_w = video_box->in_width;
- }
-
- if (bb >= 0 && bt >= 0) {
- crop_h = video_box->in_height - (bb + bt);
- } else if (bb >= 0 && bt < 0) {
- crop_h = video_box->in_height - (bb);
- } else if (bb < 0 && bt >= 0) {
- crop_h = video_box->in_height - (bt);
- } else if (bb < 0 && bt < 0) {
- crop_h = video_box->in_height;
- }
-
- GST_DEBUG_OBJECT (video_box, "Borders are: L:%d, R:%d, T:%d, B:%d", bl, br,
- bt, bb);
- GST_DEBUG_OBJECT (video_box, "Alpha value is: %u (frame) %u (border)",
- i_alpha, b_alpha);
-
- if (crop_h < 0 || crop_w < 0) {
- video_box->fill (fill_type, b_alpha, out, video_box->out_sdtv);
- } else if (bb == 0 && bt == 0 && br == 0 && bl == 0) {
- video_box->copy (i_alpha, out, video_box->out_sdtv, 0, 0, in,
- video_box->in_sdtv, 0, 0, crop_w, crop_h);
+ if (video_box->converter) {
+ gst_video_converter_frame (video_box->converter, in, out);
+ GST_LOG_OBJECT (video_box, "image created");
} else {
- gint src_x = 0, src_y = 0;
- gint dest_x = 0, dest_y = 0;
-
- /* Fill everything if a border should be added somewhere */
- if (bt < 0 || bb < 0 || br < 0 || bl < 0)
- video_box->fill (fill_type, b_alpha, out, video_box->out_sdtv);
-
- /* Top border */
- if (bt < 0) {
- dest_y += -bt;
- } else {
- src_y += bt;
- }
-
- /* Left border */
- if (bl < 0) {
- dest_x += -bl;
- } else {
- src_x += bl;
- }
-
- /* Frame */
- video_box->copy (i_alpha, out, video_box->out_sdtv, dest_x, dest_y,
- in, video_box->in_sdtv, src_x, src_y, crop_w, crop_h);
+ GST_WARNING_OBJECT (video_box, "Converter not found");
}
-
- GST_LOG_OBJECT (video_box, "image created");
}
static void
@@ -3326,6 +944,7 @@ gst_video_box_transform_frame (GstVideoFilter * vfilter,
g_mutex_lock (&video_box->mutex);
gst_video_box_process (video_box, in_frame, out_frame);
g_mutex_unlock (&video_box->mutex);
+
return GST_FLOW_OK;
}
diff --git a/gst/videobox/gstvideobox.h b/gst/videobox/gstvideobox.h
index cbb98ac39..57ee8ec0c 100644
--- a/gst/videobox/gstvideobox.h
+++ b/gst/videobox/gstvideobox.h
@@ -78,8 +78,9 @@ struct _GstVideoBox
gboolean autocrop;
- void (*fill) (GstVideoBoxFill fill_type, guint b_alpha, GstVideoFrame *dest, gboolean sdtv);
- void (*copy) (guint i_alpha, GstVideoFrame * dest, gboolean dest_sdtv, gint dest_x, gint dest_y, GstVideoFrame * src, gboolean src_sdtv, gint src_x, gint src_y, gint w, gint h);
+ GstVideoConverter *converter;
+ gint crop_w, crop_h, src_x, src_y, dest_x, dest_y;
+
};
struct _GstVideoBoxClass