Activating pads when adding dynamically before entering PAUSED state

Tony Houghton h at realh.co.uk
Mon Oct 5 18:59:32 UTC 2020


On Thu, 1 Oct 2020 at 00:57, Tim Müller <tim at centricular.com> wrote:

> Hi Tony,
>
> > I've got a simpler question about adding pads dynamically.
> > Apparently, when adding a pad to an element, you should call
> > gst_pad_set_active(pad, TRUE); and examples show this being called
> > before adding the pad. But according to the API this calls its
> > activate virtual function. I would have thought a pad should only be
> > activated when it's at least entering PAUSED state.
>
> PAUSED is an element state, pads only have active/non-active states
> (plus flushing/eos).
>

Right, but shouldn't pads only be active when their elements are PAUSED or
PLAYING?

> And shouldn't you at least wait until the pipeline's push/pull mode
> > has been negotiated?
>
> Pads usually get activated as part of the state change mechanism, when
> elements go from READY to PAUSED state.
>

OK, I'm getting a better understanding of this now, but that seems to be
contradicted in parts of the documentation which say things like "need to
activate the pad before adding
<https://gstreamer.freedesktop.org/documentation/plugin-development/advanced/request.html?gi-language=c>".
Wouldn't that cause problems eg if a source tried to start a push task
before the pipeline was ready to preroll or play? I guess it only needs to
activate it in that example because it adds pads while the pipeline is
running, but wouldn't it be better to activate the new pad immediately
after adding it instead of before?


> When pads get activated, they get activated in a mode, i.e. pull mode
> or push mode.
>
> Figuring out what mode to activate a pad in is part of the pad
> activation / element state change mechanism.
>
> Pipeline state is usually set topologically going element by element
> from sink elements towards source elements. At each point, when an
> element goes from READY to PAUSED state it will activate the pads, and
> in the rare case that the element supports pull mode (mostly only
> parser + demuxers + typefind), it will query the element upstream if it
> also supports pull mode when activating its sink pad(s), and if not
> fall back to push mode.
>
> So the negotiation of the push/pull modes is directly linked to the
> pipeline state change propagation mechanism.
>

 OK. I think I got confused because the information is a bit fragmented
(examples/tutorials, design doc, application manual, plugin writer's guide,
API reference).


> >  What if I want to add a pad before either of those conditions?
>
> Not sure what conditions those are. If you add a pad before the element
> goes to PAUSED it will be activated as part of the state change
> mechanism later. You can activate it already of course, but it would be
> pointless since there's no streaming going on yet.
>

One of the conditions was push/pull negotiation, but now I realise that
didn't make sense because it happens simultaneously to activation. The
other condition is the pipeline going from READY to PAUSED. If it's OK to
activate a pad before that, then a custom activate or activate_mode handler
should check the parent's state and not do anything like start a pushing
task if it isn't PAUSED/PLAYING?


> I'm not entirely sure what you want to achieve exactly to be honest. As
> an application you would typically only activate ghost pads perhaps,
> but usually it's the elements who activate pads at runtime before
> adding them. Pads that the element doesn't know about rarely make sense
> after all.
>

I'm writing a plugin for the HTS protocol (tvheadend). I've written a basic
source for recordings ("htsprecsrc"), which was quite simple, because it
can just copy filesrc's behaviour with open()/read() etc replaced by
corresponding network messages. The payload is an MPEG transport stream,
which tsdemux can handle. If I add URI handling it works in a playbin
(almost?) every time.

The trouble is live TV is handled differently, but it would be handy to be
able to use the same URI scheme. So I moved the URI handling to a manager
element derived from GstBin, which adds an htsprecsrc to itself when it
gets a recording URI (I haven't started writing the live TV support yet),
with a SOMETIMES ghost pad to expose the htsprecsrc's ALWAYS source.

Initially that failed, with an error about the ghost pad not being
activated in pull mode, which I've described in another message. I got rid
of that error by setting a custom activate callback on the ghost pad's
proxy which simply calls activate_mode with pull. Is it OK for the callback
to be that simple, or am I skipping other important functionality. This
sometimes works, under certain conditions, but usually it just freezes
before playback starts. It seems more likely to play successfully if I
increase the logging verbosity, which doesn't help getting to the bottom of
the problem. I seem to have a deadlock depending on a race condition.

I've also tried adding a tsdemux element to my bin, which adds ghost pads
for each pad-added callback on the tsdemux. This is a preferable solution
in the long run I think, but it freezes every time. I get a set of
pad-added callbacks as expected, but it stops there. I've also connected to
the demuxer's no-more-pads signal, but it never arrives.

-- 
TH
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20201005/8c20811c/attachment-0001.htm>


More information about the gstreamer-devel mailing list