diff options
author | Wim Taymans <wim.taymans@gmail.com> | 2002-01-13 22:27:25 +0000 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2002-01-13 22:27:25 +0000 |
commit | 93e9ac34a1058caab1ef680071874d620a10d132 (patch) | |
tree | 4c730c821178cc2ea708454dc276a1d36b5bfe1b /ext/hermes | |
parent | e92b7beff5470ec3f1662e2413622295b37f8710 (diff) | |
download | gst-plugins-bad-93e9ac34a1058caab1ef680071874d620a10d132.tar.gz gst-plugins-bad-93e9ac34a1058caab1ef680071874d620a10d132.tar.bz2 gst-plugins-bad-93e9ac34a1058caab1ef680071874d620a10d132.zip |
Bring the plugins in sync with the new core capsnego system.
Original commit message from CVS:
Bring the plugins in sync with the new core capsnego system.
Added some features, enhancements...
Diffstat (limited to 'ext/hermes')
-rw-r--r-- | ext/hermes/Makefile.am | 2 | ||||
-rw-r--r-- | ext/hermes/gstcolorspace.c | 382 | ||||
-rw-r--r-- | ext/hermes/gstcolorspace.h | 8 | ||||
-rw-r--r-- | ext/hermes/rgb2yuv.c | 150 |
4 files changed, 387 insertions, 155 deletions
diff --git a/ext/hermes/Makefile.am b/ext/hermes/Makefile.am index 15e7c1e8..b221c5cb 100644 --- a/ext/hermes/Makefile.am +++ b/ext/hermes/Makefile.am @@ -14,7 +14,7 @@ else PLUGIN_EXTRA_LIBS = endif -libgstcolorspace_la_SOURCES = gstcolorspace.c yuv2yuv.c yuv2rgb.c $(ARCHSRCS) +libgstcolorspace_la_SOURCES = gstcolorspace.c yuv2yuv.c yuv2rgb.c rgb2yuv.c $(ARCHSRCS) libgstcolorspace_la_CFLAGS = $(GST_CFLAGS) libgstcolorspace_la_LIBADD = $(GST_LIBS) $(PLUGIN_EXTRA_LIBS) diff --git a/ext/hermes/gstcolorspace.c b/ext/hermes/gstcolorspace.c index eebe19b6..40ada827 100644 --- a/ext/hermes/gstcolorspace.c +++ b/ext/hermes/gstcolorspace.c @@ -52,7 +52,13 @@ GST_PADTEMPLATE_FACTORY (colorspace_src_template_factory, GST_CAPS_NEW ( "colorspace_src", "video/raw", - NULL + "format", GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")) + ), + "width", GST_PROPS_INT_RANGE (0, G_MAXINT), + "height", GST_PROPS_INT_RANGE (0, G_MAXINT) ) ) @@ -63,20 +69,41 @@ GST_PADTEMPLATE_FACTORY (colorspace_sink_template_factory, GST_CAPS_NEW ( "colorspace_sink", "video/raw", - NULL + "format", GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")), + GST_PROPS_FOURCC (GST_STR_FOURCC ("RGB ")) + ), + "width", GST_PROPS_INT_RANGE (0, G_MAXINT), + "height", GST_PROPS_INT_RANGE (0, G_MAXINT) ) ) static void gst_colorspace_class_init (GstColorspaceClass *klass); static void gst_colorspace_init (GstColorspace *space); -static void gst_colorspace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_colorspace_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); - +static void gst_colorspace_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_colorspace_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); + +static GstPadConnectReturn + gst_colorspace_sinkconnect (GstPad *pad, GstCaps *caps); +static GstPadConnectReturn + gst_colorspace_srcconnect (GstPad *pad, GstCaps *caps); +static GstPadConnectReturn + gst_colorspace_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps); static void gst_colorspace_chain (GstPad *pad, GstBuffer *buf); +static GstElementStateReturn + gst_colorspace_change_state (GstElement *element); // FIXME -extern void gst_colorspace_yuy2_to_i420(unsigned char *src, unsigned char *dest, guint width, guint height); +extern void gst_colorspace_yuy2_to_i420 (unsigned char *src, unsigned char *dest, + guint width, guint height); +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 GstElementClass *parent_class = NULL; //static guint gst_colorspace_signals[LAST_SIGNAL] = { 0 }; @@ -88,20 +115,16 @@ colorspace_get_bufferpool (GstPad *pad) space = GST_COLORSPACE (gst_pad_get_parent (pad)); - if (space->type == GST_COLORSPACE_NONE) + if (space->type == GST_COLORSPACE_NONE && !space->disabled) return gst_pad_get_bufferpool (space->srcpad); else return NULL; } static gboolean -colorspace_setup_converter (GstColorspace *space) +colorspace_setup_converter (GstColorspace *space, GstCaps *from_caps, GstCaps *to_caps) { gulong from_space, to_space; - GstCaps *from_caps, *to_caps; - - from_caps = space->sinkcaps; - to_caps = space->srccaps; g_return_val_if_fail (to_caps != NULL, FALSE); g_return_val_if_fail (from_caps != NULL, FALSE); @@ -109,26 +132,29 @@ colorspace_setup_converter (GstColorspace *space) from_space = gst_caps_get_fourcc_int (from_caps, "format"); to_space = gst_caps_get_fourcc_int (to_caps, "format"); - g_warning ("set up converter for %08lx to %08lx\n", from_space, to_space); + GST_INFO (GST_CAT_NEGOTIATION, "set up converter for %08lx to %08lx", from_space, to_space); switch (from_space) { case GST_MAKE_FOURCC ('R','G','B',' '): + { + gint from_bpp = gst_caps_get_int (from_caps, "bpp"); + switch (to_space) { -#ifdef HAVE_LIBHERMES case GST_MAKE_FOURCC ('R','G','B',' '): +#ifdef HAVE_HERMES { space->source.r = gst_caps_get_int (from_caps, "red_mask"); space->source.g = gst_caps_get_int (from_caps, "green_mask"); space->source.b = gst_caps_get_int (from_caps, "blue_mask"); space->source.a = 0; - space->srcbpp = space->source.bits = gst_caps_get_int (from_caps, "bpp"); + space->srcbpp = space->source.bits = from_bpp; space->source.indexed = 0; space->source.has_colorkey = 0; - GST_INFO (0,"source red mask %08x\n", space->source.r); - GST_INFO (0, "source green mask %08x\n", space->source.g); - GST_INFO (0, "source blue mask %08x\n", space->source.b); - GST_INFO (0, "source bpp %08x\n", space->srcbpp); + GST_INFO (GST_CAT_PLUGIN_INFO, "source red mask %08x", space->source.r); + GST_INFO (GST_CAT_PLUGIN_INFO, "source green mask %08x", space->source.g); + GST_INFO (GST_CAT_PLUGIN_INFO, "source blue mask %08x", space->source.b); + GST_INFO (GST_CAT_PLUGIN_INFO, "source bpp %08x", space->srcbpp); space->dest.r = gst_caps_get_int (to_caps, "red_mask"); space->dest.g = gst_caps_get_int (to_caps, "green_mask"); @@ -138,173 +164,189 @@ colorspace_setup_converter (GstColorspace *space) space->dest.indexed = 0; space->dest.has_colorkey = 0; - GST_INFO (0, "dest red mask %08x\n", space->dest.r); - GST_INFO (0, "dest green mask %08x\n", space->dest.g); - GST_INFO (0, "dest blue mask %08x\n", space->dest.b); - GST_INFO (0, "dest bpp %08x\n", space->destbpp); + GST_INFO (GST_CAT_PLUGIN_INFO, "dest red mask %08x", space->dest.r); + GST_INFO (GST_CAT_PLUGIN_INFO, "dest green mask %08x", space->dest.g); + GST_INFO (GST_CAT_PLUGIN_INFO, "dest blue mask %08x", space->dest.b); + GST_INFO (GST_CAT_PLUGIN_INFO, "dest bpp %08x", space->destbpp); if (!Hermes_ConverterRequest (space->h_handle, &space->source, &space->dest)) { - g_warning ("could not get converter\n"); + g_warning ("Hermes: could not get converter\n"); return FALSE; } - GST_INFO (0, "converter set up\n"); + GST_INFO (GST_CAT_PLUGIN_INFO, "converter set up"); space->type = GST_COLORSPACE_HERMES; - break; + return TRUE; } +#else + g_warning ("colorspace: compiled without hermes!"); + return FALSE; #endif - case GST_MAKE_FOURCC ('Y','U','Y','2'): + case GST_MAKE_FOURCC ('Y','V','1','2'): + if (from_bpp == 32) { + space->type = GST_COLORSPACE_RGB32_YV12; + space->destbpp = 12; + return TRUE; + } case GST_MAKE_FOURCC ('I','4','2','0'): - g_error ("colorspace: RGB to YUV implement me"); - break; + if (from_bpp == 32) { + space->type = GST_COLORSPACE_RGB32_I420; + space->destbpp = 12; + return TRUE; + } + case GST_MAKE_FOURCC ('Y','U','Y','2'): + GST_INFO (GST_CAT_NEGOTIATION, "colorspace: RGB to YUV with bpp %d not implemented!!", from_bpp); + return FALSE; } break; - case GST_MAKE_FOURCC ('Y','U','Y','2'): + } case GST_MAKE_FOURCC ('I','4','2','0'): switch (to_space) { case GST_MAKE_FOURCC ('R','G','B',' '): - g_warning ("colorspace: YUV to RGB"); + GST_INFO (GST_CAT_NEGOTIATION, "colorspace: YUV to RGB"); space->destbpp = gst_caps_get_int (to_caps, "bpp"); space->converter = gst_colorspace_yuv2rgb_get_converter (from_caps, to_caps); space->type = GST_COLORSPACE_YUV_RGB; - break; + return TRUE; + case GST_MAKE_FOURCC ('I','4','2','0'): + space->type = GST_COLORSPACE_NONE; + 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_COLORSPACE_YUY2_I420; space->destbpp = 12; - break; + return TRUE; + case GST_MAKE_FOURCC ('Y','U','Y','2'): + space->type = GST_COLORSPACE_NONE; + space->destbpp = 16; + return TRUE; } break; } - return TRUE; + return FALSE; } -static GstPadNegotiateReturn -colorspace_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) +static GstCaps* +gst_colorspace_getcaps (GstPad *pad, GstCaps *caps) { - GstColorspace* space = GST_COLORSPACE (gst_object_get_parent (GST_OBJECT (pad))); - GstCaps *original; - gint src_width, src_height; - - GST_DEBUG (GST_CAT_NEGOTIATION, "colorspace: src negotiate\n"); - - g_return_val_if_fail (space->sinkcaps != NULL, GST_PAD_NEGOTIATE_FAIL); - - src_width = gst_caps_get_int (space->sinkcaps, "width"); - src_height = gst_caps_get_int (space->sinkcaps, "height"); - - space->width = src_width; - space->height = src_height; - - if (*caps==NULL) { - *caps = gst_caps_new ("colorspace_caps", - "video/raw", - gst_props_new ( - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - "width", GST_PROPS_INT (src_width), - "height", GST_PROPS_INT (src_height), - NULL)); - space->srccaps = gst_caps_ref (*caps); - return GST_PAD_NEGOTIATE_TRY; - //return gst_pad_negotiate_proxy (pad, space->sinkpad, caps); - } + GstColorspace *space; + GstCaps *result; + GstCaps *peercaps; + GstCaps *ourcaps; + + space = GST_COLORSPACE (gst_pad_get_parent (pad)); + /* we can do everything our peer can... */ + peercaps = gst_caps_copy (gst_pad_get_allowed_caps (space->srcpad)); + /* and our own template of course */ + ourcaps = gst_caps_copy (gst_pad_get_padtemplate_caps (pad)); - original = gst_caps_copy (*caps); - //g_print ("%d %d\n", src_width, src_height); + /* merge them together, we prefer the peercaps first */ + result = gst_caps_prepend (ourcaps, peercaps); - // peers couldn't agree, we need to help - switch (gst_caps_get_fourcc_int (original, "format")) { - case GST_MAKE_FOURCC ('R','G','B',' '): - gst_caps_ref (*caps); - if (gst_caps_get_int (*caps, "width") == src_width && - gst_caps_get_int (*caps, "height") == src_height) - { - space->srccaps = *caps; - if (colorspace_setup_converter (space)) { - return GST_PAD_NEGOTIATE_AGREE; - } - } - else { - gst_caps_set (*caps, "width", GST_PROPS_INT (src_width)); - gst_caps_set (*caps, "height", GST_PROPS_INT (src_height)); + return result; +} - space->srccaps = *caps; - // FIXME - GST_PAD_CAPS (space->srcpad) = gst_caps_ref (*caps); +static GstPadConnectReturn +gst_colorspace_sinkconnect (GstPad *pad, GstCaps *caps) +{ + GstColorspace *space; + GstPad *peer; - return GST_PAD_NEGOTIATE_TRY; - } - break; - case GST_MAKE_FOURCC ('Y','U','Y','2'): - case GST_MAKE_FOURCC ('I','4','2','0'): - //space->srccaps = original; - //fprintf (stderr, "found something suitable\n"); - return GST_PAD_NEGOTIATE_AGREE; - default: - *caps = NULL; - return GST_PAD_NEGOTIATE_TRY; - break; + space = GST_COLORSPACE (gst_pad_get_parent (pad)); + + if (!GST_CAPS_IS_FIXED (caps)) { + return GST_PAD_CONNECT_DELAYED; + } + + space->width = gst_caps_get_int (caps, "width"); + space->height = gst_caps_get_int (caps, "height"); + + GST_INFO (GST_CAT_PROPERTIES, "size: %dx%d", space->width, space->height); + + space->sinkcaps = caps; + + peer = gst_pad_get_peer (pad); + if (peer) { + if (!gst_colorspace_srcconnect_func (pad, gst_pad_get_allowed_caps (space->srcpad), FALSE)) { + space->sinkcaps = NULL; + return GST_PAD_CONNECT_REFUSED; + } } - return GST_PAD_NEGOTIATE_FAIL; + + return GST_PAD_CONNECT_OK; } -static GstPadNegotiateReturn -colorspace_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) +static GstPadConnectReturn +gst_colorspace_srcconnect (GstPad *pad, GstCaps *caps) { - GstColorspace* space = GST_COLORSPACE (gst_object_get_parent (GST_OBJECT (pad))); - GstCaps *original; + return gst_colorspace_srcconnect_func (pad, caps, TRUE); +} - GST_DEBUG (GST_CAT_NEGOTIATION, "colorspace: sink negotiate\n"); +static GstPadConnectReturn +gst_colorspace_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps) +{ + GstColorspace *space; + GstCaps *peercaps; + GstCaps *ourcaps; - if (*caps==NULL) - return gst_pad_negotiate_proxy (pad, space->srcpad, caps); - //return GST_PAD_NEGOTIATE_FAIL; - + space = GST_COLORSPACE (gst_pad_get_parent (pad)); - space->type = GST_COLORSPACE_NONE; + /* we cannot operate if we didn't get src caps */ + ourcaps = space->sinkcaps; + if (!ourcaps) { + if (newcaps) + gst_pad_recalc_allowed_caps (space->sinkpad); - original = gst_caps_copy (*caps); + return GST_PAD_CONNECT_DELAYED; + } - // see if a common format exists between both peers... - switch (gst_pad_negotiate_proxy (pad, space->srcpad, caps)) { - case GST_PAD_NEGOTIATE_AGREE: - //g_print ("colorspace: common format found\n"); - return GST_PAD_NEGOTIATE_AGREE; - default: - break; + /* first see if we can do the format natively by filtering the peer caps + * with our incomming caps */ + peercaps = gst_caps_intersect (caps, ourcaps); + if (peercaps) { + /* see if the peer likes it too, it should as the caps say so.. */ + if (gst_pad_try_set_caps (space->srcpad, peercaps)) { + space->type = GST_COLORSPACE_NONE; + space->disabled = FALSE; + return GST_PAD_CONNECT_OK; + } } - g_warning ("colorspace: no common format found\n"); - g_warning ("colorspace: src: %08lx\n", gst_caps_get_fourcc_int (original, "format")); - - // peers couldn't agree, we need to help - space->sinkcaps = original; - - /* - space->width = gst_caps_get_int (original, "width"); - space->height = gst_caps_get_int (original, "height"); - - space->srccaps = gst_caps_new ( - "testcaps", - "video/raw", - gst_props_new ( - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), - "width", GST_PROPS_INT (gst_caps_get_int (original, "width")), - "height", GST_PROPS_INT (gst_caps_get_int (original, "height")), - NULL - )); - - GST_PAD_CAPS (space->srcpad) = space->srccaps; - */ - - if (gst_pad_renegotiate (space->srcpad)) { - g_warning ("found something suitable\n"); - if (colorspace_setup_converter (space)) { - return GST_PAD_NEGOTIATE_AGREE; + /* then see what the peer has that matches the size */ + peercaps = gst_caps_intersect (caps, + GST_CAPS_NEW ( + "colorspace_filter", + "video/raw", + "width", GST_PROPS_INT (space->width), + "height", GST_PROPS_INT (space->height) + )); + + /* we are looping over the caps, so we have to get rid of the lists */ + peercaps = gst_caps_normalize (peercaps); + + /* loop over all possibilities and select the first one we can convert and + * is accepted by the peer */ + while (peercaps) { + if (colorspace_setup_converter (space, ourcaps, peercaps)) { + if (gst_pad_try_set_caps (space->srcpad, peercaps)) { + space->disabled = FALSE; + return GST_PAD_CONNECT_OK; + } } + peercaps = peercaps->next; } + + gst_element_error (GST_ELEMENT (space), "could not agree on caps with peer pads"); + /* we disable ourself here */ + space->disabled = TRUE; - return GST_PAD_NEGOTIATE_FAIL; -} + return GST_PAD_CONNECT_REFUSED; +} GType gst_colorspace_get_type (void) @@ -340,6 +382,8 @@ gst_colorspace_class_init (GstColorspaceClass *klass) gobject_class->set_property = gst_colorspace_set_property; gobject_class->get_property = gst_colorspace_get_property; + + gstelement_class->change_state = gst_colorspace_change_state; } static void @@ -347,21 +391,23 @@ gst_colorspace_init (GstColorspace *space) { space->sinkpad = gst_pad_new_from_template ( GST_PADTEMPLATE_GET (colorspace_sink_template_factory), "sink"); - gst_pad_set_negotiate_function (space->sinkpad, colorspace_negotiate_sink); + gst_pad_set_connect_function (space->sinkpad, gst_colorspace_sinkconnect); + gst_pad_set_getcaps_function (space->sinkpad, gst_colorspace_getcaps); gst_pad_set_bufferpool_function (space->sinkpad, colorspace_get_bufferpool); 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 ( GST_PADTEMPLATE_GET (colorspace_src_template_factory), "src"); - gst_pad_set_negotiate_function (space->srcpad, colorspace_negotiate_src); gst_element_add_pad(GST_ELEMENT(space),space->srcpad); + gst_pad_set_connect_function (space->srcpad, gst_colorspace_srcconnect); -#ifdef HAVE_LIBHERMES +#ifdef HAVE_HERMES space->h_handle = Hermes_ConverterInstance (0); #endif space->pool = NULL; space->converter = NULL; + space->disabled = TRUE; } static void @@ -380,16 +426,17 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf) g_return_if_fail (space != NULL); g_return_if_fail (GST_IS_COLORSPACE (space)); + if (space->disabled) { + gst_buffer_unref (buf); + return; + } + if (space->type == GST_COLORSPACE_NONE) { outbuf = buf; } else { gint dest_bytes, src_bytes; - if (!space->pool) { - space->pool = gst_pad_get_bufferpool (space->srcpad); - } - size = space->width * space->height; dest_bytes = ((space->destbpp+7)/8); src_bytes = ((space->srcbpp+7)/8); @@ -408,7 +455,7 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf) if (space->type == GST_COLORSPACE_YUV_RGB) { gst_colorspace_convert (space->converter, GST_BUFFER_DATA (buf), GST_BUFFER_DATA (outbuf)); } -#ifdef HAVE_LIBHERMES +#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, @@ -421,6 +468,18 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf) 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); + } GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); @@ -429,6 +488,27 @@ gst_colorspace_chain (GstPad *pad,GstBuffer *buf) gst_pad_push (space->srcpad, outbuf); } +static GstElementStateReturn +gst_colorspace_change_state (GstElement *element) +{ + GstColorspace *space; + + space = GST_COLORSPACE (element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_PAUSED_TO_PLAYING: + space->pool = gst_pad_get_bufferpool (space->srcpad); + break; + case GST_STATE_PLAYING_TO_PAUSED: + space->pool = NULL; + break; + } + + parent_class->change_state (element); + + return GST_STATE_SUCCESS; +} + static void gst_colorspace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { @@ -464,7 +544,7 @@ static gboolean plugin_init (GModule *module, GstPlugin *plugin) { GstElementFactory *factory; -#ifdef HAVE_LIBHERMES +#ifdef HAVE_HERMES gint hermes_res; hermes_res = Hermes_Init(); diff --git a/ext/hermes/gstcolorspace.h b/ext/hermes/gstcolorspace.h index 8d780b41..ca345fde 100644 --- a/ext/hermes/gstcolorspace.h +++ b/ext/hermes/gstcolorspace.h @@ -26,7 +26,7 @@ #include <gst/gst.h> #include "yuv2rgb.h" -#ifdef HAVE_LIBHERMES +#ifdef HAVE_HERMES # include <Hermes/Hermes.h> #endif @@ -57,6 +57,8 @@ typedef enum { GST_COLORSPACE_HERMES, GST_COLORSPACE_YUV_RGB, GST_COLORSPACE_YUY2_I420, + GST_COLORSPACE_RGB32_I420, + GST_COLORSPACE_RGB32_YV12, } GstColorSpaceConverterType; struct _GstColorspace { @@ -64,7 +66,7 @@ struct _GstColorspace { GstPad *sinkpad,*srcpad; -#ifdef HAVE_LIBHERMES +#ifdef HAVE_HERMES HermesHandle h_handle; HermesFormat source, dest; #endif @@ -74,8 +76,8 @@ struct _GstColorspace { GstColorSpaceConverterType type; gint width, height; gint srcbpp, destbpp; + gboolean disabled; - GstCaps *srccaps; GstCaps *sinkcaps; GstBufferPool *pool; diff --git a/ext/hermes/rgb2yuv.c b/ext/hermes/rgb2yuv.c new file mode 100644 index 00000000..7495c71b --- /dev/null +++ b/ext/hermes/rgb2yuv.c @@ -0,0 +1,150 @@ +/* + * + * 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 RGB2YUV_SHIFT 8 +#define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5)) +#define BV ((int)(-0.071*(1<<RGB2YUV_SHIFT)+0.5)) +#define BU ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) +#define GY ((int)( 0.504*(1<<RGB2YUV_SHIFT)+0.5)) +#define GV ((int)(-0.368*(1<<RGB2YUV_SHIFT)+0.5)) +#define GU ((int)(-0.291*(1<<RGB2YUV_SHIFT)+0.5)) +#define RY ((int)( 0.257*(1<<RGB2YUV_SHIFT)+0.5)) +#define RV ((int)( 0.439*(1<<RGB2YUV_SHIFT)+0.5)) +#define RU ((int)(-0.148*(1<<RGB2YUV_SHIFT)+0.5)) + +/** + * + * height should be a multiple of 2 and width should be a multiple of 2 (if this is a + * problem for anyone then tell me, and ill fix it) + * chrominance data is only taken from every secound line others are ignored FIXME write HQ version + */ +void +gst_colorspace_rgb32_to_i420 (unsigned char *src, unsigned char *dest, guint width, guint height) +{ + int y; + const int chrom_width = width >> 1; + const int chrom_size = (width * height) >> 2; + + unsigned char *ydst = dest; + unsigned char *udst = ydst + (width * height); + unsigned char *vdst = udst + chrom_size; + + for (y = 0; y < height; y += 2) { + int i; + + for (i = 0; i < chrom_width; i++) { + unsigned int b = src[8 * i + 0]; + unsigned int g = src[8 * i + 1]; + unsigned int r = src[8 * i + 2]; + + unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128; + unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128; + + udst[i] = U; + vdst[i] = V; + ydst[2 * i] = Y; + + b = src[8 * i + 4]; + g = src[8 * i + 5]; + r = src[8 * i + 6]; + + Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + ydst[2 * i + 1] = Y; + } + ydst += width; + src += (width * 4); + + for (i = 0; i < chrom_width; i++) { + unsigned int b = src[8 * i + 0]; + unsigned int g = src[8 * i + 1]; + unsigned int r = src[8 * i + 2]; + + unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + + ydst[2 * i] = Y; + + b = src[8 * i + 4]; + g = src[8 * i + 5]; + r = src[8 * i + 6]; + + Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + ydst[2 * i + 1] = Y; + } + udst += chrom_width; + vdst += chrom_width; + ydst += width; + src += (width * 4); + } +} + +void +gst_colorspace_rgb32_to_yv12 (unsigned char *src, unsigned char *dest, guint width, guint height) +{ + int y; + const int chrom_width = width >> 1; + const int chrom_size = (width * height) >> 2; + + unsigned char *ydst = dest; + unsigned char *vdst = ydst + (width * height); + unsigned char *udst = vdst + chrom_size; + + for (y = 0; y < height; y += 2) { + int i; + + for (i = 0; i < chrom_width; i++) { + unsigned int b = src[8 * i + 0]; + unsigned int g = src[8 * i + 1]; + unsigned int r = src[8 * i + 2]; + + unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + unsigned int V = ((RV * r + GV * g + BV * b) >> RGB2YUV_SHIFT) + 128; + unsigned int U = ((RU * r + GU * g + BU * b) >> RGB2YUV_SHIFT) + 128; + + udst[i] = U; + vdst[i] = V; + ydst[2 * i] = Y; + + b = src[8 * i + 4]; + g = src[8 * i + 5]; + r = src[8 * i + 6]; + + Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + ydst[2 * i + 1] = Y; + } + ydst += width; + src += (width * 4); + + for (i = 0; i < chrom_width; i++) { + unsigned int b = src[8 * i + 0]; + unsigned int g = src[8 * i + 1]; + unsigned int r = src[8 * i + 2]; + + unsigned int Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + + ydst[2 * i] = Y; + + b = src[8 * i + 4]; + g = src[8 * i + 5]; + r = src[8 * i + 6]; + + Y = ((RY * r + GY * g + BY * b) >> RGB2YUV_SHIFT) + 16; + ydst[2 * i + 1] = Y; + } + udst += chrom_width; + vdst += chrom_width; + ydst += width; + src += (width * 4); + } +} |