[MediaRouter] Update MR-2-Extension's PostMessage to return boolean.
[chromium-blink-merge.git] / chromecast / media / cma / pipeline / audio_pipeline_impl.cc
blob006ea820437f9ce537c0779b29433c92dbbd4894
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/media/cma/pipeline/audio_pipeline_impl.h"
7 #include "base/bind.h"
8 #include "chromecast/media/cma/backend/audio_pipeline_device.h"
9 #include "chromecast/media/cma/base/buffering_defs.h"
10 #include "chromecast/media/cma/base/cma_logging.h"
11 #include "chromecast/media/cma/base/coded_frame_provider.h"
12 #include "chromecast/media/cma/base/decoder_config_adapter.h"
13 #include "chromecast/media/cma/pipeline/av_pipeline_impl.h"
14 #include "chromecast/public/media/decoder_config.h"
15 #include "media/base/audio_decoder_config.h"
17 namespace chromecast {
18 namespace media {
20 namespace {
21 const size_t kMaxAudioFrameSize = 32 * 1024;
24 AudioPipelineImpl::AudioPipelineImpl(AudioPipelineDevice* audio_device)
25 : audio_device_(audio_device),
26 weak_factory_(this) {
27 av_pipeline_impl_.reset(new AvPipelineImpl(
28 audio_device_,
29 base::Bind(&AudioPipelineImpl::OnUpdateConfig, base::Unretained(this))));
30 weak_this_ = weak_factory_.GetWeakPtr();
33 AudioPipelineImpl::~AudioPipelineImpl() {
36 void AudioPipelineImpl::SetCodedFrameProvider(
37 scoped_ptr<CodedFrameProvider> frame_provider) {
38 av_pipeline_impl_->SetCodedFrameProvider(
39 frame_provider.Pass(), kAppAudioBufferSize, kMaxAudioFrameSize);
42 void AudioPipelineImpl::SetClient(const AvPipelineClient& client) {
43 audio_client_ = client;
44 av_pipeline_impl_->SetClient(client);
47 bool AudioPipelineImpl::StartPlayingFrom(
48 base::TimeDelta time,
49 const scoped_refptr<BufferingState>& buffering_state) {
50 CMALOG(kLogControl) << "AudioPipelineImpl::StartPlayingFrom t0="
51 << time.InMilliseconds();
53 // Reset the pipeline statistics.
54 previous_stats_ = ::media::PipelineStatistics();
56 // Start playing.
57 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError)
58 return false;
59 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kFlushed);
61 if (!av_pipeline_impl_->StartPlayingFrom(time, buffering_state)) {
62 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kError);
63 return false;
65 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kPlaying);
67 return true;
70 void AudioPipelineImpl::Flush(const ::media::PipelineStatusCB& status_cb) {
71 CMALOG(kLogControl) << "AudioPipelineImpl::Flush";
72 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) {
73 status_cb.Run(::media::PIPELINE_ERROR_ABORT);
74 return;
76 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kPlaying);
77 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushing);
78 av_pipeline_impl_->Flush(
79 base::Bind(&AudioPipelineImpl::OnFlushDone, weak_this_, status_cb));
82 void AudioPipelineImpl::OnFlushDone(
83 const ::media::PipelineStatusCB& status_cb) {
84 CMALOG(kLogControl) << "AudioPipelineImpl::OnFlushDone";
85 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) {
86 status_cb.Run(::media::PIPELINE_ERROR_ABORT);
87 return;
89 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed);
90 status_cb.Run(::media::PIPELINE_OK);
93 void AudioPipelineImpl::Stop() {
94 CMALOG(kLogControl) << "AudioPipelineImpl::Stop";
95 av_pipeline_impl_->Stop();
96 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kStopped);
99 void AudioPipelineImpl::SetCdm(BrowserCdmCast* media_keys) {
100 av_pipeline_impl_->SetCdm(media_keys);
103 void AudioPipelineImpl::Initialize(
104 const ::media::AudioDecoderConfig& audio_config,
105 scoped_ptr<CodedFrameProvider> frame_provider,
106 const ::media::PipelineStatusCB& status_cb) {
107 CMALOG(kLogControl) << "AudioPipelineImpl::Initialize "
108 << audio_config.AsHumanReadableString();
109 if (frame_provider)
110 SetCodedFrameProvider(frame_provider.Pass());
112 DCHECK(audio_config.IsValidConfig());
113 if (!audio_device_->SetConfig(
114 DecoderConfigAdapter::ToCastAudioConfig(kPrimary, audio_config)) ||
115 !av_pipeline_impl_->Initialize()) {
116 status_cb.Run(::media::PIPELINE_ERROR_INITIALIZATION_FAILED);
117 return;
119 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed);
120 status_cb.Run(::media::PIPELINE_OK);
123 void AudioPipelineImpl::SetVolume(float volume) {
124 audio_device_->SetStreamVolumeMultiplier(volume);
127 void AudioPipelineImpl::OnUpdateConfig(
128 StreamId id,
129 const ::media::AudioDecoderConfig& audio_config,
130 const ::media::VideoDecoderConfig& video_config) {
131 if (audio_config.IsValidConfig()) {
132 CMALOG(kLogControl) << "AudioPipelineImpl::OnUpdateConfig id:" << id << " "
133 << audio_config.AsHumanReadableString();
135 bool success = audio_device_->SetConfig(
136 DecoderConfigAdapter::ToCastAudioConfig(id, audio_config));
137 if (!success && !audio_client_.playback_error_cb.is_null())
138 audio_client_.playback_error_cb.Run(::media::PIPELINE_ERROR_DECODE);
142 void AudioPipelineImpl::UpdateStatistics() {
143 if (audio_client_.statistics_cb.is_null())
144 return;
146 MediaComponentDevice::Statistics device_stats;
147 if (!audio_device_->GetStatistics(&device_stats))
148 return;
150 ::media::PipelineStatistics current_stats;
151 current_stats.audio_bytes_decoded = device_stats.decoded_bytes;
153 ::media::PipelineStatistics delta_stats;
154 delta_stats.audio_bytes_decoded =
155 current_stats.audio_bytes_decoded - previous_stats_.audio_bytes_decoded;
157 previous_stats_ = current_stats;
159 audio_client_.statistics_cb.Run(delta_stats);
162 } // namespace media
163 } // namespace chromecast