blob: b89a5a55d820ea745979acb8334e41264c91da57 [file] [log] [blame]
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.