Add ability for NetLogLogger to gather data from more than just NetLog
[chromium-blink-merge.git] / chromecast / media / cma / pipeline / audio_pipeline_impl.cc
blob13fd6e05b6eca3d46246d9039987e44285ee2f2c
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/pipeline/av_pipeline_impl.h"
13 #include "media/base/audio_decoder_config.h"
15 namespace chromecast {
16 namespace media {
18 namespace {
19 const size_t kMaxAudioFrameSize = 32 * 1024;
22 AudioPipelineImpl::AudioPipelineImpl(AudioPipelineDevice* audio_device)
23 : audio_device_(audio_device),
24 weak_factory_(this) {
25 av_pipeline_impl_ = new AvPipelineImpl(
26 audio_device_,
27 base::Bind(&AudioPipelineImpl::OnUpdateConfig, base::Unretained(this)));
28 weak_this_ = weak_factory_.GetWeakPtr();
31 AudioPipelineImpl::~AudioPipelineImpl() {
32 av_pipeline_impl_->Finalize();
35 void AudioPipelineImpl::SetCodedFrameProvider(
36 scoped_ptr<CodedFrameProvider> frame_provider) {
37 av_pipeline_impl_->SetCodedFrameProvider(
38 frame_provider.Pass(), kAppAudioBufferSize, kMaxAudioFrameSize);
41 void AudioPipelineImpl::SetClient(const AvPipelineClient& client) {
42 audio_client_ = client;
43 av_pipeline_impl_->SetClient(client);
46 bool AudioPipelineImpl::StartPlayingFrom(
47 base::TimeDelta time,
48 const scoped_refptr<BufferingState>& buffering_state) {
49 CMALOG(kLogControl) << "AudioPipelineImpl::StartPlayingFrom t0="
50 << time.InMilliseconds();
52 // Reset the pipeline statistics.
53 previous_stats_ = ::media::PipelineStatistics();
55 // Start playing.
56 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError)
57 return false;
58 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kFlushed);
60 if (!av_pipeline_impl_->StartPlayingFrom(time, buffering_state)) {
61 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kError);
62 return false;
64 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kPlaying);
66 return true;
69 void AudioPipelineImpl::Flush(const ::media::PipelineStatusCB& status_cb) {
70 CMALOG(kLogControl) << "AudioPipelineImpl::Flush";
71 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) {
72 status_cb.Run(::media::PIPELINE_ERROR_ABORT);
73 return;
75 DCHECK_EQ(av_pipeline_impl_->GetState(), AvPipelineImpl::kPlaying);
76 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushing);
77 av_pipeline_impl_->Flush(
78 base::Bind(&AudioPipelineImpl::OnFlushDone, weak_this_, status_cb));
81 void AudioPipelineImpl::OnFlushDone(
82 const ::media::PipelineStatusCB& status_cb) {
83 CMALOG(kLogControl) << "AudioPipelineImpl::OnFlushDone";
84 if (av_pipeline_impl_->GetState() == AvPipelineImpl::kError) {
85 status_cb.Run(::media::PIPELINE_ERROR_ABORT);
86 return;
88 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed);
89 status_cb.Run(::media::PIPELINE_OK);
92 void AudioPipelineImpl::Stop() {
93 CMALOG(kLogControl) << "AudioPipelineImpl::Stop";
94 av_pipeline_impl_->Stop();
95 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kStopped);
98 void AudioPipelineImpl::SetCdm(BrowserCdmCast* media_keys) {
99 av_pipeline_impl_->SetCdm(media_keys);
102 void AudioPipelineImpl::Initialize(
103 const ::media::AudioDecoderConfig& audio_config,
104 scoped_ptr<CodedFrameProvider> frame_provider,
105 const ::media::PipelineStatusCB& status_cb) {
106 CMALOG(kLogControl) << "AudioPipelineImpl::Initialize "
107 << audio_config.AsHumanReadableString();
108 if (frame_provider)
109 SetCodedFrameProvider(frame_provider.Pass());
111 if (!audio_device_->SetConfig(audio_config) ||
112 !av_pipeline_impl_->Initialize()) {
113 status_cb.Run(::media::PIPELINE_ERROR_INITIALIZATION_FAILED);
114 return;
116 av_pipeline_impl_->TransitionToState(AvPipelineImpl::kFlushed);
117 status_cb.Run(::media::PIPELINE_OK);
120 void AudioPipelineImpl::SetVolume(float volume) {
121 audio_device_->SetStreamVolumeMultiplier(volume);
124 void AudioPipelineImpl::OnUpdateConfig(
125 const ::media::AudioDecoderConfig& audio_config,
126 const ::media::VideoDecoderConfig& video_config) {
127 if (audio_config.IsValidConfig()) {
128 CMALOG(kLogControl) << "AudioPipelineImpl::OnUpdateConfig "
129 << audio_config.AsHumanReadableString();
131 bool success = audio_device_->SetConfig(audio_config);
132 if (!success && !audio_client_.playback_error_cb.is_null())
133 audio_client_.playback_error_cb.Run(::media::PIPELINE_ERROR_DECODE);
137 void AudioPipelineImpl::UpdateStatistics() {
138 if (audio_client_.statistics_cb.is_null())
139 return;
141 MediaComponentDevice::Statistics device_stats;
142 if (!audio_device_->GetStatistics(&device_stats))
143 return;
145 ::media::PipelineStatistics current_stats;
146 current_stats.audio_bytes_decoded = device_stats.decoded_bytes;
148 ::media::PipelineStatistics delta_stats;
149 delta_stats.audio_bytes_decoded =
150 current_stats.audio_bytes_decoded - previous_stats_.audio_bytes_decoded;
152 previous_stats_ = current_stats;
154 audio_client_.statistics_cb.Run(delta_stats);
157 } // namespace media
158 } // namespace chromecast