[gst-devel] Problems with deinterleave plugin
Stefan Kost
ensonic at hora-obscura.de
Mon Sep 28 14:51:36 CEST 2009
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
> gstreamer-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
>
More information about the gstreamer-devel
mailing list