summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2004-01-15 08:58:22 +0000
committerDavid Schleef <ds@schleef.org>2004-01-15 08:58:22 +0000
commit4910efb9b7baced502f3f78cf54ba580603d4415 (patch)
tree7c0ca8f3bca493926990f9f12b97970b3294051d
parent4506b4c38b4a74556e1134b2989334a118dcb3ca (diff)
downloadgst-plugins-bad-4910efb9b7baced502f3f78cf54ba580603d4415.tar.gz
gst-plugins-bad-4910efb9b7baced502f3f78cf54ba580603d4415.tar.bz2
gst-plugins-bad-4910efb9b7baced502f3f78cf54ba580603d4415.zip
Duplicate the ext/hermes colorspace plugin, and remove Hermes code and GPL code. Fix for new caps negotiation. Rewr...
Original commit message from CVS: * configure.ac: * gst/colorspace/Makefile.am: * gst/colorspace/gstcolorspace.c: * gst/colorspace/gstcolorspace.h: * gst/colorspace/yuv2rgb.c: * gst/colorspace/yuv2rgb.h: Duplicate the ext/hermes colorspace plugin, and remove Hermes code and GPL code. Fix for new caps negotiation. Rewrite much of the format handling code, and some of the conversion code. Basically, rewrote almost everything. This element handles I420, YV12 to RGB conversions. * ext/hermes/Makefile.am: * ext/hermes/gsthermescolorspace.c: Rename colorspace to hermescolorspace. Fix negotiation issues. Remove non-Hermes related code. This element handles lots of RGB to RGB conversions, but no YUV. * ext/hermes/gstcolorspace.c: * ext/hermes/gstcolorspace.h: * ext/hermes/rgb2yuv.c: * ext/hermes/yuv2rgb.c: * ext/hermes/yuv2rgb.h: * ext/hermes/yuv2rgb_mmx16.s: * ext/hermes/yuv2yuv.c: * ext/hermes/yuv2yuv.h: Remove old code.
-rw-r--r--ChangeLog28
-rw-r--r--configure.ac2
-rw-r--r--ext/hermes/Makefile.am21
-rw-r--r--ext/hermes/gsthermescolorspace.c650
-rw-r--r--ext/hermes/rgb2yuv.c80
-rw-r--r--ext/hermes/yuv2rgb_mmx16.s188
-rw-r--r--ext/hermes/yuv2yuv.c79
-rw-r--r--ext/hermes/yuv2yuv.h29
-rw-r--r--gst/colorspace/Makefile.am15
-rw-r--r--gst/colorspace/gstcolorspace.c (renamed from ext/hermes/gstcolorspace.c)356
-rw-r--r--gst/colorspace/gstcolorspace.h (renamed from ext/hermes/gstcolorspace.h)64
-rw-r--r--gst/colorspace/yuv2rgb.c (renamed from ext/hermes/yuv2rgb.c)649
-rw-r--r--gst/colorspace/yuv2rgb.h (renamed from ext/hermes/yuv2rgb.h)47
13 files changed, 1221 insertions, 987 deletions
diff --git a/ChangeLog b/ChangeLog
index f7085c4e..53716c91 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2004-01-15 David Schleef <ds@schleef.org>
+
+ * configure.ac:
+ * gst/colorspace/Makefile.am:
+ * gst/colorspace/gstcolorspace.c:
+ * gst/colorspace/gstcolorspace.h:
+ * gst/colorspace/yuv2rgb.c:
+ * gst/colorspace/yuv2rgb.h:
+ Duplicate the ext/hermes colorspace plugin, and remove Hermes
+ code and GPL code. Fix for new caps negotiation. Rewrite
+ much of the format handling code, and some of the conversion
+ code. Basically, rewrote almost everything. This element
+ handles I420, YV12 to RGB conversions.
+ * ext/hermes/Makefile.am:
+ * ext/hermes/gsthermescolorspace.c:
+ Rename colorspace to hermescolorspace. Fix negotiation issues.
+ Remove non-Hermes related code. This element handles lots of
+ RGB to RGB conversions, but no YUV.
+ * ext/hermes/gstcolorspace.c:
+ * ext/hermes/gstcolorspace.h:
+ * ext/hermes/rgb2yuv.c:
+ * ext/hermes/yuv2rgb.c:
+ * ext/hermes/yuv2rgb.h:
+ * ext/hermes/yuv2rgb_mmx16.s:
+ * ext/hermes/yuv2yuv.c:
+ * ext/hermes/yuv2yuv.h:
+ Remove old code.
+
2004-01-14 Colin Walters <walters@verbum.org>
* ext/mad/gstid3tag.c (gst_id3_tag_chain): Don't nego caps if
diff --git a/configure.ac b/configure.ac
index 51da5521..af1fef40 100644
--- a/configure.ac
+++ b/configure.ac
@@ -341,6 +341,7 @@ GST_PLUGINS_ALL="\
avi \
cdxaparse \
chart \
+ colorspace \
cutter \
debug \
deinterlace \
@@ -1525,6 +1526,7 @@ gst/avi/Makefile
gst/asfdemux/Makefile
gst/cdxaparse/Makefile
gst/chart/Makefile
+gst/colorspace/Makefile
gst/cutter/Makefile
gst/debug/Makefile
gst/deinterlace/Makefile
diff --git a/ext/hermes/Makefile.am b/ext/hermes/Makefile.am
index f08b401b..452c2f56 100644
--- a/ext/hermes/Makefile.am
+++ b/ext/hermes/Makefile.am
@@ -1,21 +1,10 @@
-plugin_LTLIBRARIES = libgstcolorspace.la
+plugin_LTLIBRARIES = libgsthermescolorspace.la
-if HAVE_CPU_I386
-ARCHSRCS = yuv2rgb_mmx16.s
-else
-ARCHSRCS =
-endif
-
-if USE_HERMES
PLUGIN_EXTRA_LIBS = $(HERMES_LIBS)
-else
-PLUGIN_EXTRA_LIBS =
-endif
-libgstcolorspace_la_SOURCES = gstcolorspace.c yuv2yuv.c yuv2rgb.c rgb2yuv.c $(ARCHSRCS)
-libgstcolorspace_la_CFLAGS = $(GST_CFLAGS)
-libgstcolorspace_la_LIBADD = $(PLUGIN_EXTRA_LIBS)
-libgstcolorspace_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgsthermescolorspace_la_SOURCES = gsthermescolorspace.c
+libgsthermescolorspace_la_CFLAGS = $(GST_CFLAGS)
+libgsthermescolorspace_la_LIBADD = $(PLUGIN_EXTRA_LIBS)
+libgsthermescolorspace_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-noinst_HEADERS = gstcolorspace.h yuv2rgb.h yuv2yuv.h
diff --git a/ext/hermes/gsthermescolorspace.c b/ext/hermes/gsthermescolorspace.c
new file mode 100644
index 00000000..c42ef7c6
--- /dev/null
+++ b/ext/hermes/gsthermescolorspace.c
@@ -0,0 +1,650 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <Hermes/Hermes.h>
+
+
+#define GST_TYPE_COLORSPACE \
+ (gst_hermes_colorspace_get_type())
+#define GST_HERMES_COLORSPACE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COLORSPACE,GstHermesColorspace))
+#define GST_HERMES_COLORSPACE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstHermesColorspace))
+#define GST_IS_COLORSPACE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COLORSPACE))
+#define GST_IS_COLORSPACE_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COLORSPACE))
+
+typedef struct _GstHermesColorspace GstHermesColorspace;
+typedef struct _GstHermesColorspaceClass GstHermesColorspaceClass;
+
+typedef enum {
+ GST_HERMES_COLORSPACE_NONE,
+ GST_HERMES_COLORSPACE_HERMES,
+ GST_HERMES_COLORSPACE_YUV_RGB,
+ GST_HERMES_COLORSPACE_YUY2_I420,
+ GST_HERMES_COLORSPACE_RGB32_I420,
+ GST_HERMES_COLORSPACE_RGB32_YV12,
+ GST_HERMES_COLORSPACE_420_SWAP,
+} GstColorSpaceConverterType;
+
+struct _GstHermesColorspace {
+ GstElement element;
+
+ GstPad *sinkpad,*srcpad;
+
+ HermesHandle h_handle;
+ HermesFormat sink_format;
+ HermesFormat src_format;
+
+ int src_format_index;
+ int sink_format_index;
+
+ int src_size;
+ int sink_size;
+
+ int src_stride;
+ int sink_stride;
+
+ gint width, height;
+ gdouble fps;
+ gboolean passthru;
+};
+
+struct _GstHermesColorspaceClass {
+ GstElementClass parent_class;
+};
+
+GType gst_hermes_colorspace_get_type(void);
+
+typedef struct _GstHermesColorspaceFormat {
+ GstStaticCaps caps;
+
+} GstHermesColorspaceFormat;
+
+static GstHermesColorspaceFormat gst_hermes_colorspace_formats[] = {
+ { GST_STATIC_CAPS (GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_32_REVERSE) },
+ { GST_STATIC_CAPS (GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_32) },
+ { GST_STATIC_CAPS (GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_15) },
+ { GST_STATIC_CAPS (GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_16) },
+};
+
+static GstElementDetails colorspace_details = {
+ "Colorspace converter",
+ "Filter/Converter/Video",
+ "Converts video from one colorspace to another using libhermes",
+ "Wim Taymans <wim.taymans@chello.be>",
+};
+
+
+/* Stereo signals and args */
+enum {
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_SOURCE,
+ ARG_DEST,
+};
+
+static void gst_hermes_colorspace_base_init (gpointer g_class);
+static void gst_hermes_colorspace_class_init (GstHermesColorspaceClass *klass);
+static void gst_hermes_colorspace_init (GstHermesColorspace *space);
+
+static void gst_hermes_colorspace_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec);
+static void gst_hermes_colorspace_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec);
+
+static GstPadLinkReturn
+ gst_hermes_colorspace_link (GstPad *pad, const GstCaps *caps);
+static void gst_hermes_colorspace_chain (GstPad *pad, GstData *_data);
+static GstElementStateReturn
+ gst_hermes_colorspace_change_state (GstElement *element);
+
+
+static GstElementClass *parent_class = NULL;
+/*static guint gst_hermes_colorspace_signals[LAST_SIGNAL] = { 0 }; */
+
+#if 0
+static gboolean
+colorspace_setup_converter (GstHermesColorspace *space, GstCaps *from_caps, GstCaps *to_caps)
+{
+ guint32 from_space, to_space;
+ GstStructure *from_struct;
+ GstStructure *to_struct;
+
+ g_return_val_if_fail (to_caps != NULL, FALSE);
+ g_return_val_if_fail (from_caps != NULL, FALSE);
+
+ from_struct = gst_caps_get_structure (from_caps, 0);
+ to_struct = gst_caps_get_structure (to_caps, 0);
+
+ from_space = GST_MAKE_FOURCC ('R','G','B',' ');
+ gst_structure_get_fourcc (from_struct, "format", &from_space);
+
+ to_space = GST_MAKE_FOURCC ('R','G','B',' ');
+ gst_structure_get_fourcc (to_struct, "format", &to_space);
+
+ GST_INFO ("set up converter for " GST_FOURCC_FORMAT
+ " (%08x) to " GST_FOURCC_FORMAT " (%08x)",
+ GST_FOURCC_ARGS (from_space), from_space,
+ GST_FOURCC_ARGS (to_space), to_space);
+
+ switch (from_space) {
+ case GST_MAKE_FOURCC ('R','G','B',' '):
+ {
+ gint from_bpp;
+
+ gst_structure_get_int (from_struct, "bpp", &from_bpp);
+
+ switch (to_space) {
+ case GST_MAKE_FOURCC ('R','G','B',' '):
+#ifdef HAVE_HERMES
+ {
+ gint to_bpp;
+
+ gst_structure_get_int (to_struct, "bpp", &to_bpp);
+
+ gst_structure_get_int (from_struct, "red_mask", &space->source.r);
+ gst_structure_get_int (from_struct, "green_mask", &space->source.g);
+ gst_structure_get_int (from_struct, "blue_mask", &space->source.b);
+ space->source.a = 0;
+ space->srcbpp = space->source.bits = from_bpp;
+ space->source.indexed = 0;
+ space->source.has_colorkey = 0;
+
+ GST_INFO ( "source red mask %08x", space->source.r);
+ GST_INFO ( "source green mask %08x", space->source.g);
+ GST_INFO ( "source blue mask %08x", space->source.b);
+ GST_INFO ( "source bpp %08x", space->srcbpp);
+
+ gst_structure_get_int (to_struct, "red_mask", &space->dest.r);
+ gst_structure_get_int (to_struct, "green_mask", &space->dest.g);
+ gst_structure_get_int (to_struct, "blue_mask", &space->dest.b);
+ space->dest.a = 0;
+ space->destbpp = space->dest.bits = to_bpp;
+ space->dest.indexed = 0;
+ space->dest.has_colorkey = 0;
+
+ GST_INFO ( "dest red mask %08x", space->dest.r);
+ GST_INFO ( "dest green mask %08x", space->dest.g);
+ GST_INFO ( "dest blue mask %08x", space->dest.b);
+ GST_INFO ( "dest bpp %08x", space->destbpp);
+
+ if (!Hermes_ConverterRequest (space->h_handle, &space->source, &space->dest)) {
+ g_warning ("Hermes: could not get converter\n");
+ return FALSE;
+ }
+ GST_INFO ( "converter set up");
+ space->type = GST_HERMES_COLORSPACE_HERMES;
+ return TRUE;
+ }
+#else
+ g_warning ("colorspace: compiled without hermes!");
+ return FALSE;
+#endif
+ case GST_MAKE_FOURCC ('Y','V','1','2'):
+ if (from_bpp == 32) {
+ space->type = GST_HERMES_COLORSPACE_RGB32_YV12;
+ space->destbpp = 12;
+ return TRUE;
+ }
+ case GST_MAKE_FOURCC ('I','4','2','0'):
+ if (from_bpp == 32) {
+ space->type = GST_HERMES_COLORSPACE_RGB32_I420;
+ space->destbpp = 12;
+ return TRUE;
+ }
+ case GST_MAKE_FOURCC ('Y','U','Y','2'):
+ GST_INFO ( "colorspace: RGB to YUV with bpp %d not implemented!!", from_bpp);
+ return FALSE;
+ }
+ break;
+ }
+ case GST_MAKE_FOURCC ('I','4','2','0'):
+ switch (to_space) {
+ case GST_MAKE_FOURCC ('R','G','B',' '):
+ GST_INFO ( "colorspace: YUV to RGB");
+
+ gst_structure_get_int (to_struct, "bpp", &space->destbpp);
+ space->converter = gst_hermes_colorspace_yuv2rgb_get_converter (from_caps, to_caps);
+ space->type = GST_HERMES_COLORSPACE_YUV_RGB;
+ return TRUE;
+ case GST_MAKE_FOURCC ('I','4','2','0'):
+ space->type = GST_HERMES_COLORSPACE_NONE;
+ space->destbpp = 12;
+ return TRUE;
+ case GST_MAKE_FOURCC ('Y','V','1','2'):
+ space->type = GST_HERMES_COLORSPACE_420_SWAP;
+ space->destbpp = 12;
+ return TRUE;
+
+ }
+ break;
+ case GST_MAKE_FOURCC ('Y','U','Y','2'):
+ switch (to_space) {
+ case GST_MAKE_FOURCC ('I','4','2','0'):
+ space->type = GST_HERMES_COLORSPACE_YUY2_I420;
+ space->destbpp = 12;
+ return TRUE;
+ case GST_MAKE_FOURCC ('Y','U','Y','2'):
+ space->type = GST_HERMES_COLORSPACE_NONE;
+ space->destbpp = 16;
+ return TRUE;
+ case GST_MAKE_FOURCC ('R','G','B',' '):
+ GST_INFO ( "colorspace: YUY2 to RGB not implemented!!");
+ return FALSE;
+ }
+ break;
+ case GST_MAKE_FOURCC ('Y','V','1','2'):
+ switch (to_space) {
+ case GST_MAKE_FOURCC ('R','G','B',' '):
+ GST_INFO ( "colorspace: YV12 to RGB");
+
+ gst_structure_get_int (to_struct, "bpp", &space->destbpp);
+ space->converter = gst_hermes_colorspace_yuv2rgb_get_converter (from_caps, to_caps);
+ space->type = GST_HERMES_COLORSPACE_YUV_RGB;
+ return TRUE;
+ case GST_MAKE_FOURCC ('I','4','2','0'):
+ space->type = GST_HERMES_COLORSPACE_420_SWAP;
+ space->destbpp = 12;
+ return TRUE;
+ case GST_MAKE_FOURCC ('Y','V','1','2'):
+ space->type = GST_HERMES_COLORSPACE_NONE;
+ space->destbpp = 12;
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+#endif
+
+static GstCaps *
+gst_hermes_colorspace_caps_remove_format_info (GstCaps *caps)
+{
+ int i;
+ GstStructure *structure;
+ GstCaps *rgbcaps;
+
+ for (i=0; i<gst_caps_get_size (caps); i++) {
+ structure = gst_caps_get_structure (caps, i);
+
+ gst_structure_remove_field (structure, "format");
+ gst_structure_remove_field (structure, "endianness");
+ gst_structure_remove_field (structure, "depth");
+ gst_structure_remove_field (structure, "bpp");
+ gst_structure_remove_field (structure, "red_mask");
+ gst_structure_remove_field (structure, "green_mask");
+ gst_structure_remove_field (structure, "blue_mask");
+ }
+
+ rgbcaps = gst_caps_simplify (caps);
+ gst_caps_free (caps);
+
+ return rgbcaps;
+}
+
+static void
+gst_hermes_colorspace_structure_to_hermes_format (HermesFormat *format,
+ GstStructure *structure)
+{
+ gst_structure_get_int (structure, "red_mask", &format->r);
+ gst_structure_get_int (structure, "green_mask", &format->g);
+ gst_structure_get_int (structure, "blue_mask", &format->b);
+ format->a = 0;
+ gst_structure_get_int (structure, "bpp", &format->bits);
+ format->indexed = 0;
+ format->has_colorkey = 0;
+}
+
+static GstCaps*
+gst_hermes_colorspace_getcaps (GstPad *pad)
+{
+ GstHermesColorspace *space;
+ GstPad *otherpad;
+ GstCaps *othercaps;
+ GstCaps *caps;
+
+ space = GST_HERMES_COLORSPACE (gst_pad_get_parent (pad));
+
+ otherpad = (pad == space->srcpad) ? space->sinkpad : space->srcpad;
+
+ othercaps = gst_pad_get_allowed_caps (otherpad);
+
+ othercaps = gst_hermes_colorspace_caps_remove_format_info (othercaps);
+
+ caps = gst_caps_intersect (othercaps, gst_pad_get_pad_template_caps (pad));
+ gst_caps_free (othercaps);
+
+ return caps;
+}
+
+static GstPadLinkReturn
+gst_hermes_colorspace_link (GstPad *pad, const GstCaps *caps)
+{
+ GstHermesColorspace *space;
+ GstPad *otherpad;
+ GstStructure *structure;
+ GstPadLinkReturn link_ret;
+ int width, height;
+ double fps;
+ int i;
+
+ space = GST_HERMES_COLORSPACE (gst_pad_get_parent (pad));
+ otherpad = (pad == space->sinkpad) ? space->srcpad : space->sinkpad;
+
+ link_ret = gst_pad_try_set_caps (otherpad, caps);
+ if (link_ret == GST_PAD_LINK_OK) {
+ space->passthru = TRUE;
+ return link_ret;
+ }
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ for(i=0; i<G_N_ELEMENTS (gst_hermes_colorspace_formats); i++) {
+ GstCaps *icaps;
+ GstCaps *fcaps;
+
+ fcaps = gst_caps_copy (gst_static_caps_get (
+ &gst_hermes_colorspace_formats[i].caps));
+
+ icaps = gst_caps_intersect (caps, fcaps);
+ if (!gst_caps_is_empty (icaps)) {
+ break;
+ }
+ gst_caps_free (icaps);
+ }
+ if (i==G_N_ELEMENTS (gst_hermes_colorspace_formats)) {
+ g_assert_not_reached ();
+ return GST_PAD_LINK_REFUSED;
+ }
+
+ gst_structure_get_int (structure, "width", &width);
+ gst_structure_get_int (structure, "height", &height);
+ gst_structure_get_double (structure, "framerate", &fps);
+
+ GST_INFO ( "size: %dx%d", space->width, space->height);
+
+ if (gst_pad_is_negotiated (otherpad)) {
+ GstCaps *othercaps;
+
+ othercaps = gst_caps_copy (gst_pad_get_negotiated_caps (otherpad));
+
+ gst_caps_set_simple (othercaps,
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ "framerate", G_TYPE_DOUBLE, fps, NULL);
+
+ link_ret = gst_pad_try_set_caps (otherpad, othercaps);
+ if (link_ret != GST_PAD_LINK_OK) {
+ return link_ret;
+ }
+ }
+
+ if (pad == space->srcpad) {
+ space->src_format_index = i;
+ gst_hermes_colorspace_structure_to_hermes_format (&space->src_format, structure);
+ } else {
+ space->sink_format_index = i;
+ gst_hermes_colorspace_structure_to_hermes_format (&space->sink_format, structure);
+ }
+
+ space->sink_stride = width*(space->sink_format.bits/8);
+ space->src_stride = width*(space->src_format.bits/8);
+ space->sink_size = space->sink_stride * height;
+ space->src_size = space->src_stride * height;
+ space->width = width;
+ space->height = height;
+ space->fps = fps;
+
+ if (gst_pad_is_negotiated (otherpad)) {
+ if (!Hermes_ConverterRequest (space->h_handle, &space->sink_format,
+ &space->src_format)) {
+ g_warning ("Hermes: could not get converter\n");
+ return GST_PAD_LINK_REFUSED;
+ }
+g_print("inited\n");
+ }
+
+ return GST_PAD_LINK_OK;
+}
+
+GType
+gst_hermes_colorspace_get_type (void)
+{
+ static GType colorspace_type = 0;
+
+ if (!colorspace_type) {
+ static const GTypeInfo colorspace_info = {
+ sizeof(GstHermesColorspaceClass),
+ gst_hermes_colorspace_base_init,
+ NULL,
+ (GClassInitFunc)gst_hermes_colorspace_class_init,
+ NULL,
+ NULL,
+ sizeof(GstHermesColorspace),
+ 0,
+ (GInstanceInitFunc)gst_hermes_colorspace_init,
+ };
+ colorspace_type = g_type_register_static(GST_TYPE_ELEMENT, "GstHermesColorspace", &colorspace_info, 0);
+ }
+ return colorspace_type;
+}
+
+static GstStaticPadTemplate gst_hermes_colorspace_src_pad_template =
+GST_STATIC_PAD_TEMPLATE (
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (
+ GST_VIDEO_YUV_PAD_TEMPLATE_CAPS ("{ I420, YV12, YUY2 }") "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_32_REVERSE "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_32 "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_15 "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_16)
+);
+
+static GstStaticPadTemplate gst_hermes_colorspace_sink_pad_template =
+GST_STATIC_PAD_TEMPLATE (
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (
+ GST_VIDEO_YUV_PAD_TEMPLATE_CAPS ("{ I420, YV12, YUY2 }") "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_32_REVERSE "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24_32 "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_15 "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_16)
+);
+
+static void
+gst_hermes_colorspace_base_init (gpointer g_class)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_hermes_colorspace_src_pad_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_hermes_colorspace_sink_pad_template));
+
+ gst_element_class_set_details (element_class, &colorspace_details);
+}
+
+static void
+gst_hermes_colorspace_class_init (GstHermesColorspaceClass *klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass*)klass;
+ gstelement_class = (GstElementClass*)klass;
+
+ parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+ gobject_class->set_property = gst_hermes_colorspace_set_property;
+ gobject_class->get_property = gst_hermes_colorspace_get_property;
+
+ gstelement_class->change_state = gst_hermes_colorspace_change_state;
+}
+
+static void
+gst_hermes_colorspace_init (GstHermesColorspace *space)
+{
+ space->sinkpad = gst_pad_new_from_template (
+ gst_static_pad_template_get (&gst_hermes_colorspace_sink_pad_template),
+ "sink");
+ gst_pad_set_link_function (space->sinkpad, gst_hermes_colorspace_link);
+ gst_pad_set_getcaps_function (space->sinkpad, gst_hermes_colorspace_getcaps);
+ gst_pad_set_chain_function(space->sinkpad,gst_hermes_colorspace_chain);
+ gst_element_add_pad(GST_ELEMENT(space),space->sinkpad);
+
+ space->srcpad = gst_pad_new_from_template (
+ gst_static_pad_template_get (&gst_hermes_colorspace_src_pad_template),
+ "src");
+ gst_element_add_pad(GST_ELEMENT(space),space->srcpad);
+ gst_pad_set_link_function (space->srcpad, gst_hermes_colorspace_link);
+
+ space->h_handle = Hermes_ConverterInstance (0);
+ space->passthru = FALSE;
+}
+
+static void
+gst_hermes_colorspace_chain (GstPad *pad,GstData *_data)
+{
+ GstBuffer *buf = GST_BUFFER (_data);
+ GstHermesColorspace *space;
+ GstBuffer *outbuf = NULL;
+
+ g_return_if_fail (pad != NULL);
+ g_return_if_fail (GST_IS_PAD (pad));
+ g_return_if_fail (buf != NULL);
+
+ space = GST_HERMES_COLORSPACE (gst_pad_get_parent (pad));
+
+ g_return_if_fail (space != NULL);
+ g_return_if_fail (GST_IS_COLORSPACE (space));
+
+ if (space->passthru) {
+ gst_pad_push (space->srcpad, _data);
+ return;
+ }
+
+ if (GST_BUFFER_SIZE (buf) < space->sink_size) {
+ g_critical ("input size is smaller than expected");
+ }
+
+ outbuf = gst_pad_alloc_buffer (space->srcpad, GST_BUFFER_OFFSET_NONE,
+ space->src_size);
+
+ Hermes_ConverterCopy (space->h_handle,
+ GST_BUFFER_DATA (buf), 0, 0, space->width, space->height,
+ space->sink_stride, GST_BUFFER_DATA (outbuf), 0, 0,
+ space->width, space->height, space->src_stride);
+
+ GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
+ GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+
+ gst_buffer_unref (buf);
+ gst_pad_push (space->srcpad, GST_DATA (outbuf));
+}
+
+static GstElementStateReturn
+gst_hermes_colorspace_change_state (GstElement *element)
+{
+ GstHermesColorspace *space;
+
+ space = GST_HERMES_COLORSPACE (element);
+
+ switch (GST_STATE_TRANSITION (element)) {
+ case GST_STATE_PAUSED_TO_PLAYING:
+ break;
+ case GST_STATE_PLAYING_TO_PAUSED:
+ break;
+ case GST_STATE_PAUSED_TO_READY:
+ break;
+ }
+
+ return parent_class->change_state (element);
+}
+
+static void
+gst_hermes_colorspace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GstHermesColorspace *space;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_COLORSPACE(object));
+ space = GST_HERMES_COLORSPACE(object);
+
+ switch (prop_id) {
+ default:
+ break;
+ }
+}
+
+static void
+gst_hermes_colorspace_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GstHermesColorspace *space;
+
+ /* it's not null if we got it, but it might not be ours */
+ g_return_if_fail(GST_IS_COLORSPACE(object));
+ space = GST_HERMES_COLORSPACE(object);
+
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+plugin_init (GstPlugin *plugin)
+{
+ gint hermes_res;
+
+ hermes_res = Hermes_Init();
+ g_return_val_if_fail (hermes_res != 0, FALSE);
+
+ if (!gst_element_register (plugin, "hermescolorspace", GST_RANK_PRIMARY,
+ GST_TYPE_COLORSPACE))
+ return FALSE;
+
+ return TRUE;
+}
+
+GST_PLUGIN_DEFINE (
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "hermescolorspace",
+ "Hermes colorspace converter",
+ plugin_init,
+ VERSION,
+ "LGPL",
+ GST_PACKAGE,
+ GST_ORIGIN)
diff --git a/ext/hermes/rgb2yuv.c b/ext/hermes/rgb2yuv.c
deleted file mode 100644
index 6aa1e805..00000000
--- a/ext/hermes/rgb2yuv.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *
- * rgb2rgb.c, Software RGB to YUV convertor
- * Written by Nick Kurshev.
- * palette & yuv & runtime cpu stuff by Michael (michaelni@gmx.at) (under GPL)
- */
-
-#include "config.h"
-
-#include <math.h>
-#include <stdlib.h>
-
-#include <gst/gst.h>
-
-#define Y_FROM_RGB(r,g,b) ((9798 * (r) + 19235 * (g) + 3736 * (b)) >> 15)
-#define U_FROM_BY(b,y) ((16122 * ((b) - (y))) >> 15) + 128;
-#define V_FROM_RY(r,y) ((25203 * ((r) - (y))) >> 15) + 128;
-
-static void
-gst_colorspace_rgb32_to_yuv (unsigned char *src,
- unsigned char *ydst,
- unsigned char *udst,
- unsigned char *vdst,
- guint width, guint height)
-{
- int y;
- const int chrom_width = width >> 1;
- int Y;
- int b, g, r;
-
- for (y = height; y; y -= 2) {
- int i;
-
- for (i = chrom_width; i; i--) {
- b = *src++;
- g = *src++;
- r = *src++;
- src++;
-
- Y = Y_FROM_RGB (r,g,b);
-
- *ydst++ = Y;
- *udst++ = U_FROM_BY (b,Y);
- *vdst++ = V_FROM_RY (r,Y);
-
- b = *src++;
- g = *src++;
- r = *src++; src++;
-
- *ydst++ = Y_FROM_RGB (r,g,b);
- }
-
- for (i = width; i; i--) {
- b = *src++;
- g = *src++;
- r = *src++; src++;
- *ydst++ = Y_FROM_RGB (r,g,b);
- }
- }
-}
-
-void
-gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest, guint width, guint height)
-{
- unsigned char *ydst = dest;
- unsigned char *udst = ydst + (width * height);
- unsigned char *vdst = udst + ((width * height) >> 2);
-
- gst_colorspace_rgb32_to_yuv (src, ydst, udst, vdst, width, height);
-}
-
-void
-gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height)
-{
- unsigned char *ydst = dest;
- unsigned char *vdst = ydst + (width * height);
- unsigned char *udst = vdst + ((width * height) >> 2);
-
- gst_colorspace_rgb32_to_yuv (src, ydst, udst, vdst, width, height);
-}
diff --git a/ext/hermes/yuv2rgb_mmx16.s b/ext/hermes/yuv2rgb_mmx16.s
deleted file mode 100644
index 8f7b1f77..00000000
--- a/ext/hermes/yuv2rgb_mmx16.s
+++ /dev/null
@@ -1,188 +0,0 @@
-.globl mmx_80w
-.data
- .align 4
- .type mmx_80w,@object
- .size mmx_80w,8
-mmx_80w:
- .long 8388736
- .long 8388736
-.globl mmx_10w
- .align 4
- .type mmx_10w,@object
- .size mmx_10w,8
-mmx_10w:
- .long 269488144
- .long 269488144
-.globl mmx_00ffw
- .align 4
- .type mmx_00ffw,@object
- .size mmx_00ffw,8
-mmx_00ffw:
- .long 16711935
- .long 16711935
-.globl mmx_Y_coeff
- .align 4
- .type mmx_Y_coeff,@object
- .size mmx_Y_coeff,8
-mmx_Y_coeff:
- .long 624895295
- .long 624895295
-.globl mmx_U_green
- .align 4
- .type mmx_U_green,@object
- .size mmx_U_green,8
-mmx_U_green:
- .long -209849475
- .long -209849475
-.globl mmx_U_blue
- .align 4
- .type mmx_U_blue,@object
- .size mmx_U_blue,8
-mmx_U_blue:
- .long 1083392147
- .long 1083392147
-.globl mmx_V_red
- .align 4
- .type mmx_V_red,@object
- .size mmx_V_red,8
-mmx_V_red:
- .long 856830738
- .long 856830738
-.globl mmx_V_green
- .align 4
- .type mmx_V_green,@object
- .size mmx_V_green,8
-mmx_V_green:
- .long -436410884
- .long -436410884
-.globl mmx_redmask
- .align 4
- .type mmx_redmask,@object
- .size mmx_redmask,8
-mmx_redmask:
- .long -117901064
- .long -117901064
-.globl mmx_grnmask
- .align 4
- .type mmx_grnmask,@object
- .size mmx_grnmask,8
-mmx_grnmask:
- .long -50529028
- .long -50529028
-.text
- .align 4
-.globl gst_colorspace_yuv_to_bgr16_mmx
- .type gst_colorspace_yuv_to_bgr16_mmx,@function
-gst_colorspace_yuv_to_bgr16_mmx:
- subl $8,%esp
- pushl %ebp
- pushl %edi
- pushl %esi
- movl 28(%esp),%edi
- movl 32(%esp),%ecx
- movl 36(%esp),%edx
- movl $1,%ebp
- movl 48(%esp),%esi
- sarl $1,%esi
- movl %esi,16(%esp)
-
- pxor %mm4, %mm4 # zero mm4
-
- movl %esi,12(%esp)
- sarl $2,12(%esp)
-
- movl 40(%esp),%esi
-
- .p2align 4,,7
-.L68:
-
- movd (%ecx), %mm0 # Load 4 Cb 00 00 00 00 00 u3 u2 u1 u0
- movd (%edx), %mm1 # Load 4 Cr 00 00 00 00 00 v2 v1 v0
- movq (%edi), %mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
-
- movl 12(%esp),%eax
-
- .p2align 4,,7
-.L74:
- punpcklbw %mm4, %mm0 # scatter 4 Cb 00 u3 00 u2 00 u1 00 u0
- punpcklbw %mm4, %mm1 # scatter 4 Cr 00 v3 00 v2 00 v1 00 v0
- psubsw mmx_80w, %mm0 # Cb -= 128
- psubsw mmx_80w, %mm1 # Cr -= 128
- psllw $3, %mm0 # Promote precision
- psllw $3, %mm1 # Promote precision
- movq %mm0, %mm2 # Copy 4 Cb 00 u3 00 u2 00 u1 00 u0
- movq %mm1, %mm3 # Copy 4 Cr 00 v3 00 v2 00 v1 00 v0
- pmulhw mmx_U_green, %mm2 # Mul Cb with green coeff -> Cb green
- pmulhw mmx_V_green, %mm3 # Mul Cr with green coeff -> Cr green
- pmulhw mmx_U_blue, %mm0 # Mul Cb -> Cblue 00 b3 00 b2 00 b1 00 b0
- pmulhw mmx_V_red, %mm1 # Mul Cr -> Cred 00 r3 00 r2 00 r1 00 r0
- paddsw %mm3, %mm2 # Cb green + Cr green -> Cgreen
- psubusb mmx_10w, %mm6 # Y -= 16
- movq %mm6, %mm7 # Copy 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- pand mmx_00ffw, %mm6 # get Y even 00 Y6 00 Y4 00 Y2 00 Y0
- psrlw $8, %mm7 # get Y odd 00 Y7 00 Y5 00 Y3 00 Y1
- psllw $3, %mm6 # Promote precision
- psllw $3, %mm7 # Promote precision
- pmulhw mmx_Y_coeff, %mm6 # Mul 4 Y even 00 y6 00 y4 00 y2 00 y0
- pmulhw mmx_Y_coeff, %mm7 # Mul 4 Y odd 00 y7 00 y5 00 y3 00 y1
- movq %mm0, %mm3 # Copy Cblue
- movq %mm1, %mm4 # Copy Cred
- movq %mm2, %mm5 # Copy Cgreen
- paddsw %mm6, %mm0 # Y even + Cblue 00 B6 00 B4 00 B2 00 B0
- paddsw %mm7, %mm3 # Y odd + Cblue 00 B7 00 B5 00 B3 00 B1
- paddsw %mm6, %mm1 # Y even + Cred 00 R6 00 R4 00 R2 00 R0
- paddsw %mm7, %mm4 # Y odd + Cred 00 R7 00 R5 00 R3 00 R1
- paddsw %mm6, %mm2 # Y even + Cgreen 00 G6 00 G4 00 G2 00 G0
- paddsw %mm7, %mm5 # Y odd + Cgreen 00 G7 00 G5 00 G3 00 G1
- packuswb %mm0, %mm0 # B6 B4 B2 B0 | B6 B4 B2 B0
- packuswb %mm1, %mm1 # R6 R4 R2 R0 | R6 R4 R2 R0
- packuswb %mm2, %mm2 # G6 G4 G2 G0 | G6 G4 G2 G0
- packuswb %mm3, %mm3 # B7 B5 B3 B1 | B7 B5 B3 B1
- packuswb %mm4, %mm4 # R7 R5 R3 R1 | R7 R5 R3 R1
- packuswb %mm5, %mm5 # G7 G5 G3 G1 | G7 G5 G3 G1
- punpcklbw %mm3, %mm0 # B7 B6 B5 B4 B3 B2 B1 B0
- punpcklbw %mm4, %mm1 # R7 R6 R5 R4 R3 R2 R1 R0
- punpcklbw %mm5, %mm2 # G7 G6 G5 G4 G3 G2 G1 G0
- pand mmx_redmask, %mm0 # b7b6b5b4 b3_0_0_0 b7b6b5b4 b3_0_0_0
- pand mmx_grnmask, %mm2 # g7g6g5g4 g3g2_0_0 g7g6g5g4 g3g2_0_0
- pand mmx_redmask, %mm1 # r7r6r5r4 r3_0_0_0 r7r6r5r4 r3_0_0_0
- psrlw $3,%mm0 #0_0_0_b7 b6b5b4b3 0_0_0_b7 b6b5b4b3
- pxor %mm4, %mm4 # zero mm4
- movq %mm0, %mm5 # Copy B7-B0
- movq %mm2, %mm7 # Copy G7-G0
- punpcklbw %mm4, %mm2 # 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0
- punpcklbw %mm1, %mm0 # r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3
- psllw $3,%mm2 # 0_0_0_0 0_g7g6g5 g4g3g2_0 0_0_0_0
- por %mm2, %mm0 # r7r6r5r4 r3g7g6g5 g4g3g2b7 b6b5b4b3
- movq 8(%edi), %mm6 # Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
- movq %mm0, (%esi) # store pixel 0-3
- punpckhbw %mm4, %mm7 # 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0
- punpckhbw %mm1, %mm5 # r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3
- psllw $3,%mm7 # 0_0_0_0 0_g7g6g5 g4g3g2_0 0_0_0_0
- movd 4(%ecx), %mm0 # Load 4 Cb 00 00 00 00 u3 u2 u1 u0
- por %mm7, %mm5 # r7r6r5r4 r3g7g6g5 g4g3g2b7 b6b5b4b3
- movd 4(%edx), %mm1 # Load 4 Cr 00 00 00 00 v3 v2 v1 v0
- movq %mm5, 8(%esi) # store pixel 4-7
-
- addl $8,%edi
- addl $4,%ecx
- addl $4,%edx
- addl $16,%esi
- decl %eax
- jnz .L74
-.L72:
- xorl $1,%ebp
- jne .L76
- subl 16(%esp),%ecx
- subl 16(%esp),%edx
-.L76:
- subl $1,44(%esp)
- jnz .L68
-
- emms
-
- popl %esi
- popl %edi
- popl %ebp
- addl $8,%esp
- ret
diff --git a/ext/hermes/yuv2yuv.c b/ext/hermes/yuv2yuv.c
deleted file mode 100644
index 4a7560d4..00000000
--- a/ext/hermes/yuv2yuv.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gst/gst.h>
-
-/*#undef HAVE_LIBMMX */
-
-#ifdef HAVE_LIBMMX
-#include "mmx.h"
-#endif
-
-void gst_colorspace_yuy2_to_i420(unsigned char *src, unsigned char *dest, guint width, guint height)
-{
- int size, i, j;
- guchar *desty, *destr, *destb;
-
- size = width * height;
-
- desty = dest;
- destr = desty + size;
- destb = destr + (size>>2);
-
- for (i=0; i<height; i++) {
- for (j=0; j<(width>>1); j++) {
- *desty++ = *src;
- *desty++ = *(src+2);
- if ((i&1) == 0) {
- *destr++ = *(src+1);
- *destb++ = *(src+3);
- }
- src += 4;
- }
- }
-}
-
-void gst_colorspace_i420_to_yv12(unsigned char *src, unsigned char *dest, guint width, guint height)
-{
- int size, i;
- guint8 *destcr, *destcb;
-
- size = width * height;
-
- memcpy (dest, src, size);
-
- src += size;
- destcr = dest + size;
- size >>=2;
- destcb = destcr + size;
-
- i=size;
- while (i--)
- *destcb++ = *src++;
- i=size;
- while (i--)
- *destcr++ = *src++;
-}
-
diff --git a/ext/hermes/yuv2yuv.h b/ext/hermes/yuv2yuv.h
deleted file mode 100644
index e42894cf..00000000
--- a/ext/hermes/yuv2yuv.h
+++ /dev/null
@@ -1,29 +0,0 @@
- /* GStreamer
- * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __YUV2YUV_H__
-#define __YUV2YUV_H__
-
-#include <gst/gst.h>
-
-void gst_colorspace_yuy2_to_i420 (guchar *src, guchar *dest, guint width, guint height);
-void gst_colorspace_i420_to_yv12 (guchar *src, guchar *dest, guint width, guint height);
-
-#endif
-
diff --git a/gst/colorspace/Makefile.am b/gst/colorspace/Makefile.am
new file mode 100644
index 00000000..a6d2ca32
--- /dev/null
+++ b/gst/colorspace/Makefile.am
@@ -0,0 +1,15 @@
+
+plugin_LTLIBRARIES = libgstcolorspace.la
+
+if HAVE_CPU_I386
+ARCHSRCS = yuv2rgb_mmx16.s
+else
+ARCHSRCS =
+endif
+
+libgstcolorspace_la_SOURCES = gstcolorspace.c yuv2rgb.c yuv2yuv.c
+libgstcolorspace_la_CFLAGS = $(GST_CFLAGS)
+libgstcolorspace_la_LIBADD =
+libgstcolorspace_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+
+#noinst_HEADERS = yuv2rgb.h yuv2yuv.h
diff --git a/ext/hermes/gstcolorspace.c b/gst/colorspace/gstcolorspace.c
index 7c97ff23..e923c3a1 100644
--- a/ext/hermes/gstcolorspace.c
+++ b/gst/colorspace/gstcolorspace.c
@@ -20,21 +20,56 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <gstcolorspace.h>
#include <gst/gst.h>
#include <gst/video/video.h>
-#include "gstcolorspace.h"
#include "yuv2rgb.h"
-#include "yuv2yuv.h"
-static GstElementDetails colorspace_details = {
- "Colorspace converter",
- "Filter/Converter/Video",
- "Converts video from one colorspace to another using libhermes",
- "Wim Taymans <wim.taymans@chello.be>",
+static GstColorspaceFormat gst_colorspace_formats[] = {
+ { GST_STATIC_CAPS (GST_VIDEO_YUV_PAD_TEMPLATE_CAPS("I420")) },
+ { GST_STATIC_CAPS (GST_VIDEO_YUV_PAD_TEMPLATE_CAPS("YV12")) },
+ { GST_STATIC_CAPS (GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_32) },
+ { GST_STATIC_CAPS (GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24) },
+ { GST_STATIC_CAPS (GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_16) },
};
+static GstColorspaceConverter gst_colorspace_converters[] = {
+ { GST_COLORSPACE_I420, GST_COLORSPACE_RGB32, gst_colorspace_I420_to_rgb32 },
+ { GST_COLORSPACE_YV12, GST_COLORSPACE_RGB32, gst_colorspace_YV12_to_rgb32 },
+ { GST_COLORSPACE_I420, GST_COLORSPACE_RGB24, gst_colorspace_I420_to_rgb24 },
+ { GST_COLORSPACE_YV12, GST_COLORSPACE_RGB24, gst_colorspace_YV12_to_rgb24 },
+ { GST_COLORSPACE_I420, GST_COLORSPACE_RGB16, gst_colorspace_I420_to_rgb16 },
+ { GST_COLORSPACE_YV12, GST_COLORSPACE_RGB16, gst_colorspace_YV12_to_rgb16 },
+};
+
+static GstElementDetails colorspace_details = GST_ELEMENT_DETAILS (
+ "Colorspace converter",
+ "Filter/Converter/Video",
+ "Converts video from one colorspace to another",
+ "Wim Taymans <wim.taymans@chello.be>"
+);
+
+static GstStaticPadTemplate gst_colorspace_sink_template =
+GST_STATIC_PAD_TEMPLATE (
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_YUV_PAD_TEMPLATE_CAPS ("{ I420, YV12 }"))
+);
+
+static GstStaticPadTemplate gst_colorspace_src_template =
+GST_STATIC_PAD_TEMPLATE (
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_32 "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_24 "; "
+ GST_VIDEO_RGB_PAD_TEMPLATE_CAPS_16
+ )
+);
/* Stereo signals and args */
enum {
@@ -63,16 +98,11 @@ static void gst_colorspace_chain (GstPad *pad, GstData *_data);
static GstElementStateReturn
gst_colorspace_change_state (GstElement *element);
-/* FIXME */
-extern void gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest,
- guint width, guint height);
-extern void gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest,
- guint width, guint height);
-static GstPadTemplate *srctempl, *sinktempl;
static GstElementClass *parent_class = NULL;
/*static guint gst_colorspace_signals[LAST_SIGNAL] = { 0 }; */
+#if 0
static gboolean
colorspace_setup_converter (GstColorspace *space, GstCaps *from_caps, GstCaps *to_caps)
{
@@ -225,26 +255,128 @@ colorspace_setup_converter (GstColorspace *space, GstCaps *from_caps, GstCaps *t
}
return FALSE;
}
+#endif
+
+static GstCaps *
+gst_colorspace_caps_remove_format_info (GstCaps *caps, const char *media_type)
+{
+ int i;
+ GstStructure *structure;
+ GstCaps *rgbcaps;
+
+ for (i=0; i<gst_caps_get_size (caps); i++) {
+ structure = gst_caps_get_structure (caps, i);
+
+ gst_structure_set_name (structure, media_type);
+ gst_structure_remove_field (structure, "format");
+ gst_structure_remove_field (structure, "endianness");
+ gst_structure_remove_field (structure, "depth");
+ gst_structure_remove_field (structure, "bpp");
+ gst_structure_remove_field (structure, "red_mask");
+ gst_structure_remove_field (structure, "green_mask");
+ gst_structure_remove_field (structure, "blue_mask");
+ }
+
+ rgbcaps = gst_caps_simplify (caps);
+ gst_caps_free (caps);
+
+ return rgbcaps;
+}
static GstCaps*
gst_colorspace_getcaps (GstPad *pad)
{
GstColorspace *space;
- GstCaps *peercaps;
- GstCaps *ourcaps;
+ GstPad *otherpad;
+ GstCaps *othercaps;
+ GstCaps *caps;
space = GST_COLORSPACE (gst_pad_get_parent (pad));
- /* we can do everything our peer can... */
- peercaps = gst_pad_get_allowed_caps (space->srcpad);
+ otherpad = (pad == space->srcpad) ? space->sinkpad : space->srcpad;
- /* and our own template of course */
- ourcaps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+ othercaps = gst_pad_get_allowed_caps (otherpad);
- /* merge them together, we prefer the peercaps first */
- gst_caps_append (peercaps, ourcaps);
+ othercaps = gst_colorspace_caps_remove_format_info (othercaps,
+ (pad == space->srcpad) ? "video/x-raw-rgb" : "video/x-raw-yuv");
- return peercaps;
+ caps = gst_caps_intersect (othercaps, gst_pad_get_pad_template_caps (pad));
+ gst_caps_free (othercaps);
+
+ return caps;
+}
+
+static GstColorSpaceFormatType
+gst_colorspace_get_format (const GstCaps *caps)
+{
+ int i;
+
+ for(i=0; i<G_N_ELEMENTS (gst_colorspace_formats); i++) {
+ GstCaps *icaps;
+ GstCaps *fcaps;
+
+ fcaps = gst_caps_copy (gst_static_caps_get (
+ &gst_colorspace_formats[i].caps));
+
+ icaps = gst_caps_intersect (caps, fcaps);
+ if (!gst_caps_is_empty (icaps)) {
+ gst_caps_free (icaps);
+ return i;
+ }
+ gst_caps_free (icaps);
+ }
+
+ g_assert_not_reached();
+ return -1;
+}
+
+#define ROUND_UP_2(x) (((x)+1)&~1)
+#define ROUND_UP_4(x) (((x)+3)&~3)
+#define ROUND_UP_8(x) (((x)+7)&~7)
+
+static int
+gst_colorspace_format_get_size(GstColorSpaceFormatType index, int width,
+ int height)
+{
+ int size;
+
+ switch (index) {
+ case GST_COLORSPACE_I420:
+ case GST_COLORSPACE_YV12:
+ size = ROUND_UP_4 (width) * ROUND_UP_2 (height);
+ size += ROUND_UP_8 (width)/2 * ROUND_UP_2 (height)/2;
+ size += ROUND_UP_8 (width)/2 * ROUND_UP_2 (height)/2;
+ return size;
+ break;
+ case GST_COLORSPACE_RGB32:
+ return width*height*4;
+ break;
+ case GST_COLORSPACE_RGB24:
+ return ROUND_UP_4 (width*3) * height;
+ break;
+ case GST_COLORSPACE_RGB16:
+ return ROUND_UP_4 (width*2) * height;
+ break;
+ }
+
+ g_assert_not_reached();
+ return 0;
+}
+
+static int
+gst_colorspace_get_converter (GstColorSpaceFormatType from,
+ GstColorSpaceFormatType to)
+{
+ int i;
+
+ for (i=0; i<G_N_ELEMENTS (gst_colorspace_converters); i++) {
+ GstColorspaceConverter *converter = gst_colorspace_converters + i;
+ if (from == converter->from && to == converter->to) {
+ return i;
+ }
+ }
+ g_assert_not_reached();
+ return -1;
}
static GstPadLinkReturn
@@ -253,42 +385,75 @@ gst_colorspace_link (GstPad *pad, const GstCaps *caps)
GstColorspace *space;
GstPad *otherpad;
GstStructure *structure;
+ GstPadLinkReturn link_ret;
+ int width, height;
+ double fps;
+ int format_index;
space = GST_COLORSPACE (gst_pad_get_parent (pad));
otherpad = (pad == space->sinkpad) ? space->srcpad : space->sinkpad;
+ link_ret = gst_pad_try_set_caps (otherpad, caps);
+ if (link_ret == GST_PAD_LINK_OK) {
+ return link_ret;
+ }
+
structure = gst_caps_get_structure (caps, 0);
- gst_structure_get_int (structure, "width", &space->width);
- gst_structure_get_int (structure, "height", &space->height);
- gst_structure_get_double (structure, "framerate", &space->fps);
+ format_index = gst_colorspace_get_format (caps);
+ g_print("format index is %d\n", format_index);
+
+ gst_structure_get_int (structure, "width", &width);
+ gst_structure_get_int (structure, "height", &height);
+ gst_structure_get_double (structure, "framerate", &fps);
GST_INFO ( "size: %dx%d", space->width, space->height);
- if (pad == space->sinkpad) {
- gst_caps_replace (&space->sinkcaps, gst_caps_copy(caps));
- } else {
- gst_caps_replace (&space->srccaps, gst_caps_copy(caps));
+ if (gst_pad_is_negotiated (otherpad)) {
+ GstCaps *othercaps;
+
+ othercaps = gst_caps_copy (gst_pad_get_negotiated_caps (otherpad));
+
+ gst_caps_set_simple (othercaps,
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ "framerate", G_TYPE_DOUBLE, fps, NULL);
+
+ link_ret = gst_pad_try_set_caps (otherpad, othercaps);
+ if (link_ret != GST_PAD_LINK_OK) {
+ return link_ret;
+ }
}
-#if 0
- peer = gst_pad_get_peer (otherpad);
- if (!peer) {
- return GST_PAD_LINK_DELAYED;
+ if (pad == space->srcpad) {
+ space->src_format_index = format_index;
+ } else {
+ space->sink_format_index = format_index;
}
-#endif
- if (gst_pad_try_set_caps (otherpad, caps) >= 0) {
- space->passthru = TRUE;
+ if (gst_pad_is_negotiated (otherpad)) {
+ space->converter_index = gst_colorspace_get_converter (
+ space->sink_format_index, space->src_format_index);
+
+ g_print("using index %d\n", space->converter_index);
- return GST_PAD_LINK_OK;
+ space->sink_size = gst_colorspace_format_get_size(space->sink_format_index,
+ width,height);
+ space->src_size = gst_colorspace_format_get_size(space->src_format_index,
+ width,height);
+ space->width = width;
+ space->height = height;
+ space->fps = fps;
}
- if (colorspace_setup_converter (space, space->sinkcaps, space->srccaps)) {
- return GST_PAD_LINK_OK;
+#if 0
+ if (gst_pad_is_negotiated (otherpad)) {
+ g_warning ("could not get converter\n");
+ return GST_PAD_LINK_REFUSED;
}
+#endif
- return GST_PAD_LINK_REFUSED;
+ return GST_PAD_LINK_OK;
}
GType
@@ -317,31 +482,12 @@ static void
gst_colorspace_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
- GstCaps *caps;
-
- /* create caps for templates */
- caps = gst_caps_from_string (
- GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2 }") "; "
- GST_VIDEO_CAPS_RGB "; "
- GST_VIDEO_CAPS_BGR "; "
- GST_VIDEO_CAPS_xBGR "; "
- GST_VIDEO_CAPS_xRGB "; "
- GST_VIDEO_CAPS_BGRx "; "
- GST_VIDEO_CAPS_RGBx "; "
- GST_VIDEO_CAPS_RGB_15 "; "
- GST_VIDEO_CAPS_RGB_16);
- /* build templates */
- srctempl = gst_pad_template_new ("src",
- GST_PAD_SRC,
- GST_PAD_ALWAYS,
- caps);
- sinktempl = gst_pad_template_new ("sink",
- GST_PAD_SINK,
- GST_PAD_ALWAYS,
- caps);
- gst_element_class_add_pad_template (element_class, srctempl);
- gst_element_class_add_pad_template (element_class, sinktempl);
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_colorspace_src_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_colorspace_sink_template));
+
gst_element_class_set_details (element_class, &colorspace_details);
}
@@ -360,26 +506,26 @@ gst_colorspace_class_init (GstColorspaceClass *klass)
gobject_class->get_property = gst_colorspace_get_property;
gstelement_class->change_state = gst_colorspace_change_state;
+
+ gst_colorspace_table_init(NULL);
}
static void
gst_colorspace_init (GstColorspace *space)
{
- space->sinkpad = gst_pad_new_from_template (sinktempl, "sink");
+ space->sinkpad = gst_pad_new_from_template (
+ gst_static_pad_template_get (&gst_colorspace_sink_template),
+ "sink");
gst_pad_set_link_function (space->sinkpad, gst_colorspace_link);
gst_pad_set_getcaps_function (space->sinkpad, gst_colorspace_getcaps);
gst_pad_set_chain_function(space->sinkpad,gst_colorspace_chain);
gst_element_add_pad(GST_ELEMENT(space),space->sinkpad);
- space->srcpad = gst_pad_new_from_template (srctempl, "src");
+ space->srcpad = gst_pad_new_from_template (
+ gst_static_pad_template_get (&gst_colorspace_src_template),
+ "src");
gst_element_add_pad(GST_ELEMENT(space),space->srcpad);
gst_pad_set_link_function (space->srcpad, gst_colorspace_link);
-
-#ifdef HAVE_HERMES
- space->h_handle = Hermes_ConverterInstance (0);
-#endif
- space->converter = NULL;
- space->passthru = FALSE;
}
static void
@@ -387,9 +533,8 @@ gst_colorspace_chain (GstPad *pad,GstData *_data)
{
GstBuffer *buf = GST_BUFFER (_data);
GstColorspace *space;
- gint size;
GstBuffer *outbuf = NULL;
- gint dest_bytes, src_bytes;
+ GstColorspaceConverter *converter;
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
@@ -400,54 +545,19 @@ gst_colorspace_chain (GstPad *pad,GstData *_data)
g_return_if_fail (space != NULL);
g_return_if_fail (GST_IS_COLORSPACE (space));
- if (space->passthru) {
- gst_pad_push (space->srcpad, _data);
- return;
+ if (GST_BUFFER_SIZE (buf) < space->sink_size) {
+ g_critical ("input size is smaller than expected");
}
- size = space->width * space->height;
- dest_bytes = ((space->destbpp+7)/8);
- src_bytes = ((space->srcbpp+7)/8);
-
outbuf = gst_pad_alloc_buffer (space->srcpad, GST_BUFFER_OFFSET_NONE,
- (size * space->destbpp)/8);
+ space->src_size);
- if (space->type == GST_COLORSPACE_YUV_RGB) {
- gst_colorspace_convert (space->converter, GST_BUFFER_DATA (buf), GST_BUFFER_DATA (outbuf));
- }
-#ifdef HAVE_HERMES
- else if (space->type == GST_COLORSPACE_HERMES) {
- Hermes_ConverterCopy (space->h_handle,
- GST_BUFFER_DATA (buf), 0, 0, space->width, space->height, space->width * src_bytes,
- GST_BUFFER_DATA (outbuf), 0, 0, space->width, space->height, space->width * dest_bytes);
- }
-#endif
- else if (space->type == GST_COLORSPACE_YUY2_I420) {
- gst_colorspace_yuy2_to_i420 (GST_BUFFER_DATA (buf),
- GST_BUFFER_DATA (outbuf),
- space->width,
- space->height);
- }
- else if (space->type == GST_COLORSPACE_420_SWAP) {
- gst_colorspace_i420_to_yv12 (GST_BUFFER_DATA (buf),
- GST_BUFFER_DATA (outbuf),
- space->width,
- space->height);
- }
- else if (space->type == GST_COLORSPACE_RGB32_I420) {
- gst_colorspace_rgb32_to_i420 (GST_BUFFER_DATA (buf),
- GST_BUFFER_DATA (outbuf),
- space->width,
- space->height);
- }
- else if (space->type == GST_COLORSPACE_RGB32_YV12) {
- gst_colorspace_rgb32_to_yv12 (GST_BUFFER_DATA (buf),
- GST_BUFFER_DATA (outbuf),
- space->width,
- space->height);
- }
+ converter = gst_colorspace_converters + space->converter_index;
+ converter->convert (space, GST_BUFFER_DATA (outbuf),
+ GST_BUFFER_DATA (buf));
GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
+ GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
gst_buffer_unref (buf);
gst_pad_push (space->srcpad, GST_DATA (outbuf));
@@ -466,10 +576,6 @@ gst_colorspace_change_state (GstElement *element)
case GST_STATE_PLAYING_TO_PAUSED:
break;
case GST_STATE_PAUSED_TO_READY:
- gst_colorspace_converter_destroy (space->converter);
- space->converter = NULL;
- space->type = GST_COLORSPACE_NONE;
- gst_caps_replace (&space->sinkcaps, NULL);
break;
}
@@ -510,14 +616,8 @@ gst_colorspace_get_property (GObject *object, guint prop_id, GValue *value, GPar
static gboolean
plugin_init (GstPlugin *plugin)
{
-#ifdef HAVE_HERMES
- gint hermes_res;
-
- hermes_res = Hermes_Init();
- g_return_val_if_fail (hermes_res != 0, FALSE);
-#endif
-
- if (!gst_element_register (plugin, "colorspace", GST_RANK_PRIMARY, GST_TYPE_COLORSPACE))
+ if (!gst_element_register (plugin, "colorspace", GST_RANK_PRIMARY,
+ GST_TYPE_COLORSPACE))
return FALSE;
return TRUE;
diff --git a/ext/hermes/gstcolorspace.h b/gst/colorspace/gstcolorspace.h
index 0cf6f2d7..22e2f7ec 100644
--- a/ext/hermes/gstcolorspace.h
+++ b/gst/colorspace/gstcolorspace.h
@@ -17,25 +17,12 @@
* Boston, MA 02111-1307, USA.
*/
-
-#ifndef __GST_COLORSPACE_H__
-#define __GST_COLORSPACE_H__
-
+#ifndef _GST_COLORSPACE_H_
+#define _GST_COLORSPACE_H_
#include <gst/gst.h>
-#include "yuv2rgb.h"
-
-#ifdef HAVE_HERMES
-# include <Hermes/Hermes.h>
-#endif
-
-/* #include <gst/meta/audioraw.h> */
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+G_BEGIN_DECLS
#define GST_TYPE_COLORSPACE \
(gst_colorspace_get_type())
@@ -66,21 +53,19 @@ struct _GstColorspace {
GstPad *sinkpad,*srcpad;
-#ifdef HAVE_HERMES
- HermesHandle h_handle;
- HermesFormat source, dest;
-#endif
+ int converter_index;
- GstColorSpaceConverter *converter;
+ int src_format_index;
+ int sink_format_index;
+
+ int src_size;
+ int sink_size;
+
+ int src_stride;
+ int sink_stride;
- GstColorSpaceConverterType type;
gint width, height;
gdouble fps;
- gint srcbpp, destbpp;
- gboolean passthru;
-
- GstCaps *sinkcaps;
- GstCaps *srccaps;
};
struct _GstColorspaceClass {
@@ -89,9 +74,26 @@ struct _GstColorspaceClass {
GType gst_colorspace_get_type(void);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+typedef struct _GstColorspaceFormat {
+ GstStaticCaps caps;
+
+} GstColorspaceFormat;
+
+typedef enum {
+ GST_COLORSPACE_I420,
+ GST_COLORSPACE_YV12,
+ GST_COLORSPACE_RGB32,
+ GST_COLORSPACE_RGB24,
+ GST_COLORSPACE_RGB16,
+} GstColorSpaceFormatType;
+
+typedef struct _GstColorspaceConverter {
+ GstColorSpaceFormatType from;
+ GstColorSpaceFormatType to;
+ void (*convert) (GstColorspace *colorspace, unsigned char *dest, unsigned char *src);
+} GstColorspaceConverter;
+G_END_DECLS
+
+#endif
-#endif /* __GST_COLORSPACE_H */
diff --git a/ext/hermes/yuv2rgb.c b/gst/colorspace/yuv2rgb.c
index b3b1b494..3627e896 100644
--- a/ext/hermes/yuv2rgb.c
+++ b/gst/colorspace/yuv2rgb.c
@@ -17,19 +17,26 @@
* Boston, MA 02111-1307, USA.
*/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include <math.h>
#include <stdlib.h>
#include "yuv2rgb.h"
-/* #define HAVE_LIBMMX */
+#undef HAVE_LIBMMX
#ifdef HAVE_LIBMMX
#include <mmx.h>
#endif
+static int V_r_tab [256];
+static int V_g_tab [256];
+static int U_g_tab [256];
+static int U_b_tab [256];
+
#define CB_BASE 1
#define CR_BASE (CB_BASE*CB_RANGE)
#define LUM_BASE (CR_BASE*CR_RANGE)
@@ -52,215 +59,175 @@
: Max(-128.0, ((x) * chromaCorrect)))
-static void gst_colorspace_I420_to_rgb16 (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
-static void gst_colorspace_I420_to_rgb24 (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
-static void gst_colorspace_I420_to_rgb32 (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_I420_to_rgb16 (GstColorspace *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_I420_to_rgb24 (GstColorspace *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_I420_to_rgb32 (GstColorspace *space, unsigned char *src, unsigned char *dest);
#ifdef HAVE_LIBMMX
-static void gst_colorspace_I420_to_bgr16_mmx (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
-static void gst_colorspace_I420_to_bgr32_mmx (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_I420_to_bgr16_mmx (GstColorspace *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_I420_to_bgr32_mmx (GstColorspace *space, unsigned char *src, unsigned char *dest);
#endif
-static void gst_colorspace_YV12_to_rgb16 (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
-static void gst_colorspace_YV12_to_rgb24 (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
-static void gst_colorspace_YV12_to_rgb32 (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_YV12_to_rgb16 (GstColorspace *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_YV12_to_rgb24 (GstColorspace *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_YV12_to_rgb32 (GstColorspace *space, unsigned char *src, unsigned char *dest);
#ifdef HAVE_LIBMMX
-static void gst_colorspace_YV12_to_bgr16_mmx (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
-static void gst_colorspace_YV12_to_bgr32_mmx (GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_YV12_to_bgr16_mmx (GstColorspace *space, unsigned char *src, unsigned char *dest);
+void gst_colorspace_YV12_to_bgr32_mmx (GstColorspace *space, unsigned char *src, unsigned char *dest);
#endif
-static void gst_colorspace_yuv_to_rgb16(GstColorSpaceYUVTables *tables,
+static void
+gst_colorspace_yuv_to_rgb16(GstColorspace *space,
+ unsigned char *out,
+ unsigned char *lum,
+ unsigned char *cr,
+ unsigned char *cb,
+ int cols, int rows);
+static void
+gst_colorspace_yuv_to_rgb24(GstColorspace *space,
+ unsigned char *out,
+ unsigned char *lum,
+ unsigned char *cr,
+ unsigned char *cb,
+ int cols, int rows);
+static void
+gst_colorspace_yuv_to_rgb32(GstColorspace *space,
+ unsigned char *out,
+ unsigned char *lum,
+ unsigned char *cr,
+ unsigned char *cb,
+ int cols, int rows);
+#if 0
+static void gst_colorspace_yuv_to_rgb16(GstColorspaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
-static void gst_colorspace_yuv_to_rgb24(GstColorSpaceYUVTables *tables,
+static void gst_colorspace_yuv_to_rgb24(GstColorspaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
-static void gst_colorspace_yuv_to_rgb32(GstColorSpaceYUVTables *tables,
+static void gst_colorspace_yuv_to_rgb32(GstColorspaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
#ifdef HAVE_LIBMMX
-static void gst_colorspace_yuv_to_bgr32_mmx(GstColorSpaceYUVTables *tables,
+void gst_colorspace_yuv_to_bgr32_mmx(GstColorspaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
-extern void gst_colorspace_yuv_to_bgr16_mmx(GstColorSpaceYUVTables *tables,
+extern void gst_colorspace_yuv_to_bgr16_mmx(GstColorspaceYUVTables *tables,
unsigned char *lum,
unsigned char *cr,
unsigned char *cb,
unsigned char *out,
int cols, int rows);
#endif
+#endif
-static GstColorSpaceYUVTables * gst_colorspace_init_yuv(long depth,
- long red_mask, long green_mask, long blue_mask);
-
-GstColorSpaceConverter*
-gst_colorspace_yuv2rgb_get_converter (const GstCaps *from, const GstCaps *to)
-{
- guint32 from_space;
- GstColorSpaceConverter *new;
- gint to_bpp;
- GstStructure *struct_from, *struct_to;
-
- GST_DEBUG ("gst_colorspace_yuv2rgb_get_converter");
-
- new = g_malloc (sizeof (GstColorSpaceConverter));
-
- struct_from = gst_caps_get_structure (from, 0);
- struct_to = gst_caps_get_structure (to, 0);
-
- gst_structure_get_int (struct_from, "width", &new->width);
- gst_structure_get_int (struct_from, "height", &new->height);
- new->color_tables = NULL;
+#define ROUND_UP_2(x) (((x)+1)&~1)
+#define ROUND_UP_4(x) (((x)+3)&~3)
+#define ROUND_UP_8(x) (((x)+7)&~7)
- gst_structure_get_fourcc (struct_from, "format", &from_space);
- gst_structure_get_int (struct_to, "bpp", &to_bpp);
- /* FIXME we leak new here. */
+void gst_colorspace_I420_to_rgb32(GstColorspace *space, unsigned char *dest,
+ unsigned char *src)
+{
+ unsigned char *src_U;
+ unsigned char *src_V;
- switch(from_space) {
- case GST_MAKE_FOURCC ('Y','V','1','2'):
- case GST_MAKE_FOURCC ('I','4','2','0'):
- {
- gint red_mask;
- gint green_mask;
- gint blue_mask;
+ src_U = src + ROUND_UP_4 (space->width) * ROUND_UP_2 (space->height);
+ src_V = src_U + ROUND_UP_8 (space->width)/2 * ROUND_UP_2 (space->height)/2;
- gst_structure_get_int (struct_to, "red_mask", &red_mask);
- gst_structure_get_int (struct_to, "green_mask", &green_mask);
- gst_structure_get_int (struct_to, "blue_mask", &blue_mask);
+ gst_colorspace_yuv_to_rgb32(space,
+ dest,
+ src, src_U, src_V,
+ space->width, space->height);
+}
- GST_INFO ( "red_mask %08x", red_mask);
- GST_INFO ( "green_mask %08x", green_mask);
- GST_INFO ( "blue_mask %08x", blue_mask);
+void gst_colorspace_I420_to_rgb24(GstColorspace *space, unsigned char *dest,
+ unsigned char *src)
+{
+ unsigned char *src_U;
+ unsigned char *src_V;
- new->insize = new->width * new->height + new->width * new->height/2;
- new->color_tables = gst_colorspace_init_yuv (to_bpp, red_mask, green_mask, blue_mask);
- new->outsize = new->width * new->height * (to_bpp/8);
+ src_U = src + ROUND_UP_4 (space->width) * ROUND_UP_2 (space->height);
+ src_V = src_U + ROUND_UP_8 (space->width)/2 * ROUND_UP_2 (space->height)/2;
- switch(to_bpp) {
- case 32:
-#ifdef HAVE_LIBMMX
- if (red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff &&
- (gst_cpu_get_flags () & GST_CPU_FLAG_MMX) ) {
- if (from_space == GST_STR_FOURCC ("I420"))
- new->convert = gst_colorspace_I420_to_bgr32_mmx;
- else
- new->convert = gst_colorspace_YV12_to_bgr32_mmx;
- }
- else
-#endif
- if (from_space == GST_STR_FOURCC ("I420"))
- new->convert = gst_colorspace_I420_to_rgb32;
- else
- new->convert = gst_colorspace_YV12_to_rgb32;
- break;
- case 24:
- if (from_space == GST_STR_FOURCC ("I420"))
- new->convert = gst_colorspace_I420_to_rgb24;
- else
- new->convert = gst_colorspace_YV12_to_rgb24;
- break;
- case 15:
- case 16:
-#ifdef HAVE_LIBMMX
- if (red_mask == 0xf800 && green_mask == 0x07e0 && blue_mask == 0x001f &&
- (gst_cpu_get_flags () & GST_CPU_FLAG_MMX) ) {
- if (from_space == GST_STR_FOURCC ("I420"))
- new->convert = gst_colorspace_I420_to_bgr16_mmx;
- else
- new->convert = gst_colorspace_YV12_to_bgr16_mmx;
- }
- else
-#endif
- if (from_space == GST_STR_FOURCC ("I420"))
- new->convert = gst_colorspace_I420_to_rgb16;
- else
- new->convert = gst_colorspace_YV12_to_rgb16;
- break;
- default:
- g_print("gst_colorspace_yuv2rgb not implemented\n");
- g_free (new);
- new = NULL;
- }
- break;
- }
- default:
- g_print("gst_colorspace_yuv2rgb not implemented\n");
- g_free (new);
- new = NULL;
- }
- return new;
+ gst_colorspace_yuv_to_rgb24(space,
+ dest,
+ src, src_U, src_V,
+ space->width, space->height);
}
-void
-gst_colorspace_converter_destroy (GstColorSpaceConverter *conv)
+void gst_colorspace_I420_to_rgb16(GstColorspace *space, unsigned char *dest,
+ unsigned char *src)
{
- if (conv)
- g_free (conv);
+ unsigned char *src_U;
+ unsigned char *src_V;
+
+ src_U = src + ROUND_UP_4 (space->width) * ROUND_UP_2 (space->height);
+ src_V = src_U + ROUND_UP_8 (space->width)/2 * ROUND_UP_2 (space->height)/2;
+
+ gst_colorspace_yuv_to_rgb16(space,
+ dest,
+ src, src_U, src_V,
+ space->width, space->height);
}
-static void gst_colorspace_I420_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
+void gst_colorspace_YV12_to_rgb32(GstColorspace *space, unsigned char *dest,
+ unsigned char *src)
{
- int size;
- GST_DEBUG ("gst_colorspace_I420_to_rgb32");
+ unsigned char *src_U;
+ unsigned char *src_V;
- size = space->width * space->height;
-
- gst_colorspace_yuv_to_rgb32(space->color_tables,
- src, /* Y component */
- src+size, /* cr component */
- src+size+(size>>2), /* cb component */
- dest,
- space->height,
- space->width);
+ src_V = src + ROUND_UP_4 (space->width) * ROUND_UP_2 (space->height);
+ src_U = src_V + ROUND_UP_8 (space->width)/2 * ROUND_UP_2 (space->height)/2;
+ gst_colorspace_yuv_to_rgb32(space,
+ dest,
+ src, src_U, src_V,
+ space->width, space->height);
}
-static void gst_colorspace_I420_to_rgb24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
- int size;
- GST_DEBUG ("gst_colorspace_I420_to_rgb24");
-
- size = space->width * space->height;
+void gst_colorspace_YV12_to_rgb24(GstColorspace *space, unsigned char *dest,
+ unsigned char *src)
+{
+ unsigned char *src_U;
+ unsigned char *src_V;
- gst_colorspace_yuv_to_rgb24(space->color_tables,
- src, /* Y component */
- src+size, /* cr component */
- src+size+(size>>2), /* cb component */
- dest,
- space->height,
- space->width);
+ src_V = src + ROUND_UP_4 (space->width) * ROUND_UP_2 (space->height);
+ src_U = src_V + ROUND_UP_8 (space->width)/2 * ROUND_UP_2 (space->height)/2;
+ gst_colorspace_yuv_to_rgb24(space,
+ dest,
+ src, src_U, src_V,
+ space->width, space->height);
}
-static void gst_colorspace_I420_to_rgb16(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
- int size;
- GST_DEBUG ("gst_colorspace_I420_to_rgb16");
+void gst_colorspace_YV12_to_rgb16(GstColorspace *space, unsigned char *dest,
+ unsigned char *src)
+{
+ unsigned char *src_U;
+ unsigned char *src_V;
- size = space->width * space->height;
-
- gst_colorspace_yuv_to_rgb16(space->color_tables,
- src, /* Y component */
- src+size, /* cr component */
- src+size+(size>>2), /* cb component */
- dest,
- space->height,
- space->width);
+ src_V = src + ROUND_UP_4 (space->width) * ROUND_UP_2 (space->height);
+ src_U = src_V + ROUND_UP_8 (space->width)/2 * ROUND_UP_2 (space->height)/2;
+ gst_colorspace_yuv_to_rgb16(space,
+ dest,
+ src, src_U, src_V,
+ space->width, space->height);
}
#ifdef HAVE_LIBMMX
-static void gst_colorspace_I420_to_bgr32_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
+void gst_colorspace_I420_to_bgr32_mmx(GstColorspace *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG ("gst_colorspace_I420_to_rgb32_mmx");
@@ -275,7 +242,8 @@ static void gst_colorspace_I420_to_bgr32_mmx(GstColorSpaceConverter *space, unsi
space->width);
}
-static void gst_colorspace_I420_to_bgr16_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
+
+void gst_colorspace_I420_to_bgr16_mmx(GstColorspace *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG ("gst_colorspace_I420_to_bgr16_mmx ");
@@ -291,60 +259,8 @@ static void gst_colorspace_I420_to_bgr16_mmx(GstColorSpaceConverter *space, unsi
GST_DEBUG ("gst_colorspace_I420_to_bgr16_mmx done");
}
-#endif
-
-
-static void gst_colorspace_YV12_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest)
-{
- int size;
- GST_DEBUG ("gst_colorspace_YV12_to_rgb32");
-
- size = space->width * space->height;
-
- gst_colorspace_yuv_to_rgb32(space->color_tables,
- src, /* Y component */
- src+size+(size>>2), /* cb component */
- src+size, /* cr component */
- dest,
- space->height,
- space->width);
-
-}
-
-static void gst_colorspace_YV12_to_rgb24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
- int size;
- GST_DEBUG ("gst_colorspace_YV12_to_rgb24");
-
- size = space->width * space->height;
-
- gst_colorspace_yuv_to_rgb24(space->color_tables,
- src, /* Y component */
- src+size+(size>>2), /* cb component */
- src+size, /* cr component */
- dest,
- space->height,
- space->width);
-
-}
-
-static void gst_colorspace_YV12_to_rgb16(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
- int size;
- GST_DEBUG ("gst_colorspace_YV12_to_rgb16");
-
- size = space->width * space->height;
-
- gst_colorspace_yuv_to_rgb16(space->color_tables,
- src, /* Y component */
- src+size+(size>>2), /* cb component */
- src+size, /* cr component */
- dest,
- space->height,
- space->width);
-
-}
-#ifdef HAVE_LIBMMX
-static void gst_colorspace_YV12_to_bgr32_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
+void gst_colorspace_YV12_to_bgr32_mmx(GstColorspace *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG ("gst_colorspace_YV12_to_rgb32_mmx");
@@ -359,7 +275,8 @@ static void gst_colorspace_YV12_to_bgr32_mmx(GstColorSpaceConverter *space, unsi
space->width);
}
-static void gst_colorspace_YV12_to_bgr16_mmx(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) {
+
+void gst_colorspace_YV12_to_bgr16_mmx(GstColorspace *space, unsigned char *src, unsigned char *dest) {
int size;
GST_DEBUG ("gst_colorspace_YV12_to_bgr16_mmx ");
@@ -436,21 +353,33 @@ unsigned long a;
*--------------------------------------------------------------
*/
-static GstColorSpaceYUVTables *
-gst_colorspace_init_yuv(long depth, long red_mask, long green_mask, long blue_mask)
+void
+gst_colorspace_table_init (GstColorspace *space)
{
+ int i;
+
+ for (i=0; i<256; i++) {
+ V_r_tab[i] = (0.419/0.299) * (i-128);
+ V_g_tab[i] = -(0.299/0.419) * (i-128);
+ U_g_tab[i] = -(0.114/0.331) * (i-128);
+ U_b_tab[i] = (0.587/0.331) * (i-128);
+ }
+#if 0
int CR, CB, i;
int *L_tab, *Cr_r_tab, *Cr_g_tab, *Cb_g_tab, *Cb_b_tab;
long *r_2_pix_alloc;
long *g_2_pix_alloc;
long *b_2_pix_alloc;
- GstColorSpaceYUVTables *tables = g_malloc(sizeof(GstColorSpaceYUVTables));
+ long depth = 32;
+ long red_mask = 0xff0000;
+ long green_mask = 0x00ff00;
+ long blue_mask = 0x0000ff;
- L_tab = tables->L_tab = (int *)malloc(256*sizeof(int));
- Cr_r_tab = tables->Cr_r_tab = (int *)malloc(256*sizeof(int));
- Cr_g_tab = tables->Cr_g_tab = (int *)malloc(256*sizeof(int));
- Cb_g_tab = tables->Cb_g_tab = (int *)malloc(256*sizeof(int));
- Cb_b_tab = tables->Cb_b_tab = (int *)malloc(256*sizeof(int));
+ L_tab = space->L_tab = (int *)malloc(256*sizeof(int));
+ Cr_r_tab = space->Cr_r_tab = (int *)malloc(256*sizeof(int));
+ Cr_g_tab = space->Cr_g_tab = (int *)malloc(256*sizeof(int));
+ Cb_g_tab = space->Cb_g_tab = (int *)malloc(256*sizeof(int));
+ Cb_b_tab = space->Cb_b_tab = (int *)malloc(256*sizeof(int));
r_2_pix_alloc = (long *)malloc(768*sizeof(long));
g_2_pix_alloc = (long *)malloc(768*sizeof(long));
@@ -546,234 +475,100 @@ gst_colorspace_init_yuv(long depth, long red_mask, long green_mask, long blue_ma
b_2_pix_alloc[i+ 512] = b_2_pix_alloc[511];
}
- tables->r_2_pix = r_2_pix_alloc + 256;
- tables->g_2_pix = g_2_pix_alloc + 256;
- tables->b_2_pix = b_2_pix_alloc + 256;
-
- return tables;
-
+ space->r_2_pix = r_2_pix_alloc + 256;
+ space->g_2_pix = g_2_pix_alloc + 256;
+ space->b_2_pix = b_2_pix_alloc + 256;
+#endif
}
-/*
- *--------------------------------------------------------------
- *
- * Color16DitherImage --
- *
- * Converts image into 16 bit color.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
static void
-gst_colorspace_yuv_to_rgb16(tables, lum, cb, cr, out, rows, cols)
- GstColorSpaceYUVTables *tables;
- unsigned char *lum;
- unsigned char *cr;
- unsigned char *cb;
- unsigned char *out;
- int cols, rows;
-
+gst_colorspace_yuv_to_rgb32(GstColorspace *space,
+ unsigned char *dest,
+ unsigned char *Y,
+ unsigned char *U,
+ unsigned char *V,
+ int width, int height)
{
- int L, CR, CB;
- unsigned short *row1, *row2;
- unsigned char *lum2;
- int x, y;
- int cr_r;
- int crb_g;
- int cb_b;
- int cols_2 = cols>>1;
-
- row1 = (unsigned short *)out;
- row2 = row1 + cols;
- lum2 = lum + cols;
-
- for (y=rows>>1; y; y--) {
- for (x=cols_2; x; x--) {
-
- CR = *cr++;
- CB = *cb++;
- cr_r = tables->Cr_r_tab[CR];
- crb_g = tables->Cr_g_tab[CR] + tables->Cb_g_tab[CB];
- cb_b = tables->Cb_b_tab[CB];
-
- L = tables->L_tab[(int) *lum++];
-
- *row1++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
-
- L = tables->L_tab[(int) *lum++];
-
- *row1++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
-
- /*
- * Now, do second row.
- */
- L = tables->L_tab[(int) *lum2++];
-
- *row2++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
-
- L = tables->L_tab[(int) *lum2++];
-
- *row2++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
- }
- /*
- * These values are at the start of the next line, (due
- * to the ++'s above),but they need to be at the start
- * of the line after that.
- */
- lum = lum2;
- row1 = row2;
- lum2 += cols;
- row2 += cols;
+ int x,y;
+ int src_rowstride;
+ int dest_rowstride;
+
+ src_rowstride = ROUND_UP_4 (space->width);
+ dest_rowstride = width * 4;
+ for(y=0;y<height;y++){
+ for(x=0;x<width;x++){
+ dest[x*4 + 0] = 0;
+ dest[x*3 + 1] = CLAMP (Y[x] + V_r_tab[V[x/2]], 0, 255);
+ dest[x*3 + 2] = CLAMP (Y[x] + U_g_tab[U[x/2]] + V_g_tab[V[x/2]], 0, 255);
+ dest[x*3 + 3] = CLAMP (Y[x] + U_b_tab[U[x/2]], 0, 255);
+ }
+ Y += src_rowstride;
+ dest += dest_rowstride;
+ if (y&1) {
+ U += src_rowstride/2;
+ V += src_rowstride/2;
}
+ }
}
static void
-gst_colorspace_yuv_to_rgb24(tables, lum, cb, cr, out, rows, cols)
- GstColorSpaceYUVTables *tables;
- unsigned char *lum;
- unsigned char *cr;
- unsigned char *cb;
- unsigned char *out;
- int cols, rows;
-
+gst_colorspace_yuv_to_rgb24(GstColorspace *space,
+ unsigned char *dest,
+ unsigned char *Y,
+ unsigned char *U,
+ unsigned char *V,
+ int width, int height)
{
- int L, CR, CB;
- unsigned char *row1, *row2;
- unsigned char *lum2;
- int x, y;
- int cr_r;
- int crb_g;
- int cb_b;
- int cols_2 = cols>>1;
- int cols_3 = cols*3;
- unsigned char pixels[4];
-
- row1 = out;
- row2 = row1 + cols_3;
- lum2 = lum + cols;
- for (y=rows>>1; y; y--) {
- for (x=cols_2; x; x--) {
-
- CR = *cr++;
- CB = *cb++;
- cr_r = tables->Cr_r_tab[CR];
- crb_g = tables->Cr_g_tab[CR] + tables->Cb_g_tab[CB];
- cb_b = tables->Cb_b_tab[CB];
-
- L = tables->L_tab[(int) *lum++];
-
- ((int *)pixels)[0] = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
- *row1++ = pixels[0]; *row1++ = pixels[1]; *row1++ = pixels[2];
-
- L = tables->L_tab[(int) *lum++];
-
- ((int *)pixels)[0] = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
- *row1++ = pixels[0]; *row1++ = pixels[1]; *row1++ = pixels[2];
-
- /*
- * Now, do second row.
- */
-
- L = tables->L_tab [(int) *lum2++];
-
- ((int *)pixels)[0] = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
- *row2++ = pixels[0]; *row2++ = pixels[1]; *row2++ = pixels[2];
-
- L = tables->L_tab [(int) *lum2++];
-
- ((int *)pixels)[0] = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
- *row2++ = pixels[0]; *row2++ = pixels[1]; *row2++ = pixels[2];
- }
- lum = lum2;
- row1 = row2;
- lum2 += cols;
- row2 += cols_3;
+ int x,y;
+ int src_rowstride;
+ int dest_rowstride;
+
+ src_rowstride = ROUND_UP_4 (space->width);
+ dest_rowstride = ROUND_UP_4 (width * 3);
+ for(y=0;y<height;y++){
+ for(x=0;x<width;x++){
+ dest[x*3 + 0] = CLAMP (Y[x] + V_r_tab[V[x/2]], 0, 255);
+ dest[x*3 + 1] = CLAMP (Y[x] + U_g_tab[U[x/2]] + V_g_tab[V[x/2]], 0, 255);
+ dest[x*3 + 2] = CLAMP (Y[x] + U_b_tab[U[x/2]], 0, 255);
}
+ Y += src_rowstride;
+ dest += dest_rowstride;
+ if (y&1) {
+ U += src_rowstride/2;
+ V += src_rowstride/2;
+ }
+ }
}
-/*
- *--------------------------------------------------------------
- *
- * Color32DitherImage --
- *
- * Converts image into 32 bit color (or 24-bit non-packed).
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
-/*
- * This is a copysoft version of the function above with ints instead
- * of shorts to cause a 4-byte pixel size
- */
-
static void
-gst_colorspace_yuv_to_rgb32(tables, lum, cb, cr, out, rows, cols)
- GstColorSpaceYUVTables *tables;
- unsigned char *lum;
- unsigned char *cr;
- unsigned char *cb;
- unsigned char *out;
- int cols, rows;
-
+gst_colorspace_yuv_to_rgb16(GstColorspace *space,
+ unsigned char *dest,
+ unsigned char *Y,
+ unsigned char *U,
+ unsigned char *V,
+ int width, int height)
{
- int L, CR, CB;
- unsigned int *row1, *row2;
- unsigned char *lum2;
- int x, y;
- int cr_r;
- int crb_g;
- int cb_b;
- int cols_2 = cols>>1;
-
- row1 = (guint32 *)out;
- row2 = row1 + cols;
- lum2 = lum + cols;
- for (y=rows>>1; y; y--) {
- for (x=cols_2; x; x--) {
-
- CR = *cr++;
- CB = *cb++;
- cr_r = tables->Cr_r_tab[CR];
- crb_g = tables->Cr_g_tab[CR] + tables->Cb_g_tab[CB];
- cb_b = tables->Cb_b_tab[CB];
-
- L = tables->L_tab[(int) *lum++];
-
- *row1++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
-
- L = tables->L_tab[(int) *lum++];
-
- *row1++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
-
- /*
- * Now, do second row.
- */
-
- L = tables->L_tab [(int) *lum2++];
-
- *row2++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
-
- L = tables->L_tab [(int) *lum2++];
-
- *row2++ = (tables->r_2_pix[L+cr_r] | tables->g_2_pix[L+crb_g] | tables->b_2_pix[L+cb_b]);
- }
- lum = lum2;
- row1 = row2;
- lum2 += cols;
- row2 += cols;
+ int x,y;
+ int src_rowstride;
+ int dest_rowstride;
+ int r, g, b;
+
+ src_rowstride = ROUND_UP_4 (space->width);
+ dest_rowstride = ROUND_UP_4 (width * 2);
+ for(y=0;y<height;y++){
+ for(x=0;x<width;x++){
+ r = CLAMP (Y[x] + V_r_tab[V[x/2]], 0, 255);
+ g = CLAMP (Y[x] + U_g_tab[U[x/2]] + V_g_tab[V[x/2]], 0, 255);
+ b = CLAMP (Y[x] + U_b_tab[U[x/2]], 0, 255);
+ *(unsigned short *)(dest + x*2) = ((r&0xf8)<<8) | ((g&0xfc)<<3) | (b>>3);
}
+ Y += src_rowstride;
+ dest += dest_rowstride;
+ if (y&1) {
+ U += src_rowstride/2;
+ V += src_rowstride/2;
+ }
+ }
}
#ifdef HAVE_LIBMMX
@@ -789,7 +584,7 @@ static mmx_t MMX32_Vgrncoeff = (mmx_t)(long long)0xffd2ffd2ffd2ffd2LL;
static void
gst_colorspace_yuv_to_bgr32_mmx(tables, lum, cr, cb, out, rows, cols)
- GstColorSpaceYUVTables *tables;
+ GstColorspaceYUVTables *tables;
unsigned char *lum;
unsigned char *cr;
unsigned char *cb;
diff --git a/ext/hermes/yuv2rgb.h b/gst/colorspace/yuv2rgb.h
index 7edfa377..be173bca 100644
--- a/ext/hermes/yuv2rgb.h
+++ b/gst/colorspace/yuv2rgb.h
@@ -23,10 +23,14 @@
#define __YUV2RGB_H__
#include <gst/gst.h>
+#include <gstcolorspace.h>
-typedef struct _GstColorSpaceYUVTables GstColorSpaceYUVTables;
+G_BEGIN_DECLS
-struct _GstColorSpaceYUVTables {
+#if 0
+typedef struct _GstColorspaceYUVTables GstColorspaceYUVTables;
+
+struct _GstColorspaceYUVTables {
int gammaCorrectFlag;
double gammaCorrect;
int chromaCorrectFlag;
@@ -45,24 +49,49 @@ struct _GstColorSpaceYUVTables {
};
-typedef struct _GstColorSpaceConverter GstColorSpaceConverter;
-typedef void (*GstColorSpaceConvertFunction) (GstColorSpaceConverter *space, guchar *src, guchar *dest);
+typedef struct _GstColorspaceConverter GstColorspaceConverter;
+typedef void (*GstColorspaceConvertFunction) (GstColorspaceConverter *space, guchar *src, guchar *dest);
-struct _GstColorSpaceConverter {
+struct _GstColorspaceConverter {
guint width;
guint height;
guint insize;
guint outsize;
/* private */
- GstColorSpaceYUVTables *color_tables;
- GstColorSpaceConvertFunction convert;
+ GstColorspaceYUVTables *color_tables;
+ GstColorspaceConvertFunction convert;
};
+#endif
+
+void gst_colorspace_table_init (GstColorspace *space);
+
+void gst_colorspace_I420_to_rgb32(GstColorspace *space,
+ unsigned char *src, unsigned char *dest);
+void gst_colorspace_I420_to_rgb24(GstColorspace *space,
+ unsigned char *src, unsigned char *dest);
+void gst_colorspace_I420_to_rgb16(GstColorspace *space,
+ unsigned char *src, unsigned char *dest);
+void gst_colorspace_YV12_to_rgb32(GstColorspace *space,
+ unsigned char *src, unsigned char *dest);
+void gst_colorspace_YV12_to_rgb24(GstColorspace *space,
+ unsigned char *src, unsigned char *dest);
+void gst_colorspace_YV12_to_rgb16(GstColorspace *space,
+ unsigned char *src, unsigned char *dest);
+
+#if 0
+GstColorspaceYUVTables * gst_colorspace_init_yuv(long depth,
+ long red_mask, long green_mask, long blue_mask);
+#endif
-GstColorSpaceConverter* gst_colorspace_yuv2rgb_get_converter (const GstCaps *from, const GstCaps *to);
+#if 0
+GstColorspaceConverter* gst_colorspace_yuv2rgb_get_converter (const GstCaps *from, const GstCaps *to);
#define gst_colorspace_convert(converter, src, dest) \
(converter)->convert((converter), (src), (dest))
-void gst_colorspace_converter_destroy (GstColorSpaceConverter *space);
+void gst_colorspace_converter_destroy (GstColorspaceConverter *space);
+#endif
+
+G_END_DECLS
#endif