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

Unified Diff: services/media/framework_mojo/audio_track_controller.cc

Issue 1692443002: Motown: Framework parts for mojo transport (producer/consumer/mediapipe) and control (audiotrack). (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Added comments to AudioTrackController::SetRate regarding the proper way to implement it. 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
Index: services/media/framework_mojo/audio_track_controller.cc
diff --git a/services/media/framework_mojo/audio_track_controller.cc b/services/media/framework_mojo/audio_track_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c93a013351b2d585b1aa1d9b781ede9db6be0300
--- /dev/null
+++ b/services/media/framework_mojo/audio_track_controller.cc
@@ -0,0 +1,162 @@
+// 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.
+
+#include <list>
+
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "mojo/services/media/audio/interfaces/audio_server.mojom.h"
+#include "mojo/services/media/audio/interfaces/audio_track.mojom.h"
+#include "mojo/services/media/common/cpp/linear_transform.h"
+#include "mojo/services/media/common/cpp/local_time.h"
+#include "services/media/framework/conversion_pipeline_builder.h"
+#include "services/media/framework_mojo/audio_track_controller.h"
+#include "services/media/framework_mojo/mojo_type_conversions.h"
+
+namespace mojo {
+namespace media {
+
+AudioTrackController::AudioTrackController(
+ const String& url,
+ std::unique_ptr<StreamType> stream_type,
+ Graph* graph,
+ OutputRef output,
+ ApplicationImpl* app,
+ const ConstructorCallback& callback) {
+ DCHECK(stream_type);
+ DCHECK(graph);
+ DCHECK(output);
+ DCHECK(app);
+
+ AudioServerPtr audio_server;
+ app->ConnectToService(url, &audio_server);
+ audio_server->CreateTrack(GetProxy(&audio_track_));
+
+ // TODO(dalesat): Remove capture hack once c++14 is happening.
+ std::shared_ptr<StreamType> captured_stream_type(stream_type.release());
+
+ // Query the track's format capabilities.
+ audio_track_->Describe(
+ [this, callback, captured_stream_type, graph, output]
+ (AudioTrackDescriptorPtr descriptor) {
+ std::unique_ptr<StreamType> producer_stream_type;
+
+ // Add transforms to the pipeline to convert from stream_type to a type
+ // supported by the track.
+ OutputRef out = output;
+ bool result = BuildConversionPipeline(
+ *captured_stream_type,
+ *Convert(descriptor->supported_media_types),
+ graph,
+ &out,
+ &producer_stream_type);
+ if (!result) {
+ // Failed to build conversion pipeline.
+ callback.Run(nullptr);
+ return;
+ }
+
+ switch (producer_stream_type->scheme()) {
+ case StreamType::Scheme::kLpcm:
+ frames_per_second_ =
+ producer_stream_type->lpcm()->frames_per_second();
+ break;
+ case StreamType::Scheme::kCompressedAudio:
+ frames_per_second_ =
+ producer_stream_type->compressed_audio()->frames_per_second();
+ break;
+ default:
+ // Unsupported producer stream type.
+ callback.Run(nullptr);
+ return;
+ }
+
+ AudioTrackConfigurationPtr config = AudioTrackConfiguration::New();
+ config->media_type = Convert(std::move(producer_stream_type));
+
+ audio_track_->Configure(config.Pass(), GetProxy(&pipe_));
+
+ std::shared_ptr<AudioTrackProducer> sink =
+ AudioTrackProducer::Create(pipe_.Pass());
+ graph->ConnectOutputToPart(out, graph->Add(sink));
+ callback.Run(sink);
+ });
+}
+
+AudioTrackController::~AudioTrackController() {}
+
+void AudioTrackController::SetRate(
+ float rate_factor,
+ const SetRateCallback& callback) {
+ // TODO(dalesat): Set the rate at a particular local time to coordinate rate
+ // changes for multiple outputs.
+ // TODO(dalesat): Need to specify the starting media time for seek and for
+ // sources that don't start at zero.
+ if (!rate_control_.is_bound()) {
+ audio_track_->GetRateControl(GetProxy(&rate_control_));
+ }
+
+ LinearTransform::Ratio audio_rate(
+ static_cast<uint32_t>(frames_per_second_ * rate_factor), 1);
+ LinearTransform::Ratio local_time_rate(
+ LocalDuration::period::num,
+ LocalDuration::period::den);
+
+ LinearTransform::Ratio rate;
+ bool success =
+ LinearTransform::Ratio::Compose(local_time_rate, audio_rate, &rate);
+ DCHECK(success)
+ << "LinearTransform::Ratio::Compose reports loss of precision";
+
+ rate_control_->SetRate(rate.numerator, rate.denominator);
+
+ // TODO(dalesat): Replace this with a clock.
+ // The code below produces a transform that translates local time into media
+ // time in nanosecond units. That transform is delivered to the application,
+ // which uses it to implement a progress bar. This is OK for demo purposes,
+ // but we really need a clock rather than this static transform.
+ rate_control_->GetCurrentTransform(
+ [this, callback](TimelineTransformPtr transform) {
+ // Get the frame rate in local duration units.
+ LinearTransform::Ratio audio_rate(frames_per_second_, 1);
+ LinearTransform::Ratio local_time_rate(
+ LocalDuration::period::num,
+ LocalDuration::period::den);
+ LinearTransform::Ratio presentation_rate;
+ bool success = LinearTransform::Ratio::Compose(
+ local_time_rate,
+ audio_rate,
+ &presentation_rate);
+ DCHECK(success)
+ << "LinearTransform::Ratio::Compose reports loss of precision";
+
+ // Create a LinearTransform to translate from presentation units to
+ // local duration units.
+ LinearTransform local_to_presentation(0, presentation_rate, 0);
+
+ // Translate the current transform quad so the presentation time units
+ // are the same as the local time units.
+ success = local_to_presentation.DoReverseTransform(
+ transform->quad->reference_offset,
+ &transform->quad->reference_offset);
+ DCHECK(success)
+ << "LinearTransform::DoReverseTransform reports loss of precision";
+ int64_t presentation_delta;
+ success = local_to_presentation.DoReverseTransform(
+ static_cast<int64_t>(transform->quad->reference_delta),
+ &presentation_delta);
+ DCHECK(success)
+ << "LinearTransform::DoReverseTransform reports loss of precision";
+ transform->quad->reference_delta =
+ static_cast<int32_t>(presentation_delta);
+ LinearTransform::Ratio::Reduce(
+ &transform->quad->reference_delta,
+ &transform->quad->target_delta);
+
+ callback(transform.Clone());
+ });
+}
+
+} // namespace media
+} // namespace mojo
« no previous file with comments | « services/media/framework_mojo/audio_track_controller.h ('k') | services/media/framework_mojo/audio_track_producer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698