diff --git a/ext/Makefile.am b/ext/Makefile.am index bd24b63787..4676b25ba0 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -151,7 +151,8 @@ RTP_DIR= endif if USE_SDL -SDL_DIR=sdl +#SDL_DIR=sdl +SDL_DIR= else SDL_DIR= endif diff --git a/ext/audiofile/gstafsrc.c b/ext/audiofile/gstafsrc.c index 630e79d9f9..ae4e54a280 100644 --- a/ext/audiofile/gstafsrc.c +++ b/ext/audiofile/gstafsrc.c @@ -350,21 +350,20 @@ gst_afsrc_open_file (GstAFSrc *src) /* set caps on src */ //FIXME: add all the possible formats, especially float ! */ - gst_pad_set_caps (src->srcpad, gst_caps_new ( - "af_src", - "audio/raw", - gst_props_new ( - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), //FIXME - "endianness", GST_PROPS_INT (G_BYTE_ORDER), //FIXME - "signed", GST_PROPS_BOOLEAN (src->is_signed), - "width", GST_PROPS_INT (src->width), - "depth", GST_PROPS_INT (src->width), - "rate", GST_PROPS_INT (src->rate), - "channels", GST_PROPS_INT (src->channels), - NULL - ) - )); + gst_pad_try_set_caps (src->srcpad, + GST_CAPS_NEW ( + "af_src", + "audio/raw", + "format", GST_PROPS_STRING ("int"), + "law", GST_PROPS_INT (0), //FIXME + "endianness", GST_PROPS_INT (G_BYTE_ORDER), //FIXME + "signed", GST_PROPS_BOOLEAN (src->is_signed), + "width", GST_PROPS_INT (src->width), + "depth", GST_PROPS_INT (src->width), + "rate", GST_PROPS_INT (src->rate), + "channels", GST_PROPS_INT (src->channels) + ) + ); GST_FLAG_SET (src, GST_AFSRC_OPEN); diff --git a/ext/gsm/gstgsmdec.c b/ext/gsm/gstgsmdec.c index 5ead519c1a..8a61453a90 100644 --- a/ext/gsm/gstgsmdec.c +++ b/ext/gsm/gstgsmdec.c @@ -45,11 +45,11 @@ enum { /* FILL ME */ }; -static void gst_gsmdec_class_init (GstGSMDec *klass); -static void gst_gsmdec_init (GstGSMDec *gsmdec); +static void gst_gsmdec_class_init (GstGSMDec *klass); +static void gst_gsmdec_init (GstGSMDec *gsmdec); -static void gst_gsmdec_chain (GstPad *pad, GstBuffer *buf); -static void gst_gsmdec_newcaps (GstPad *pad, GstCaps *caps); +static void gst_gsmdec_chain (GstPad *pad, GstBuffer *buf); +static GstPadConnectReturn gst_gsmdec_sinkconnect (GstPad *pad, GstCaps *caps); static GstElementClass *parent_class = NULL; //static guint gst_gsmdec_signals[LAST_SIGNAL] = { 0 }; @@ -93,7 +93,7 @@ gst_gsmdec_init (GstGSMDec *gsmdec) gsmdec->sinkpad = gst_pad_new_from_template (gsmdec_sink_template, "sink"); gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->sinkpad); gst_pad_set_chain_function (gsmdec->sinkpad, gst_gsmdec_chain); - gst_pad_set_newcaps_function (gsmdec->sinkpad, gst_gsmdec_newcaps); + gst_pad_set_connect_function (gsmdec->sinkpad, gst_gsmdec_sinkconnect); gsmdec->srcpad = gst_pad_new_from_template (gsmdec_src_template, "src"); gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad); @@ -102,13 +102,18 @@ gst_gsmdec_init (GstGSMDec *gsmdec) gsmdec->bufsize = 0; } -static void -gst_gsmdec_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_gsmdec_sinkconnect (GstPad *pad, GstCaps *caps) { GstGSMDec *gsmdec; gsmdec = GST_GSMDEC (gst_pad_get_parent (pad)); - gst_pad_set_caps (gsmdec->srcpad, GST_CAPS_NEW ( + + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; + + if (gst_pad_try_set_caps (gsmdec->srcpad, + GST_CAPS_NEW ( "gsm_raw", "audio/raw", "format", GST_PROPS_STRING ("int"), @@ -119,7 +124,11 @@ gst_gsmdec_newcaps (GstPad *pad, GstCaps *caps) "depth", GST_PROPS_INT (16), "rate", GST_PROPS_INT (gst_caps_get_int (caps, "rate")), "channels", GST_PROPS_INT (1) - )); + ))) + { + return GST_PAD_CONNECT_OK; + } + return GST_PAD_CONNECT_REFUSED; } static void diff --git a/ext/gsm/gstgsmenc.c b/ext/gsm/gstgsmenc.c index b5ad0bcec6..abe4279d01 100644 --- a/ext/gsm/gstgsmenc.c +++ b/ext/gsm/gstgsmenc.c @@ -46,22 +46,11 @@ enum { /* FILL ME */ }; -GST_PADTEMPLATE_FACTORY (src_factory, - "src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_CAPS_NEW ( - "gsm_enc", - "audio/x-gsm", - "rate", GST_PROPS_INT_RANGE (1000, 48000) - ) -); +static void gst_gsmenc_class_init (GstGSMEnc *klass); +static void gst_gsmenc_init (GstGSMEnc *gsmenc); -static void gst_gsmenc_class_init (GstGSMEnc *klass); -static void gst_gsmenc_init (GstGSMEnc *gsmenc); - -static void gst_gsmenc_chain (GstPad *pad,GstBuffer *buf); -static void gst_gsmenc_newcaps (GstPad *pad, GstCaps *caps); +static void gst_gsmenc_chain (GstPad *pad,GstBuffer *buf); +static GstPadConnectReturn gst_gsmenc_sinkconnect (GstPad *pad, GstCaps *caps); static GstElementClass *parent_class = NULL; static guint gst_gsmenc_signals[LAST_SIGNAL] = { 0 }; @@ -113,7 +102,7 @@ gst_gsmenc_init (GstGSMEnc *gsmenc) gsmenc->sinkpad = gst_pad_new_from_template (gsmenc_sink_template, "sink"); gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad); gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain); - gst_pad_set_newcaps_function (gsmenc->sinkpad, gst_gsmenc_newcaps); + gst_pad_set_connect_function (gsmenc->sinkpad, gst_gsmenc_sinkconnect); gsmenc->srcpad = gst_pad_new_from_template (gsmenc_src_template, "src"); gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->srcpad); @@ -124,19 +113,27 @@ gst_gsmenc_init (GstGSMEnc *gsmenc) gsmenc->rate = 8000; } -static void -gst_gsmenc_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_gsmenc_sinkconnect (GstPad *pad, GstCaps *caps) { GstGSMEnc *gsmenc; gsmenc = GST_GSMENC (gst_pad_get_parent (pad)); + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; + gsmenc->rate = gst_caps_get_int (caps, "rate"); - gst_pad_set_caps (gsmenc->srcpad, GST_CAPS_NEW ( + if (gst_pad_try_set_caps (gsmenc->srcpad, GST_CAPS_NEW ( "gsm_gsm", "audio/x-gsm", "rate", GST_PROPS_INT (gsmenc->rate) - )); + ))) + { + return GST_PAD_CONNECT_OK; + } + return GST_PAD_CONNECT_REFUSED; + } static void @@ -153,7 +150,7 @@ gst_gsmenc_chain (GstPad *pad, GstBuffer *buf) gsmenc = GST_GSMENC (GST_OBJECT_PARENT (pad)); if (!GST_PAD_CAPS (gsmenc->srcpad)) { - gst_pad_set_caps (gsmenc->srcpad, + gst_pad_try_set_caps (gsmenc->srcpad, GST_CAPS_NEW ( "gsm_enc", "audio/x-gsm", diff --git a/ext/hermes/Makefile.am b/ext/hermes/Makefile.am index 15e7c1e848..b221c5cb02 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 eebe19b690..40ada8279f 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_YUY2_I420; + space->type = GST_COLORSPACE_NONE; space->destbpp = 12; - break; - } - break; - } - return TRUE; -} + return TRUE; -static GstPadNegotiateReturn -colorspace_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) -{ - 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); - } - - - original = gst_caps_copy (*caps); - //g_print ("%d %d\n", src_width, src_height); - - // 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)); - - space->srccaps = *caps; - // FIXME - GST_PAD_CAPS (space->srcpad) = gst_caps_ref (*caps); - - 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; + switch (to_space) { + case GST_MAKE_FOURCC ('I','4','2','0'): + space->type = GST_COLORSPACE_YUY2_I420; + space->destbpp = 12; + return TRUE; + case GST_MAKE_FOURCC ('Y','U','Y','2'): + space->type = GST_COLORSPACE_NONE; + space->destbpp = 16; + return TRUE; + } break; } - return GST_PAD_NEGOTIATE_FAIL; + return FALSE; } -static GstPadNegotiateReturn -colorspace_negotiate_sink (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; - - GST_DEBUG (GST_CAT_NEGOTIATION, "colorspace: sink negotiate\n"); + GstColorspace *space; + GstCaps *result; + 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)); + /* 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)); - space->type = GST_COLORSPACE_NONE; + /* merge them together, we prefer the peercaps first */ + result = gst_caps_prepend (ourcaps, peercaps); - original = gst_caps_copy (*caps); + return result; +} - // 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; +static GstPadConnectReturn +gst_colorspace_sinkconnect (GstPad *pad, GstCaps *caps) +{ + GstColorspace *space; + GstPad *peer; + + space = GST_COLORSPACE (gst_pad_get_parent (pad)); + + if (!GST_CAPS_IS_FIXED (caps)) { + return GST_PAD_CONNECT_DELAYED; } - 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 (caps, "width"); + space->height = gst_caps_get_int (caps, "height"); - /* - space->width = gst_caps_get_int (original, "width"); - space->height = gst_caps_get_int (original, "height"); + GST_INFO (GST_CAT_PROPERTIES, "size: %dx%d", space->width, space->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 - )); + space->sinkcaps = caps; - 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; + 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 GstPadConnectReturn +gst_colorspace_srcconnect (GstPad *pad, GstCaps *caps) +{ + return gst_colorspace_srcconnect_func (pad, caps, TRUE); +} + +static GstPadConnectReturn +gst_colorspace_srcconnect_func (GstPad *pad, GstCaps *caps, gboolean newcaps) +{ + GstColorspace *space; + GstCaps *peercaps; + GstCaps *ourcaps; + + space = GST_COLORSPACE (gst_pad_get_parent (pad)); + + /* we cannot operate if we didn't get src caps */ + ourcaps = space->sinkcaps; + if (!ourcaps) { + if (newcaps) + gst_pad_recalc_allowed_caps (space->sinkpad); + + return GST_PAD_CONNECT_DELAYED; + } + + /* 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; + } + } + /* 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_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 8d780b4138..ca345fde6a 100644 --- a/ext/hermes/gstcolorspace.h +++ b/ext/hermes/gstcolorspace.h @@ -26,7 +26,7 @@ #include #include "yuv2rgb.h" -#ifdef HAVE_LIBHERMES +#ifdef HAVE_HERMES # include #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 0000000000..7495c71b85 --- /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 +#include + +#include + +#define RGB2YUV_SHIFT 8 +#define BY ((int)( 0.098*(1<> 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); + } +} diff --git a/ext/ladspa/gstladspa.c b/ext/ladspa/gstladspa.c index b83f0268c8..53f1d5e382 100644 --- a/ext/ladspa/gstladspa.c +++ b/ext/ladspa/gstladspa.c @@ -85,9 +85,9 @@ static GstPadTemplate *srctempl, *sinktempl; static void gst_ladspa_class_init (GstLADSPAClass *klass); static void gst_ladspa_init (GstLADSPA *ladspa); -static GstPadNegotiateReturn gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data); -static GstPadNegotiateReturn gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data); -static GstPadNegotiateReturn gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data); +//static GstPadNegotiateReturn gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data); +//static GstPadNegotiateReturn gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data); +//static GstPadNegotiateReturn gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data); static void gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad); static void gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); @@ -347,9 +347,9 @@ gst_ladspa_init (GstLADSPA *ladspa) // mono chain if (sinkcount==1 && srccount==1){ //g_print("inplace mono chain mode\n"); - gst_pad_set_negotiate_function (ladspa->sinkpads[0], gst_ladspa_negotiate_sink_mono); + //gst_pad_set_negotiate_function (ladspa->sinkpads[0], gst_ladspa_negotiate_sink_mono); gst_pad_set_chain_function(ladspa->sinkpads[0],gst_ladspa_chain_inplace_mono); - gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_mono); + //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_mono); } // mono get (no sink pads) @@ -359,7 +359,7 @@ gst_ladspa_init (GstLADSPA *ladspa) ladspa->samplerate = 44100; ladspa->buffersize = 64; gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get_mono); - gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono); + //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono); gst_ladspa_instantiate(ladspa); } @@ -370,12 +370,13 @@ gst_ladspa_init (GstLADSPA *ladspa) ladspa->samplerate = 44100; ladspa->buffersize = 64; gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get); - gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono); + //gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono); gst_ladspa_instantiate(ladspa); ladspa->buffers = g_new0(GstBuffer*,oclass->numsrcpads); } } +#if 0 static GstPadNegotiateReturn gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data) { @@ -416,12 +417,13 @@ gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data) } return GST_PAD_NEGOTIATE_FAIL; } +#endif static void gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad) { // g_print("forcing caps\n"); - gst_pad_set_caps (pad, gst_caps_new ( + gst_pad_try_set_caps (pad, gst_caps_new ( "ladspa_src_caps", "audio/raw", gst_props_new ( diff --git a/gst/chart/gstchart.c b/gst/chart/gstchart.c index 1ec259705c..a08c475d5f 100644 --- a/gst/chart/gstchart.c +++ b/gst/chart/gstchart.c @@ -44,6 +44,7 @@ struct _GstChart { gint depth; gint width; gint height; + gboolean first_buffer; gint samplerate; gint framerate; // desired frame rate @@ -162,10 +163,10 @@ static void gst_chart_get_property (GObject *object, guint prop_id, GValue *valu static void gst_chart_chain (GstPad *pad, GstBuffer *buf); -static GstElementClass *parent_class = NULL; +static GstPadConnectReturn + gst_chart_sinkconnect (GstPad *pad, GstCaps *caps); -static void gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps); -static void gst_chart_newsrccaps (GstPad *pad, GstCaps *caps); +static GstElementClass *parent_class = NULL; GType gst_chart_get_type (void) @@ -211,9 +212,7 @@ gst_chart_init (GstChart *chart) gst_element_add_pad (GST_ELEMENT (chart), chart->srcpad); gst_pad_set_chain_function (chart->sinkpad, gst_chart_chain); - gst_pad_set_newcaps_function (chart->sinkpad, gst_chart_newsinkcaps); - gst_pad_set_newcaps_function (chart->srcpad, gst_chart_newsrccaps); - + gst_pad_set_connect_function (chart->sinkpad, gst_chart_sinkconnect); chart->next_time = 0; chart->peerpool = NULL; @@ -221,8 +220,9 @@ gst_chart_init (GstChart *chart) // reset the initial video state chart->bpp = 16; chart->depth = 16; - chart->width = -1; - chart->height = -1; + chart->first_buffer = TRUE; + chart->width = 256; + chart->height = 128; chart->samplerate = -1; chart->framerate = 25; // desired frame rate @@ -230,8 +230,8 @@ gst_chart_init (GstChart *chart) chart->samples_since_last_frame = 0; } -static void -gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_chart_sinkconnect (GstPad *pad, GstCaps *caps) { GstChart *chart; chart = GST_CHART (gst_pad_get_parent (pad)); @@ -242,22 +242,8 @@ gst_chart_newsinkcaps (GstPad *pad, GstCaps *caps) GST_DEBUG (0, "CHART: new sink caps: rate %d\n", chart->samplerate); //gst_chart_sync_parms (chart); -} - -static void -gst_chart_newsrccaps (GstPad *pad, GstCaps *caps) -{ - GstChart *chart; - chart = GST_CHART (gst_pad_get_parent (pad)); - - chart->bpp = gst_caps_get_int (caps, "bpp"); - chart->depth = gst_caps_get_int (caps, "depth"); - chart->width = gst_caps_get_int (caps, "width"); - chart->height = gst_caps_get_int (caps, "height"); - - GST_DEBUG (0, "CHART: new src caps: bpp %d, depth %d, width %d, height %d\n", - chart->bpp, chart->depth, chart->width, chart->height); - //gst_chart_sync_parms (chart); + // + return GST_PAD_CONNECT_OK; } static void @@ -347,28 +333,6 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin) if (chart->samples_between_frames <= chart->samples_since_last_frame) { chart->samples_since_last_frame = 0; - // Check if we need to renegotiate size. - if (chart->width == -1 || chart->height == -1) { - chart->width = 256; - chart->height = 128; - GST_DEBUG (0, "making new pad\n"); - gst_pad_set_caps (chart->srcpad, - gst_caps_new ( - "chartsrc", - "video/raw", - gst_props_new ( - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')), - "bpp", GST_PROPS_INT (chart->bpp), - "depth", GST_PROPS_INT (chart->depth), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "red_mask", GST_PROPS_INT (0xf800), - "green_mask", GST_PROPS_INT (0x07e0), - "blue_mask", GST_PROPS_INT (0x001f), - "width", GST_PROPS_INT (chart->width), - "height", GST_PROPS_INT (chart->height), - NULL))); - } - // get data to draw into buffer if (samples_in >= chart->width) { // make a new buffer for the output @@ -384,9 +348,35 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin) // FIXME: call different routines for different properties draw_chart_16bpp(dataout, chart->width, chart->height, (gint16 *)datain, samples_in); + gst_buffer_unref(bufin); + // set timestamp GST_BUFFER_TIMESTAMP (bufout) = chart->next_time; + // Check if we need to renegotiate size. + if (chart->first_buffer) { + GST_DEBUG (0, "making new pad\n"); + if (!gst_pad_try_set_caps (chart->srcpad, + GST_CAPS_NEW ( + "chartsrc", + "video/raw", + "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('R','G','B',' ')), + "bpp", GST_PROPS_INT (chart->bpp), + "depth", GST_PROPS_INT (chart->depth), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "red_mask", GST_PROPS_INT (0xf800), + "green_mask", GST_PROPS_INT (0x07e0), + "blue_mask", GST_PROPS_INT (0x001f), + "width", GST_PROPS_INT (chart->width), + "height", GST_PROPS_INT (chart->height) + ))) + { + gst_element_error (GST_ELEMENT (chart), "could not set caps"); + return; + } + chart->first_buffer = FALSE; + } + GST_DEBUG (0, "CHART: outputting buffer\n"); // output buffer GST_BUFFER_FLAG_SET (bufout, GST_BUFFER_READONLY); @@ -394,9 +384,9 @@ gst_chart_chain (GstPad *pad, GstBuffer *bufin) } } else { GST_DEBUG (0, "CHART: skipping buffer\n"); + gst_buffer_unref(bufin); } - gst_buffer_unref(bufin); GST_DEBUG (0, "CHART: exiting chainfunc\n"); } diff --git a/gst/deinterlace/gstdeinterlace.c b/gst/deinterlace/gstdeinterlace.c index 99a70c84e8..0ad6ea8ec8 100644 --- a/gst/deinterlace/gstdeinterlace.c +++ b/gst/deinterlace/gstdeinterlace.c @@ -54,7 +54,9 @@ GST_PADTEMPLATE_FACTORY (deinterlace_src_factory, GST_CAPS_NEW ( "deinterlace_src", "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) + "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), + "width", GST_PROPS_INT_POSITIVE, + "height", GST_PROPS_INT_POSITIVE ) ) @@ -65,7 +67,9 @@ GST_PADTEMPLATE_FACTORY (deinterlace_sink_factory, GST_CAPS_NEW ( "deinterlace_src", "video/raw", - "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")) + "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")), + "width", GST_PROPS_INT_POSITIVE, + "height", GST_PROPS_INT_POSITIVE ) ) @@ -74,36 +78,16 @@ static GType gst_deinterlace_get_type (void); static void gst_deinterlace_class_init (GstDeInterlaceClass *klass); static void gst_deinterlace_init (GstDeInterlace *filter); -static void gst_deinterlace_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_deinterlace_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_deinterlace_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_deinterlace_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); static void gst_deinterlace_chain (GstPad *pad, GstBuffer *buf); static GstElementClass *parent_class = NULL; //static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; -static GstPadNegotiateReturn -deinterlace_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstDeInterlace* filter = GST_DEINTERLACE (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps); -} - -static GstPadNegotiateReturn -deinterlace_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstDeInterlace* filter = GST_DEINTERLACE (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); -} - static GType gst_deinterlace_get_type(void) { static GType deinterlace_type = 0; @@ -152,12 +136,15 @@ gst_deinterlace_class_init (GstDeInterlaceClass *klass) gobject_class->get_property = gst_deinterlace_get_property; } -static void -gst_deinterlace_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_deinterlace_sinkconnect (GstPad *pad, GstCaps *caps) { GstDeInterlace *filter; filter = GST_DEINTERLACE(gst_pad_get_parent (pad)); + + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; filter->width = gst_caps_get_int (caps, "width"); filter->height = gst_caps_get_int (caps, "height"); @@ -168,19 +155,21 @@ gst_deinterlace_newcaps (GstPad *pad, GstCaps *caps) filter->picsize = filter->width*filter->height; filter->src = g_malloc(filter->picsize); } + if (gst_pad_try_set_caps (filter->srcpad, caps)) { + return GST_PAD_CONNECT_OK; + } + return GST_PAD_CONNECT_REFUSED; } static void gst_deinterlace_init (GstDeInterlace *filter) { filter->sinkpad = gst_pad_new_from_template(deinterlace_sink_factory (),"sink"); - gst_pad_set_negotiate_function(filter->sinkpad,deinterlace_negotiate_sink); gst_pad_set_chain_function(filter->sinkpad,gst_deinterlace_chain); - gst_pad_set_newcaps_function(filter->sinkpad,gst_deinterlace_newcaps); + gst_pad_set_connect_function(filter->sinkpad,gst_deinterlace_sinkconnect); gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); filter->srcpad = gst_pad_new_from_template(deinterlace_src_factory (),"src"); - gst_pad_set_negotiate_function(filter->srcpad,deinterlace_negotiate_src); gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad); filter->show_deinterlaced_area_only = FALSE; diff --git a/gst/flx/gstflxdec.c b/gst/flx/gstflxdec.c index 5fd5eb2377..95e55cc635 100644 --- a/gst/flx/gstflxdec.c +++ b/gst/flx/gstflxdec.c @@ -22,6 +22,8 @@ #include "flx_fmt.h" #include "gstflxdec.h" +#define JIFFIE (1000000/70) + static GstCaps* flxdec_typefind(GstBuffer *buf, gpointer private); /* flx element information */ @@ -89,6 +91,9 @@ static void gst_flxdec_init (GstFlxDec *flxdec); static void gst_flxdec_loop (GstElement *element); +static GstElementStateReturn + gst_flxdec_change_state (GstElement *element); + static void gst_flxdec_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gst_flxdec_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); @@ -108,10 +113,10 @@ flxdec_typefind (GstBuffer *buf, gpointer private) guchar *data = GST_BUFFER_DATA(buf); GstCaps *new; - // check magic + /* check magic */ if ((data[4] == 0x11 || data[4] == 0x12 || data[4] == 0x30 || data[4] == 0x44) && data[5] == 0xaf) { - // check the frame type of the first frame + /* check the frame type of the first frame */ if ((data[132] == 0x00 || data[132] == 0xfa) && data[133] == 0xf1) { g_print("GstFlxDec: found supported flx format\n"); new = gst_caps_new("flxdec_typefind","video/fli", NULL); @@ -158,6 +163,7 @@ gst_flxdec_class_init (GstFlxDecClass *klass) gobject_class->set_property = NULL; gobject_class->get_property = NULL; + gstelement_class->change_state = gst_flxdec_change_state; } @@ -175,9 +181,9 @@ gst_flxdec_init(GstFlxDec *flxdec) gst_element_add_pad(GST_ELEMENT(flxdec),flxdec->srcpad); flxdec->buf = NULL; - flxdec->offset = 0; - flxdec->new_buf = TRUE; - + flxdec->bs = NULL; + flxdec->frame = NULL; + flxdec->delta = NULL; } static void @@ -428,15 +434,13 @@ flx_get_data(GstFlxDec *flxdec, gulong size) g_return_val_if_fail (flxdec != NULL, NULL); - if (flxdec->new_buf) { - retbuf = gst_pad_pullregion(flxdec->sinkpad, - GST_REGION_OFFSET_LEN, 0, size); - flxdec->new_buf = FALSE; - flxdec->offset = size; - } else { - retbuf = gst_pad_pullregion(flxdec->sinkpad, GST_REGION_OFFSET_LEN, - flxdec->offset, size); - flxdec->offset += size; + retbuf = gst_bytestream_read (flxdec->bs, size); + if (!retbuf) { + GstEvent *event; + guint32 remaining; + + gst_bytestream_get_status (flxdec->bs, &remaining, &event); + gst_pad_event_default (flxdec->sinkpad, event); } return retbuf; @@ -461,33 +465,41 @@ gst_flxdec_loop (GstElement *element) flxdec = GST_FLXDEC(element); - databuf = flx_get_data(flxdec, FlxHeaderSize); + if (flxdec->state == GST_FLXDEC_READ_HEADER) { + databuf = flx_get_data(flxdec, FlxHeaderSize); - g_return_if_fail (databuf != NULL); + data = GST_BUFFER_DATA(databuf); - data = GST_BUFFER_DATA(databuf); + memcpy((char *) &flxdec->hdr, data, sizeof(FlxHeader)); - memcpy((char *) &flxdec->hdr, data, sizeof(FlxHeader)); + gst_buffer_unref (databuf); - gst_buffer_unref (databuf); + flxh = &flxdec->hdr; - flxh = &flxdec->hdr; - - // check header - if (flxh->type != FLX_MAGICHDR_FLI && + /* check header */ + if (flxh->type != FLX_MAGICHDR_FLI && flxh->type != FLX_MAGICHDR_FLC && flxh->type != FLX_MAGICHDR_FLX) return; - g_print("GstFlxDec: size : %d\n", flxh->size); - g_print("GstFlxDec: frames : %d\n", flxh->frames); - g_print("GstFlxDec: width : %d\n", flxh->width); - g_print("GstFlxDec: height : %d\n", flxh->height); - g_print("GstFlxDec: depth : %d\n", flxh->depth); - g_print("GstFlxDec: speed : %d\n", flxh->speed); + g_print("GstFlxDec: size : %d\n", flxh->size); + g_print("GstFlxDec: frames : %d\n", flxh->frames); + g_print("GstFlxDec: width : %d\n", flxh->width); + g_print("GstFlxDec: height : %d\n", flxh->height); + g_print("GstFlxDec: depth : %d\n", flxh->depth); + g_print("GstFlxDec: speed : %d\n", flxh->speed); - gst_pad_set_caps (flxdec->srcpad, + flxdec->next_time = 0; + + if (flxh->type == FLX_MAGICHDR_FLI) { + flxdec->frame_time = JIFFIE * flxh->speed; + } + else { + flxdec->frame_time = flxh->speed * 1000; + } + + gst_pad_try_set_caps (flxdec->srcpad, gst_caps_new ( "src_video", "video/raw", @@ -503,41 +515,37 @@ gst_flxdec_loop (GstElement *element) "height", GST_PROPS_INT (flxh->height), NULL))); - if (flxh->depth <= 8) - flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height); + if (flxh->depth <= 8) + flxdec->converter = flx_colorspace_converter_new(flxh->width, flxh->height); - if (flxh->type == FLX_MAGICHDR_FLC || - flxh->type == FLX_MAGICHDR_FLX) { - g_print("GstFlxDec: (FLC) aspect_dx : %d\n", - flxh->aspect_dx); - g_print("GstFlxDec: (FLC) aspect_dy : %d\n", - flxh->aspect_dy); - g_print("GstFlxDec: (FLC) oframe1 : 0x%08x\n", - flxh->oframe1); - g_print("GstFlxDec: (FLC) oframe2 : 0x%08x\n", - flxh->oframe2); + if (flxh->type == FLX_MAGICHDR_FLC || + flxh->type == FLX_MAGICHDR_FLX) { + g_print("GstFlxDec: (FLC) aspect_dx : %d\n", flxh->aspect_dx); + g_print("GstFlxDec: (FLC) aspect_dy : %d\n", flxh->aspect_dy); + g_print("GstFlxDec: (FLC) oframe1 : 0x%08x\n", flxh->oframe1); + g_print("GstFlxDec: (FLC) oframe2 : 0x%08x\n", flxh->oframe2); + } + + + flxdec->size = (flxh->width * flxh->height); + + /* create delta and output frame */ + flxdec->frame = gst_buffer_new(); + flxdec->delta = gst_buffer_new(); + GST_BUFFER_DATA(flxdec->frame) = g_malloc(flxdec->size); + GST_BUFFER_SIZE(flxdec->frame) = flxdec->size; + GST_BUFFER_DATA(flxdec->delta) = g_malloc(flxdec->size); + GST_BUFFER_SIZE(flxdec->delta) = flxdec->size; + + flxdec->state = GST_FLXDEC_PLAYING; } - - - flxdec->size = (flxh->width * flxh->height); - - // create delta and output frame - flxdec->frame = gst_buffer_new(); - flxdec->delta = gst_buffer_new(); - GST_BUFFER_DATA(flxdec->frame) = g_malloc(flxdec->size); - GST_BUFFER_SIZE(flxdec->frame) = flxdec->size; - GST_BUFFER_DATA(flxdec->delta) = g_malloc(flxdec->size); - GST_BUFFER_SIZE(flxdec->delta) = flxdec->size; - - do - { + else if (flxdec->state == GST_FLXDEC_PLAYING) { databuf = flx_get_data(flxdec, FlxFrameChunkSize); flxfh = (FlxFrameChunk *) GST_BUFFER_DATA(databuf); - switch(flxfh->id) - { + switch(flxfh->id) { case FLX_FRAME_TYPE: buf = flx_get_data(flxdec, flxfh->size-FlxFrameChunkSize); @@ -546,43 +554,74 @@ gst_flxdec_loop (GstElement *element) if (((FlxFrameType *)chunk)->chunks == 0) break; - // create 32 bits output frame + /* create 32 bits output frame */ flxdec->out = gst_buffer_new(); GST_BUFFER_DATA(flxdec->out) = g_malloc(flxdec->size * 4); GST_BUFFER_SIZE(flxdec->out) = flxdec->size * 4; - // decode chunks + /* decode chunks */ flx_decode_chunks(flxdec, ((FlxFrameType *)chunk)->chunks, GST_BUFFER_DATA(buf) + FlxFrameTypeSize, GST_BUFFER_DATA(flxdec->frame)); - // destroy input buffer + /* destroy input buffer*/ gst_buffer_unref(buf); - // save copy of the current frame for possible delta. + /* save copy of the current frame for possible delta. */ memcpy(GST_BUFFER_DATA(flxdec->delta), GST_BUFFER_DATA(flxdec->frame), GST_BUFFER_SIZE(flxdec->delta)); - // convert current frame. + /* convert current frame. */ flx_colorspace_convert(flxdec->converter, GST_BUFFER_DATA(flxdec->frame), GST_BUFFER_DATA(flxdec->out)); + GST_BUFFER_TIMESTAMP (flxdec->out) = flxdec->next_time; + flxdec->next_time += flxdec->frame_time; + gst_pad_push(flxdec->srcpad, flxdec->out); break; } - // destroy header buffer + /* destroy header buffer */ gst_buffer_unref(databuf); - - gst_element_yield (element); } - while (TRUE); +} +static GstElementStateReturn +gst_flxdec_change_state (GstElement *element) +{ + GstFlxDec *flxdec; + + flxdec = GST_FLXDEC(element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + flxdec->bs = gst_bytestream_new (flxdec->sinkpad); + break; + case GST_STATE_READY_TO_PAUSED: + flxdec->state = GST_FLXDEC_READ_HEADER; + break; + case GST_STATE_PAUSED_TO_PLAYING: + break; + case GST_STATE_PLAYING_TO_PAUSED: + break; + case GST_STATE_PAUSED_TO_READY: + gst_buffer_unref (flxdec->frame); + gst_buffer_unref (flxdec->delta); + break; + case GST_STATE_READY_TO_NULL: + gst_bytestream_destroy (flxdec->bs); + break; + } + + parent_class->change_state (element); + + return GST_STATE_SUCCESS; } static void @@ -622,6 +661,12 @@ plugin_init (GModule *module, GstPlugin *plugin) GstElementFactory *factory; GstTypeFactory *type; + /* this filter needs the bytestream package */ + if (!gst_library_load("gstbytestream")) { + gst_info("flxdec:: could not load support library: 'gstbytestream'\n"); + return FALSE; + } + factory = gst_elementfactory_new("flxdec", GST_TYPE_FLXDEC, &flxdec_details); g_return_val_if_fail(factory != NULL, FALSE); diff --git a/gst/flx/gstflxdec.h b/gst/flx/gstflxdec.h index cc4c94dbeb..5b06252d09 100644 --- a/gst/flx/gstflxdec.h +++ b/gst/flx/gstflxdec.h @@ -23,23 +23,35 @@ #include #include "flx_color.h" +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +typedef enum { + GST_FLXDEC_READ_HEADER, + GST_FLXDEC_PLAYING, +} GstFlxDecState; + /* Definition of structure storing data for this element. */ typedef struct _GstFlxDec GstFlxDec; + struct _GstFlxDec { GstElement element; GstPad *sinkpad,*srcpad; - gboolean active, new_meta, new_buf; + gboolean active, new_meta; GstBuffer *buf, *out, *delta, *frame; - gulong offset, size; + GstByteStream *bs; + gulong size; + GstFlxDecState state; + glong frame_time; + gint64 next_time; FlxColorSpaceConverter *converter; @@ -64,9 +76,6 @@ struct _GstFlxDecClass { #define GST_IS_FLXDEC_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FLXDEC)) -#define FLXDEC_BUFSIZE(buf, offset) \ - ((GST_BUFFER_OFFSET(buf) + GST_BUFFER_SIZE(buf)) - offset) - /* Standard function returning type information. */ GType gst_flxdec_get_type(void); diff --git a/gst/mpeg1videoparse/gstmp1videoparse.c b/gst/mpeg1videoparse/gstmp1videoparse.c index 39fdfa298e..0d54d27ef1 100644 --- a/gst/mpeg1videoparse/gstmp1videoparse.c +++ b/gst/mpeg1videoparse/gstmp1videoparse.c @@ -138,12 +138,10 @@ static void gst_mp1videoparse_init (Mp1VideoParse *mp1videoparse) { mp1videoparse->sinkpad = gst_pad_new_from_template (sink_template, "sink"); - gst_pad_set_caps (mp1videoparse->sinkpad, gst_pad_get_padtemplate_caps (mp1videoparse->sinkpad)); gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->sinkpad); gst_pad_set_chain_function(mp1videoparse->sinkpad,gst_mp1videoparse_chain); mp1videoparse->srcpad = gst_pad_new_from_template (src_template, "src"); - gst_pad_set_caps (mp1videoparse->srcpad, gst_pad_get_padtemplate_caps (mp1videoparse->srcpad)); gst_element_add_pad(GST_ELEMENT(mp1videoparse),mp1videoparse->srcpad); mp1videoparse->partialbuf = NULL; diff --git a/gst/mpegaudioparse/gstmpegaudioparse.c b/gst/mpegaudioparse/gstmpegaudioparse.c index 220d6dd2e3..9e19b319d7 100644 --- a/gst/mpegaudioparse/gstmpegaudioparse.c +++ b/gst/mpegaudioparse/gstmpegaudioparse.c @@ -142,7 +142,6 @@ static void gst_mp3parse_init (GstMPEGAudioParse *mp3parse) { mp3parse->sinkpad = gst_pad_new_from_template(sink_temp, "sink"); - //gst_pad_set_caps(mp3parse->sinkpad, gst_pad_get_padtemplate_caps (mp3parse->sinkpad)); gst_element_add_pad(GST_ELEMENT(mp3parse),mp3parse->sinkpad); #if 1 // set this to one to use the old chaining code diff --git a/gst/passthrough/gstpassthrough.c b/gst/passthrough/gstpassthrough.c index 0faa878bd6..d9f0bac15a 100644 --- a/gst/passthrough/gstpassthrough.c +++ b/gst/passthrough/gstpassthrough.c @@ -107,6 +107,7 @@ passthrough_get_bufferpool (GstPad *pad) return gst_pad_get_bufferpool (filter->srcpad); } +/* static GstPadNegotiateReturn passthrough_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) { @@ -134,6 +135,7 @@ passthrough_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); } +*/ static gint passthrough_parse_caps (GstPassthrough *filter, GstCaps *caps) @@ -222,10 +224,10 @@ static void passthrough_init (GstPassthrough *filter) { filter->sinkpad = gst_pad_new_from_template(passthrough_sink_factory (),"sink"); - gst_pad_set_negotiate_function(filter->sinkpad,passthrough_negotiate_sink); + //gst_pad_set_negotiate_function(filter->sinkpad,passthrough_negotiate_sink); gst_pad_set_bufferpool_function(filter->sinkpad,passthrough_get_bufferpool); filter->srcpad = gst_pad_new_from_template(passthrough_src_factory (),"src"); - gst_pad_set_negotiate_function(filter->srcpad,passthrough_negotiate_src); + //gst_pad_set_negotiate_function(filter->srcpad,passthrough_negotiate_src); gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad); diff --git a/gst/playondemand/gstplayondemand.c b/gst/playondemand/gstplayondemand.c index 2f7ebb080d..b3d99846bc 100644 --- a/gst/playondemand/gstplayondemand.c +++ b/gst/playondemand/gstplayondemand.c @@ -117,6 +117,7 @@ play_on_demand_get_bufferpool (GstPad *pad) return gst_pad_get_bufferpool(filter->srcpad); } +/* static GstPadNegotiateReturn play_on_demand_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) { @@ -144,6 +145,7 @@ play_on_demand_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) return gst_pad_negotiate_proxy(pad, filter->srcpad, caps); } +*/ static gint play_on_demand_parse_caps (GstPlayOnDemand *filter, GstCaps *caps) @@ -264,11 +266,11 @@ play_on_demand_init (GstPlayOnDemand *filter) guint i; filter->sinkpad = gst_pad_new_from_template(play_on_demand_sink_factory(), "sink"); - gst_pad_set_negotiate_function(filter->sinkpad, play_on_demand_negotiate_sink); + //gst_pad_set_negotiate_function(filter->sinkpad, play_on_demand_negotiate_sink); gst_pad_set_bufferpool_function(filter->sinkpad, play_on_demand_get_bufferpool); filter->srcpad = gst_pad_new_from_template(play_on_demand_src_factory(), "src"); - gst_pad_set_negotiate_function(filter->srcpad, play_on_demand_negotiate_src); + //gst_pad_set_negotiate_function(filter->srcpad, play_on_demand_negotiate_src); gst_element_add_pad(GST_ELEMENT(filter), filter->sinkpad); gst_element_add_pad(GST_ELEMENT(filter), filter->srcpad); diff --git a/gst/smooth/gstsmooth.c b/gst/smooth/gstsmooth.c index 5f1f507caa..ea32194063 100644 --- a/gst/smooth/gstsmooth.c +++ b/gst/smooth/gstsmooth.c @@ -80,28 +80,6 @@ static void gst_smooth_get_property (GObject *object, guint prop_id, GValue *val static GstElementClass *parent_class = NULL; //static guint gst_smooth_signals[LAST_SIGNAL] = { 0 }; -static GstPadNegotiateReturn -smooth_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstSmooth* filter = GST_SMOOTH (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy (pad, filter->sinkpad, caps); -} - -static GstPadNegotiateReturn -smooth_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstSmooth* filter = GST_SMOOTH (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy (pad, filter->srcpad, caps); -} - GType gst_smooth_get_type (void) { @@ -149,15 +127,20 @@ gst_smooth_class_init (GstSmoothClass *klass) } -static void -gst_smooth_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_smooth_sinkconnect (GstPad *pad, GstCaps *caps) { GstSmooth *filter; filter = GST_SMOOTH (gst_pad_get_parent (pad)); + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; + filter->width = gst_caps_get_int (caps, "width"); filter->height = gst_caps_get_int (caps, "height"); + + return GST_PAD_CONNECT_OK; } static void @@ -165,14 +148,12 @@ gst_smooth_init (GstSmooth *smooth) { smooth->sinkpad = gst_pad_new_from_template ( GST_PADTEMPLATE_GET (smooth_sink_factory), "sink"); - gst_pad_set_negotiate_function (smooth->sinkpad, smooth_negotiate_sink); - gst_pad_set_newcaps_function (smooth->sinkpad, gst_smooth_newcaps); + gst_pad_set_connect_function (smooth->sinkpad, gst_smooth_sinkconnect); gst_pad_set_chain_function (smooth->sinkpad, gst_smooth_chain); gst_element_add_pad (GST_ELEMENT (smooth), smooth->sinkpad); smooth->srcpad = gst_pad_new_from_template ( GST_PADTEMPLATE_GET (smooth_src_factory), "src"); - gst_pad_set_negotiate_function (smooth->srcpad, smooth_negotiate_src); gst_element_add_pad (GST_ELEMENT (smooth), smooth->srcpad); smooth->active = TRUE; diff --git a/gst/speed/gstspeed.c b/gst/speed/gstspeed.c index feca25338c..8cf9019185 100644 --- a/gst/speed/gstspeed.c +++ b/gst/speed/gstspeed.c @@ -109,6 +109,7 @@ static void speed_loop (GstElement *element); static GstElementClass *parent_class = NULL; //static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; +/* static GstPadNegotiateReturn speed_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) { @@ -136,6 +137,7 @@ speed_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); } +*/ static gint speed_parse_caps (GstSpeed *filter, GstCaps *caps) @@ -228,10 +230,10 @@ static void speed_init (GstSpeed *filter) { filter->sinkpad = gst_pad_new_from_template(speed_sink_factory (),"sink"); - gst_pad_set_negotiate_function(filter->sinkpad,speed_negotiate_sink); + //gst_pad_set_negotiate_function(filter->sinkpad,speed_negotiate_sink); gst_pad_set_bufferpool_function (filter->sinkpad, speed_sink_get_bufferpool); filter->srcpad = gst_pad_new_from_template(speed_src_factory (),"src"); - gst_pad_set_negotiate_function(filter->srcpad,speed_negotiate_src); + //gst_pad_set_negotiate_function(filter->srcpad,speed_negotiate_src); gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad); diff --git a/gst/y4m/gsty4mencode.c b/gst/y4m/gsty4mencode.c index 69fc58dcff..ac82d65a67 100644 --- a/gst/y4m/gsty4mencode.c +++ b/gst/y4m/gsty4mencode.c @@ -115,15 +115,20 @@ gst_lavencode_class_init (GstLavEncodeClass *klass) gobject_class->get_property = gst_lavencode_get_property; } -static void -gst_lavencode_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_lavencode_sinkconnect (GstPad *pad, GstCaps *caps) { GstLavEncode *filter; filter = GST_LAVENCODE (gst_pad_get_parent (pad)); + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; + filter->width = gst_caps_get_int (caps, "width"); filter->height = gst_caps_get_int (caps, "height"); + + return GST_PAD_CONNECT_OK; } static void @@ -133,7 +138,7 @@ gst_lavencode_init (GstLavEncode *filter) GST_PADTEMPLATE_GET (lavencode_sink_factory), "sink"); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_pad_set_chain_function (filter->sinkpad, gst_lavencode_chain); - gst_pad_set_newcaps_function (filter->sinkpad, gst_lavencode_newcaps); + gst_pad_set_connect_function (filter->sinkpad, gst_lavencode_sinkconnect); filter->srcpad = gst_pad_new_from_template( GST_PADTEMPLATE_GET (lavencode_src_factory), "src"); diff --git a/sys/qcam/gstqcamsrc.c b/sys/qcam/gstqcamsrc.c index ed1afe98a2..22ab35caae 100644 --- a/sys/qcam/gstqcamsrc.c +++ b/sys/qcam/gstqcamsrc.c @@ -245,7 +245,7 @@ gst_qcamsrc_get (GstPad *pad) qc_set (qcamsrc->qcam); if (!GST_PAD_CAPS (pad)) { - gst_pad_set_caps (pad, GST_CAPS_NEW ( + gst_pad_try_set_caps (pad, GST_CAPS_NEW ( "qcam_caps", "video/raw", "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("I420")),