This directory contains the
PlayerCore class and related classes. These classes are part of the Fuchsia media player implementation.
PlayerCore is concerned with managing a graph that contains the demux, decoders, renderers and other components that constitute a media player graph. It deals with graph building, priming, timeline control, flushing, end-of-stream and related issues. It aggregates some aspects of the underlying components, leaving other aspects to direct communication between those compenents and the client (
PlayerCore delegates many of its concerns to subordinate segments, each of which manages a subset (segment) of the graph. A
PlayerCore has at most one source segment (defined by the
SourceSegment abstract class) and at most one sink segment (defined by the
SinkSegment abstract class) per medium (audio, video, text, subpicture).
The client creates the segments it wants the player to use and registers them with the player. For example,
PlayerImpl typically wants the player to host a demux, so it will create a
DemuxSourceSegment and register it with the player using
PlayerImpl wants content rendered, so it creates one or more
RendererSinkSegment objects and registers them using
RendererSinkSegment uses the renderer provided to it in its constructor, which means
PlayerImpl has to create that, too. This creates the opportunity for
PlayerImpl to have its own relationship with a renderer that doesn‘t concern the player or the sink segments. For example,
PlayerImpl can control gain on the audio renderer directly and doesn’t need
RendererSinkSegment to help with that. The video renderer reports video geometry and supports the creation of Scenic views, both aspects of its direct relationship with
DemuxSourceSegment is a source segment that hosts a demux. Its job is to add the demux to the graph, enumerate the demux‘s elementary streams for the player and control the demux on behalf of the player. The
DemuxSourceSegment constructor accepts a demux, so
PlayerImpl has to create the demux. This allows
PlayerImpl to decide how it wants to set up the demux and allows
PlayerImpl to have a relationship with the demux that doesn’t involve the player. For example, the player doesn't concern itself with metadata, which
PlayerImpl obtains directly from the demux.
RenderSinkSegment is a sink segment that hosts a renderer. Its job is to add the renderer to the graph and insert whatever type conversion nodes (e.g. decoder) required to convert the elementary stream to a type that the renderer can handle. It also controls the renderer on behalf of the player. The
RenderSinkSegment accepts a renderer, so
PlayerImpl has to create the renderer and can talk to the renderer directly. This allows
PlayerCore to be ignorant of the medium-specific aspects of the renderers. Neither
PlayerCore concern themselves with gain control, view creation or video geometry.
PlayerCore will eventually be dynamic in the sense that it will handle precisely-timed replacement of segments while playback is underway. This will enable features such as gapless transitions from one source to another and gapless rerouting to renderers.
In order to enable routing of elementary streams to multiple renderers concurrently, a new sink segment will be created that aggregates multiple subordinate sink segments. This enables fanout to multiple renderers without complicating the
Currently, the only source segment implemented is
DemuxSourceSegment, which hosts a demux. A new source segment will be implemented that handles FIDL sources that supply separate elementary streams.