Commit 687ff845 authored by Sebastian Dröge's avatar Sebastian Dröge
Browse files

videobox: Add support for 3 byte RGB formats and refactor RGB code a bit

parent d0ad28ad
......@@ -730,52 +730,88 @@ copy_i420_ayuv (guint i_alpha, GstVideoFormat dest_format, guint8 * dest,
}
static void
fill_rgb32 (GstVideoBoxFill fill_type, guint b_alpha, GstVideoFormat format,
guint8 * dest, gboolean sdtv, gint width, gint height)
_argb_order (GstVideoFormat format, gint p[4], gboolean * alpha)
{
guint32 empty_pixel;
gint a_off, r_off, g_off, b_off;
*alpha = FALSE;
switch (format) {
case GST_VIDEO_FORMAT_ARGB:
*alpha = TRUE;
case GST_VIDEO_FORMAT_xRGB:
a_off = 24;
r_off = 16;
g_off = 8;
b_off = 0;
p[0] = 0;
p[1] = 1;
p[2] = 2;
p[3] = 3;
break;
case GST_VIDEO_FORMAT_ABGR:
*alpha = TRUE;
case GST_VIDEO_FORMAT_xBGR:
a_off = 24;
b_off = 16;
g_off = 8;
r_off = 0;
p[0] = 0;
p[1] = 3;
p[2] = 2;
p[3] = 1;
break;
case GST_VIDEO_FORMAT_RGBA:
*alpha = TRUE;
case GST_VIDEO_FORMAT_RGBx:
r_off = 24;
g_off = 16;
b_off = 8;
a_off = 0;
case GST_VIDEO_FORMAT_RGB:
p[0] = 3;
p[1] = 0;
p[2] = 1;
p[3] = 2;
break;
case GST_VIDEO_FORMAT_BGRA:
*alpha = TRUE;
case GST_VIDEO_FORMAT_BGRx:
b_off = 24;
g_off = 16;
r_off = 8;
a_off = 0;
case GST_VIDEO_FORMAT_BGR:
p[0] = 3;
p[1] = 2;
p[2] = 1;
p[3] = 0;
break;
default:
g_assert_not_reached ();
}
}
static void
fill_rgb32 (GstVideoBoxFill fill_type, guint b_alpha, GstVideoFormat format,
guint8 * dest, gboolean sdtv, gint width, gint height)
{
guint32 empty_pixel;
gint p[4];
gboolean alpha;
empty_pixel = GUINT32_FROM_BE ((b_alpha << a_off) |
(rgb_colors_R[fill_type] << r_off) |
(rgb_colors_G[fill_type] << g_off) | (rgb_colors_B[fill_type] << b_off));
_argb_order (format, p, &alpha);
empty_pixel = GUINT32_FROM_BE ((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)));
oil_splat_u32_ns ((guint32 *) dest, &empty_pixel, width * height);
}
static void
fill_rgb24 (GstVideoBoxFill fill_type, guint b_alpha, GstVideoFormat format,
guint8 * dest, gboolean sdtv, gint width, gint height)
{
gint dest_stride = GST_ROUND_UP_4 (width * 3);
gint p[4];
gboolean alpha;
gint i, j;
_argb_order (format, p, &alpha);
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
dest[3 * j + p[0]] = rgb_colors_R[fill_type];
dest[3 * j + p[1]] = rgb_colors_G[fill_type];
dest[3 * j + p[2]] = rgb_colors_B[fill_type];
}
dest += dest_stride;
}
}
static void
copy_rgb32 (guint i_alpha, GstVideoFormat dest_format, guint8 * dest,
gboolean dest_sdtv, gint dest_width, gint dest_height, gint dest_x,
......@@ -784,200 +820,29 @@ copy_rgb32 (guint i_alpha, GstVideoFormat dest_format, guint8 * dest,
gint w, gint h)
{
gint i, j;
gint src_stride = 4 * src_width;
gint dest_stride = 4 * dest_width;
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 = (dest_format == GST_VIDEO_FORMAT_RGB
|| dest_format == GST_VIDEO_FORMAT_BGR);
gboolean packed_in = (src_format == GST_VIDEO_FORMAT_RGB
|| src_format == GST_VIDEO_FORMAT_BGR);
switch (dest_format) {
case GST_VIDEO_FORMAT_ARGB:
out_alpha = TRUE;
case GST_VIDEO_FORMAT_xRGB:
p_out[0] = 0;
p_out[1] = 1;
p_out[2] = 2;
p_out[3] = 3;
switch (src_format) {
case GST_VIDEO_FORMAT_ARGB:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_xRGB:
p_in[0] = 0;
p_in[1] = 1;
p_in[2] = 2;
p_in[3] = 3;
break;
case GST_VIDEO_FORMAT_ABGR:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_xBGR:
p_in[0] = 0;
p_in[1] = 3;
p_in[2] = 2;
p_in[3] = 1;
break;
case GST_VIDEO_FORMAT_RGBA:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_RGBx:
p_in[0] = 3;
p_in[1] = 0;
p_in[2] = 1;
p_in[3] = 2;
break;
case GST_VIDEO_FORMAT_BGRA:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_BGRx:
p_in[0] = 3;
p_in[1] = 2;
p_in[2] = 1;
p_in[3] = 0;
break;
default:
g_assert_not_reached ();
}
break;
case GST_VIDEO_FORMAT_ABGR:
out_alpha = TRUE;
case GST_VIDEO_FORMAT_xBGR:
p_out[0] = 0;
p_out[1] = 3;
p_out[2] = 2;
p_out[3] = 1;
switch (src_format) {
case GST_VIDEO_FORMAT_ARGB:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_xRGB:
p_in[0] = 0;
p_in[1] = 1;
p_in[2] = 2;
p_in[3] = 3;
break;
case GST_VIDEO_FORMAT_ABGR:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_xBGR:
p_in[0] = 0;
p_in[1] = 3;
p_in[2] = 2;
p_in[3] = 1;
break;
case GST_VIDEO_FORMAT_RGBA:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_RGBx:
p_in[0] = 3;
p_in[1] = 0;
p_in[2] = 1;
p_in[3] = 2;
break;
case GST_VIDEO_FORMAT_BGRA:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_BGRx:
p_in[0] = 3;
p_in[1] = 2;
p_in[2] = 1;
p_in[3] = 0;
break;
default:
g_assert_not_reached ();
}
break;
case GST_VIDEO_FORMAT_RGBA:
out_alpha = TRUE;
case GST_VIDEO_FORMAT_RGBx:
p_out[0] = 3;
p_out[1] = 0;
p_out[2] = 1;
p_out[3] = 2;
switch (src_format) {
case GST_VIDEO_FORMAT_ARGB:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_xRGB:
p_in[0] = 0;
p_in[1] = 1;
p_in[2] = 2;
p_in[3] = 3;
break;
case GST_VIDEO_FORMAT_ABGR:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_xBGR:
p_in[0] = 0;
p_in[1] = 3;
p_in[2] = 2;
p_in[3] = 1;
break;
case GST_VIDEO_FORMAT_RGBA:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_RGBx:
p_in[0] = 3;
p_in[1] = 0;
p_in[2] = 1;
p_in[3] = 2;
break;
case GST_VIDEO_FORMAT_BGRA:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_BGRx:
p_in[0] = 3;
p_in[1] = 2;
p_in[2] = 1;
p_in[3] = 0;
break;
default:
g_assert_not_reached ();
}
break;
case GST_VIDEO_FORMAT_BGRA:
out_alpha = TRUE;
case GST_VIDEO_FORMAT_BGRx:
p_out[0] = 3;
p_out[1] = 2;
p_out[2] = 1;
p_out[3] = 0;
switch (src_format) {
case GST_VIDEO_FORMAT_ARGB:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_xRGB:
p_in[0] = 0;
p_in[1] = 1;
p_in[2] = 2;
p_in[3] = 3;
break;
case GST_VIDEO_FORMAT_ABGR:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_xBGR:
p_in[0] = 0;
p_in[1] = 3;
p_in[2] = 2;
p_in[3] = 1;
break;
case GST_VIDEO_FORMAT_RGBA:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_RGBx:
p_in[0] = 3;
p_in[1] = 0;
p_in[2] = 1;
p_in[3] = 2;
break;
case GST_VIDEO_FORMAT_BGRA:
in_alpha = TRUE;
case GST_VIDEO_FORMAT_BGRx:
p_in[0] = 3;
p_in[1] = 2;
p_in[2] = 1;
p_in[3] = 0;
break;
default:
g_assert_not_reached ();
}
break;
default:
g_assert_not_reached ();
break;
}
src_stride = (packed_in) ? GST_ROUND_UP_4 (3 * src_width) : 4 * src_width;
dest_stride = (packed_out) ? GST_ROUND_UP_4 (3 * dest_width) : 4 * dest_width;
in_bpp = (packed_in) ? 3 : 4;
out_bpp = (packed_out) ? 3 : 4;
dest = dest + dest_y * dest_width * 4 + dest_x * 4;
src = src + src_y * src_width * 4 + src_x * 4;
_argb_order (dest_format, p_out, &out_alpha);
_argb_order (src_format, p_in, &in_alpha);
w *= 4;
dest = dest + dest_y * dest_stride + dest_x * out_bpp;
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;
......@@ -988,7 +853,8 @@ copy_rgb32 (guint i_alpha, GstVideoFormat dest_format, guint8 * dest,
dest += dest_stride;
src += src_stride;
}
} else if (out_alpha) {
} else if (out_alpha && !packed_in) {
w *= 4;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j += 4) {
dest[j + p_out[0]] = i_alpha & 0xff;
......@@ -999,7 +865,8 @@ copy_rgb32 (guint i_alpha, GstVideoFormat dest_format, guint8 * dest,
dest += dest_stride;
src += src_stride;
}
} else {
} 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]];
......@@ -1009,6 +876,16 @@ copy_rgb32 (guint i_alpha, GstVideoFormat dest_format, guint8 * dest,
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;
}
}
}
......@@ -1043,7 +920,8 @@ static GstStaticPadTemplate gst_video_box_src_template =
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBx ";"
GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_BGRA ";"
GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_RGBA)
GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_RGBA ";"
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR)
);
static GstStaticPadTemplate gst_video_box_sink_template =
......@@ -1055,7 +933,8 @@ static GstStaticPadTemplate gst_video_box_sink_template =
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xBGR ";" GST_VIDEO_CAPS_RGBx ";"
GST_VIDEO_CAPS_ARGB ";" GST_VIDEO_CAPS_BGRA ";"
GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_RGBA)
GST_VIDEO_CAPS_ABGR ";" GST_VIDEO_CAPS_RGBA ";"
GST_VIDEO_CAPS_RGB ";" GST_VIDEO_CAPS_BGR)
);
GST_BOILERPLATE (GstVideoBox, gst_video_box, GstBaseTransform,
......@@ -1388,7 +1267,7 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
structure = gst_caps_get_structure (to, 0);
/* For I420/AYUV we support conversion, for all
* 32bpp RGBs we support conversion and for
* 24/32bpp RGBs we support conversion and for
* everything else we only support passthrough
*/
name = gst_structure_get_name (structure);
......@@ -1420,12 +1299,14 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
} else if (g_str_equal (name, "video/x-raw-rgb")) {
gint bpp;
if (gst_structure_get_int (structure, "bpp", &bpp) && bpp == 32) {
if (gst_structure_get_int (structure, "bpp", &bpp) &&
(bpp == 32 || bpp == 24)) {
GValue list = { 0, };
GValue val = { 0, };
/* get rid of format */
gst_structure_remove_field (structure, "depth");
gst_structure_remove_field (structure, "bpp");
gst_structure_remove_field (structure, "red_mask");
gst_structure_remove_field (structure, "green_mask");
gst_structure_remove_field (structure, "blue_mask");
......@@ -1440,6 +1321,7 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
gst_value_list_append_value (&list, &val);
g_value_reset (&val);
gst_structure_set_value (structure, "depth", &list);
gst_structure_set_value (structure, "bpp", &list);
g_value_unset (&list);
}
}
......@@ -1556,7 +1438,11 @@ gst_video_box_select_processing_functions (GstVideoBox * video_box)
case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx:
video_box->fill = fill_rgb32;
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:
......@@ -1566,6 +1452,8 @@ gst_video_box_select_processing_functions (GstVideoBox * video_box)
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;
default:
break;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment