summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2010-11-02 16:05:37 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2010-11-02 16:07:07 +0100
commit50fa9610b1e59e1db7c9b0cdd037ff19bcb31f49 (patch)
tree8263d72ca989e6b064526d223e01aa6f99e57a70
parentd96964e391b26eb72164a90c340374c8600bef15 (diff)
colorspace: Add support for 8 bit paletted RGB
This needs the 8 bit paletted support from -base which will be committed after release. Without this the 8 bit parts are disabled.
-rw-r--r--gst/colorspace/colorspace.c72
-rw-r--r--gst/colorspace/colorspace.h3
-rw-r--r--gst/colorspace/gstcolorspace.c61
-rw-r--r--gst/colorspace/gstcolorspace.h1
4 files changed, 120 insertions, 17 deletions
diff --git a/gst/colorspace/colorspace.c b/gst/colorspace/colorspace.c
index a20f5e26d..854176731 100644
--- a/gst/colorspace/colorspace.c
+++ b/gst/colorspace/colorspace.c
@@ -61,6 +61,7 @@ colorspace_convert_new (GstVideoFormat to_format, ColorSpaceColorSpec to_spec,
|| gst_video_format_is_yuv (from_format)
|| (gst_video_format_is_gray (from_format) &&
from_spec == COLOR_SPEC_GRAY), NULL);
+ g_return_val_if_fail (to_format != from_format, NULL);
convert = g_malloc (sizeof (ColorspaceConvert));
memset (convert, 0, sizeof (ColorspaceConvert));
@@ -98,6 +99,30 @@ colorspace_convert_new (GstVideoFormat to_format, ColorSpaceColorSpec to_spec,
convert->tmpline = g_malloc (sizeof (guint32) * width * 2);
+#ifdef GST_VIDEO_CAPS_RGB8_PALETTED
+ if (to_format == GST_VIDEO_FORMAT_RGB8_PALETTED) {
+ /* build poor man's palette, taken from ffmpegcolorspace */
+ static const guint8 pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff };
+ guint32 *palette;
+ gint r, g, b;
+
+ convert->palette = palette = g_new (guint32, 256);
+ i = 0;
+ for (r = 0; r < 6; r++) {
+ for (g = 0; g < 6; g++) {
+ for (b = 0; b < 6; b++) {
+ palette[i++] =
+ (0xffU << 24) | (pal_value[r] << 16) | (pal_value[g] << 8) |
+ pal_value[b];
+ }
+ }
+ }
+ palette[i++] = 0; /* 100% transparent, i == 6*6*6 */
+ while (i < 256)
+ palette[i++] = 0xff000000;
+ }
+#endif
+
return convert;
}
@@ -120,7 +145,8 @@ colorspace_convert_set_interlaced (ColorspaceConvert * convert,
}
void
-colorspace_convert_set_palette (ColorspaceConvert * convert, guint32 * palette)
+colorspace_convert_set_palette (ColorspaceConvert * convert,
+ const guint32 * palette)
{
if (convert->palette == NULL) {
convert->palette = g_malloc (sizeof (guint32) * 256);
@@ -128,6 +154,12 @@ colorspace_convert_set_palette (ColorspaceConvert * convert, guint32 * palette)
memcpy (convert->palette, palette, sizeof (guint32) * 256);
}
+const guint32 *
+colorspace_convert_get_palette (ColorspaceConvert * convert)
+{
+ return convert->palette;
+}
+
void
colorspace_convert_convert (ColorspaceConvert * convert,
guint8 * dest, const guint8 * src)
@@ -850,6 +882,41 @@ putline_A420 (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
FRAME_GET_LINE (dest, 3, j), src, convert->width / 2);
}
+#ifdef GST_VIDEO_CAPS_RGB8_PALETTED
+static void
+getline_RGB8P (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
+ int j)
+{
+ int i;
+ const guint8 *srcline = FRAME_GET_LINE (src, 0, j);
+ for (i = 0; i < convert->width; i++) {
+ guint32 v = convert->palette[srcline[i]];
+ dest[i * 4 + 0] = (v >> 24) & 0xff;
+ dest[i * 4 + 1] = (v >> 16) & 0xff;
+ dest[i * 4 + 2] = (v >> 8) & 0xff;
+ dest[i * 4 + 3] = (v) & 0xff;
+ }
+}
+
+static void
+putline_RGB8P (ColorspaceConvert * convert, guint8 * dest, const guint8 * src,
+ int j)
+{
+ int i;
+ guint8 *destline = FRAME_GET_LINE (dest, 0, j);
+ /* Use our poor man's palette, taken from ffmpegcolorspace too */
+ for (i = 0; i < convert->width; i++) {
+ /* crude approximation for alpha ! */
+ if (src[i * 4 + 0] < 0x80)
+ destline[i] = 6 * 6 * 6;
+ else
+ destline[i] =
+ ((((src[i * 4 + 1]) / 47) % 6) * 6 * 6 + (((src[i * 4 +
+ 2]) / 47) % 6) * 6 + (((src[i * 4 + 3]) / 47) % 6));
+ }
+}
+#endif
+
typedef struct
{
GstVideoFormat format;
@@ -894,6 +961,9 @@ static const ColorspaceLine lines[] = {
{GST_VIDEO_FORMAT_BGR15, getline_BGR15, putline_BGR15},
{GST_VIDEO_FORMAT_UYVP, getline_UYVP, putline_UYVP},
{GST_VIDEO_FORMAT_A420, getline_A420, putline_A420}
+#ifdef GST_VIDEO_CAPS_RGB8_PALETTED
+ , {GST_VIDEO_FORMAT_RGB8_PALETTED, getline_RGB8P, putline_RGB8P}
+#endif
};
static void
diff --git a/gst/colorspace/colorspace.h b/gst/colorspace/colorspace.h
index ee2f548fb..b12b032df 100644
--- a/gst/colorspace/colorspace.h
+++ b/gst/colorspace/colorspace.h
@@ -69,7 +69,8 @@ ColorspaceConvert * colorspace_convert_new (GstVideoFormat to_format,
void colorspace_convert_set_interlaced (ColorspaceConvert *convert,
gboolean interlaced);
void colorspace_convert_set_palette (ColorspaceConvert *convert,
- guint32 *palette);
+ const guint32 *palette);
+const guint32 * colorspace_convert_get_palette (ColorspaceConvert *convert);
void colorspace_convert_free (ColorspaceConvert * convert);
void colorspace_convert_convert (ColorspaceConvert * convert,
guint8 *dest, const guint8 *src);
diff --git a/gst/colorspace/gstcolorspace.c b/gst/colorspace/gstcolorspace.c
index dd2e03da0..e39814a0a 100644
--- a/gst/colorspace/gstcolorspace.c
+++ b/gst/colorspace/gstcolorspace.c
@@ -40,10 +40,20 @@
#include "gstcolorspace.h"
#include <gst/video/video.h>
+#include <string.h>
+
GST_DEBUG_CATEGORY (colorspace_debug);
#define GST_CAT_DEFAULT colorspace_debug
GST_DEBUG_CATEGORY (colorspace_performance);
+#ifndef GST_VIDEO_CAPS_RGB8_PALETTED
+#define GST_VIDEO_CAPS_RGB8_PALETTED \
+ "video/x-raw-rgb, bpp = (int)8, depth = (int)8, " \
+ "width = "GST_VIDEO_SIZE_RANGE" , " \
+ "height = " GST_VIDEO_SIZE_RANGE ", " \
+ "framerate = "GST_VIDEO_FPS_RANGE
+#endif
+
#define CSP_VIDEO_CAPS \
"video/x-raw-yuv, width = "GST_VIDEO_SIZE_RANGE" , " \
"height="GST_VIDEO_SIZE_RANGE",framerate="GST_VIDEO_FPS_RANGE"," \
@@ -62,10 +72,7 @@ GST_DEBUG_CATEGORY (colorspace_performance);
GST_VIDEO_CAPS_BGR_16";" \
GST_VIDEO_CAPS_RGB_15";" \
GST_VIDEO_CAPS_BGR_15";" \
- "video/x-raw-rgb, bpp = (int)8, depth = (int)8, " \
- "width = "GST_VIDEO_SIZE_RANGE" , " \
- "height = " GST_VIDEO_SIZE_RANGE ", " \
- "framerate = "GST_VIDEO_FPS_RANGE ";" \
+ GST_VIDEO_CAPS_RGB8_PALETTED";" \
GST_VIDEO_CAPS_GRAY8";" \
GST_VIDEO_CAPS_GRAY16("BIG_ENDIAN")";" \
GST_VIDEO_CAPS_GRAY16("LITTLE_ENDIAN")";"
@@ -306,11 +313,34 @@ gst_csp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
if (space->convert) {
colorspace_convert_set_interlaced (space->convert, in_interlaced);
}
-
+#ifdef GST_VIDEO_CAPS_RGB8_PALETTED
/* palette, only for from data */
- /* FIXME add palette handling */
-#if 0
- colorspace_convert_set_palette (convert, palette);
+ if (space->from_format == GST_VIDEO_FORMAT_RGB8_PALETTED &&
+ space->to_format == GST_VIDEO_FORMAT_RGB8_PALETTED) {
+ goto format_mismatch;
+ } else if (space->from_format == GST_VIDEO_FORMAT_RGB8_PALETTED) {
+ GstBuffer *palette;
+
+ palette = gst_video_parse_caps_palette (incaps);
+
+ if (!palette || GST_BUFFER_SIZE (palette) < 256 * 4) {
+ if (palette)
+ gst_buffer_unref (palette);
+ goto invalid_palette;
+ }
+ colorspace_convert_set_palette (space->convert,
+ (const guint32 *) GST_BUFFER_DATA (palette));
+ gst_buffer_unref (palette);
+ } else if (space->to_format == GST_VIDEO_FORMAT_RGB8_PALETTED) {
+ const guint32 *palette;
+ GstBuffer *p_buf;
+
+ palette = colorspace_convert_get_palette (space->convert);
+ p_buf = gst_buffer_new_and_alloc (256 * 4);
+ memcpy (GST_BUFFER_DATA (p_buf), palette, 256 * 4);
+ gst_caps_set_simple (outcaps, "palette_data", GST_TYPE_BUFFER, p_buf, NULL);
+ gst_buffer_unref (p_buf);
+ }
#endif
GST_DEBUG ("reconfigured %d %d", space->from_format, space->to_format);
@@ -339,6 +369,15 @@ format_mismatch:
space->to_format = GST_VIDEO_FORMAT_UNKNOWN;
return FALSE;
}
+#ifdef GST_VIDEO_CAPS_RGB8_PALETTED
+invalid_palette:
+ {
+ GST_ERROR_OBJECT (space, "invalid palette");
+ space->from_format = GST_VIDEO_FORMAT_UNKNOWN;
+ space->to_format = GST_VIDEO_FORMAT_UNKNOWN;
+ return FALSE;
+ }
+#endif
}
GST_BOILERPLATE (GstCsp, gst_csp, GstVideoFilter, GST_TYPE_VIDEO_FILTER);
@@ -366,11 +405,6 @@ gst_csp_base_init (gpointer klass)
static void
gst_csp_finalize (GObject * obj)
{
- GstCsp *space = GST_CSP (obj);
-
- if (space->palette)
- g_free (space->palette);
-
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
@@ -398,7 +432,6 @@ gst_csp_init (GstCsp * space, GstCspClass * klass)
{
space->from_format = GST_VIDEO_FORMAT_UNKNOWN;
space->to_format = GST_VIDEO_FORMAT_UNKNOWN;
- space->palette = NULL;
}
static gboolean
diff --git a/gst/colorspace/gstcolorspace.h b/gst/colorspace/gstcolorspace.h
index 9dcdb5e25..c97705cea 100644
--- a/gst/colorspace/gstcolorspace.h
+++ b/gst/colorspace/gstcolorspace.h
@@ -54,7 +54,6 @@ struct _GstCsp {
ColorSpaceColorSpec from_spec;
GstVideoFormat to_format;
ColorSpaceColorSpec to_spec;
- guint32 *palette;
ColorspaceConvert *convert;
};