[gst-devel] Patch for RGB/BGR 15/16 bit support
Martin Bisson
martin.bisson at gmail.com
Tue Jun 1 23:28:39 CEST 2010
Hi,
Here is a small patch that adds RGB (and BGR) 15 and 16 bit video format to
GstVideoFormat and adds the necessary supporting code in
gst-plugins-base/gst-libs/gst/video/video.{c,h}.
It's the first time I "submit" a patch. What I actually want more is
feedback on it, because aside from the little tests I did with my own little
use cases, I have a hard time evaluating the impact of this patch on the
whole project. So I would be interested in your feedback and/or way to test
it more and/or any suggestions and/or advice on how to properly publish this
patch in gstreamer.
Thank you,
Martin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20100601/010e5d5b/attachment.htm>
-------------- next part --------------
From 699a7d33c157d49a789d1cd2bd7e6f55c142373e Mon Sep 17 00:00:00 2001
From: Martin Bisson <martin.bisson at gmail.com>
Date: Tue, 1 Jun 2010 14:42:54 +0000
Subject: [PATCH 1/2] video.{c,h}: Add support for RGB and BGR with 15 and 16 bits.
---
gst-libs/gst/video/video.c | 137 ++++++++++++++++++++++++++++++++++++++++----
gst-libs/gst/video/video.h | 92 ++++++++++++++++++------------
2 files changed, 181 insertions(+), 48 deletions(-)
diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c
index e5c2c82..a456336 100644
--- a/gst-libs/gst/video/video.c
+++ b/gst-libs/gst/video/video.c
@@ -43,6 +43,8 @@ static GstVideoFormat gst_video_format_from_rgba32_masks (int red_mask,
int green_mask, int blue_mask, int alpha_mask);
static GstVideoFormat gst_video_format_from_rgb24_masks (int red_mask,
int green_mask, int blue_mask);
+static GstVideoFormat gst_video_format_from_rgb16_masks (int red_mask,
+ int green_mask, int blue_mask);
/**
@@ -381,6 +383,13 @@ gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
ok = FALSE;
}
+ } else if ((depth == 15 || depth == 16) && bpp == 16 &&
+ endianness == G_BIG_ENDIAN) {
+ *format = gst_video_format_from_rgb16_masks (red_mask, green_mask,
+ blue_mask);
+ if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
+ ok = FALSE;
+ }
} else {
ok = FALSE;
}
@@ -584,23 +593,65 @@ gst_video_format_new_caps (GstVideoFormat format, int width, int height,
depth = 24;
have_alpha = FALSE;
break;
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ bpp = 16;
+ depth = 16;
+ have_alpha = FALSE;
+ break;
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
+ bpp = 16;
+ depth = 15;
+ have_alpha = FALSE;
+ break;
default:
return NULL;
}
- if (bpp == 32) {
- mask = 0xff000000;
+ if (bpp == 32 || bpp == 24) {
+ if (bpp == 32) {
+ mask = 0xff000000;
+ } else {
+ mask = 0xff0000;
+ }
+ red_mask =
+ mask >> (8 * gst_video_format_get_component_offset (format, 0, width,
+ height));
+ green_mask =
+ mask >> (8 * gst_video_format_get_component_offset (format, 1, width,
+ height));
+ blue_mask =
+ mask >> (8 * gst_video_format_get_component_offset (format, 2, width,
+ height));
+ } else if (bpp == 16) {
+ switch (format) {
+ case GST_VIDEO_FORMAT_RGB16:
+ red_mask = GST_VIDEO_COMP1_MASK_16_INT;
+ green_mask = GST_VIDEO_COMP2_MASK_16_INT;
+ blue_mask = GST_VIDEO_COMP3_MASK_16_INT;
+ break;
+ case GST_VIDEO_FORMAT_BGR16:
+ red_mask = GST_VIDEO_COMP3_MASK_16_INT;
+ green_mask = GST_VIDEO_COMP2_MASK_16_INT;
+ blue_mask = GST_VIDEO_COMP1_MASK_16_INT;
+ break;
+ break;
+ case GST_VIDEO_FORMAT_RGB15:
+ red_mask = GST_VIDEO_COMP1_MASK_15_INT;
+ green_mask = GST_VIDEO_COMP2_MASK_15_INT;
+ blue_mask = GST_VIDEO_COMP3_MASK_15_INT;
+ break;
+ case GST_VIDEO_FORMAT_BGR15:
+ red_mask = GST_VIDEO_COMP3_MASK_15_INT;
+ green_mask = GST_VIDEO_COMP2_MASK_15_INT;
+ blue_mask = GST_VIDEO_COMP1_MASK_15_INT;
+ break;
+ default:
+ return NULL;
+ }
} else {
- mask = 0xff0000;
+ return NULL;
}
- red_mask =
- mask >> (8 * gst_video_format_get_component_offset (format, 0, width,
- height));
- green_mask =
- mask >> (8 * gst_video_format_get_component_offset (format, 1, width,
- height));
- blue_mask =
- mask >> (8 * gst_video_format_get_component_offset (format, 2, width,
- height));
caps = gst_caps_new_simple ("video/x-raw-rgb",
"bpp", G_TYPE_INT, bpp,
@@ -844,6 +895,33 @@ gst_video_format_from_rgb24_masks (int red_mask, int green_mask, int blue_mask)
return GST_VIDEO_FORMAT_UNKNOWN;
}
+static GstVideoFormat
+gst_video_format_from_rgb16_masks (int red_mask, int green_mask, int blue_mask)
+{
+ if (red_mask == GST_VIDEO_COMP1_MASK_16_INT
+ && green_mask == GST_VIDEO_COMP2_MASK_16_INT
+ && blue_mask == GST_VIDEO_COMP3_MASK_16_INT) {
+ return GST_VIDEO_FORMAT_RGB16;
+ }
+ if (red_mask == GST_VIDEO_COMP3_MASK_16_INT
+ && green_mask == GST_VIDEO_COMP2_MASK_16_INT
+ && blue_mask == GST_VIDEO_COMP1_MASK_16_INT) {
+ return GST_VIDEO_FORMAT_BGR16;
+ }
+ if (red_mask == GST_VIDEO_COMP1_MASK_15_INT
+ && green_mask == GST_VIDEO_COMP2_MASK_15_INT
+ && blue_mask == GST_VIDEO_COMP3_MASK_15_INT) {
+ return GST_VIDEO_FORMAT_RGB15;
+ }
+ if (red_mask == GST_VIDEO_COMP3_MASK_15_INT
+ && green_mask == GST_VIDEO_COMP2_MASK_15_INT
+ && blue_mask == GST_VIDEO_COMP1_MASK_15_INT) {
+ return GST_VIDEO_FORMAT_BGR15;
+ }
+
+ return GST_VIDEO_FORMAT_UNKNOWN;
+}
+
/**
* gst_video_format_is_rgb:
* @format: a #GstVideoFormat
@@ -883,6 +961,10 @@ gst_video_format_is_rgb (GstVideoFormat format)
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
return TRUE;
default:
return FALSE;
@@ -928,6 +1010,10 @@ gst_video_format_is_yuv (GstVideoFormat format)
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
return FALSE;
default:
return FALSE;
@@ -998,6 +1084,10 @@ gst_video_format_has_alpha (GstVideoFormat format)
case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
return FALSE;
default:
return FALSE;
@@ -1052,6 +1142,11 @@ gst_video_format_get_row_stride (GstVideoFormat format, int component,
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR:
return width * 4;
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
+ return GST_ROUND_UP_4 (width * 2);
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
case GST_VIDEO_FORMAT_v308:
@@ -1132,6 +1227,11 @@ gst_video_format_get_pixel_stride (GstVideoFormat format, int component)
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR:
return 4;
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
+ return 2;
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
case GST_VIDEO_FORMAT_v308:
@@ -1215,6 +1315,10 @@ gst_video_format_get_component_width (GstVideoFormat format, int component,
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
case GST_VIDEO_FORMAT_Y444:
case GST_VIDEO_FORMAT_v308:
case GST_VIDEO_FORMAT_NV12:
@@ -1276,6 +1380,10 @@ gst_video_format_get_component_height (GstVideoFormat format, int component,
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
case GST_VIDEO_FORMAT_Y444:
case GST_VIDEO_FORMAT_v210:
case GST_VIDEO_FORMAT_v216:
@@ -1528,6 +1636,11 @@ gst_video_format_get_size (GstVideoFormat format, int width, int height)
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR:
return width * 4 * height;
+ case GST_VIDEO_FORMAT_RGB16:
+ case GST_VIDEO_FORMAT_BGR16:
+ case GST_VIDEO_FORMAT_RGB15:
+ case GST_VIDEO_FORMAT_BGR15:
+ return GST_ROUND_UP_4 (width * 2) * height;
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
case GST_VIDEO_FORMAT_v308:
diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h
index ebf20b9..a3ec55d 100644
--- a/gst-libs/gst/video/video.h
+++ b/gst-libs/gst/video/video.h
@@ -57,6 +57,10 @@ G_BEGIN_DECLS
* @GST_VIDEO_FORMAT_GRAY16_BE: 16-bit grayscale, most significant byte first (Since: 0.10.29)
* @GST_VIDEO_FORMAT_GRAY16_LE: 16-bit grayscale, least significant byte first (Since: 0.10.29)
* @GST_VIDEO_FORMAT_v308: packed 4:4:4 YUV (Since: 0.10.29)
+ * @GST_VIDEO_FORMAT_RGB16: rgb 5-6-5 bits per component (Since: 0.10.29)
+ * @GST_VIDEO_FORMAT_BGR16: reverse rgb 5-6-5 bits per component (Since: 0.10.29)
+ * @GST_VIDEO_FORMAT_RGB15: rgb 5-5-5 bits per component (Since: 0.10.29)
+ * @GST_VIDEO_FORMAT_BGR15: reverse rgb 5-5-5 bits per component (Since: 0.10.29)
*
* Enum value describing the most common video formats.
*/
@@ -88,7 +92,11 @@ typedef enum {
GST_VIDEO_FORMAT_GRAY8,
GST_VIDEO_FORMAT_GRAY16_BE,
GST_VIDEO_FORMAT_GRAY16_LE,
- GST_VIDEO_FORMAT_v308
+ GST_VIDEO_FORMAT_v308,
+ GST_VIDEO_FORMAT_RGB16,
+ GST_VIDEO_FORMAT_BGR16,
+ GST_VIDEO_FORMAT_RGB15,
+ GST_VIDEO_FORMAT_BGR15
} GstVideoFormat;
#define GST_VIDEO_BYTE1_MASK_32 "0xFF000000"
@@ -109,21 +117,21 @@ typedef enum {
#define GST_VIDEO_BYTE2_MASK_24_INT 0x0000FF00
#define GST_VIDEO_BYTE3_MASK_24_INT 0x000000FF
-#define GST_VIDEO_RED_MASK_16 "0xf800"
-#define GST_VIDEO_GREEN_MASK_16 "0x07e0"
-#define GST_VIDEO_BLUE_MASK_16 "0x001f"
+#define GST_VIDEO_COMP1_MASK_16 "0xf800"
+#define GST_VIDEO_COMP2_MASK_16 "0x07e0"
+#define GST_VIDEO_COMP3_MASK_16 "0x001f"
-#define GST_VIDEO_RED_MASK_15 "0x7c00"
-#define GST_VIDEO_GREEN_MASK_15 "0x03e0"
-#define GST_VIDEO_BLUE_MASK_15 "0x001f"
+#define GST_VIDEO_COMP1_MASK_15 "0x7c00"
+#define GST_VIDEO_COMP2_MASK_15 "0x03e0"
+#define GST_VIDEO_COMP3_MASK_15 "0x001f"
-#define GST_VIDEO_RED_MASK_16_INT 0xf800
-#define GST_VIDEO_GREEN_MASK_16_INT 0x07e0
-#define GST_VIDEO_BLUE_MASK_16_INT 0x001f
+#define GST_VIDEO_COMP1_MASK_16_INT 0xf800
+#define GST_VIDEO_COMP2_MASK_16_INT 0x07e0
+#define GST_VIDEO_COMP3_MASK_16_INT 0x001f
-#define GST_VIDEO_RED_MASK_15_INT 0x7c00
-#define GST_VIDEO_GREEN_MASK_15_INT 0x03e0
-#define GST_VIDEO_BLUE_MASK_15_INT 0x001f
+#define GST_VIDEO_COMP1_MASK_15_INT 0x7c00
+#define GST_VIDEO_COMP2_MASK_15_INT 0x03e0
+#define GST_VIDEO_COMP3_MASK_15_INT 0x001f
#define GST_VIDEO_SIZE_RANGE "(int) [ 1, max ]"
#define GST_VIDEO_FPS_RANGE "(fraction) [ 0, max ]"
@@ -166,6 +174,30 @@ typedef enum {
"height = " GST_VIDEO_SIZE_RANGE ", " \
"framerate = " GST_VIDEO_FPS_RANGE
+#define __GST_VIDEO_CAPS_MAKE_16(R, G, B) \
+ "video/x-raw-rgb, " \
+ "bpp = (int) 16, " \
+ "depth = (int) 16, " \
+ "endianness = (int) BIG_ENDIAN, " \
+ "red_mask = (int) " GST_VIDEO_COMP ## R ## _MASK_16 ", " \
+ "green_mask = (int) " GST_VIDEO_COMP ## G ## _MASK_16 ", " \
+ "blue_mask = (int) " GST_VIDEO_COMP ## B ## _MASK_16 ", " \
+ "width = " GST_VIDEO_SIZE_RANGE ", " \
+ "height = " GST_VIDEO_SIZE_RANGE ", " \
+ "framerate = " GST_VIDEO_FPS_RANGE
+
+#define __GST_VIDEO_CAPS_MAKE_15(R, G, B) \
+ "video/x-raw-rgb, " \
+ "bpp = (int) 16, " \
+ "depth = (int) 15, " \
+ "endianness = (int) BIG_ENDIAN, " \
+ "red_mask = (int) " GST_VIDEO_COMP ## R ## _MASK_15 ", " \
+ "green_mask = (int) " GST_VIDEO_COMP ## G ## _MASK_15 ", " \
+ "blue_mask = (int) " GST_VIDEO_COMP ## B ## _MASK_15 ", " \
+ "width = " GST_VIDEO_SIZE_RANGE ", " \
+ "height = " GST_VIDEO_SIZE_RANGE ", " \
+ "framerate = " GST_VIDEO_FPS_RANGE
+
/* 24 bit */
@@ -218,29 +250,17 @@ typedef enum {
/* 15/16 bit */
-#define GST_VIDEO_CAPS_RGB_16 \
- "video/x-raw-rgb, " \
- "bpp = (int) 16, " \
- "depth = (int) 16, " \
- "endianness = (int) BYTE_ORDER, " \
- "red_mask = (int) " GST_VIDEO_RED_MASK_16 ", " \
- "green_mask = (int) " GST_VIDEO_GREEN_MASK_16 ", " \
- "blue_mask = (int) " GST_VIDEO_BLUE_MASK_16 ", " \
- "width = " GST_VIDEO_SIZE_RANGE ", " \
- "height = " GST_VIDEO_SIZE_RANGE ", " \
- "framerate = " GST_VIDEO_FPS_RANGE
-
-#define GST_VIDEO_CAPS_RGB_15 \
- "video/x-raw-rgb, " \
- "bpp = (int) 16, " \
- "depth = (int) 15, " \
- "endianness = (int) BYTE_ORDER, " \
- "red_mask = (int) " GST_VIDEO_RED_MASK_15 ", " \
- "green_mask = (int) " GST_VIDEO_GREEN_MASK_15 ", " \
- "blue_mask = (int) " GST_VIDEO_BLUE_MASK_15 ", " \
- "width = " GST_VIDEO_SIZE_RANGE ", " \
- "height = " GST_VIDEO_SIZE_RANGE ", " \
- "framerate = " GST_VIDEO_FPS_RANGE
+#define GST_VIDEO_CAPS_RGB_16 \
+ __GST_VIDEO_CAPS_MAKE_16 (1, 2, 3)
+
+#define GST_VIDEO_CAPS_BGR_16 \
+ __GST_VIDEO_CAPS_MAKE_16 (3, 2, 1)
+
+#define GST_VIDEO_CAPS_RGB_15 \
+ __GST_VIDEO_CAPS_MAKE_15 (1, 2, 3)
+
+#define GST_VIDEO_CAPS_BGR_15 \
+ __GST_VIDEO_CAPS_MAKE_15 (3, 2, 1)
/**
* GST_VIDEO_CAPS_YUV:
--
1.6.4.4
From 9cdd2d4d9ccc984f805bcc2c8745ae2878833049 Mon Sep 17 00:00:00 2001
From: Martin Bisson <martin.bisson at gmail.com>
Date: Tue, 1 Jun 2010 16:45:34 +0000
Subject: [PATCH 2/2] video.{c,h}: Fix an endianness bug fix.
This commit makes sure the endianness is ok for RGB/BGR 15/16 formats.
---
gst-libs/gst/video/video.c | 2 +-
gst-libs/gst/video/video.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c
index a456336..b670f46 100644
--- a/gst-libs/gst/video/video.c
+++ b/gst-libs/gst/video/video.c
@@ -384,7 +384,7 @@ gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
ok = FALSE;
}
} else if ((depth == 15 || depth == 16) && bpp == 16 &&
- endianness == G_BIG_ENDIAN) {
+ endianness == G_BYTE_ORDER) {
*format = gst_video_format_from_rgb16_masks (red_mask, green_mask,
blue_mask);
if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h
index a3ec55d..e145c33 100644
--- a/gst-libs/gst/video/video.h
+++ b/gst-libs/gst/video/video.h
@@ -178,7 +178,7 @@ typedef enum {
"video/x-raw-rgb, " \
"bpp = (int) 16, " \
"depth = (int) 16, " \
- "endianness = (int) BIG_ENDIAN, " \
+ "endianness = (int) BYTE_ORDER, " \
"red_mask = (int) " GST_VIDEO_COMP ## R ## _MASK_16 ", " \
"green_mask = (int) " GST_VIDEO_COMP ## G ## _MASK_16 ", " \
"blue_mask = (int) " GST_VIDEO_COMP ## B ## _MASK_16 ", " \
@@ -190,7 +190,7 @@ typedef enum {
"video/x-raw-rgb, " \
"bpp = (int) 16, " \
"depth = (int) 15, " \
- "endianness = (int) BIG_ENDIAN, " \
+ "endianness = (int) BYTE_ORDER, " \
"red_mask = (int) " GST_VIDEO_COMP ## R ## _MASK_15 ", " \
"green_mask = (int) " GST_VIDEO_COMP ## G ## _MASK_15 ", " \
"blue_mask = (int) " GST_VIDEO_COMP ## B ## _MASK_15 ", " \
--
1.6.4.4
More information about the gstreamer-devel
mailing list