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.
This commit is contained in:
Sebastian Dröge 2010-11-02 16:05:37 +01:00
parent d96964e391
commit 50fa9610b1
4 changed files with 120 additions and 17 deletions

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -54,7 +54,6 @@ struct _GstCsp {
ColorSpaceColorSpec from_spec;
GstVideoFormat to_format;
ColorSpaceColorSpec to_spec;
guint32 *palette;
ColorspaceConvert *convert;
};