| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "media/filters/audio_renderer_base.h" | 5 #include "media/filters/audio_renderer_base.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "media/base/filter_host.h" | 9 #include "media/base/filter_host.h" |
| 10 #include "media/filters/audio_renderer_algorithm_ola.h" | 10 #include "media/filters/audio_renderer_algorithm_ola.h" |
| 11 | 11 |
| 12 namespace media { | 12 namespace media { |
| 13 | 13 |
| 14 AudioRendererBase::AudioRendererBase() | 14 AudioRendererBase::AudioRendererBase() |
| 15 : state_(kUninitialized), | 15 : state_(kUninitialized), |
| 16 recieved_end_of_stream_(false), |
| 17 rendered_end_of_stream_(false), |
| 16 pending_reads_(0) { | 18 pending_reads_(0) { |
| 17 } | 19 } |
| 18 | 20 |
| 19 AudioRendererBase::~AudioRendererBase() { | 21 AudioRendererBase::~AudioRendererBase() { |
| 20 // Stop() should have been called and |algorithm_| should have been destroyed. | 22 // Stop() should have been called and |algorithm_| should have been destroyed. |
| 21 DCHECK(state_ == kUninitialized || state_ == kStopped); | 23 DCHECK(state_ == kUninitialized || state_ == kStopped); |
| 22 DCHECK(!algorithm_.get()); | 24 DCHECK(!algorithm_.get()); |
| 23 } | 25 } |
| 24 | 26 |
| 25 void AudioRendererBase::Play(FilterCallback* callback) { | 27 void AudioRendererBase::Play(FilterCallback* callback) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 54 | 56 |
| 55 void AudioRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) { | 57 void AudioRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) { |
| 56 AutoLock auto_lock(lock_); | 58 AutoLock auto_lock(lock_); |
| 57 DCHECK_EQ(kPaused, state_); | 59 DCHECK_EQ(kPaused, state_); |
| 58 DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed"; | 60 DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed"; |
| 59 state_ = kSeeking; | 61 state_ = kSeeking; |
| 60 seek_callback_.reset(callback); | 62 seek_callback_.reset(callback); |
| 61 | 63 |
| 62 // Throw away everything and schedule our reads. | 64 // Throw away everything and schedule our reads. |
| 63 last_fill_buffer_time_ = base::TimeDelta(); | 65 last_fill_buffer_time_ = base::TimeDelta(); |
| 66 recieved_end_of_stream_ = false; |
| 67 rendered_end_of_stream_ = false; |
| 64 | 68 |
| 65 // |algorithm_| will request more reads. | 69 // |algorithm_| will request more reads. |
| 66 algorithm_->FlushBuffers(); | 70 algorithm_->FlushBuffers(); |
| 67 } | 71 } |
| 68 | 72 |
| 69 void AudioRendererBase::Initialize(AudioDecoder* decoder, | 73 void AudioRendererBase::Initialize(AudioDecoder* decoder, |
| 70 FilterCallback* callback) { | 74 FilterCallback* callback) { |
| 71 DCHECK(decoder); | 75 DCHECK(decoder); |
| 72 DCHECK(callback); | 76 DCHECK(callback); |
| 73 DCHECK_EQ(kUninitialized, state_); | 77 DCHECK_EQ(kUninitialized, state_); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 sample_rate, | 111 sample_rate, |
| 108 sample_bits, | 112 sample_bits, |
| 109 GetPlaybackRate(), | 113 GetPlaybackRate(), |
| 110 cb); | 114 cb); |
| 111 | 115 |
| 112 // Finally, execute the start callback. | 116 // Finally, execute the start callback. |
| 113 state_ = kPaused; | 117 state_ = kPaused; |
| 114 callback->Run(); | 118 callback->Run(); |
| 115 } | 119 } |
| 116 | 120 |
| 121 bool AudioRendererBase::HasEnded() { |
| 122 AutoLock auto_lock(lock_); |
| 123 if (rendered_end_of_stream_) { |
| 124 DCHECK(algorithm_->IsQueueEmpty()) |
| 125 << "Audio queue should be empty if we have rendered end of stream"; |
| 126 } |
| 127 return recieved_end_of_stream_ && rendered_end_of_stream_; |
| 128 } |
| 129 |
| 117 void AudioRendererBase::OnReadComplete(Buffer* buffer_in) { | 130 void AudioRendererBase::OnReadComplete(Buffer* buffer_in) { |
| 118 AutoLock auto_lock(lock_); | 131 AutoLock auto_lock(lock_); |
| 119 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying); | 132 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying); |
| 120 DCHECK_GT(pending_reads_, 0u); | 133 DCHECK_GT(pending_reads_, 0u); |
| 121 --pending_reads_; | 134 --pending_reads_; |
| 122 | 135 |
| 123 // Don't enqueue an end-of-stream buffer because it has no data. | 136 // Don't enqueue an end-of-stream buffer because it has no data. |
| 124 if (!buffer_in->IsEndOfStream()) { | 137 if (buffer_in->IsEndOfStream()) { |
| 138 recieved_end_of_stream_ = true; |
| 139 } else { |
| 125 // Note: Calling this may schedule more reads. | 140 // Note: Calling this may schedule more reads. |
| 126 algorithm_->EnqueueBuffer(buffer_in); | 141 algorithm_->EnqueueBuffer(buffer_in); |
| 127 } | 142 } |
| 128 | 143 |
| 129 // Check for our preroll complete condition. | 144 // Check for our preroll complete condition. |
| 130 if (state_ == kSeeking) { | 145 if (state_ == kSeeking) { |
| 131 DCHECK(seek_callback_.get()); | 146 DCHECK(seek_callback_.get()); |
| 132 if (algorithm_->IsQueueFull() || buffer_in->IsEndOfStream()) { | 147 if (algorithm_->IsQueueFull() || recieved_end_of_stream_) { |
| 133 // Transition into paused whether we have data in |algorithm_| or not. | 148 // Transition into paused whether we have data in |algorithm_| or not. |
| 134 // FillBuffer() will play silence if there's nothing to fill. | 149 // FillBuffer() will play silence if there's nothing to fill. |
| 135 state_ = kPaused; | 150 state_ = kPaused; |
| 136 seek_callback_->Run(); | 151 seek_callback_->Run(); |
| 137 seek_callback_.reset(); | 152 seek_callback_.reset(); |
| 138 } | 153 } |
| 139 } else if (state_ == kPaused && pending_reads_ == 0) { | 154 } else if (state_ == kPaused && pending_reads_ == 0) { |
| 140 // No more pending reads! We're now officially "paused". | 155 // No more pending reads! We're now officially "paused". |
| 141 if (pause_callback_.get()) { | 156 if (pause_callback_.get()) { |
| 142 pause_callback_->Run(); | 157 pause_callback_->Run(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 167 return dest_written; | 182 return dest_written; |
| 168 } | 183 } |
| 169 | 184 |
| 170 // Save a local copy of last fill buffer time and reset the member. | 185 // Save a local copy of last fill buffer time and reset the member. |
| 171 last_fill_buffer_time = last_fill_buffer_time_; | 186 last_fill_buffer_time = last_fill_buffer_time_; |
| 172 last_fill_buffer_time_ = base::TimeDelta(); | 187 last_fill_buffer_time_ = base::TimeDelta(); |
| 173 | 188 |
| 174 // Do the fill. | 189 // Do the fill. |
| 175 dest_written = algorithm_->FillBuffer(dest, dest_len); | 190 dest_written = algorithm_->FillBuffer(dest, dest_len); |
| 176 | 191 |
| 192 // Check if we finally reached end of stream by emptying |algorithm_|. |
| 193 if (recieved_end_of_stream_ && algorithm_->IsQueueEmpty()) { |
| 194 if (!rendered_end_of_stream_) { |
| 195 rendered_end_of_stream_ = true; |
| 196 host()->NotifyEnded(); |
| 197 } |
| 198 } |
| 199 |
| 177 // Get the current time. | 200 // Get the current time. |
| 178 last_fill_buffer_time_ = algorithm_->GetTime(); | 201 last_fill_buffer_time_ = algorithm_->GetTime(); |
| 179 } | 202 } |
| 180 | 203 |
| 181 // Update the pipeline's time if it was set last time. | 204 // Update the pipeline's time if it was set last time. |
| 182 if (last_fill_buffer_time.InMicroseconds() > 0 && | 205 if (last_fill_buffer_time.InMicroseconds() > 0 && |
| 183 last_fill_buffer_time != last_fill_buffer_time_) { | 206 last_fill_buffer_time != last_fill_buffer_time_) { |
| 184 // Adjust the |last_fill_buffer_time| with the playback delay. | 207 // Adjust the |last_fill_buffer_time| with the playback delay. |
| 185 // TODO(hclam): If there is a playback delay, the pipeline would not be | 208 // TODO(hclam): If there is a playback delay, the pipeline would not be |
| 186 // updated with a correct timestamp when the stream is played at the very | 209 // updated with a correct timestamp when the stream is played at the very |
| (...skipping 30 matching lines...) Expand all Loading... |
| 217 | 240 |
| 218 void AudioRendererBase::SetPlaybackRate(float playback_rate) { | 241 void AudioRendererBase::SetPlaybackRate(float playback_rate) { |
| 219 algorithm_->set_playback_rate(playback_rate); | 242 algorithm_->set_playback_rate(playback_rate); |
| 220 } | 243 } |
| 221 | 244 |
| 222 float AudioRendererBase::GetPlaybackRate() { | 245 float AudioRendererBase::GetPlaybackRate() { |
| 223 return algorithm_->playback_rate(); | 246 return algorithm_->playback_rate(); |
| 224 } | 247 } |
| 225 | 248 |
| 226 } // namespace media | 249 } // namespace media |
| OLD | NEW |