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/aalib/gstaasink.c b/ext/aalib/gstaasink.c index 83d9687fb3..7d41010ecf 100644 --- a/ext/aalib/gstaasink.c +++ b/ext/aalib/gstaasink.c @@ -70,10 +70,12 @@ GST_PADTEMPLATE_FACTORY (sink_template, static void gst_aasink_class_init (GstAASinkClass *klass); static void gst_aasink_init (GstAASink *aasink); -static void gst_aasink_chain (GstPad *pad, GstBuffer *buf); +static void gst_aasink_chain (GstPad *pad, GstBuffer *buf); -static void gst_aasink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_aasink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_aasink_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_aasink_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); static GstElementStateReturn gst_aasink_change_state (GstElement *element); @@ -87,7 +89,12 @@ gst_aasink_get_type (void) if (!aasink_type) { static const GTypeInfo aasink_info = { - sizeof(GstAASinkClass), NULL, NULL, (GClassInitFunc)gst_aasink_class_init, NULL, NULL, + sizeof(GstAASinkClass), + NULL, + NULL, + (GClassInitFunc) gst_aasink_class_init, + NULL, + NULL, sizeof(GstAASink), 0, (GInstanceInitFunc)gst_aasink_init, @@ -224,14 +231,17 @@ gst_aasink_class_init (GstAASinkClass *klass) gstelement_class->change_state = gst_aasink_change_state; } -static void -gst_aasink_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_aasink_sinkconnect (GstPad *pad, GstCaps *caps) { GstAASink *aasink; gulong print_format; aasink = GST_AASINK (gst_pad_get_parent (pad)); + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; + aasink->width = gst_caps_get_int (caps, "width"); aasink->height = gst_caps_get_int (caps, "height"); @@ -241,6 +251,8 @@ gst_aasink_newcaps (GstPad *pad, GstCaps *caps) g_signal_emit( G_OBJECT (aasink), gst_aasink_signals[SIGNAL_HAVE_SIZE], 0, aasink->width, aasink->height); + + return GST_PAD_CONNECT_OK; } static void @@ -250,7 +262,7 @@ gst_aasink_init (GstAASink *aasink) GST_PADTEMPLATE_GET (sink_template), "sink"); gst_element_add_pad (GST_ELEMENT (aasink), aasink->sinkpad); gst_pad_set_chain_function (aasink->sinkpad, gst_aasink_chain); - gst_pad_set_newcaps_function (aasink->sinkpad, gst_aasink_newcaps); + gst_pad_set_connect_function (aasink->sinkpad, gst_aasink_sinkconnect); aasink->clock = gst_clock_get_system(); gst_clock_register(aasink->clock, GST_OBJECT(aasink)); diff --git a/ext/dv/gstdvdec.c b/ext/dv/gstdvdec.c index 4ea06b801c..8fff3320cd 100644 --- a/ext/dv/gstdvdec.c +++ b/ext/dv/gstdvdec.c @@ -236,11 +236,9 @@ gst_dvdec_init(GstDVDec *dvdec) gst_element_add_pad(GST_ELEMENT(dvdec),dvdec->sinkpad); dvdec->videosrcpad = gst_pad_new_from_template (GST_PADTEMPLATE_GET(video_src_temp), "video"); - //gst_pad_set_caps (dvdec->videosrcpad, gst_pad_get_padtemplate_caps (dvdec->videosrcpad)); gst_element_add_pad(GST_ELEMENT(dvdec),dvdec->videosrcpad); // dvdec->audiosrcpad = gst_pad_new_from_template (GST_PADTEMPLATE_GET(audio_src_temp), "audio"); -// gst_pad_set_caps (dvdec->audiosrcpad, gst_pad_get_padtemplate_caps (dvdec->audiosrcpad)); // gst_element_add_pad(GST_ELEMENT(dvdec),dvdec->audiosrcpad); gst_element_set_loop_function (GST_ELEMENT(dvdec), gst_dvdec_loop); @@ -291,7 +289,7 @@ gst_dvdec_loop (GstElement *element) } if (!GST_PAD_CAPS (dvdec->videosrcpad)) { - gst_pad_set_caps (dvdec->videosrcpad, gst_pad_get_padtemplate_caps (dvdec->videosrcpad)); + gst_pad_try_set_caps (dvdec->videosrcpad, gst_pad_get_padtemplate_caps (dvdec->videosrcpad)); } if (!dvdec->pool) { diff --git a/ext/esd/esdsink.c b/ext/esd/esdsink.c index 16a056b7af..b0aba3cb36 100644 --- a/ext/esd/esdsink.c +++ b/ext/esd/esdsink.c @@ -86,12 +86,14 @@ static gboolean gst_esdsink_open_audio (GstEsdsink *sink); static void gst_esdsink_close_audio (GstEsdsink *sink); static GstElementStateReturn gst_esdsink_change_state (GstElement *element); static gboolean gst_esdsink_sync_parms (GstEsdsink *esdsink); -static void gst_esdsink_newcaps (GstPad *pad, GstCaps *caps); +static GstPadConnectReturn gst_esdsink_sinkconnect (GstPad *pad, GstCaps *caps); static void gst_esdsink_chain (GstPad *pad, GstBuffer *buf); -static void gst_esdsink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void gst_esdsink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_esdsink_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec); +static void gst_esdsink_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec); #define GST_TYPE_ESDSINK_DEPTHS (gst_esdsink_depths_get_type()) static GType @@ -190,7 +192,7 @@ gst_esdsink_init(GstEsdsink *esdsink) GST_PADTEMPLATE_GET (sink_factory), "sink"); gst_element_add_pad(GST_ELEMENT(esdsink), esdsink->sinkpad); gst_pad_set_chain_function(esdsink->sinkpad, GST_DEBUG_FUNCPTR(gst_esdsink_chain)); - gst_pad_set_newcaps_function(esdsink->sinkpad, gst_esdsink_newcaps); + gst_pad_set_connect_function(esdsink->sinkpad, gst_esdsink_sinkconnect); esdsink->mute = FALSE; esdsink->fd = -1; @@ -215,18 +217,24 @@ gst_esdsink_sync_parms (GstEsdsink *esdsink) return gst_esdsink_open_audio (esdsink); } -static void -gst_esdsink_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_esdsink_sinkconnect (GstPad *pad, GstCaps *caps) { GstEsdsink *esdsink; esdsink = GST_ESDSINK (gst_pad_get_parent (pad)); + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; + esdsink->depth = gst_caps_get_int (caps, "depth"); esdsink->channels = gst_caps_get_int (caps, "channels"); esdsink->frequency = gst_caps_get_int (caps, "rate"); - gst_esdsink_sync_parms (esdsink); + if (gst_esdsink_sync_parms (esdsink)) + return GST_PAD_CONNECT_OK; + + return GST_PAD_CONNECT_REFUSED; } static void diff --git a/ext/flac/gstflacdec.c b/ext/flac/gstflacdec.c index d7619b55ec..97a2fab97a 100644 --- a/ext/flac/gstflacdec.c +++ b/ext/flac/gstflacdec.c @@ -184,7 +184,7 @@ gst_flacdec_write (const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, flacdec = GST_FLACDEC (client_data); if (!GST_PAD_CAPS (flacdec->srcpad)) { - gst_pad_set_caps (flacdec->srcpad, + gst_pad_try_set_caps (flacdec->srcpad, GST_CAPS_NEW ( "flac_caps", "audio/raw", diff --git a/ext/flac/gstflacenc.c b/ext/flac/gstflacenc.c index 8167f77687..004a2bb10f 100644 --- a/ext/flac/gstflacenc.c +++ b/ext/flac/gstflacenc.c @@ -100,13 +100,16 @@ gst_flacenc_class_init (FlacEncClass *klass) gobject_class->get_property = gst_flacenc_get_property; } -static void -gst_flacenc_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_flacenc_sinkconnect (GstPad *pad, GstCaps *caps) { FlacEnc *flacenc; flacenc = GST_FLACENC (gst_pad_get_parent (pad)); + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; + flacenc->channels = gst_caps_get_int (caps, "channels"); flacenc->depth = gst_caps_get_int (caps, "depth"); flacenc->sample_rate = gst_caps_get_int (caps, "rate"); @@ -114,6 +117,8 @@ gst_flacenc_newcaps (GstPad *pad, GstCaps *caps) FLAC__stream_encoder_set_bits_per_sample (flacenc->encoder, flacenc->depth); FLAC__stream_encoder_set_sample_rate (flacenc->encoder, flacenc->sample_rate); FLAC__stream_encoder_set_channels (flacenc->encoder, flacenc->channels); + + return GST_PAD_CONNECT_OK; } static void @@ -122,10 +127,9 @@ gst_flacenc_init (FlacEnc *flacenc) flacenc->sinkpad = gst_pad_new_from_template (enc_sink_template, "sink"); gst_element_add_pad(GST_ELEMENT(flacenc),flacenc->sinkpad); gst_pad_set_chain_function(flacenc->sinkpad,gst_flacenc_chain); - gst_pad_set_newcaps_function (flacenc->sinkpad, gst_flacenc_newcaps); + gst_pad_set_connect_function (flacenc->sinkpad, gst_flacenc_sinkconnect); flacenc->srcpad = gst_pad_new_from_template (enc_src_template, "src"); - gst_pad_set_caps (flacenc->srcpad, gst_pad_get_padtemplate_caps (flacenc->srcpad)); gst_element_add_pad(GST_ELEMENT(flacenc),flacenc->srcpad); flacenc->encoder = FLAC__stream_encoder_new(); diff --git a/ext/jpeg/gstjpegdec.c b/ext/jpeg/gstjpegdec.c index 025338fee0..6184d49003 100644 --- a/ext/jpeg/gstjpegdec.c +++ b/ext/jpeg/gstjpegdec.c @@ -173,7 +173,7 @@ gst_jpegdec_chain (GstPad *pad, GstBuffer *buf) jpegdec = GST_JPEGDEC (GST_OBJECT_PARENT (pad)); - if (!GST_PAD_CONNECTED (jpegdec->srcpad)) { + if (!GST_PAD_IS_CONNECTED (jpegdec->srcpad)) { gst_buffer_unref (buf); return; } @@ -220,14 +220,14 @@ gst_jpegdec_chain (GstPad *pad, GstBuffer *buf) jpegdec->line[2] = g_realloc(jpegdec->line[2], height*sizeof(char*)); jpegdec->height = height; - gst_pad_set_caps (jpegdec->srcpad, gst_caps_new ( + gst_pad_try_set_caps (jpegdec->srcpad, + GST_CAPS_NEW ( "jpegdec_caps", "video/raw", - gst_props_new ( - "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')), - "width", GST_PROPS_INT (width), - "height", GST_PROPS_INT (height), - NULL))); + "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('I','4','2','0')), + "width", GST_PROPS_INT (width), + "height", GST_PROPS_INT (height) + )); } /* mind the swap, jpeglib outputs blue chroma first */ 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/ext/mikmod/gstmikmod.c b/ext/mikmod/gstmikmod.c index a2b5038d01..037187fad5 100644 --- a/ext/mikmod/gstmikmod.c +++ b/ext/mikmod/gstmikmod.c @@ -170,9 +170,6 @@ static GstElementStateReturn gst_mikmod_change_state (GstElement *element); -static GstPadNegotiateReturn mikmod_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data); -static GstPadNegotiateReturn mikmod_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data); - static GstElementClass *parent_class = NULL; #define GST_TYPE_MIKMOD_MIXFREQ (gst_mikmod_mixfreq_get_type()) @@ -194,29 +191,6 @@ gst_mikmod_mixfreq_get_type (void) return mikmod_mixfreq_type; } -static GstPadNegotiateReturn -mikmod_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstMikMod* filter = GST_MIKMOD (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps); -} - -static GstPadNegotiateReturn -mikmod_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstMikMod* filter = GST_MIKMOD (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); -} - - GType gst_mikmod_get_type(void) { static GType mikmod_type = 0; @@ -302,6 +276,7 @@ gst_mikmod_class_init (GstMikModClass *klass) gobject_class->set_property = gst_mikmod_set_property; gobject_class->get_property = gst_mikmod_get_property; + gstelement_class->change_state = gst_mikmod_change_state; } @@ -312,15 +287,12 @@ gst_mikmod_init (GstMikMod *filter) filter->sinkpad = gst_pad_new_from_template(mikmod_sink_factory (),"sink"); filter->srcpad = gst_pad_new_from_template(mikmod_src_factory (),"src"); - /*gst_pad_set_negotiate_function(filter->sinkpad,mikmod_negotiate_sink); - gst_pad_set_negotiate_function(filter->srcpad,mikmod_negotiate_src);*/ - gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad); gst_element_set_loop_function (GST_ELEMENT (filter), gst_mikmod_loop); - filter->Buffer = gst_buffer_new(); + filter->Buffer = NULL; filter->stereo = TRUE; filter->surround = TRUE; @@ -351,26 +323,20 @@ gst_mikmod_loop (GstElement *element) srcpad = mikmod->srcpad; mikmod->Buffer = NULL; - while ((buffer_in = gst_pad_pull( mikmod->sinkpad ))) /*&& GST_BUFFER_SIZE(buffer_tmp) != 0 && GST_BUFFER_SIZE(buffer_tmp) != -1 ) */ - { - if ( GST_IS_EVENT (buffer_in) ) - { + while ((buffer_in = gst_pad_pull( mikmod->sinkpad ))) { + if ( GST_IS_EVENT (buffer_in) ) { GstEvent *event = GST_EVENT (buffer_in); - if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) - break; + if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) + break; } - /*if ( GST_BUFFER_SIZE(buffer_in) != 0 && GST_BUFFER_SIZE(buffer_in) != -1 ) - {*/ - if ( mikmod->Buffer ) - { - mikmod->Buffer = gst_buffer_append( mikmod->Buffer, buffer_in ); - gst_buffer_unref( buffer_in ); - } - else - mikmod->Buffer = buffer_in; - /* }*/ + if ( mikmod->Buffer ) { + mikmod->Buffer = gst_buffer_append( mikmod->Buffer, buffer_in ); + gst_buffer_unref( buffer_in ); + } + else + mikmod->Buffer = buffer_in; } if ( mikmod->_16bit ) @@ -385,24 +351,23 @@ gst_mikmod_loop (GstElement *element) reader = GST_READER_new( mikmod ); module = Player_LoadGeneric ( reader, 64, 0 ); + gst_buffer_unref (mikmod->Buffer); + if ( ! Player_Active() ) Player_Start(module); - gst_pad_set_caps (mikmod->srcpad, gst_caps_new ( - "mikmod_src", - "audio/raw", - gst_props_new ( - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (TRUE), - "width", GST_PROPS_INT (mode16bits), - "depth", GST_PROPS_INT (mode16bits), - "rate", GST_PROPS_INT (mikmod->mixfreq), - "channels", GST_PROPS_INT (2), - NULL - ) - )); + gst_pad_try_set_caps (mikmod->srcpad, + GST_CAPS_NEW ( + "mikmod_src", + "audio/raw", + "format", GST_PROPS_STRING ("int"), + "law", GST_PROPS_INT (0), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "signed", GST_PROPS_BOOLEAN (TRUE), + "width", GST_PROPS_INT (mode16bits), + "depth", GST_PROPS_INT (mode16bits), + "rate", GST_PROPS_INT (mikmod->mixfreq), + "channels", GST_PROPS_INT (2))); do { if ( Player_Active() ) { diff --git a/gst/auparse/gstparseau.c b/gst/auparse/gstparseau.c index 782148d7b8..9246658223 100644 --- a/gst/auparse/gstparseau.c +++ b/gst/auparse/gstparseau.c @@ -77,8 +77,7 @@ GST_PADTEMPLATE_FACTORY (src_factory_templ, "auparse_src", "audio/raw", "format", GST_PROPS_STRING ("int"), - //"law", GST_PROPS_INT_RANGE (0, 2), - "law", GST_PROPS_INT (0), + "law", GST_PROPS_INT_RANGE (0, 1), "endianness", GST_PROPS_INT (G_BYTE_ORDER), "signed", GST_PROPS_LIST( GST_PROPS_BOOLEAN (FALSE), @@ -152,7 +151,6 @@ gst_parseau_init (GstParseAu *parseau) { parseau->sinkpad = gst_pad_new_from_template ( GST_PADTEMPLATE_GET (sink_factory_templ), "sink"); - gst_pad_set_caps (parseau->sinkpad, gst_pad_get_padtemplate_caps (parseau->sinkpad)); gst_element_add_pad (GST_ELEMENT (parseau), parseau->sinkpad); gst_pad_set_chain_function (parseau->sinkpad, gst_parseau_chain); @@ -174,6 +172,8 @@ gst_parseau_chain (GstPad *pad, GstBuffer *buf) gchar *data; glong size; GstCaps* tempcaps; + gint law, depth; + gboolean sign; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); @@ -222,38 +222,44 @@ gst_parseau_chain (GstPad *pad, GstBuffer *buf) GST_DEBUG (0, "offset %ld, size %ld, encoding %ld, frequency %ld, channels %ld\n", parseau->offset,parseau->size,parseau->encoding, parseau->frequency,parseau->channels); - - tempcaps = gst_caps_copy (gst_pad_get_padtemplate_caps (parseau->srcpad)); - gst_caps_set (tempcaps, "format", GST_PROPS_STRING ("int")); - gst_caps_set (tempcaps, "rate", GST_PROPS_INT (parseau->frequency)); - gst_caps_set (tempcaps, "channels", GST_PROPS_INT (parseau->channels)); - switch (parseau->encoding) { case 1: - gst_caps_set (tempcaps, "law", GST_PROPS_INT (1)); - gst_caps_set (tempcaps, "depth", GST_PROPS_INT (8)); - gst_caps_set (tempcaps, "width", GST_PROPS_INT (8)); - gst_caps_set (tempcaps, "signed", GST_PROPS_BOOLEAN (FALSE)); + law = 1; + depth = 8; + sign = FALSE; break; case 2: - gst_caps_set (tempcaps, "law", GST_PROPS_INT (0)); - gst_caps_set (tempcaps, "depth", GST_PROPS_INT (8)); - gst_caps_set (tempcaps, "width", GST_PROPS_INT (8)); - gst_caps_set (tempcaps, "signed", GST_PROPS_BOOLEAN (TRUE)); + law = 0; + depth = 8; + sign = TRUE; break; case 3: - gst_caps_set (tempcaps, "law", GST_PROPS_INT (0)); - gst_caps_set (tempcaps, "depth", GST_PROPS_INT (16)); - gst_caps_set (tempcaps, "width", GST_PROPS_INT (16)); - gst_caps_set (tempcaps, "signed", GST_PROPS_BOOLEAN (TRUE)); + law = 0; + depth = 16; + sign = TRUE; break; default: g_warning ("help!, dont know how to deal with this format yet\n"); return; } - gst_pad_set_caps (parseau->srcpad, tempcaps); + tempcaps = GST_CAPS_NEW ("auparse_src", + "audio/raw", + "format", GST_PROPS_STRING ("int"), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "rate", GST_PROPS_INT (parseau->frequency), + "channels", GST_PROPS_INT (parseau->channels), + "law", GST_PROPS_INT (law), + "depth", GST_PROPS_INT (depth), + "width", GST_PROPS_INT (depth), + "signed", GST_PROPS_BOOLEAN (sign)); + + if (!gst_pad_try_set_caps (parseau->srcpad, tempcaps)) { + gst_buffer_unref (buf); + gst_element_error (GST_ELEMENT (parseau), "could not set audio caps"); + return; + } newbuf = gst_buffer_new (); GST_BUFFER_DATA (newbuf) = (gpointer) malloc (size-(parseau->offset)); @@ -266,7 +272,6 @@ gst_parseau_chain (GstPad *pad, GstBuffer *buf) return; } - gst_pad_push (parseau->srcpad, buf); } diff --git a/gst/avi/audiocodecs.c b/gst/avi/audiocodecs.c index 9415055c3f..3414ab7f7b 100644 --- a/gst/avi/audiocodecs.c +++ b/gst/avi/audiocodecs.c @@ -50,19 +50,19 @@ GstPad *gst_avi_decoder_get_audio_srcpad(GstAviDecoder *avi_decoder, guint pad_n switch (strf->format) { case GST_RIFF_WAVE_FORMAT_PCM: newpad = gst_pad_new("audio_00", GST_PAD_SRC); - gst_pad_set_caps (newpad, gst_caps_new ( + gst_pad_try_set_caps (newpad, + GST_CAPS_NEW ( "avidecoder_caps", "audio/raw", - gst_props_new ( - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (TRUE), - "width", GST_PROPS_INT ((gint)strf->size), - "depth", GST_PROPS_INT ((gint)strf->size), - "rate", GST_PROPS_INT ((gint)strf->rate), - "channels", GST_PROPS_INT ((gint)strf->channels), - NULL))); + "format", GST_PROPS_STRING ("int"), + "law", GST_PROPS_INT (0), + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "signed", GST_PROPS_BOOLEAN (TRUE), + "width", GST_PROPS_INT ((gint)strf->size), + "depth", GST_PROPS_INT ((gint)strf->size), + "rate", GST_PROPS_INT ((gint)strf->rate), + "channels", GST_PROPS_INT ((gint)strf->channels) + )); avi_decoder->audio_pad[pad_nr] = newpad; return newpad; diff --git a/gst/avi/gstavidecoder.c b/gst/avi/gstavidecoder.c index 85024139d1..b91473e6a3 100644 --- a/gst/avi/gstavidecoder.c +++ b/gst/avi/gstavidecoder.c @@ -245,10 +245,6 @@ gst_avi_decoder_new_pad (GstElement *element, GstPad *pad, GstAviDecoder *avi_de } if (!new_element && (media_type == AVI_TYPE_VIDEO)) { - gst_pad_disconnect (pad, gst_element_get_pad (type, "sink")); - - new_element = gst_elementfactory_make ("windec", "decoder"); - padname = "src"; } else if (!new_element && (media_type == AVI_TYPE_AUDIO)) { diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c index 6c5888ed9c..1be29e1bea 100644 --- a/gst/avi/gstavidemux.c +++ b/gst/avi/gstavidemux.c @@ -300,10 +300,10 @@ gst_avi_demux_strf_vids (GstAviDemux *avi_demux) GST_PADTEMPLATE_GET (src_video_templ), g_strdup_printf ("video_%02d", avi_demux->num_video_pads)); - gst_pad_set_caps (srcpad, gst_caps_new ( + gst_pad_try_set_caps (srcpad, + GST_CAPS_NEW ( "avidec_video_src", "video/avi", - gst_props_new ( "format", GST_PROPS_STRING ("strf_vids"), "size", GST_PROPS_INT (GUINT32_FROM_LE (strf->size)), "width", GST_PROPS_INT (GUINT32_FROM_LE (strf->width)), @@ -315,8 +315,8 @@ gst_avi_demux_strf_vids (GstAviDemux *avi_demux) "xpels_meter", GST_PROPS_INT (GUINT32_FROM_LE (strf->xpels_meter)), "ypels_meter", GST_PROPS_INT (GUINT32_FROM_LE (strf->ypels_meter)), "num_colors", GST_PROPS_INT (GUINT32_FROM_LE (strf->num_colors)), - "imp_colors", GST_PROPS_INT (GUINT32_FROM_LE (strf->imp_colors)), - NULL))); + "imp_colors", GST_PROPS_INT (GUINT32_FROM_LE (strf->imp_colors)) + )); avi_demux->video_pad[avi_demux->num_video_pads++] = srcpad; gst_element_add_pad (GST_ELEMENT (avi_demux), srcpad); @@ -343,18 +343,18 @@ gst_avi_demux_strf_auds (GstAviDemux *avi_demux) GST_PADTEMPLATE_GET (src_audio_templ), g_strdup_printf ("audio_%02d", avi_demux->num_audio_pads)); - gst_pad_set_caps (srcpad, gst_caps_new ( + gst_pad_try_set_caps (srcpad, + GST_CAPS_NEW ( "avidec_audio_src", "video/avi", - gst_props_new ( "format", GST_PROPS_STRING ("strf_auds"), "fmt", GST_PROPS_INT (GUINT16_FROM_LE (strf->format)), "channels", GST_PROPS_INT (GUINT16_FROM_LE (strf->channels)), "rate", GST_PROPS_INT (GUINT32_FROM_LE (strf->rate)), "av_bps", GST_PROPS_INT (GUINT32_FROM_LE (strf->av_bps)), "blockalign", GST_PROPS_INT (GUINT16_FROM_LE (strf->blockalign)), - "size", GST_PROPS_INT (GUINT16_FROM_LE (strf->size)), - NULL))); + "size", GST_PROPS_INT (GUINT16_FROM_LE (strf->size)) + )); avi_demux->audio_pad[avi_demux->num_audio_pads++] = srcpad; gst_element_add_pad (GST_ELEMENT (avi_demux), srcpad); @@ -383,10 +383,10 @@ gst_avi_demux_strf_iavs (GstAviDemux *avi_demux) GST_PADTEMPLATE_GET (src_video_templ), g_strdup_printf ("video_%02d", avi_demux->num_video_pads)); - gst_pad_set_caps (srcpad, gst_caps_new ( + gst_pad_try_set_caps (srcpad, + GST_CAPS_NEW ( "avidec_iav_src", "video/avi", - gst_props_new ( "format", GST_PROPS_STRING ("strf_iavs"), "DVAAuxSrc", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVAAuxSrc)), "DVAAuxCtl", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVAAuxCtl)), @@ -395,8 +395,8 @@ gst_avi_demux_strf_iavs (GstAviDemux *avi_demux) "DVVAuxSrc", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVVAuxSrc)), "DVVAuxCtl", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVVAuxCtl)), "DVReserved1", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVReserved1)), - "DVReserved2", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVReserved2)), - NULL))); + "DVReserved2", GST_PROPS_INT (GUINT32_FROM_LE (strf->DVReserved2)) + )); avi_demux->video_pad[avi_demux->num_video_pads++] = srcpad; gst_element_add_pad (GST_ELEMENT (avi_demux), srcpad); @@ -460,14 +460,14 @@ gst_avidemux_forall_pads (GstAviDemux *avi_demux, GFunc func, gpointer user_data for(i=0; iaudio_pad[i]; - if (pad && GST_PAD_CONNECTED (pad)) { + if (pad && GST_PAD_IS_CONNECTED (pad)) { (*func) (pad, user_data); } } for(i=0; ivideo_pad[i]; - if (pad && GST_PAD_CONNECTED (pad)) { + if (pad && GST_PAD_IS_CONNECTED (pad)) { (*func) (pad, user_data); } } @@ -595,7 +595,7 @@ gst_avidemux_process_chunk (GstAviDemux *avi_demux, guint64 filepos, GST_DEBUG (0,"gst_avi_demux_chain: tag found %08x size %08x\n", chunkid, *chunksize); - if (GST_PAD_CONNECTED (avi_demux->video_pad[0])) { + if (GST_PAD_IS_CONNECTED (avi_demux->video_pad[0])) { GstBuffer *buf; if (*chunksize) { @@ -626,7 +626,7 @@ gst_avidemux_process_chunk (GstAviDemux *avi_demux, guint64 filepos, GST_DEBUG (0,"gst_avi_demux_chain: tag found %08x size %08x\n", chunkid, *chunksize); - if (GST_PAD_CONNECTED (avi_demux->audio_pad[0])) { + if (GST_PAD_IS_CONNECTED (avi_demux->audio_pad[0])) { GstBuffer *buf; if (*chunksize) { diff --git a/gst/avi/gstavimux.c b/gst/avi/gstavimux.c index c7e81019be..540e2a7b2f 100644 --- a/gst/avi/gstavimux.c +++ b/gst/avi/gstavimux.c @@ -152,8 +152,8 @@ gst_avimux_init (GstAviMux *avimux) avimux->aviheader = g_malloc0 (sizeof (gst_riff_avih)); } -static void -gst_avimux_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_avimux_sinkconnect (GstPad *pad, GstCaps *caps) { GstAviMux *avimux; const gchar* format = gst_caps_get_string (caps, "format"); @@ -161,7 +161,7 @@ gst_avimux_newcaps (GstPad *pad, GstCaps *caps) avimux = GST_AVIMUX (gst_pad_get_parent (pad)); - GST_DEBUG (0, "avimux: newcaps triggered on %s (%d), %s\n", gst_pad_get_name (pad), + GST_DEBUG (0, "avimux: sinkconnect triggered on %s (%d), %s\n", gst_pad_get_name (pad), padnum, format); if (!strncmp (format, "strf_vids", 9)) { @@ -184,6 +184,7 @@ gst_avimux_newcaps (GstPad *pad, GstCaps *caps) else if (!strncmp (format, "strf_auds", 9)) { } + return GST_PAD_CONNECT_OK; } static GstPad* @@ -228,7 +229,7 @@ gst_avimux_request_new_pad (GstElement *element, } gst_pad_set_chain_function (newpad, gst_avimux_chain); - gst_pad_set_newcaps_function (newpad, gst_avimux_newcaps); + gst_pad_set_connect_function (newpad, gst_avimux_sinkconnect); gst_element_add_pad (element, newpad); return newpad; diff --git a/gst/avi/gstavitypes.c b/gst/avi/gstavitypes.c index b43f2a0ceb..e08621302d 100644 --- a/gst/avi/gstavitypes.c +++ b/gst/avi/gstavitypes.c @@ -170,8 +170,8 @@ gst_avi_types_class_init (GstAviTypesClass *klass) gobject_class->get_property = gst_avi_types_get_property; } -static void -gst_avi_types_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_avi_types_sinkconnect (GstPad *pad, GstCaps *caps) { GstAviTypes *avi_types; const gchar *format; @@ -196,6 +196,9 @@ gst_avi_types_newcaps (GstPad *pad, GstCaps *caps) "format", GST_PROPS_STRING ("NTSC"), NULL)); default: + /* else we simply don't convert, and hope there is a native decoder + * available */ + newcaps = caps; break; } } @@ -243,9 +246,11 @@ gst_avi_types_newcaps (GstPad *pad, GstCaps *caps) } if (newcaps) { - gst_pad_set_caps (avi_types->srcpad, newcaps); + gst_pad_try_set_caps (avi_types->srcpad, newcaps); avi_types->type_found = TRUE; + return GST_PAD_CONNECT_OK; } + return GST_PAD_CONNECT_REFUSED; } static void @@ -254,7 +259,7 @@ gst_avi_types_init (GstAviTypes *avi_types) avi_types->sinkpad = gst_pad_new_from_template ( GST_PADTEMPLATE_GET (sink_templ), "sink"); gst_element_add_pad (GST_ELEMENT (avi_types), avi_types->sinkpad); - gst_pad_set_newcaps_function (avi_types->sinkpad, gst_avi_types_newcaps); + gst_pad_set_connect_function (avi_types->sinkpad, gst_avi_types_sinkconnect); gst_pad_set_chain_function (avi_types->sinkpad, gst_avi_types_chain); avi_types->srcpad = gst_pad_new_from_template ( @@ -271,7 +276,7 @@ gst_avi_types_chain (GstPad *pad, GstBuffer *buffer) avi_types = GST_AVI_TYPES (gst_pad_get_parent (pad)); - if (GST_PAD_CONNECTED (avi_types->srcpad)) + if (GST_PAD_IS_CONNECTED (avi_types->srcpad)) gst_pad_push (avi_types->srcpad, buffer); else gst_buffer_unref (buffer); diff --git a/gst/cutter/gstcutter.c b/gst/cutter/gstcutter.c index 48c3439b66..e14da5fe08 100644 --- a/gst/cutter/gstcutter.c +++ b/gst/cutter/gstcutter.c @@ -88,27 +88,6 @@ void gst_cutter_get_caps (GstPad *pad, GstCutter* filter); static GstElementClass *parent_class = NULL; static guint gst_cutter_signals[LAST_SIGNAL] = { 0 }; -static GstPadNegotiateReturn -cutter_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstCutter* filter = GST_CUTTER (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps); -} - -static GstPadNegotiateReturn -cutter_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstCutter* filter = GST_CUTTER (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); -} GType gst_cutter_get_type(void) { @@ -180,9 +159,6 @@ gst_cutter_init (GstCutter *filter) filter->pre_length = 0.2; filter->pre_run_length = 0.0; filter->pre_buffer = NULL; - - gst_pad_set_negotiate_function (filter->sinkpad,cutter_negotiate_sink); - gst_pad_set_negotiate_function (filter->srcpad,cutter_negotiate_src); gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); gst_pad_set_chain_function (filter->sinkpad, gst_cutter_chain); 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/law/alaw-decode.c b/gst/law/alaw-decode.c index 872d533578..23dd608456 100644 --- a/gst/law/alaw-decode.c +++ b/gst/law/alaw-decode.c @@ -46,7 +46,8 @@ static void gst_alawdec_chain (GstPad *pad, GstBuffer *buf); static GstElementClass *parent_class = NULL; //static guint gst_stereo_signals[LAST_SIGNAL] = { 0 }; - +// +/* static GstPadNegotiateReturn alawdec_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) { @@ -65,7 +66,7 @@ alawdec_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) gst_caps_set(tempcaps,"width",GST_PROPS_INT(16)); gst_caps_set(tempcaps,"signed",GST_PROPS_BOOLEAN(TRUE)); - if (gst_pad_set_caps (alawdec->srcpad, tempcaps)) + if (gst_pad_try_set_caps (alawdec->srcpad, tempcaps)) { return GST_PAD_NEGOTIATE_AGREE; } @@ -74,6 +75,7 @@ alawdec_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) return GST_PAD_NEGOTIATE_FAIL; } } +*/ GType gst_alawdec_get_type(void) { @@ -115,7 +117,7 @@ gst_alawdec_init (GstALawDec *alawdec) { alawdec->sinkpad = gst_pad_new_from_template(alawdec_sink_template,"sink"); alawdec->srcpad = gst_pad_new_from_template(alawdec_src_template,"src"); - gst_pad_set_negotiate_function(alawdec->sinkpad, alawdec_negotiate_sink); + //gst_pad_set_negotiate_function(alawdec->sinkpad, alawdec_negotiate_sink); gst_element_add_pad(GST_ELEMENT(alawdec),alawdec->sinkpad); gst_pad_set_chain_function(alawdec->sinkpad,gst_alawdec_chain); diff --git a/gst/law/alaw-encode.c b/gst/law/alaw-encode.c index ab54bd1679..ed4f6851a4 100644 --- a/gst/law/alaw-encode.c +++ b/gst/law/alaw-encode.c @@ -47,6 +47,7 @@ static void gst_alawenc_chain (GstPad *pad, GstBuffer *buf); static GstElementClass *parent_class = NULL; //static guint gst_stereo_signals[LAST_SIGNAL] = { 0 }; +/* static GstPadNegotiateReturn alawenc_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) { @@ -65,7 +66,7 @@ alawenc_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) gst_caps_set(tempcaps,"width",GST_PROPS_INT(8)); gst_caps_set(tempcaps,"signed",GST_PROPS_BOOLEAN(FALSE)); - if (gst_pad_set_caps (alawenc->srcpad, tempcaps)) + if (gst_pad_try_set_caps (alawenc->srcpad, tempcaps)) { return GST_PAD_NEGOTIATE_AGREE; } @@ -74,6 +75,7 @@ alawenc_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) return GST_PAD_NEGOTIATE_FAIL; } } +*/ GType gst_alawenc_get_type(void) { @@ -115,7 +117,7 @@ gst_alawenc_init (GstALawEnc *alawenc) { alawenc->sinkpad = gst_pad_new_from_template(alawenc_sink_template,"sink"); alawenc->srcpad = gst_pad_new_from_template(alawenc_src_template,"src"); - gst_pad_set_negotiate_function(alawenc->sinkpad, alawenc_negotiate_sink); + //gst_pad_set_negotiate_function(alawenc->sinkpad, alawenc_negotiate_sink); gst_element_add_pad(GST_ELEMENT(alawenc),alawenc->sinkpad); gst_pad_set_chain_function(alawenc->sinkpad,gst_alawenc_chain); diff --git a/gst/law/mulaw-decode.c b/gst/law/mulaw-decode.c index d93c6904e6..8e27c8fc3d 100644 --- a/gst/law/mulaw-decode.c +++ b/gst/law/mulaw-decode.c @@ -46,6 +46,7 @@ static void gst_mulawdec_chain (GstPad *pad, GstBuffer *buf); static GstElementClass *parent_class = NULL; //static guint gst_stereo_signals[LAST_SIGNAL] = { 0 }; +/* static GstPadNegotiateReturn mulawdec_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) { @@ -64,7 +65,7 @@ mulawdec_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) gst_caps_set(tempcaps,"width",GST_PROPS_INT(16)); gst_caps_set(tempcaps,"signed",GST_PROPS_BOOLEAN(TRUE)); - if (gst_pad_set_caps (mulawdec->srcpad, tempcaps)) + if (gst_pad_try_set_caps (mulawdec->srcpad, tempcaps)) { return GST_PAD_NEGOTIATE_AGREE; } @@ -73,6 +74,7 @@ mulawdec_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) return GST_PAD_NEGOTIATE_FAIL; } } +*/ GType gst_mulawdec_get_type(void) { @@ -114,7 +116,7 @@ gst_mulawdec_init (GstMuLawDec *mulawdec) { mulawdec->sinkpad = gst_pad_new_from_template(mulawdec_sink_template,"sink"); mulawdec->srcpad = gst_pad_new_from_template(mulawdec_src_template,"src"); - gst_pad_set_negotiate_function(mulawdec->sinkpad, mulawdec_negotiate_sink); + //gst_pad_set_negotiate_function(mulawdec->sinkpad, mulawdec_negotiate_sink); gst_element_add_pad(GST_ELEMENT(mulawdec),mulawdec->sinkpad); gst_pad_set_chain_function(mulawdec->sinkpad,gst_mulawdec_chain); diff --git a/gst/law/mulaw-encode.c b/gst/law/mulaw-encode.c index 40d868d9a0..3c88121c0d 100644 --- a/gst/law/mulaw-encode.c +++ b/gst/law/mulaw-encode.c @@ -46,6 +46,7 @@ static void gst_mulawenc_chain (GstPad *pad, GstBuffer *buf); static GstElementClass *parent_class = NULL; //static guint gst_stereo_signals[LAST_SIGNAL] = { 0 }; +/* static GstPadNegotiateReturn mulawenc_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) { @@ -64,7 +65,7 @@ mulawenc_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) gst_caps_set(tempcaps,"width",GST_PROPS_INT(8)); gst_caps_set(tempcaps,"signed",GST_PROPS_BOOLEAN(FALSE)); - if (gst_pad_set_caps (mulawenc->srcpad, tempcaps)) + if (gst_pad_try_set_caps (mulawenc->srcpad, tempcaps)) { return GST_PAD_NEGOTIATE_AGREE; } @@ -73,6 +74,7 @@ mulawenc_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) return GST_PAD_NEGOTIATE_FAIL; } } +*/ GType gst_mulawenc_get_type(void) { @@ -114,7 +116,7 @@ gst_mulawenc_init (GstMuLawEnc *mulawenc) { mulawenc->sinkpad = gst_pad_new_from_template(mulawenc_sink_template,"sink"); mulawenc->srcpad = gst_pad_new_from_template(mulawenc_src_template,"src"); - gst_pad_set_negotiate_function(mulawenc->sinkpad, mulawenc_negotiate_sink); + //gst_pad_set_negotiate_function(mulawenc->sinkpad, mulawenc_negotiate_sink); gst_element_add_pad(GST_ELEMENT(mulawenc),mulawenc->sinkpad); gst_pad_set_chain_function(mulawenc->sinkpad,gst_mulawenc_chain); diff --git a/gst/level/gstlevel.c b/gst/level/gstlevel.c index cd839a32d5..4b24ce8178 100644 --- a/gst/level/gstlevel.c +++ b/gst/level/gstlevel.c @@ -99,28 +99,6 @@ static void inline gst_level_fast_8bit_chain (gint8* data, gint8** out_data, static GstElementClass *parent_class = NULL; //static guint gst_filter_signals[LAST_SIGNAL] = { 0 }; -static GstPadNegotiateReturn -level_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstLevel* filter = GST_LEVEL (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps); -} - -static GstPadNegotiateReturn -level_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstLevel* filter = GST_LEVEL (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy(pad,filter->srcpad,caps); -} - GType gst_level_get_type(void) { static GType level_type = 0; @@ -162,9 +140,6 @@ gst_level_init (GstLevel *filter) filter->sinkpad = gst_pad_new_from_template(level_sink_factory (),"sink"); filter->srcpad = gst_pad_new_from_template(level_src_factory (),"src"); - gst_pad_set_negotiate_function(filter->sinkpad,level_negotiate_sink); - gst_pad_set_negotiate_function(filter->srcpad,level_negotiate_src); - gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad); gst_pad_set_chain_function(filter->sinkpad,gst_level_chain); filter->srcpad = gst_pad_new("src",GST_PAD_SRC); diff --git a/gst/median/gstmedian.c b/gst/median/gstmedian.c index f0e836afe9..89a9a8c2f7 100644 --- a/gst/median/gstmedian.c +++ b/gst/median/gstmedian.c @@ -80,28 +80,6 @@ static void gst_median_get_property (GObject *object, guint prop_id, GValue *val static GstElementClass *parent_class = NULL; //static guint gst_median_signals[LAST_SIGNAL] = { 0 }; -static GstPadNegotiateReturn -median_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstMedian* filter = GST_MEDIAN (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy (pad, filter->sinkpad, caps); -} - -static GstPadNegotiateReturn -median_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) -{ - GstMedian* filter = GST_MEDIAN (gst_pad_get_parent (pad)); - - if (*caps==NULL) - return GST_PAD_NEGOTIATE_FAIL; - - return gst_pad_negotiate_proxy (pad, filter->srcpad, caps); -} - GType gst_median_get_type (void) { @@ -146,29 +124,32 @@ gst_median_class_init (GstMedianClass *klass) gobject_class->get_property = gst_median_get_property; } -static void -gst_median_newcaps (GstPad *pad, GstCaps *caps) +static gboolean +gst_median_sinkconnect (GstPad *pad, GstCaps *caps) { GstMedian *filter; filter = GST_MEDIAN (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; } void gst_median_init (GstMedian *median) { median->sinkpad = gst_pad_new_from_template ( GST_PADTEMPLATE_GET (median_sink_factory), "sink"); - gst_pad_set_negotiate_function (median->sinkpad, median_negotiate_sink); - gst_pad_set_newcaps_function (median->sinkpad, gst_median_newcaps); + gst_pad_set_connect_function (median->sinkpad, gst_median_sinkconnect); gst_pad_set_chain_function (median->sinkpad, gst_median_chain); gst_element_add_pad (GST_ELEMENT (median), median->sinkpad); median->srcpad = gst_pad_new_from_template ( GST_PADTEMPLATE_GET (median_src_factory), "src"); - gst_pad_set_negotiate_function (median->srcpad, median_negotiate_src); gst_element_add_pad (GST_ELEMENT (median), median->srcpad); median->filtersize = 5; diff --git a/gst/udp/gstudpsink.c b/gst/udp/gstudpsink.c index 81d7a9528c..9d4143e214 100644 --- a/gst/udp/gstudpsink.c +++ b/gst/udp/gstudpsink.c @@ -111,8 +111,8 @@ gst_udpsink_class_init (GstUDPSink *klass) } -static void -gst_udpsink_newcaps (GstPad *pad, GstCaps *caps) +static GstPadConnectReturn +gst_udpsink_sinkconnect (GstPad *pad, GstCaps *caps) { GstUDPSink *udpsink; struct sockaddr_in serv_addr; @@ -127,15 +127,15 @@ gst_udpsink_newcaps (GstPad *pad, GstCaps *caps) fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) { - perror("socket"); - return; + perror("socket"); + return GST_PAD_CONNECT_REFUSED; } memset(&serv_addr, 0, sizeof(serv_addr)); /* its a name rather than an ipnum */ serverhost = gethostbyname(udpsink->host); if (serverhost == (struct hostent *)0) { perror("gethostbyname"); - return; + return GST_PAD_CONNECT_REFUSED; } memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length); @@ -145,7 +145,7 @@ gst_udpsink_newcaps (GstPad *pad, GstCaps *caps) if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) { g_printerr ("udpsink: connect to %s port %d failed: %s\n", udpsink->host, udpsink->port, sys_errlist[errno]); - return; + return GST_PAD_CONNECT_REFUSED; } f = fdopen (dup (fd), "wb"); @@ -159,6 +159,8 @@ gst_udpsink_newcaps (GstPad *pad, GstCaps *caps) fclose (f); close (fd); + + return GST_PAD_CONNECT_OK; } static void @@ -168,7 +170,7 @@ gst_udpsink_init (GstUDPSink *udpsink) udpsink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); gst_element_add_pad (GST_ELEMENT (udpsink), udpsink->sinkpad); gst_pad_set_chain_function (udpsink->sinkpad, gst_udpsink_chain); - gst_pad_set_newcaps_function (udpsink->sinkpad, gst_udpsink_newcaps); + gst_pad_set_connect_function (udpsink->sinkpad, gst_udpsink_sinkconnect); udpsink->host = g_strdup (UDP_DEFAULT_HOST); udpsink->port = UDP_DEFAULT_PORT; diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c index 4400a06427..7bd5df833d 100644 --- a/gst/udp/gstudpsrc.c +++ b/gst/udp/gstudpsrc.c @@ -161,7 +161,7 @@ gst_udpsrc_get (GstPad *pad) doc = xmlParseMemory(buf, ret); caps = gst_caps_load_thyself(doc->xmlRootNode); - gst_pad_set_caps (udpsrc->srcpad, caps); + gst_pad_try_set_caps (udpsrc->srcpad, caps); #endif outbuf = NULL; diff --git a/gst/wavparse/gstwavparse.c b/gst/wavparse/gstwavparse.c index 2e57da8320..fc0e0984c6 100644 --- a/gst/wavparse/gstwavparse.c +++ b/gst/wavparse/gstwavparse.c @@ -256,21 +256,19 @@ gst_parsewav_chain (GstPad *pad, GstBuffer *buf) format = (GstParseWavFormat *)((guchar *) GST_BUFFER_DATA (buf) + fmt->offset); /* set the caps on the src pad */ - gst_pad_set_caps (parsewav->srcpad, gst_caps_new ( - "parsewav_src", - "audio/raw", - gst_props_new ( - "format", GST_PROPS_STRING ("int"), - "law", GST_PROPS_INT (0), //FIXME - "endianness", GST_PROPS_INT (G_BYTE_ORDER), - "signed", GST_PROPS_BOOLEAN (TRUE), //FIXME - "width", GST_PROPS_INT (format->wBitsPerSample), - "depth", GST_PROPS_INT (format->wBitsPerSample), - "rate", GST_PROPS_INT (format->dwSamplesPerSec), - "channels", GST_PROPS_INT (format->wChannels), - NULL - ) - )); + gst_pad_try_set_caps (parsewav->srcpad, + GST_CAPS_NEW ( + "parsewav_src", + "audio/raw", + "format", GST_PROPS_STRING ("int"), + "law", GST_PROPS_INT (0), //FIXME + "endianness", GST_PROPS_INT (G_BYTE_ORDER), + "signed", GST_PROPS_BOOLEAN (TRUE), //FIXME + "width", GST_PROPS_INT (format->wBitsPerSample), + "depth", GST_PROPS_INT (format->wBitsPerSample), + "rate", GST_PROPS_INT (format->dwSamplesPerSec), + "channels", GST_PROPS_INT (format->wChannels) + )); parsewav->bps = format->wBlockAlign; GST_DEBUG (0, "frequency %d, channels %d\n", diff --git a/sys/oss/gstossgst.c b/sys/oss/gstossgst.c index 332f8214b0..ddaecaaa10 100644 --- a/sys/oss/gstossgst.c +++ b/sys/oss/gstossgst.c @@ -276,7 +276,7 @@ gst_ossgst_get (GstPad *pad) cmd.cmd.format.stereo, cmd.cmd.format.rate); - gst_pad_set_caps (ossgst->srcpad, caps); + gst_pad_try_set_caps (ossgst->srcpad, caps); } break; default: diff --git a/sys/oss/gstosssink.c b/sys/oss/gstosssink.c index 5c06d04324..86d07e2810 100644 --- a/sys/oss/gstosssink.c +++ b/sys/oss/gstosssink.c @@ -47,9 +47,9 @@ static void gst_osssink_finalize (GObject *object); static gboolean gst_osssink_open_audio (GstOssSink *sink); static void gst_osssink_close_audio (GstOssSink *sink); -static void gst_osssink_sync_parms (GstOssSink *osssink); +static gboolean gst_osssink_sync_parms (GstOssSink *osssink); static GstElementStateReturn gst_osssink_change_state (GstElement *element); -static GstPadNegotiateReturn gst_osssink_negotiate (GstPad *pad, GstCaps **caps, gpointer *user_data); +static GstPadConnectReturn gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps); static void gst_osssink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); @@ -87,9 +87,9 @@ GST_PADTEMPLATE_FACTORY (osssink_sink_factory, "law", GST_PROPS_INT (0), "endianness", GST_PROPS_INT (G_BYTE_ORDER), "signed", GST_PROPS_LIST ( - GST_PROPS_BOOLEAN (FALSE), - GST_PROPS_BOOLEAN (TRUE) - ), + GST_PROPS_BOOLEAN (FALSE), + GST_PROPS_BOOLEAN (TRUE) + ), "width", GST_PROPS_LIST ( GST_PROPS_INT (8), GST_PROPS_INT (16) @@ -220,7 +220,7 @@ gst_osssink_init (GstOssSink *osssink) osssink->sinkpad = gst_pad_new_from_template ( GST_PADTEMPLATE_GET (osssink_sink_factory), "sink"); gst_element_add_pad (GST_ELEMENT (osssink), osssink->sinkpad); - gst_pad_set_negotiate_function (osssink->sinkpad, gst_osssink_negotiate); + gst_pad_set_connect_function (osssink->sinkpad, gst_osssink_sinkconnect); gst_pad_set_bufferpool_function (osssink->sinkpad, gst_osssink_get_bufferpool); gst_pad_set_chain_function (osssink->sinkpad, gst_osssink_chain); @@ -245,20 +245,22 @@ gst_osssink_init (GstOssSink *osssink) GST_FLAG_SET (osssink, GST_ELEMENT_THREAD_SUGGESTED); } -static gboolean -gst_osssink_parse_caps (GstOssSink *osssink, GstCaps *caps) +static GstPadConnectReturn +gst_osssink_sinkconnect (GstPad *pad, GstCaps *caps) { gint law, endianness, width, depth; gboolean sign; gint format = -1; + GstOssSink *osssink = GST_OSSSINK (gst_pad_get_parent (pad)); - // deal with the case where there are no props... - if (gst_caps_get_props(caps) == NULL) return FALSE; + if (!GST_CAPS_IS_FIXED (caps)) + return GST_PAD_CONNECT_DELAYED; width = gst_caps_get_int (caps, "width"); depth = gst_caps_get_int (caps, "depth"); - if (width != depth) return FALSE; + if (width != depth) + return GST_PAD_CONNECT_REFUSED; law = gst_caps_get_int (caps, "law"); endianness = gst_caps_get_int (caps, "endianness"); @@ -290,69 +292,51 @@ gst_osssink_parse_caps (GstOssSink *osssink, GstCaps *caps) } if (format == -1) - return FALSE; + return GST_PAD_CONNECT_REFUSED; osssink->format = format; osssink->channels = gst_caps_get_int (caps, "channels"); osssink->frequency = gst_caps_get_int (caps, "rate"); - return TRUE; + if (!gst_osssink_sync_parms (osssink)) { + return GST_PAD_CONNECT_REFUSED; + } + + return GST_PAD_CONNECT_OK; } -static GstPadNegotiateReturn -gst_osssink_negotiate (GstPad *pad, GstCaps **caps, gpointer *user_data) -{ - GstOssSink *osssink; - - g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL); - g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_NEGOTIATE_FAIL); - - osssink = GST_OSSSINK (gst_pad_get_parent (pad)); - - GST_INFO (GST_CAT_NEGOTIATION, "osssink: negotiate"); - // we decide - if (user_data == NULL) { - *caps = NULL; - return GST_PAD_NEGOTIATE_TRY; - } - // have we got caps? - else if (*caps) { - - if (gst_osssink_parse_caps (osssink, *caps)) { - gst_osssink_sync_parms (osssink); - - return GST_PAD_NEGOTIATE_AGREE; - } - - // FIXME check if the sound card was really set to these caps, - // else send out another caps.. - - return GST_PAD_NEGOTIATE_FAIL; - } - - return GST_PAD_NEGOTIATE_FAIL; -} - -static void +static gboolean gst_osssink_sync_parms (GstOssSink *osssink) { audio_buf_info ospace; int frag; + gint target_format; + gint target_channels; + gint target_frequency; g_return_if_fail (osssink != NULL); g_return_if_fail (GST_IS_OSSSINK (osssink)); - if (osssink->fd == -1) return; + if (osssink->fd == -1) + return FALSE; if (osssink->fragment >> 16) frag = osssink->fragment; else frag = 0x7FFF0000 | osssink->fragment; + GST_INFO (GST_CAT_PLUGIN_INFO, "osssink: trying to set sound card to %dHz %d bit %s (%08x fragment)", + osssink->frequency, osssink->format, + (osssink->channels == 2) ? "stereo" : "mono",frag); + ioctl (osssink->fd, SNDCTL_DSP_SETFRAGMENT, &frag); ioctl (osssink->fd, SNDCTL_DSP_RESET, 0); + target_format = osssink->format; + target_channels = osssink->channels; + target_frequency = osssink->frequency; + ioctl (osssink->fd, SNDCTL_DSP_SETFMT, &osssink->format); ioctl (osssink->fd, SNDCTL_DSP_CHANNELS, &osssink->channels); ioctl (osssink->fd, SNDCTL_DSP_SPEED, &osssink->frequency); @@ -360,15 +344,26 @@ gst_osssink_sync_parms (GstOssSink *osssink) ioctl (osssink->fd, SNDCTL_DSP_GETBLKSIZE, &frag); ioctl (osssink->fd, SNDCTL_DSP_GETOSPACE, &ospace); - /* - g_warning ("osssink: setting sound card to %dHz %d bit %s (%d bytes buffer, %d fragment)\n", - osssink->frequency, osssink->format, - (osssink->channels == 2) ? "stereo" : "mono", ospace.bytes, frag); - */ - GST_INFO (GST_CAT_PLUGIN_INFO, "osssink: setting sound card to %dHz %d bit %s (%d bytes buffer, %d fragment)", + GST_INFO (GST_CAT_PLUGIN_INFO, "osssink: set sound card to %dHz %d bit %s (%d bytes buffer, %08x fragment)", osssink->frequency, osssink->format, (osssink->channels == 2) ? "stereo" : "mono", ospace.bytes, frag); + gst_element_send_event (GST_ELEMENT (osssink), + gst_event_new_info ("samplerate", GST_PROPS_INT (osssink->frequency), NULL)); + gst_element_send_event (GST_ELEMENT (osssink), + gst_event_new_info ("channels", GST_PROPS_INT (osssink->channels), NULL)); + gst_element_send_event (GST_ELEMENT (osssink), + gst_event_new_info ("bits", GST_PROPS_INT (osssink->format), NULL)); + + if (target_format != osssink->format || + target_channels != osssink->channels || + target_frequency != osssink->frequency) + { + g_warning ("could not configure oss with required parameters, enjoy the noise :)"); + /* we could eventually return FALSE here, or just do some additional tests + * to see that the frequencies don't differ too much etc.. */ + } + return TRUE; } static void @@ -554,7 +549,6 @@ gst_osssink_open_audio (GstOssSink *sink) GST_INFO (GST_CAT_PLUGIN_INFO, "osssink: opened audio (%s) with fd=%d", sink->device, sink->fd); GST_FLAG_SET (sink, GST_OSSSINK_OPEN); - gst_osssink_sync_parms (sink); return TRUE; } diff --git a/sys/oss/gstosssrc.c b/sys/oss/gstosssrc.c index f0f9849222..8bf481446d 100644 --- a/sys/oss/gstosssrc.c +++ b/sys/oss/gstosssrc.c @@ -385,7 +385,7 @@ gst_osssrc_sync_parms (GstOssSrc *osssrc) (osssrc->channels == 2) ? "stereo" : "mono", ispace.bytes, frag); /* set caps on src pad */ - gst_pad_set_caps (osssrc->srcpad, gst_caps_new ( + gst_pad_try_set_caps (osssrc->srcpad, gst_caps_new ( "oss_src", "audio/raw", gst_props_new (