| Pad (de)activation |
| ------------------ |
| |
| Activation |
| ~~~~~~~~~~ |
| |
| When changing states, a bin will set the state on all of its children in |
| sink-to-source order. As elements undergo the READY->PAUSED transition, |
| their pads are activated so as to prepare for data flow. Some pads will |
| start tasks to drive the data flow. |
| |
| An element activates its pads from sourcepads to sinkpads. This to make |
| sure that when the sinkpads are activated and ready to accept data, the |
| sourcepads are already active to pass the data downstream. |
| |
| Pads can be activated in one of two modes, PUSH and PULL. PUSH pads are |
| the normal case, where the source pad in a link sends data to the sink |
| pad via gst_pad_push(). PULL pads instead have sink pads request data |
| from the source pads via gst_pad_pull_range(). |
| |
| To activate a pad, the core will call gst_pad_set_active() with a TRUE |
| argument, indicating that the pad should be active. If the pad is |
| already active, be it in a PUSH or PULL mode, gst_pad_set_active() will |
| return without doing anything. Otherwise it will call the activation |
| function of the pad. |
| |
| Because the core does not know in which mode to activate a pad (PUSH or |
| PULL), it delegates that choice to a method on the pad, activate(). The |
| activate() function of a pad should choose whether to operate in PUSH or |
| PULL mode. Once the choice is made, it should call activate_mode() |
| with the selected activation mode. |
| The default activate() function will call activate_mode() with |
| #GST_PAD_MODE_PUSH, as it is the default mechanism for data flow. |
| A sink pad that supports either mode of operation might call |
| activate_mode(PULL) if the SCHEDULING query upstream contains the |
| #GST_PAD_MODE_PULL scheduling mode, and activate_mode(PUSH) otherwise. |
| |
| Consider the case fakesrc ! fakesink, where fakesink is configured to |
| operate in PULL mode. State changes in the pipeline will start with |
| fakesink, which is the most downstream element. The core will call |
| activate() on fakesink's sink pad. For fakesink to go into PULL mode, it |
| needs to implement a custom activate() function that will call |
| activate_mode(PULL) on its sink pad (because the default is to |
| use PUSH mode). activate_mode(PULL) is then responsible for starting |
| the task that pulls from fakesrc:src. Clearly, fakesrc needs to be |
| notified that fakesrc is about to pull on its src pad, even though the |
| pipeline has not yet changed fakesrc's state. For this reason, |
| GStreamer will first call call activate_mode(PULL) on fakesink:sink's |
| peer before calling activate_mode(PULL) on fakesink:sinks. |
| |
| In short, upstream elements operating in PULL mode must be ready to |
| produce data in READY, after having activate_mode(PULL) called on their |
| source pad. Also, a call to activate_mode(PULL) needs to propagate through |
| the pipeline to every pad that a gst_pad_pull() will reach. In the case |
| fakesrc ! identity ! fakesink, calling activate_mode(PULL) on identity's |
| source pad would need to activate its sink pad in pull mode as well, |
| which should propagate all the way to fakesrc. |
| |
| If, on the other hand, fakesrc ! fakesink is operating in PUSH mode, the |
| activation sequence is different. First, activate() on fakesink:sink |
| calls activate_mode(PUSH) on fakesink:sink. Then fakesrc's pads are |
| activated: sources first, then sinks (of which fakesrc has none). |
| fakesrc:src's activation function is then called. |
| |
| Note that it does not make sense to set an activation function on a |
| source pad. The peer of a source pad is downstream, meaning it should |
| have been activated first. If it was activated in PULL mode, the |
| source pad should have already had activate_mode(PULL) called on it, and |
| thus needs no further activation. Otherwise it should be in PUSH mode, |
| which is the choice of the default activation function. |
| |
| So, in the PUSH case, the default activation function chooses PUSH mode, |
| which calls activate_mode(PUSH), which will then start a task on the source |
| pad and begin pushing. In this way PUSH scheduling is a bit easier, |
| because it follows the order of state changes in a pipeline. fakesink is |
| already in PAUSED with an active sink pad by the time fakesrc starts |
| pushing data. |
| |
| Deactivation |
| ~~~~~~~~~~~~ |
| |
| Pad deactivation occurs when its parent goes into the READY state or when the |
| pad is deactivated explicitly by the application or element. |
| gst_pad_set_active() is called with a FALSE argument, which then calls |
| activate_mode(PUSH) or activate_mode(PULL) with a FALSE argument, depending |
| on the current activation mode of the pad. |
| |
| Mode switching |
| ~~~~~~~~~~~~~~ |
| |
| Changing from push to pull modes needs a bit of thought. This is actually |
| possible and implemented but not yet documented here. |
| |