mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-21 15:56:42 +00:00
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:
parent
d96964e391
commit
50fa9610b1
4 changed files with 120 additions and 17 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -54,7 +54,6 @@ struct _GstCsp {
|
|||
ColorSpaceColorSpec from_spec;
|
||||
GstVideoFormat to_format;
|
||||
ColorSpaceColorSpec to_spec;
|
||||
guint32 *palette;
|
||||
|
||||
ColorspaceConvert *convert;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue