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

Side by Side Diff: chromecast/media/cma/pipeline/audio_pipeline_impl.cc

Issue 1372393007: [Chromecast] Upgrade to new CMA backend API (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Address alokp@ comments Created 5 years, 2 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromecast/media/cma/pipeline/audio_pipeline_impl.h" 5 #include "chromecast/media/cma/pipeline/audio_pipeline_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "chromecast/media/cma/base/buffering_defs.h" 8 #include "chromecast/media/cma/base/buffering_defs.h"
9 #include "chromecast/media/cma/base/cma_logging.h" 9 #include "chromecast/media/cma/base/cma_logging.h"
10 #include "chromecast/media/cma/base/coded_frame_provider.h" 10 #include "chromecast/media/cma/base/coded_frame_provider.h"
11 #include "chromecast/media/cma/base/decoder_config_adapter.h" 11 #include "chromecast/media/cma/base/decoder_config_adapter.h"
12 #include "chromecast/media/cma/pipeline/av_pipeline_impl.h" 12 #include "chromecast/media/cma/pipeline/av_pipeline_impl.h"
13 #include "chromecast/public/media/audio_pipeline_device.h"
14 #include "chromecast/public/media/decoder_config.h" 13 #include "chromecast/public/media/decoder_config.h"
15 #include "media/base/audio_decoder_config.h" 14 #include "media/base/audio_decoder_config.h"
16 15
17 namespace chromecast { 16 namespace chromecast {
18 namespace media { 17 namespace media {
19 18
20 namespace { 19 namespace {
21 const size_t kMaxAudioFrameSize = 32 * 1024; 20 const size_t kMaxAudioFrameSize = 32 * 1024;
22 } 21 }
23 22
24 AudioPipelineImpl::AudioPipelineImpl(AudioPipelineDevice* audio_device) 23 AudioPipelineImpl::AudioPipelineImpl(
25 : audio_device_(audio_device), 24 MediaPipelineBackend::AudioDecoder* decoder,
26 weak_factory_(this) { 25 const AvPipelineClient& client)
26 : decoder_(decoder), audio_client_(client), weak_factory_(this) {
27 av_pipeline_impl_.reset(new AvPipelineImpl( 27 av_pipeline_impl_.reset(new AvPipelineImpl(
28 audio_device_, 28 decoder_,
29 base::Bind(&AudioPipelineImpl::OnUpdateConfig, base::Unretained(this)))); 29 base::Bind(&AudioPipelineImpl::OnUpdateConfig, base::Unretained(this))));
30 weak_this_ = weak_factory_.GetWeakPtr(); 30 weak_this_ = weak_factory_.GetWeakPtr();
31 } 31 }
32 32
33 AudioPipelineImpl::~AudioPipelineImpl() { 33 AudioPipelineImpl::~AudioPipelineImpl() {
34 } 34 }
35 35
36 void AudioPipelineImpl::SetCodedFrameProvider( 36 void AudioPipelineImpl::SetCodedFrameProvider(
37 scoped_ptr<CodedFrameProvider> frame_provider) { 37 scoped_ptr<CodedFrameProvider> frame_provider) {
38 av_pipeline_impl_->SetCodedFrameProvider( 38 av_pipeline_impl_->SetCodedFrameProvider(
39 frame_provider.Pass(), kAppAudioBufferSize, kMaxAudioFrameSize); 39 frame_provider.Pass(), kAppAudioBufferSize, kMaxAudioFrameSize);
40 } 40 }
41 41
42 void AudioPipelineImpl::SetClient(const AvPipelineClient& client) {
43 audio_client_ = client;
44 av_pipeline_impl_->SetClient(client);
45 }
46
47 bool AudioPipelineImpl::StartPlayingFrom( 42 bool AudioPipelineImpl::StartPlayingFrom(
48 base::TimeDelta time, 43 base::TimeDelta time,
49 const scoped_refptr<BufferingState>& buffering_state) { 44 const scoped_refptr<BufferingState>& buffering_state) {
50 CMALOG(kLogControl) << "AudioPipelineImpl::StartPlayingFrom t0=" 45 CMALOG(kLogControl) << __FUNCTION__ << " t0=" << time.InMilliseconds();
51 << time.InMilliseconds();
52 46
53 // Reset the pipeline statistics. 47 // Reset the pipeline statistics.
54 previous_stats_ = ::media::PipelineStatistics(); 48 previous_stats_ = ::media::PipelineStatistics();
55 49
56 // Start playing. 50 // Start playing.
57 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) 51 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError)
58 return false; 52 return false;
59 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kFlushed); 53 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kFlushed);
60 54
61 if (!av_pipeline_impl_->StartPlayingFrom(time, buffering_state)) { 55 if (!av_pipeline_impl_->StartPlayingFrom(time, buffering_state)) {
62 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kError); 56 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kError);
63 return false; 57 return false;
64 } 58 }
65 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kPlaying); 59 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kPlaying);
66 60
67 return true; 61 return true;
68 } 62 }
69 63
70 void AudioPipelineImpl::Flush(const ::media::PipelineStatusCB& status_cb) { 64 void AudioPipelineImpl::Flush(const ::media::PipelineStatusCB& status_cb) {
71 CMALOG(kLogControl) << "AudioPipelineImpl::Flush"; 65 CMALOG(kLogControl) << __FUNCTION__;
72 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) { 66 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) {
73 status_cb.Run(::media::PIPELINE_ERROR_ABORT); 67 status_cb.Run(::media::PIPELINE_ERROR_ABORT);
74 return; 68 return;
75 } 69 }
76 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kPlaying); 70 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kPlaying);
77 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushing); 71 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushing);
78 av_pipeline_impl_->Flush( 72 av_pipeline_impl_->Flush(
79 base::Bind(&AudioPipelineImpl::OnFlushDone, weak_this_, status_cb)); 73 base::Bind(&AudioPipelineImpl::OnFlushDone, weak_this_, status_cb));
80 } 74 }
81 75
82 void AudioPipelineImpl::OnFlushDone( 76 void AudioPipelineImpl::OnFlushDone(
83 const ::media::PipelineStatusCB& status_cb) { 77 const ::media::PipelineStatusCB& status_cb) {
84 CMALOG(kLogControl) << "AudioPipelineImpl::OnFlushDone"; 78 CMALOG(kLogControl) << __FUNCTION__;
85 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) { 79 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) {
86 status_cb.Run(::media::PIPELINE_ERROR_ABORT); 80 status_cb.Run(::media::PIPELINE_ERROR_ABORT);
87 return; 81 return;
88 } 82 }
89 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed); 83 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed);
90 status_cb.Run(::media::PIPELINE_OK); 84 status_cb.Run(::media::PIPELINE_OK);
91 } 85 }
92 86
93 void AudioPipelineImpl::Stop() { 87 void AudioPipelineImpl::Stop() {
94 CMALOG(kLogControl) << "AudioPipelineImpl::Stop"; 88 CMALOG(kLogControl) << __FUNCTION__;
95 av_pipeline_impl_->Stop(); 89 av_pipeline_impl_->Stop();
96 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kStopped); 90 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kStopped);
97 } 91 }
98 92
99 void AudioPipelineImpl::SetCdm(BrowserCdmCast* media_keys) { 93 void AudioPipelineImpl::SetCdm(BrowserCdmCast* media_keys) {
100 av_pipeline_impl_->SetCdm(media_keys); 94 av_pipeline_impl_->SetCdm(media_keys);
101 } 95 }
102 96
103 void AudioPipelineImpl::Initialize( 97 void AudioPipelineImpl::Initialize(
104 const ::media::AudioDecoderConfig& audio_config, 98 const ::media::AudioDecoderConfig& audio_config,
105 scoped_ptr<CodedFrameProvider> frame_provider, 99 scoped_ptr<CodedFrameProvider> frame_provider,
106 const ::media::PipelineStatusCB& status_cb) { 100 const ::media::PipelineStatusCB& status_cb) {
107 CMALOG(kLogControl) << "AudioPipelineImpl::Initialize " 101 CMALOG(kLogControl) << __FUNCTION__ << " "
108 << audio_config.AsHumanReadableString(); 102 << audio_config.AsHumanReadableString();
109 if (frame_provider) 103 if (frame_provider)
110 SetCodedFrameProvider(frame_provider.Pass()); 104 SetCodedFrameProvider(frame_provider.Pass());
111 105
112 DCHECK(audio_config.IsValidConfig()); 106 DCHECK(audio_config.IsValidConfig());
113 if (!audio_device_->SetConfig( 107 if (!decoder_->SetConfig(
114 DecoderConfigAdapter::ToCastAudioConfig(kPrimary, audio_config)) || 108 DecoderConfigAdapter::ToCastAudioConfig(kPrimary, audio_config))) {
115 !av_pipeline_impl_->Initialize()) {
116 status_cb.Run(::media::PIPELINE_ERROR_INITIALIZATION_FAILED); 109 status_cb.Run(::media::PIPELINE_ERROR_INITIALIZATION_FAILED);
117 return; 110 return;
118 } 111 }
119 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed); 112 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed);
120 status_cb.Run(::media::PIPELINE_OK); 113 status_cb.Run(::media::PIPELINE_OK);
121 } 114 }
122 115
123 void AudioPipelineImpl::SetVolume(float volume) { 116 void AudioPipelineImpl::SetVolume(float volume) {
124 audio_device_->SetStreamVolumeMultiplier(volume); 117 decoder_->SetVolume(volume);
118 }
119
120 void AudioPipelineImpl::OnBufferPushed(
121 MediaPipelineBackend::BufferStatus status) {
122 av_pipeline_impl_->OnBufferPushed(status);
123 }
124
125 void AudioPipelineImpl::OnEndOfStream() {
126 if (!audio_client_.eos_cb.is_null())
127 audio_client_.eos_cb.Run();
128 }
129
130 void AudioPipelineImpl::OnError() {
131 if (!audio_client_.playback_error_cb.is_null()) {
132 audio_client_.playback_error_cb.Run(
133 ::media::PIPELINE_ERROR_COULD_NOT_RENDER);
134 }
125 } 135 }
126 136
127 void AudioPipelineImpl::OnUpdateConfig( 137 void AudioPipelineImpl::OnUpdateConfig(
128 StreamId id, 138 StreamId id,
129 const ::media::AudioDecoderConfig& audio_config, 139 const ::media::AudioDecoderConfig& audio_config,
130 const ::media::VideoDecoderConfig& video_config) { 140 const ::media::VideoDecoderConfig& video_config) {
131 if (audio_config.IsValidConfig()) { 141 if (audio_config.IsValidConfig()) {
132 CMALOG(kLogControl) << "AudioPipelineImpl::OnUpdateConfig id:" << id << " " 142 CMALOG(kLogControl) << __FUNCTION__ << " id:" << id << " "
133 << audio_config.AsHumanReadableString(); 143 << audio_config.AsHumanReadableString();
134 144
135 bool success = audio_device_->SetConfig( 145 bool success = decoder_->SetConfig(
136 DecoderConfigAdapter::ToCastAudioConfig(id, audio_config)); 146 DecoderConfigAdapter::ToCastAudioConfig(id, audio_config));
137 if (!success && !audio_client_.playback_error_cb.is_null()) 147 if (!success && !audio_client_.playback_error_cb.is_null())
138 audio_client_.playback_error_cb.Run(::media::PIPELINE_ERROR_DECODE); 148 audio_client_.playback_error_cb.Run(::media::PIPELINE_ERROR_DECODE);
139 } 149 }
140 } 150 }
141 151
142 void AudioPipelineImpl::UpdateStatistics() { 152 void AudioPipelineImpl::UpdateStatistics() {
143 if (audio_client_.statistics_cb.is_null()) 153 if (audio_client_.statistics_cb.is_null())
144 return; 154 return;
145 155
146 MediaComponentDevice::Statistics device_stats; 156 MediaPipelineBackend::Decoder::Statistics device_stats;
147 if (!audio_device_->GetStatistics(&device_stats)) 157 decoder_->GetStatistics(&device_stats);
148 return;
149 158
150 ::media::PipelineStatistics current_stats; 159 ::media::PipelineStatistics current_stats;
151 current_stats.audio_bytes_decoded = device_stats.decoded_bytes; 160 current_stats.audio_bytes_decoded = device_stats.decoded_bytes;
152 161
153 ::media::PipelineStatistics delta_stats; 162 ::media::PipelineStatistics delta_stats;
154 delta_stats.audio_bytes_decoded = 163 delta_stats.audio_bytes_decoded =
155 current_stats.audio_bytes_decoded - previous_stats_.audio_bytes_decoded; 164 current_stats.audio_bytes_decoded - previous_stats_.audio_bytes_decoded;
156 165
157 previous_stats_ = current_stats; 166 previous_stats_ = current_stats;
158 167
159 audio_client_.statistics_cb.Run(delta_stats); 168 audio_client_.statistics_cb.Run(delta_stats);
160 } 169 }
161 170
162 } // namespace media 171 } // namespace media
163 } // namespace chromecast 172 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698