From f5a690f860d9eba396e0a4e06cd07b4489fbd7e3 Mon Sep 17 00:00:00 2001 From: Martin Bisson Date: Tue, 1 Jun 2010 14:42:54 +0000 Subject: [PATCH] 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 c644b7113f..d3d8d44403 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, @@ -854,6 +905,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 @@ -893,6 +971,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; @@ -940,6 +1022,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; @@ -1014,6 +1100,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; @@ -1068,6 +1158,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: @@ -1150,6 +1245,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: @@ -1235,6 +1335,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: @@ -1298,6 +1402,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: @@ -1554,6 +1662,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 c00f0a12b8..5034a2966b 100644 --- a/gst-libs/gst/video/video.h +++ b/gst-libs/gst/video/video.h @@ -57,8 +57,12 @@ 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_Y800: same as GST_VIDEO_FORMAT_GRAY8 (Since: 0.10.29) - * @GST_VIDEO_FORMAT_Y16: same as GST_VIDEO_FORMAT_GRAY16_LE (Since: 0.10.29) + * @GST_VIDEO_FORMAT_Y800: same as GST_VIDEO_FORMAT_GRAY8 (Since: 0.10.30) + * @GST_VIDEO_FORMAT_Y16: same as GST_VIDEO_FORMAT_GRAY16_LE (Since: 0.10.30) + * @GST_VIDEO_FORMAT_RGB16: rgb 5-6-5 bits per component (Since: 0.10.30) + * @GST_VIDEO_FORMAT_BGR16: reverse rgb 5-6-5 bits per component (Since: 0.10.30) + * @GST_VIDEO_FORMAT_RGB15: rgb 5-5-5 bits per component (Since: 0.10.30) + * @GST_VIDEO_FORMAT_BGR15: reverse rgb 5-5-5 bits per component (Since: 0.10.30) * * Enum value describing the most common video formats. */ @@ -93,6 +97,10 @@ typedef enum { GST_VIDEO_FORMAT_v308, GST_VIDEO_FORMAT_Y800, GST_VIDEO_FORMAT_Y16 + GST_VIDEO_FORMAT_RGB16, + GST_VIDEO_FORMAT_BGR16, + GST_VIDEO_FORMAT_RGB15, + GST_VIDEO_FORMAT_BGR15 } GstVideoFormat; #define GST_VIDEO_BYTE1_MASK_32 "0xFF000000" @@ -113,21 +121,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 ]" @@ -170,6 +178,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 */ @@ -222,29 +254,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_16 \ + __GST_VIDEO_CAPS_MAKE_16 (1, 2, 3) -#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_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: