| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 pending_reads_(0) { | 21 pending_reads_(0) { |
| 22 } | 22 } |
| 23 | 23 |
| 24 AudioRendererBase::~AudioRendererBase() { | 24 AudioRendererBase::~AudioRendererBase() { |
| 25 // Stop() should have been called and |algorithm_| should have been destroyed. | 25 // Stop() should have been called and |algorithm_| should have been destroyed. |
| 26 DCHECK(state_ == kUninitialized || state_ == kStopped); | 26 DCHECK(state_ == kUninitialized || state_ == kStopped); |
| 27 DCHECK(!algorithm_.get()); | 27 DCHECK(!algorithm_.get()); |
| 28 } | 28 } |
| 29 | 29 |
| 30 void AudioRendererBase::Play(FilterCallback* callback) { | 30 void AudioRendererBase::Play(FilterCallback* callback) { |
| 31 AutoLock auto_lock(lock_); | 31 base::AutoLock auto_lock(lock_); |
| 32 DCHECK_EQ(kPaused, state_); | 32 DCHECK_EQ(kPaused, state_); |
| 33 scoped_ptr<FilterCallback> c(callback); | 33 scoped_ptr<FilterCallback> c(callback); |
| 34 state_ = kPlaying; | 34 state_ = kPlaying; |
| 35 callback->Run(); | 35 callback->Run(); |
| 36 } | 36 } |
| 37 | 37 |
| 38 void AudioRendererBase::Pause(FilterCallback* callback) { | 38 void AudioRendererBase::Pause(FilterCallback* callback) { |
| 39 AutoLock auto_lock(lock_); | 39 base::AutoLock auto_lock(lock_); |
| 40 DCHECK_EQ(kPlaying, state_); | 40 DCHECK_EQ(kPlaying, state_); |
| 41 pause_callback_.reset(callback); | 41 pause_callback_.reset(callback); |
| 42 state_ = kPaused; | 42 state_ = kPaused; |
| 43 | 43 |
| 44 // We'll only pause when we've finished all pending reads. | 44 // We'll only pause when we've finished all pending reads. |
| 45 if (pending_reads_ == 0) { | 45 if (pending_reads_ == 0) { |
| 46 pause_callback_->Run(); | 46 pause_callback_->Run(); |
| 47 pause_callback_.reset(); | 47 pause_callback_.reset(); |
| 48 } else { | 48 } else { |
| 49 state_ = kPaused; | 49 state_ = kPaused; |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 void AudioRendererBase::Stop(FilterCallback* callback) { | 53 void AudioRendererBase::Stop(FilterCallback* callback) { |
| 54 OnStop(); | 54 OnStop(); |
| 55 { | 55 { |
| 56 AutoLock auto_lock(lock_); | 56 base::AutoLock auto_lock(lock_); |
| 57 state_ = kStopped; | 57 state_ = kStopped; |
| 58 algorithm_.reset(NULL); | 58 algorithm_.reset(NULL); |
| 59 } | 59 } |
| 60 if (callback) { | 60 if (callback) { |
| 61 callback->Run(); | 61 callback->Run(); |
| 62 delete callback; | 62 delete callback; |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 | 65 |
| 66 void AudioRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) { | 66 void AudioRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) { |
| 67 AutoLock auto_lock(lock_); | 67 base::AutoLock auto_lock(lock_); |
| 68 DCHECK_EQ(kPaused, state_); | 68 DCHECK_EQ(kPaused, state_); |
| 69 DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed"; | 69 DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed"; |
| 70 state_ = kSeeking; | 70 state_ = kSeeking; |
| 71 seek_callback_.reset(callback); | 71 seek_callback_.reset(callback); |
| 72 seek_timestamp_ = time; | 72 seek_timestamp_ = time; |
| 73 | 73 |
| 74 // Throw away everything and schedule our reads. | 74 // Throw away everything and schedule our reads. |
| 75 last_fill_buffer_time_ = base::TimeDelta(); | 75 last_fill_buffer_time_ = base::TimeDelta(); |
| 76 recieved_end_of_stream_ = false; | 76 recieved_end_of_stream_ = false; |
| 77 rendered_end_of_stream_ = false; | 77 rendered_end_of_stream_ = false; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 callback->Run(); | 122 callback->Run(); |
| 123 return; | 123 return; |
| 124 } | 124 } |
| 125 | 125 |
| 126 // Finally, execute the start callback. | 126 // Finally, execute the start callback. |
| 127 state_ = kPaused; | 127 state_ = kPaused; |
| 128 callback->Run(); | 128 callback->Run(); |
| 129 } | 129 } |
| 130 | 130 |
| 131 bool AudioRendererBase::HasEnded() { | 131 bool AudioRendererBase::HasEnded() { |
| 132 AutoLock auto_lock(lock_); | 132 base::AutoLock auto_lock(lock_); |
| 133 if (rendered_end_of_stream_) { | 133 if (rendered_end_of_stream_) { |
| 134 DCHECK(algorithm_->IsQueueEmpty()) | 134 DCHECK(algorithm_->IsQueueEmpty()) |
| 135 << "Audio queue should be empty if we have rendered end of stream"; | 135 << "Audio queue should be empty if we have rendered end of stream"; |
| 136 } | 136 } |
| 137 return recieved_end_of_stream_ && rendered_end_of_stream_; | 137 return recieved_end_of_stream_ && rendered_end_of_stream_; |
| 138 } | 138 } |
| 139 | 139 |
| 140 void AudioRendererBase::ConsumeAudioSamples(scoped_refptr<Buffer> buffer_in) { | 140 void AudioRendererBase::ConsumeAudioSamples(scoped_refptr<Buffer> buffer_in) { |
| 141 AutoLock auto_lock(lock_); | 141 base::AutoLock auto_lock(lock_); |
| 142 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying); | 142 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying); |
| 143 DCHECK_GT(pending_reads_, 0u); | 143 DCHECK_GT(pending_reads_, 0u); |
| 144 --pending_reads_; | 144 --pending_reads_; |
| 145 | 145 |
| 146 // TODO(scherkus): this happens due to a race, primarily because Stop() is a | 146 // TODO(scherkus): this happens due to a race, primarily because Stop() is a |
| 147 // synchronous call when it should be asynchronous and accept a callback. | 147 // synchronous call when it should be asynchronous and accept a callback. |
| 148 // Refer to http://crbug.com/16059 | 148 // Refer to http://crbug.com/16059 |
| 149 if (state_ == kStopped) { | 149 if (state_ == kStopped) { |
| 150 return; | 150 return; |
| 151 } | 151 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 | 184 |
| 185 uint32 AudioRendererBase::FillBuffer(uint8* dest, | 185 uint32 AudioRendererBase::FillBuffer(uint8* dest, |
| 186 uint32 dest_len, | 186 uint32 dest_len, |
| 187 const base::TimeDelta& playback_delay, | 187 const base::TimeDelta& playback_delay, |
| 188 bool buffers_empty) { | 188 bool buffers_empty) { |
| 189 // The timestamp of the last buffer written during the last call to | 189 // The timestamp of the last buffer written during the last call to |
| 190 // FillBuffer(). | 190 // FillBuffer(). |
| 191 base::TimeDelta last_fill_buffer_time; | 191 base::TimeDelta last_fill_buffer_time; |
| 192 size_t dest_written = 0; | 192 size_t dest_written = 0; |
| 193 { | 193 { |
| 194 AutoLock auto_lock(lock_); | 194 base::AutoLock auto_lock(lock_); |
| 195 | 195 |
| 196 // Mute audio by returning 0 when not playing. | 196 // Mute audio by returning 0 when not playing. |
| 197 if (state_ != kPlaying) { | 197 if (state_ != kPlaying) { |
| 198 // TODO(scherkus): To keep the audio hardware busy we write at most 8k of | 198 // TODO(scherkus): To keep the audio hardware busy we write at most 8k of |
| 199 // zeros. This gets around the tricky situation of pausing and resuming | 199 // zeros. This gets around the tricky situation of pausing and resuming |
| 200 // the audio IPC layer in Chrome. Ideally, we should return zero and then | 200 // the audio IPC layer in Chrome. Ideally, we should return zero and then |
| 201 // the subclass can restart the conversation. | 201 // the subclass can restart the conversation. |
| 202 const uint32 kZeroLength = 8192; | 202 const uint32 kZeroLength = 8192; |
| 203 dest_written = std::min(kZeroLength, dest_len); | 203 dest_written = std::min(kZeroLength, dest_len); |
| 204 memset(dest, 0, dest_written); | 204 memset(dest, 0, dest_written); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 | 269 |
| 270 void AudioRendererBase::SetPlaybackRate(float playback_rate) { | 270 void AudioRendererBase::SetPlaybackRate(float playback_rate) { |
| 271 algorithm_->set_playback_rate(playback_rate); | 271 algorithm_->set_playback_rate(playback_rate); |
| 272 } | 272 } |
| 273 | 273 |
| 274 float AudioRendererBase::GetPlaybackRate() { | 274 float AudioRendererBase::GetPlaybackRate() { |
| 275 return algorithm_->playback_rate(); | 275 return algorithm_->playback_rate(); |
| 276 } | 276 } |
| 277 | 277 |
| 278 } // namespace media | 278 } // namespace media |
| OLD | NEW |