Chromium Code Reviews| 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..535014ef47e67c0a68c86605aae04dba078983e6 |
| --- /dev/null |
| +++ b/services/media/framework_mojo/audio_track_controller.cc |
| @@ -0,0 +1,154 @@ |
| +// 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 pass hack once c++14 is happening. |
| + StreamType* passed_stream_type = stream_type.release(); |
| + |
| + // Query the track's format capabilities. |
| + audio_track_->Describe( |
| + [this, callback, passed_stream_type, graph, output] |
| + (AudioTrackDescriptorPtr descriptor) { |
| + std::unique_ptr<StreamType> stream_type(passed_stream_type); |
|
johngro
2016/02/23 00:49:42
I think that this is going to leak the passed_stre
dalesat
2016/02/23 20:34:34
I'm really opposed to cluttering the class definit
johngro
2016/02/23 22:11:04
We are not using C++14 yet.
I went ahead and conf
dalesat
2016/02/26 19:36:22
I fixed this by capturing a shared pointer and cha
johngro
2016/02/26 20:36:26
k, works for me. FWIW - if you wanted, you could
|
| + 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( |
| + 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) { |
| + 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); |
| + |
| + 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. |
|
johngro
2016/02/23 00:49:42
So, I need to sit with you and have you explain wh
|
| + 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 |