Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(743)

Unified Diff: services/media/framework/engine.h

Issue 1678433002: Motown: Remove LPCM optimizations, fix prepare, add flush, add ActiveMultistreamSink model/stage (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Sync Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/media/framework/conversion_pipeline_builder.cc ('k') | services/media/framework/engine.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: services/media/framework/engine.h
diff --git a/services/media/framework/engine.h b/services/media/framework/engine.h
index 2ceb0cff127237a0982c94a47c7daa46f5e393b8..55b5ae55a430ef48d6ef8f0a89b594be64782209 100644
--- a/services/media/framework/engine.h
+++ b/services/media/framework/engine.h
@@ -8,98 +8,19 @@
#include <list>
#include <queue>
#include <stack>
+#include <unordered_map>
#include "base/synchronization/lock.h"
-#include "services/media/framework/stages/active_sink_stage.h"
-#include "services/media/framework/stages/active_source_stage.h"
-#include "services/media/framework/stages/distributor_stage.h"
-#include "services/media/framework/stages/lpcm_transform_stage.h"
-#include "services/media/framework/stages/packet_transform_stage.h"
+#include "services/media/framework/refs.h"
#include "services/media/framework/stages/stage.h"
namespace mojo {
namespace media {
//
-// USAGE
-//
-// TODO(dalesat): Consider adding a suffix to Engine::Part/Input/Output to
-// indicate that they're references.
-// TODO(dalesat): Consider folding PrimeSinks into Prepare.
-//
-// Engine is a container for sources, sinks and transforms ('parts') connected
-// in a graph. Engine::Part, Engine::Input and Engine::Output are all opaque
-// references to parts and their inputs and outputs. Engine provides a variety
-// of methods for adding and removing parts and for connecting inputs and
-// outputs to form a graph.
-//
-// In addition to containing parts and representing their interconnection,
-// Engine manages the coordinated operation of its constituent parts and
-// transports media from part to part. The Prepare method prepares the graph
-// for operation, and the PrimeSinks method tells the sinks in the graph to
-// prime themselves. Any additional actions required to make the graph operate
-// (such as manipulating a rate control interface) is out of scope.
-//
-// Parts added to the engine are referenced using shared pointers. The engine
-// 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
-// engine's scope. When a part is added the Engine returns an Engine::Part
-// object, which can be used to reference the part when the graph is modified.
-// Engine::Part objects can be interrogated to retrieve inputs (as Engine::Input
-// objects) and outputs (as Engine::Output objects).
-//
-// Some support is provided for modifying graphs that are operating. This
-// capability isn't fully developed at the moment. Prepare(Part) is an example
-// of a method provided for this purpose.
-//
-// 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
-// LpcmMixer - a transform that mixes LPCM frames from multiple
-// inputs and produces a single stream of LPCM frames
-// via one output
-// LpcmSource - a source that produces LPCM frames synchronously
-// LpcmTransform - a synchronous transform with one LPCM input and
-// one LPCM output
-// MultiStreamPacketSource - a source that produces multiple streams of packets
-// synchronously
-// PacketTransform - 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 Engine is implemented as a system of cooperating objects. Of those
-// objects, only the engine itself is of relevance to code that uses Engine 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 engine. Stages are uniform with respect
-// to how they interact with engine. Engine::Part references a stage.
-//
-// StageInput
-// A stage possesses zero or more StageInput instances. StageInput objects
-// implement the supply of media into the stage and demand for media signalled
-// upstream. StageInputs receive media from StageOutputs in the form of packets
-// (type Packet). LpcmStageInput is a subclass of StageInput that interoperates
-// with LpcmStageInputs in a way that provides optimizations relavant to LPCM
-// audio media. Engine::Input references a StageInput.
-//
-// StageOutput
-// A stage possesses zero or more StageOutput instances. StageOutput objects
-// implement the supply of media output of the stage to a downstream input and
-// demand for media signalled from that input. LpcmStageOutput implements
-// optimized LPCM flow. Engine::Output references a StageOutput.
-//
-// Engine uses a 'work list' algorithm to operate the contained graph. The
+// Engine uses a 'work list' algorithm to operate the graph. The
// engine has a backlog of stages that need to be updated. To advance the
// operation of the graph, the engine removes a stage from the backlog and calls
// the stage's Update method. The Stage::Update may cause stages to be added
@@ -143,7 +64,7 @@ namespace media {
// supply and/or demand.
// 3) Threads used to call update callbacks must be suitable for operating the
// engine. There is currently no affordance for processing other tasks on
-// a thread while the callback is running. A callback may run for a long
+// the thread while the callback is running. A callback may run for a long
// time, depending on how much work needs to be done.
// 4) Parts cannot rely on being called back on the same thread on which they
// invoke update callbacks. This may require additional synchronization and
@@ -161,254 +82,64 @@ namespace media {
// 2) Marshalling update callbacks to a different thread.
//
-// Host for a source, sink or transform.
+// Manages operation of a Graph.
class Engine {
public:
- class Input;
- class Output;
-
- // Opaque Stage pointer used for graph building.
- class Part {
- public:
- Part() : stage_(nullptr) {}
-
- uint32_t input_count();
- Input input(uint32_t index);
- Input input();
- uint32_t output_count();
- Output output(uint32_t index);
- Output output();
- Part upstream_part(uint32_t index);
- Part upstream_part();
- Part downstream_part(uint32_t index);
- Part downstream_part();
-
- private:
- explicit Part(Stage* stage) : stage_(stage) {}
-
- explicit operator bool() const { return stage_ != nullptr; }
-
- Stage* stage_;
-
- friend Engine;
- friend Input;
- friend Output;
- };
-
- // Opaque StageInput pointer used for graph building.
- class Input {
- public:
- Input() : stage_(nullptr), index_(0) {}
-
- explicit operator bool() const { return stage_ != nullptr; }
-
- Part part() { return Part(stage_); }
-
- bool connected() {
- DCHECK(stage_);
- return stage_input().upstream_stage() != nullptr;
- }
-
- Part upstream_part() {
- DCHECK(connected());
- return Part(stage_input().upstream_stage());
- }
-
- private:
- Input(Stage* stage, uint32_t index) :
- stage_(stage), index_(index) {
- DCHECK(stage_);
- DCHECK(index_ < stage_->input_count());
- }
-
- StageInput& stage_input() {
- DCHECK(stage_);
- return stage_->input(index_);
- }
-
- Stage* stage_;
- uint32_t index_;
-
- friend Engine;
- friend Part;
- friend Output;
- };
-
- // Opaque StageOutput pointer used for graph building.
- class Output {
- public:
- Output() : stage_(nullptr), index_(0) {}
-
- explicit operator bool() const { return stage_ != nullptr; }
-
- Part part() { return Part(stage_); }
-
- bool connected() {
- DCHECK(stage_);
- return stage_output().downstream_stage() != nullptr;
- }
-
- Part downstream_part() {
- DCHECK(connected());
- return Part(stage_output().downstream_stage());
- }
-
- private:
- Output(Stage* stage, uint32_t index) :
- stage_(stage), index_(index) {
- DCHECK(stage_);
- DCHECK(index_ < stage_->output_count());
- }
-
- StageOutput& stage_output() {
- DCHECK(stage_);
- return stage_->output(index_);
- }
-
- Stage* stage_;
- uint32_t index_;
-
- friend Engine;
- friend Part;
- friend Input;
- };
-
Engine();
~Engine();
- // Adds a part to the engine.
- template<typename T, typename TBase>
- Part Add(SharedPtr<T, TBase> t) {
- DCHECK(t);
- return Add(CreateStage(std::shared_ptr<TBase>(t)));
- }
-
- // Removes a part from the engine after disconnecting it from other parts.
- void RemovePart(Part part);
-
- // Connects an output connector to an input connector. Returns the dowstream
- // part.
- Part Connect(Output output, Input input);
-
- // Connects a part with exactly one output to a part with exactly one input.
- // Returns the downstream part.
- Part ConnectParts(Part upstream_part, Part downstream_part);
+ // Prepares the input and the subgraph upstream of it.
+ void PrepareInput(const InputRef& input_ref);
- // Connects an output connector to a part that has exactly one input. Returns
- // the downstream part.
- Part ConnectOutputToPart(Output output, Part downstream_part);
+ // Unprepares the input and the subgraph upstream of it.
+ void UnprepareInput(const InputRef& input_ref);
- // Connects a part with exactly one output to an input connector. Returns the
- // downstream part.
- Part ConnectPartToInput(Part upstream_part, Input input);
+ // Flushes the output and the subgraph downstream of it.
+ void FlushOutput(const OutputRef& output_ref);
- // Disconnects an output connector and the input connector to which it's
- // connected.
- void DisconnectOutput(Output output);
+ // Queues the stage for update and winds down the backlog.
+ void RequestUpdate(Stage* stage);
- // Disconnects an input connector and the output connector to which it's
- // connected.
- void DisconnectInput(Input input);
-
- // Disconnects and removes part and everything connected to it.
- void RemovePartsConnectedToPart(Part part);
-
- // Disconnects and removes everything connected to output.
- void RemovePartsConnectedToOutput(Output output);
-
- // Disconnects and removes everything connected to input.
- void RemovePartsConnectedToInput(Input 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>
- Output AddAndConnectAll(
- Output output,
- const T& t) {
- for (auto& element : t) {
- Part part = Add(CreateStage(element));
- Connect(output, part.input());
- output = part.output();
- }
- return output;
- }
-
- // Prepares the engine.
- void Prepare();
-
- // Prepares the part and everything upstream of it. This method is used to
- // prepare subgraphs added when the rest of the graph is already prepared.
- void Prepare(Part part);
-
- // Primes all the sinks in the graph.
- void PrimeSinks();
+ // Pushes the stage to the supply backlog if it isn't already there.
+ void PushToSupplyBacklog(Stage* stage);
- // Removes all parts from the engine.
- void Reset();
+ // Pushes the stage to the demand backlog if it isn't already there.
+ void PushToDemandBacklog(Stage* stage);
private:
- // Adds a stage to the engine.
- Part Add(Stage* stage);
-
- // Disconnects an output.
- void DisconnectOutputUnsafe(Stage* stage, uint32_t index);
-
- // Disconnects an input.
- void DisconnectInputUnsafe(Stage* stage, uint32_t index);
-
- // Removes a stage.
- void RemoveUnsafe(Stage* stage);
-
- // Creates a stage from a source, sink or transform. A specialization of this
- // template is defined for each type of source, sink or transform that can be
- // added to the engine.
- template<typename T>
- static Stage* CreateStage(std::shared_ptr<T> t);
-
- // CreateStage template specialization for MultiStreamPacketSource.
- static Stage* CreateStage(MultiStreamPacketSourcePtr source);
-
- // CreateStage template specialization for PacketTransform.
- static Stage* CreateStage(PacketTransformPtr transform);
-
- // CreateStage template specialization for ActiveSource.
- static Stage* CreateStage(ActiveSourcePtr source);
-
- // CreateStage template specialization for ActiveSink.
- static Stage* CreateStage(ActiveSinkPtr sink);
-
- // CreateStage template specialization for LpcmTransform.
- static Stage* CreateStage(LpcmTransformPtr transform);
-
- // Prepares a stage if all its downstream stages are prepared.
- void MaybePrepareUnsafe(Stage* stage);
+ using UpstreamVisitor = std::function<void(
+ const InputRef& input,
+ const OutputRef& output,
+ const Stage::UpstreamCallback& callback)>;
+ using DownstreamVisitor = std::function<void(
+ const OutputRef& output,
+ const InputRef& input,
+ const Stage::DownstreamCallback& callback)>;
+
+ void VisitUpstream(
+ const InputRef& input,
+ const UpstreamVisitor& vistor);
+
+ void VisitDownstream(
+ const OutputRef& output,
+ const DownstreamVisitor& vistor);
// Processes the entire backlog.
- void UpdateUnsafe();
+ void Update();
// Performs processing for a single stage, updating the backlog accordingly.
- void UpdateUnsafe(Stage *stage);
-
- // Pushes the stage to the supply backlog if it isn't already there.
- void PushToSupplyBacklogUnsafe(Stage* stage);
-
- // Pushes the stage to the demand backlog if it isn't already there.
- void PushToDemandBacklogUnsafe(Stage* stage);
+ void Update(Stage *stage);
// Pops a stage from the supply backlog and returns it or returns nullptr if
// the supply backlog is empty.
- Stage* PopFromSupplyBacklogUnsafe();
+ Stage* PopFromSupplyBacklog();
// Pops a stage from the demand backlog and returns it or returns nullptr if
// the demand backlog is empty.
- Stage* PopFromDemandBacklogUnsafe();
+ Stage* PopFromDemandBacklog();
mutable base::Lock lock_;
- std::list<Stage*> stages_;
- std::list<Stage*> sources_;
- std::list<Stage*> sinks_;
// supply_backlog_ contains pointers to all the stages that have been supplied
// (packets or frames) but have not been updated since. demand_backlog_ does
// the same for demand. The use of queue vs stack here is a guess as to what
@@ -417,16 +148,10 @@ class Engine {
// TODO(dalesat): Determine the best ordering and implement it.
std::queue<Stage*> supply_backlog_;
std::stack<Stage*> demand_backlog_;
- Stage::UpdateCallback update_function_;
bool packets_produced_;
-
- friend class StageInput;
- friend class StageOutput;
- friend class LpcmStageInput;
- friend class LpcmStageOutput;
};
} // namespace media
} // namespace mojo
-#endif // SERVICES_MEDIA_FRAMEWORK_ENGINE_ENGINE_H_
+#endif // SERVICES_MEDIA_FRAMEWORK_ENGINE_H_
« no previous file with comments | « services/media/framework/conversion_pipeline_builder.cc ('k') | services/media/framework/engine.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698