| Stream selection |
| = |
| |
| 1. Problem |
| URIs (that being either a media stream or a media stream plus subtitle) can |
| contain multiple streams of a type (audio, subtitle). A user has to be given |
| the option of selecting one of those streams (or none altogether). |
| |
| 2. Implementation ideas |
| Stream selection, in GStreamer, has to be integrated at the player plugging |
| level, which is (in the case of Totem) playbin. Playbin offers a feature to |
| 'mute' a stream (which means that no processing is done on that stream |
| altogether, saving the decoding step). Currently, playbin will select the |
| first occurrence of a stream type and mute all others. A queue is connected |
| (for pre-roll) to the active stream. What is missing here is a way to change |
| the active stream. |
| Playbin interface - one possible interface could simply consist of a bunch of |
| GObject properties: 'textstream' and 'audiostream', both integer. The number |
| of available streams can be retrieved using the 'stream-info' GObject property. |
| Similar to the 'nstreams' property, we could add utility GObject properties |
| for getting the number of available audio/text streams ('naudiostreams' and |
| 'ntextstreams'). Names of these streams (like language name or so) can be |
| added as an additional GObject property to streaminfo. Some container |
| formats contain such names internally. Alternatively, we could allow those |
| to be user-settable as well (for .sub files). |
| On a set of either of these properties, playbasebin would mute the old |
| selected stream (if any), unmute the newly selected stream (if any) and |
| replug the preroll queue. The queue itself is disabled as well if no new |
| stream was linked. Alternatively, a switch-like element is used, which |
| requires no replugging. Pad disabling/enabling is then enough. This also |
| makes relinking less painful. The switch-like element needs to proxy the |
| active pads' caps. However, since those caps are (in practice) always the |
| same across streams, caps setting will (inside the core) immediately |
| return success. |
| The switch-like element simply works like this: |
| = |
| static void |
| loop_func (GstElement * element) |
| { |
| GList *inpads; |
| GstPad *pad; |
| GstData *data; |
| |
| for (inpads = ..; inpads != NULL; inpads = inpads->next) { |
| pad = inpads->data; |
| if (!GST_PAD_IS_USABLE (pad)) |
| continue; |
| |
| /* you'd also want some way to synchronize the inputs... */ |
| data = gst_pad_pull (pad); |
| if (is_active_pad (pad)) |
| gst_pad_push (srcpad, data); |
| else |
| gst_data_unref (data); |
| } |
| } |
| = |
| It'd require an active-stream property itself, which (when set) takes |
| care of doing renegotiation and so on. Using internal pad linkage is |
| extremely useful here, and requires little code in the switch-like |
| element itself. Note that there is a slight bit of duplication in the |
| playbin interface and the switch-like element interface, but that's "just |
| the way it is". |
| The implemention of the switch-like element could initially be local to |
| playbin, until it has been cleaned up and confirmed to be useful to a |
| wider audience. This allows a lot of experimenting with interfaces because |
| we won't be forced to maintain a stable interface. |
| The current 'switch' element (gst-plugins/gst/switch/) already does a few |
| of those operations, but stream synchronization, re-negotiation on stream |
| changes, internal pad linkage and some other things are completely missing. |
| If we're gonna use this element, it'll need a large overhaul. The choice of |
| writing a new element or using an existing element as basis, and also the |
| choice of whether or not to make this element local to playbin, should be |
| based on technical merits and cost/effect analysis and not on personal |
| pride. |
| |
| Notes: |
| * seamless has the same switch-like element, but it's chain-based. Apart |
| from scheduler considerations, this is a good idea, but limits its use |
| (making either good docs and abuse-prevention [see multifilesrc] or |
| private-to-playbin a prerequisite). |
| * maybe text-* properties need to be renamed to subtitle-*. |
| |
| 3. Written by |
| Ronald S. Bultje <rbultje@ronald.bitfreak.net> - Jan. 2nd, 2005. |