From: Stefan K. <en...@ho...> - 2009-09-28 14:59:50
|
hi, I'll put some comments inline Alexey Chernov schrieb: > Hello, > > I'm working on a sound editor based on GStreamer and I faced the problem with > deinterleave plugin recently. > Is there project public? > To load and decode file I use pipeline: filesrc, decodebin, audioconvert, > audioresample, deinterleave and then several branches containing queue, > audioconvert and appsink (for the experiment I changed it to fakesink). > > Here's the code of main function: > > GMainLoop* _loop; > > GstElement* _pipeline; > > void load_file(const char* filename) > { > GstElement *source, *decodebin, *audio_convert, *audio_resample, *deint; > GstBus* bus; > > > > if (_loop) > { > g_main_loop_quit(_loop); > g_main_loop_unref(_loop); > } > _loop = g_main_loop_new (NULL, FALSE); > > /* Create gstreamer elements */ > if (_pipeline) > { > gst_element_set_state (_pipeline, GST_STATE_NULL); > gst_object_unref (GST_OBJECT (_pipeline)); > _pipeline=0; > } > _pipeline = gst_pipeline_new("decode_to_app"); > source = gst_element_factory_make("filesrc", "filesrc"); > decodebin = gst_element_factory_make("decodebin", "decode_bin"); > audio_convert = gst_element_factory_make("audioconvert","audio-convert"); > audio_resample = gst_element_factory_make("audioresample","audio-resample"); > deint = gst_element_factory_make("deinterleave", "deint"); > > > if (!_pipeline || !source || !decodebin || !audio_convert || !deint) > { > std::cerr<<"Elements could not be created. Exiting."<<std::endl; > } > > /* Set up the pipeline */ > > /* we set the properties to the source element to receive only rtp packets*/ > g_object_set(G_OBJECT (source), "location", filename, NULL); > > /* we add a message handler */ > bus = gst_pipeline_get_bus (GST_PIPELINE (_pipeline)); > > gst_bus_add_watch (bus, bus_call, this); > gst_object_unref (bus); > > /* we add all elements into the pipeline */ > gst_bin_add_many (GST_BIN (_pipeline), source, decodebin, audio_convert, > audio_resample, deint, NULL); > > /* we link all the elements together */ > link_two_elements(source, decodebin); > link_two_elements(audio_resample, audio_convert); > link_two_elements(audio_convert,deint); > what is link_two_elements() doing differently from gst_element_link()? > > g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (cb_new_pad), > audio_resample); > g_signal_connect (deint, "pad-added", G_CALLBACK (il_new_pad), 0); > > /* Set the pipeline to "playing" state*/ > gst_element_set_state (_pipeline, GST_STATE_PLAYING); > > /* Iterate */ > g_print ("Running...\n"); > g_main_loop_run (_loop); > > /* Out of the main loop, clean up nicely */ > g_print ("Returned, stopping listening\n"); > gst_element_set_state (_pipeline, GST_STATE_NULL); > > g_print ("Deleting pipeline\n"); > gst_object_unref (GST_OBJECT (_pipeline)); > } > > Here's il_new_pad implementation: > > > int _channels=0; > The global channels variable is a bit ugly (and might even be racy).. > void il_new_pad (GstElement *decodebin, GstPad *pad, gpointer data) > { > GstElement* element=0; > if (_pipeline) > { > GstElement *queue, *aconv, *ares, *appsink; > > char* num=itoa(_channels,num,10); > > char* name="queue"; > strcat(name,num); > queue = gst_element_factory_make("queue", name); > There is no need to do that. queue = gst_element_factory_make("queue", NULL); will make a unique name. > char* name="aconv"; > strcat(name,num); > aconv = gst_element_factory_make("audioconvert", name); > > char* name="sink"; > strcat(name,num); > appsink = gst_element_factory_make("fakesink", name); > > gst_bin_add_many (GST_BIN (_pipeline), queue, aconv, appsink, NULL); > Do gst_element_sync_state_with_parent() for each of the new elements. That hopefully fixes the warnings you see. Stefan > link_two_elements(queue, aconv); > link_two_elements(aconv,appsink); > > g_object_set(G_OBJECT (appsink), "sync", FALSE, NULL); > > element=queue; > > ++_channels; > } > > GstCaps *caps; > GstStructure *str; > GstPad *audiopad; > > /* only link once */ > audiopad = gst_element_get_static_pad (element, "sink"); > if (GST_PAD_IS_LINKED (audiopad)) > { > g_object_unref (audiopad); > } > > /* check media type */ > caps = gst_pad_get_caps (pad); > str = gst_caps_get_structure (caps, 0); > if (!g_strrstr (gst_structure_get_name (str), "audio")) > { > std::cerr<<"won't connect!"<<std::endl; > gst_caps_unref (caps); > gst_object_unref (audiopad); > } > gst_caps_unref (caps); > > /* link'n'play */ > gst_pad_link (pad, audiopad); > } > > Everything seem to start OK, il_new_pad procedure works two times (for stereo > file), but then I've got the following messages in console: > > 0:00:01.703963841 5174 0x1d712a0 INFO GST_EVENT > gstpad.c:4675:gst_pad_send_event:<queue0:sink> Received event on flushing pad. > Discarding > > 0:00:01.703978717 5174 0x1d712a0 INFO GST_EVENT > gstpad.c:4675:gst_pad_send_event:<queue1:sink> Received event on flushing pad. > Discarding > > 0:00:01.703995479 5174 0x1d712a0 INFO GST_EVENT > gstpad.c:4675:gst_pad_send_event:<queue0:sink> Received event on flushing pad. > Discarding > > 0:00:01.704007213 5174 0x1d712a0 INFO GST_EVENT > gstpad.c:4675:gst_pad_send_event:<queue1:sink> Received event on flushing pad. > Discarding > > 0:00:01.704021111 5174 0x1d712a0 INFO GST_EVENT > gstpad.c:4675:gst_pad_send_event:<queue0:sink> Received event on flushing pad. > Discarding > > 0:00:01.704032565 5174 0x1d712a0 INFO GST_EVENT > gstpad.c:4675:gst_pad_send_event:<queue1:sink> Received event on flushing pad. > Discarding > > 0:00:01.704047371 5174 0x1d712a0 INFO GST_EVENT > gstpad.c:4675:gst_pad_send_event:<queue0:sink> Received event on flushing pad. > Discarding > > 0:00:01.704058825 5174 0x1d712a0 INFO GST_EVENT > gstpad.c:4675:gst_pad_send_event:<queue1:sink> Received event on flushing pad. > Discarding > > 0:00:01.704073143 5174 0x1d712a0 WARN deinterleave > deinterleave.c:810:gst_deinterleave_process: gst_pad_alloc_buffer() returned > wrong-state > > 0:00:01.704371435 5174 0x1d712a0 WARN deinterleave > deinterleave.c:810:gst_deinterleave_process: gst_pad_alloc_buffer() returned > wrong-state > > 0:00:01.704564057 5174 0x1d712a0 WARN deinterleave > deinterleave.c:810:gst_deinterleave_process: gst_pad_alloc_buffer() returned > wrong-state > > 0:00:01.704730419 5174 0x1d712a0 WARN deinterleave > deinterleave.c:810:gst_deinterleave_process: gst_pad_alloc_buffer() returned > wrong-state > > 0:00:01.704894197 5174 0x1d712a0 WARN deinterleave > deinterleave.c:810:gst_deinterleave_process: gst_pad_alloc_buffer() returned > wrong-state > > 0:00:01.704937428 5174 0x1d712a0 INFO basesrc > gstbasesrc.c:2278:gst_base_src_loop:<filesrc> pausing after gst_pad_push() = > wrong-state > > What was the wrong in my setup? Could you please suggest how can I fix it to > get the proper behavior (that new branch with appsink (fakesink) is added to > pipeline when the new channel is recognized). > > Thank you very much in advance! > > Alexey Chernov > > ------------------------------------------------------------------------------ > Come build with us! The BlackBerry® Developer Conference in SF, CA > is the only developer event you need to attend this year. Jumpstart your > developing skills, take BlackBerry mobile applications to market and stay > ahead of the curve. Join us from November 9-12, 2009. Register now! > http://p.sf.net/sfu/devconf > _______________________________________________ > gstreamer-devel mailing list > gst...@li... > https://lists.sourceforge.net/lists/listinfo/gstreamer-devel > |