Activating pads when adding dynamically before entering PAUSED state

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Activating pads when adding dynamically before entering PAUSED state

Tony Houghton
Related to my most recent post, 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. And shouldn't you at least wait until the pipeline's push/pull mode has been negotiated? What if I want to add a pad before either of those conditions?

--
TH


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Activating pads when adding dynamically before entering PAUSED state

Tim Müller
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).


> 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.

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.


>  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.

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.

Cheers
 Tim

--
Tim Müller, Centricular Ltd - http://www.centricular.com

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Activating pads when adding dynamically before entering PAUSED state

Tony Houghton

On Thu, 1 Oct 2020 at 00:57, Tim Müller <[hidden email]> 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". 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


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel