| Index: services/media/framework/graph.h
|
| diff --git a/services/media/framework/graph.h b/services/media/framework/graph.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..de4e85e087a78b09afb037a854c77ad76240e6be
|
| --- /dev/null
|
| +++ b/services/media/framework/graph.h
|
| @@ -0,0 +1,205 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef SERVICES_MEDIA_FRAMEWORK_GRAPH_H_
|
| +#define SERVICES_MEDIA_FRAMEWORK_GRAPH_H_
|
| +
|
| +#include <list>
|
| +
|
| +#include "services/media/framework/engine.h"
|
| +#include "services/media/framework/refs.h"
|
| +#include "services/media/framework/stages/active_sink_stage.h"
|
| +#include "services/media/framework/stages/active_source_stage.h"
|
| +#include "services/media/framework/stages/multistream_source_stage.h"
|
| +#include "services/media/framework/stages/stage.h"
|
| +#include "services/media/framework/stages/transform_stage.h"
|
| +
|
| +namespace mojo {
|
| +namespace media {
|
| +
|
| +namespace {
|
| +
|
| +// StageCreator::Create creates a stage for a part. DEFINE_STAGE_CREATOR defines
|
| +// a specialization for a particular model/stage type pair. Every new
|
| +// model/stage type pair that's defined will need an entry here.
|
| +template<typename T, typename Enable = void> class StageCreator;
|
| +
|
| +#define DEFINE_STAGE_CREATOR(TModel, TStage) \
|
| +template<typename T> \
|
| +class StageCreator<T, typename std::enable_if< \
|
| + std::is_base_of<TModel, T>::value>::type> { \
|
| + public: \
|
| + static inline Stage* Create(std::shared_ptr<T> t_ptr) { \
|
| + return new TStage(std::shared_ptr<TModel>(t_ptr)); \
|
| + } \
|
| +};
|
| +
|
| +DEFINE_STAGE_CREATOR(MultistreamSource, MultistreamSourceStage);
|
| +DEFINE_STAGE_CREATOR(Transform, TransformStage);
|
| +DEFINE_STAGE_CREATOR(ActiveSource, ActiveSourceStage);
|
| +DEFINE_STAGE_CREATOR(ActiveSink, ActiveSinkStage);
|
| +
|
| +#undef DEFINE_STAGE_CREATOR
|
| +
|
| +} // namespace
|
| +
|
| +//
|
| +// USAGE
|
| +//
|
| +// Graph is a container for sources, sinks and transforms ('parts') connected
|
| +// in a graph. PartRef, InputRef and OutputRef are all
|
| +// references to parts and their inputs and outputs. Graph provides a variety
|
| +// of methods for adding and removing parts and for connecting inputs and
|
| +// outputs to form a graph.
|
| +//
|
| +// The graph isn't thread-safe. If the graph is to be modified and/or
|
| +// interrogated on multiple threads, the caller must provide its own lock
|
| +// to prevent collisions. In this case, the caller must also acquire the same
|
| +// lock when making calls that cause parts to add or remove inputs or outputs.
|
| +//
|
| +// The graph prevents the disconnection of prepared inputs and outputs. Once
|
| +// a connected input/output pair is prepared, it must be unprepared before
|
| +// disconnection. This allows the engine to operate freely over prepared
|
| +// portions of the graph (prepare and unprepare are synchronized with the
|
| +// engine).
|
| +//
|
| +// Parts added to the graph are referenced using shared pointers. The graph
|
| +// holds pointers to the parts it contains, and the application, in many cases,
|
| +// also holds pointers to the parts so it can call methods that are outside the
|
| +// graph's scope. When a part is added, the graph returns a PartRef
|
| +// object, which can be used to reference the part when the graph is modified.
|
| +// PartRef objects can be interrogated to retrieve inputs (as
|
| +// InputRef objects) and outputs (as OutputRef objects).
|
| +//
|
| +// Parts come in various flavors, defined by 'model' abstract classes. The
|
| +// current list of supported models is:
|
| +//
|
| +// ActiveSink - a sink that consumes packets asynchronously
|
| +// ActiveSource - a source that produces packets asynchronously
|
| +// MultistreamSource - a source that produces multiple streams of packets
|
| +// synchronously
|
| +// Transform - a synchronous transform that consumes and produces
|
| +// packets via one input and one output
|
| +//
|
| +// Other models will be defined in the future as needed.
|
| +//
|
| +
|
| +//
|
| +// DESIGN
|
| +//
|
| +// The Graph is implemented as a system of cooperating objects. Of those
|
| +// objects, only the graph itself is of relevance to code that uses Graph and
|
| +// to part implementations. The other objects are:
|
| +//
|
| +// Stage
|
| +// A stage hosts a single part. There are many subclasses of Stage, one for
|
| +// each supported part model. The stage's job is to implement the contract
|
| +// represented by the model so the parts that conform to the model can
|
| +// participate in the operation of the graph. Stages are uniform with respect
|
| +// to how they interact with graph. PartRef references a stage.
|
| +//
|
| +// Input
|
| +// A stage possesses zero or more Input instances. Input objects
|
| +// implement the supply of media into the stage and demand for media signalled
|
| +// upstream. Inputs recieve media from Outputs in the form of packets
|
| +// (type Packet).
|
| +//
|
| +// Output
|
| +// A stage possesses zero or more Output instances. Output objects
|
| +// implement the supply of media output of the stage to a downstream input and
|
| +// demand for media signalled from that input.
|
| +//
|
| +
|
| +// Host for a source, sink or transform.
|
| +class Graph {
|
| + public:
|
| + Graph();
|
| +
|
| + ~Graph();
|
| +
|
| + // Adds a part to the graph.
|
| + template<typename T>
|
| + PartRef Add(std::shared_ptr<T> t_ptr) {
|
| + DCHECK(t_ptr);
|
| + return Add(StageCreator<T>::Create(t_ptr));
|
| + }
|
| +
|
| + // Removes a part from the graph after disconnecting it from other parts.
|
| + void RemovePart(PartRef part);
|
| +
|
| + // Connects an output connector to an input connector. Returns the dowstream
|
| + // part.
|
| + PartRef Connect(const OutputRef& output, const InputRef& input);
|
| +
|
| + // Connects a part with exactly one output to a part with exactly one input.
|
| + // Returns the downstream part.
|
| + PartRef ConnectParts(PartRef upstream_part, PartRef downstream_part);
|
| +
|
| + // Connects an output connector to a part that has exactly one input. Returns
|
| + // the downstream part.
|
| + PartRef ConnectOutputToPart(const OutputRef& output, PartRef downstream_part);
|
| +
|
| + // Connects a part with exactly one output to an input connector. Returns the
|
| + // downstream part.
|
| + PartRef ConnectPartToInput(PartRef upstream_part, const InputRef& input);
|
| +
|
| + // Disconnects an output connector and the input connector to which it's
|
| + // connected.
|
| + void DisconnectOutput(const OutputRef& output);
|
| +
|
| + // Disconnects an input connector and the output connector to which it's
|
| + // connected.
|
| + void DisconnectInput(const InputRef& input);
|
| +
|
| + // Disconnects and removes part and everything connected to it.
|
| + void RemovePartsConnectedToPart(PartRef part);
|
| +
|
| + // Disconnects and removes everything connected to output.
|
| + void RemovePartsConnectedToOutput(const OutputRef& output);
|
| +
|
| + // Disconnects and removes everything connected to input.
|
| + void RemovePartsConnectedToInput(const InputRef& input);
|
| +
|
| + // Adds all the parts in t (which must all have one input and one output) and
|
| + // connects them in sequence to the output connector. Returns the output
|
| + // connector of the last part or the output parameter if it is empty.
|
| + template<typename T>
|
| + OutputRef AddAndConnectAll(OutputRef output, const T& t) {
|
| + for (const auto& element : t) {
|
| + PartRef part = Add(StageCreator<T>::Create(element));
|
| + Connect(output, part.input());
|
| + output = part.output();
|
| + }
|
| + return output;
|
| + }
|
| +
|
| + // Removes all parts from the graph.
|
| + void Reset();
|
| +
|
| + // Prepares the graph for operation.
|
| + void Prepare();
|
| +
|
| + // Prepares the input and everything upstream of it. This method is used to
|
| + // prepare subgraphs added when the rest of the graph is already prepared.
|
| + void PrepareInput(const InputRef& input);
|
| +
|
| + // Primes all the sinks in the graph.
|
| + void PrimeSinks();
|
| +
|
| + private:
|
| + // Adds a stage to the graph.
|
| + PartRef Add(Stage* stage);
|
| +
|
| + std::list<Stage*> stages_;
|
| + std::list<Stage*> sources_;
|
| + std::list<Stage*> sinks_;
|
| +
|
| + Engine engine_;
|
| + Stage::UpdateCallback update_function_;
|
| +};
|
| +
|
| +} // namespace media
|
| +} // namespace mojo
|
| +
|
| +#endif // SERVICES_MEDIA_FRAMEWORK_GRAPH_H_
|
|
|