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_ |