|| 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));
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;
}
}
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);
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)
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;
{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
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);
#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"," \
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")";"
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);
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);
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);
}
{
space->from_format = GST_VIDEO_FORMAT_UNKNOWN;
space->to_format = GST_VIDEO_FORMAT_UNKNOWN;
- space->palette = NULL;
}
static gboolean
ColorSpaceColorSpec from_spec;
GstVideoFormat to_format;
ColorSpaceColorSpec to_spec;
- guint32 *palette;
ColorspaceConvert *convert;
};