Pause, Change Pids, and Play Again

Eric Montellese eric.montellese at videon-central.com
Thu Dec 20 14:21:51 PST 2012


OK, I think I can probably simplify the question:

For reference, this is my pipeline:
filesrc->typefind->demux->|->vdec->vproc->vsink
                          |->asink (an audio decoder and sink element)

I believe the issue is that the filesrc (basesrc) is pausing because the
demux element is flushing itself and everything downstream.  When filesrc
tries to write to its source, it encounters this unexpected state.  That's
why I am getting this print:

0:00:00.371594153  2298  0x8134408 INFO                 basesrc
gstbasesrc.c:2519:gst_base_src_loop:<source> pausing after gst_pad_push() =
wrong-state

Looking into the basesrc.c source code, it looks like this occurs when the
basesrc is trying to send data to the next element, but it cannot because
that element is not accepting data.  This causes it to call
gst_pad_pause_task().


*So, the very simple question is:  How do I restart a filesrc element after
it has paused its task?*

thanks!
Eric


On Thu, Dec 20, 2012 at 11:03 AM, Eric Montellese <
eric.montellese at videon-central.com> wrote:

> Anyone with any ideas?  Thanks!
>
>
> On Wed, Dec 19, 2012 at 4:20 PM, Eric Montellese <
> eric.montellese at videon-central.com> wrote:
>
>> Note that if I do not call 'flush_start()' and 'flush_stop()', the
>> transition works correctly -- (except that the old audio and video play for
>> a moment after the pause, and that the decoder gets confused by the
>> discontinuity when the pid changes -- so the flush is definitely necessary,
>> I just need to know how to do it in a way that makes gstreamer happy).
>>
>> Your help is appreciated.  Thanks!
>>
>>
>> On Wed, Dec 19, 2012 at 2:40 PM, Eric Montellese <
>> eric.montellese at videon-central.com> wrote:
>>
>>> Hi folks,
>>>
>>> While playing a MPTS stream, I'm trying to pause, swap pids, and start
>>> playing again.  However, when I attempt to do this, the call to
>>> gst_element_set_state(pipeline, GST_STATE_PLAYING) is (usually) not being
>>> honored (and a subsequent call to get_state() does not return).  I believe
>>> that this is likely due to a prerolling issue, but I am unsure how to
>>> resolve it.  The source element is "filesrc," followed by "typefind," but
>>> the rest of the elements are custom plugins.  I said "usually" above,
>>> because on some occasions, playback will resume after a bit of a delay.
>>>
>>>
>>> Here's the order of my attempted steps (error checking hidden for
>>> simpler readability, and calls in-lined):
>>>
>>>
>>>
>>> gst_element_set_state(pipeline, GST_STATE_PAUSED);
>>> gst_element_get_state(pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
>>>
>>>
>>> //<begin code called within the demux element>
>>> //flush upstream and downstream.  (I have also tried only flushing
>>> down-stream as well, with no change in behavior)
>>> GST_OBJECT_LOCK(demux);
>>> gst_pad_push_event (GST_PAD(demux->sink_pad), gst_event_new_flush_start
>>> ());
>>> gst_pad_push_event (GST_PAD(demux->aud_src_pad),
>>> gst_event_new_flush_start ());
>>> gst_pad_push_event (GST_PAD(demux->vid_src_pad),
>>> gst_event_new_flush_start ());
>>> GST_OBJECT_UNLOCK(demux);
>>>
>>> //internally, this modifies the demux filters  (the audio and video
>>> codecs are the same)
>>> reconfigure_filter(demux, demux->filter[FILTER_AUDIO], 0x17dd);
>>> reconfigure_filter(demux, demux->filter[FILTER_VIDEO], 0x17dc);
>>>
>>> GST_OBJECT_LOCK(demux);
>>> gst_pad_push_event (GST_PAD(demux->sink_pad), gst_event_new_flush_stop
>>> ());
>>> gst_pad_push_event (GST_PAD(demux->aud_src_pad),
>>> gst_event_new_flush_stop ());
>>> gst_pad_push_event (GST_PAD(demux->vid_src_pad),
>>> gst_event_new_flush_stop ());
>>> GST_OBJECT_UNLOCK(demux);
>>>
>>> //internally, this sets the pcr pid
>>> demux_ts_set_pcr_pid(demux, 0x17dc));
>>>
>>> //internally, set the demux into the playing state
>>> demux_set_state(smd_element->dev_handle, ISMD_DEV_STATE_PLAY))
>>>
>>> //</end code called within the demux element>
>>>
>>>
>>> gst_element_set_state(pipeline, GST_STATE_PLAYING);
>>> gst_element_get_state(pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
>>>
>>>
>>>
>>>
>>>
>>> As I mentioned, that "get_state()" call never returns and I never see
>>> the GST_STATE_PLAYING event in ANY of the custom elements (all of the
>>> elements are custom except for 'filesrc' and 'typefind')
>>>
>>>
>>> For reference, the pipeline looks like this:
>>>
>>> filesrc->typefind->demux->|->vdec->vproc->vsink
>>>                           |->asink (an audio decoder and sink element)
>>>
>>>
>>>
>>> So what's going on?  This does not appear to be a problem with the
>>> internals of the custom elements, but rather an issue with not making the
>>> gstreamer framework happy.
>>>
>>> If I turn on lots and lots of debug prints, I will sometimes see an INFO
>>> print from the filesrc element saying "wrong-state" , but I also do not see
>>> this print reliably.
>>>
>>>  here's the print:
>>> 0:00:00.906761967  2292  0x8187428 INFO                 basesrc
>>> gstbasesrc.c:2519:gst_base_src_loop:<source> pausing after gst_pad_push() =
>>> wrong-state
>>>
>>> I have also tried adding a 2-second delay between each of the above
>>> calls, to try and narrow down any race conditions, and that *reliably*
>>> makes it not play.  Which is good that it's reliable, but I haven't been
>>> able to figure out yet why it isn't working.
>>>
>>>
>>> Ideas on where to investigate are appreciated, as well as general advice
>>> regarding flushing the pipeline from within a pipeline element.
>>>
>>> Thanks,
>>> Eric
>>>
>>>
>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20121220/d451af96/attachment.html>


More information about the gstreamer-devel mailing list