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

Side by Side Diff: media/filters/audio_renderer_algorithm_base.cc

Issue 9395057: Fix muted audio when playback rate != 1.0 or 0.0 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_algorithm_base.h" 5 #include "media/filters/audio_renderer_algorithm_base.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 23 matching lines...) Expand all
34 // Audio at these speeds would sound better under a frequency domain algorithm. 34 // Audio at these speeds would sound better under a frequency domain algorithm.
35 static const float kMinPlaybackRate = 0.5f; 35 static const float kMinPlaybackRate = 0.5f;
36 static const float kMaxPlaybackRate = 4.0f; 36 static const float kMaxPlaybackRate = 4.0f;
37 37
38 AudioRendererAlgorithmBase::AudioRendererAlgorithmBase() 38 AudioRendererAlgorithmBase::AudioRendererAlgorithmBase()
39 : channels_(0), 39 : channels_(0),
40 samples_per_second_(0), 40 samples_per_second_(0),
41 bytes_per_channel_(0), 41 bytes_per_channel_(0),
42 playback_rate_(0.0f), 42 playback_rate_(0.0f),
43 audio_buffer_(0, kStartingBufferSizeInBytes), 43 audio_buffer_(0, kStartingBufferSizeInBytes),
44 crossfade_size_(0), 44 bytes_in_crossfade_(0),
45 bytes_per_frame_(0),
46 index_into_window_(0),
47 crossfade_frame_number_(0),
48 muted_(false),
49 needs_more_data_(false),
45 window_size_(0) { 50 window_size_(0) {
46 } 51 }
47 52
48 AudioRendererAlgorithmBase::~AudioRendererAlgorithmBase() {} 53 AudioRendererAlgorithmBase::~AudioRendererAlgorithmBase() {}
49 54
50 bool AudioRendererAlgorithmBase::ValidateConfig( 55 bool AudioRendererAlgorithmBase::ValidateConfig(
51 int channels, 56 int channels,
52 int samples_per_second, 57 int samples_per_second,
53 int bits_per_channel) { 58 int bits_per_channel) {
54 bool status = true; 59 bool status = true;
(...skipping 22 matching lines...) Expand all
77 int samples_per_second, 82 int samples_per_second,
78 int bits_per_channel, 83 int bits_per_channel,
79 float initial_playback_rate, 84 float initial_playback_rate,
80 const base::Closure& callback) { 85 const base::Closure& callback) {
81 DCHECK(!callback.is_null()); 86 DCHECK(!callback.is_null());
82 DCHECK(ValidateConfig(channels, samples_per_second, bits_per_channel)); 87 DCHECK(ValidateConfig(channels, samples_per_second, bits_per_channel));
83 88
84 channels_ = channels; 89 channels_ = channels;
85 samples_per_second_ = samples_per_second; 90 samples_per_second_ = samples_per_second;
86 bytes_per_channel_ = bits_per_channel / 8; 91 bytes_per_channel_ = bits_per_channel / 8;
92 bytes_per_frame_ = bytes_per_channel_ * channels_;
87 request_read_cb_ = callback; 93 request_read_cb_ = callback;
88 SetPlaybackRate(initial_playback_rate); 94 SetPlaybackRate(initial_playback_rate);
89 95
90 window_size_ = 96 window_size_ =
91 samples_per_second_ * bytes_per_channel_ * channels_ * kWindowDuration; 97 samples_per_second_ * bytes_per_channel_ * channels_ * kWindowDuration;
92 AlignToSampleBoundary(&window_size_); 98 AlignToFrameBoundary(&window_size_);
93 99
94 crossfade_size_ = 100 bytes_in_crossfade_ =
95 samples_per_second_ * bytes_per_channel_ * channels_ * kCrossfadeDuration; 101 samples_per_second_ * bytes_per_channel_ * channels_ * kCrossfadeDuration;
96 AlignToSampleBoundary(&crossfade_size_); 102 AlignToFrameBoundary(&bytes_in_crossfade_);
97 } 103
98 104 crossfade_buffer_.reset(new uint8[bytes_in_crossfade_]);
99 uint32 AudioRendererAlgorithmBase::FillBuffer(uint8* dest, uint32 length) { 105 }
100 if (IsQueueEmpty() || playback_rate_ == 0.0f) 106
107 uint32 AudioRendererAlgorithmBase::FillBuffer(
108 uint8* dest, uint32 requested_frames) {
109 if (playback_rate_ == 0.0f || bytes_per_frame_ == 0)
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 Is "bytes_per_frame == 0" necessary because Initia
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Oops, it's not necessary! This should be a DCHECK,
101 return 0; 110 return 0;
102 111
103 // Handle the simple case of normal playback. 112 uint32 total_frames_rendered = 0;
104 if (playback_rate_ == 1.0f) { 113 uint8* output_ptr = dest;
105 uint32 bytes_written = 114 while(total_frames_rendered < requested_frames) {
106 CopyFromAudioBuffer(dest, std::min(length, bytes_buffered())); 115 if (index_into_window_ == window_size_)
107 AdvanceBufferPosition(bytes_written); 116 ResetWindow();
108 return bytes_written; 117
109 } 118 bool renders_frame = true;
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 nit: rendered_frame?
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Done.
110 119 if (playback_rate_ > 1.0)
111 // Output muted data when out of acceptable quality range. 120 renders_frame = OutputFasterPlayback(output_ptr);
112 if (playback_rate_ < kMinPlaybackRate || playback_rate_ > kMaxPlaybackRate) 121 else if (playback_rate_ < 1.0)
113 return MuteBuffer(dest, length); 122 renders_frame = OutputSlowerPlayback(output_ptr);
114 123 else
124 renders_frame = OutputNormalPlayback(output_ptr);
125
126 if (!renders_frame) {
127 needs_more_data_ = true;
128 break;
129 }
130
131 output_ptr += bytes_per_frame_;
132 total_frames_rendered++;
133 }
134 return total_frames_rendered;
135 }
136
137 void AudioRendererAlgorithmBase::ResetWindow() {
138 DCHECK_EQ(index_into_window_, window_size_);
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 Should this methods get called on FlushBuffers()?
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Good catch! Yes, this should get called then. Adde
139 index_into_window_ = 0;
140 crossfade_frame_number_ = 0;
141 muted_ = false;
142 }
143
144 bool AudioRendererAlgorithmBase::OutputFasterPlayback(uint8* dest) {
145 DCHECK_LT(index_into_window_, window_size_);
146 DCHECK_GT(playback_rate_, 1.0);
147
148 if (audio_buffer_.forward_bytes() < bytes_per_frame_)
149 return false;
150
151 if (playback_rate_ > kMaxPlaybackRate)
152 muted_ = true;
153
154 // The audio data is output in a series of windows. For sped-up playback,
155 // window is comprised of the following phases:
156 //
157 // a) Output raw data.
158 // b) Save bytes for crossfade in |crossfade_buffer_|.
159 // c) Drop data.
160 // d) Output crossfaded audio leading up to the next window.
161 //
162 // The duration of each phase is computed below based on the |window_size_|
163 // and |playback_rate_|.
115 uint32 input_step = window_size_; 164 uint32 input_step = window_size_;
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 I'm assuming we have to use uint32 everywhere beca
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Done at top of header file.
165 uint32 output_step = ceil(window_size_ / playback_rate_);
166 AlignToFrameBoundary(&output_step);
167 DCHECK_GT(input_step, output_step);
168
169 uint32 bytes_to_crossfade = bytes_in_crossfade_;
170 if (muted_ || bytes_to_crossfade > output_step)
171 bytes_to_crossfade = 0;
172
173 // This is the index of the end of phase a, beginning of phase b.
174 uint32 outtro_crossfade_begin = output_step - bytes_to_crossfade;
175
176 // This is the index of the end of phase b, beginning of phase c.
177 uint32 outtro_crossfade_end = output_step;
178
179 // This is the index of the end of phase c, beginning of phase d.
180 // This phase continues until |index_into_window_| reaches |window_size_|, at
181 // which point the window restarts.
182 uint32 intro_crossfade_begin = input_step - bytes_to_crossfade;
183
184 // a) Output a raw frame if we haven't reached the crossfade section.
185 if (index_into_window_ < outtro_crossfade_begin) {
186 ReadRawFrame(dest);
187 index_into_window_ += bytes_per_frame_;
188 return true;
189 }
190
191 // b) Drop frames until we reach the intro crossfade section.
192 while (audio_buffer_.forward_bytes() >= bytes_per_frame_ &&
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 I think just having a loop for b) and one for c) w
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Arrghhh I also mislabeled these comments! (Logic i
193 index_into_window_ < intro_crossfade_begin) {
194 if (index_into_window_ < outtro_crossfade_end) {
195 // c) Save crossfade frame into intermediate buffer.
196 uint8* place_to_copy = crossfade_buffer_.get() +
197 (index_into_window_ - outtro_crossfade_begin);
198 ReadRawFrame(place_to_copy);
199 } else {
200 DropFrame();
201 }
202 index_into_window_ += bytes_per_frame_;
203 }
204
205 // d) Crossfade and output frames.
206 if (index_into_window_ < window_size_ &&
207 index_into_window_ >= intro_crossfade_begin &&
208 audio_buffer_.forward_bytes() >= bytes_per_frame_) {
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 Reverse condition and return early to reduce inden
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Done.
209 uint32 offset_into_buffer = index_into_window_ - intro_crossfade_begin;
210 memcpy(dest, crossfade_buffer_.get() + offset_into_buffer,
211 bytes_per_frame_);
212 scoped_array<uint8> intro_frame_ptr(new uint8[bytes_per_frame_]);
213 audio_buffer_.Read(intro_frame_ptr.get(), bytes_per_frame_);
214 OutputCrossfadedFrame(dest, intro_frame_ptr.get());
215 index_into_window_ += bytes_per_frame_;
216 return true;
217 }
218
219 return false;
220 }
221
222 bool AudioRendererAlgorithmBase::OutputSlowerPlayback(uint8* dest) {
223 DCHECK_LT(index_into_window_, window_size_);
224 DCHECK_LT(playback_rate_, 1.0);
225 DCHECK_NE(playback_rate_, 0.0);
226
227 if (audio_buffer_.forward_bytes() < bytes_per_frame_)
228 return false;
229
230 if (playback_rate_ < kMinPlaybackRate)
231 muted_ = true;
232
233 // The audio data is output in a series of windows. For slowed down playback,
234 // window is comprised of the following phases:
235 //
236 // a) Output raw data.
237 // b) Output and save bytes for crossfade in |crossfade_buffer_|.
238 // c) Output raw data.
239 // d) Output crossfaded audio leading up to the next window.
240 //
241 // Phases c) and d) do not progress |audio_buffer_|'s cursor so that the
242 // |audio_buffer_|'s cursor is in the correct place for the next window.
243 //
244 // The duration of each phase is computed below based on the |window_size_|
245 // and |playback_rate_|.
246 uint32 input_step = ceil(window_size_ * playback_rate_);
247 AlignToFrameBoundary(&input_step);
116 uint32 output_step = window_size_; 248 uint32 output_step = window_size_;
117 249 DCHECK_LT(input_step, output_step);
118 if (playback_rate_ > 1.0f) { 250
119 // Playback is faster than normal; need to squish output! 251 uint32 bytes_to_crossfade = bytes_in_crossfade_;
120 output_step = ceil(window_size_ / playback_rate_); 252 if (muted_ || bytes_to_crossfade > input_step)
253 bytes_to_crossfade = 0;
254
255 // This is the index of the end of phase a, beginning of phase b.
256 uint32 intro_crossfade_begin = input_step - bytes_to_crossfade;
257
258 // This is the index of the end of phase b, beginning of phase c.
259 uint32 intro_crossfade_end = input_step;
260
261 // This is the index of the end of phase c, beginning of phase d.
262 // This phase continues until |index_into_window_| reaches |window_size_|, at
263 // which point the window restarts.
264 uint32 outtro_crossfade_begin = output_step - bytes_to_crossfade;
265
266 // a) Output raw frame.
267 if (index_into_window_ < intro_crossfade_begin) {
268 ReadRawFrame(dest);
269 index_into_window_ += bytes_per_frame_;
270 return true;
271 }
272
273 // b) Output and save raw frames that will make up the intro crossfade
274 // section.
275 if (index_into_window_ < intro_crossfade_end) {
276 uint32 offset = index_into_window_ - intro_crossfade_begin;
277 uint8* place_to_copy = crossfade_buffer_.get() + offset;
278 PeekRawFrame(place_to_copy);
279 ReadRawFrame(dest);
280 index_into_window_ += bytes_per_frame_;
281 return true;
282 }
283
284 uint32 audio_buffer_offset = index_into_window_ - intro_crossfade_end;
285
286 // c) Output more raw frames.
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 nit: Perhaps " Output more raw frames w/o advancin
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Done, and also added asterisks to the function-lev
287 if (audio_buffer_.forward_bytes() >= audio_buffer_offset + bytes_per_frame_) {
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 Reverse test and return early to reduce indenting.
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Done.
288 DCHECK_GE(index_into_window_, intro_crossfade_end);
289 PeekRawFrame(dest, audio_buffer_offset);
290
291 // d) Crossfade the next frame of |crossfade_buffer_| into |dest|.
292 if (index_into_window_ >= outtro_crossfade_begin) {
293 uint32 offset_into_crossfade_buffer =
294 index_into_window_ - outtro_crossfade_begin;
295 uint8* intro_frame_ptr =
296 crossfade_buffer_.get() + offset_into_crossfade_buffer;
297 OutputCrossfadedFrame(dest, intro_frame_ptr);
298 }
299
300 index_into_window_ += bytes_per_frame_;
301 return true;
302 }
303
304 return false;
305 }
306
307 bool AudioRendererAlgorithmBase::OutputNormalPlayback(uint8* dest) {
308 if (audio_buffer_.forward_bytes() >= bytes_per_frame_) {
309 ReadRawFrame(dest);
310 index_into_window_ += bytes_per_frame_;
311 return true;
312 }
313 return false;
314 }
315
316 void AudioRendererAlgorithmBase::ReadRawFrame(uint8* dest) {
317 PeekRawFrame(dest);
318 DropFrame();
319 }
320
321 void AudioRendererAlgorithmBase::PeekRawFrame(uint8* dest) {
322 PeekRawFrame(dest, 0);
323 }
324
325 void AudioRendererAlgorithmBase::PeekRawFrame(uint8* dest, uint32 offset) {
326 if (!muted_) {
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 nit: Reverse test, do memset, & return early. Unin
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 Done.
327 uint32 copied = audio_buffer_.Peek(dest, bytes_per_frame_, offset);
328 DCHECK_EQ(bytes_per_frame_, copied);
121 } else { 329 } else {
122 // Playback is slower than normal; need to stretch input! 330 memset(dest, 0, bytes_per_frame_);
123 input_step = ceil(window_size_ * playback_rate_); 331 }
124 } 332 }
125 333
126 AlignToSampleBoundary(&input_step); 334 void AudioRendererAlgorithmBase::DropFrame() {
127 AlignToSampleBoundary(&output_step); 335 audio_buffer_.Seek(bytes_per_frame_);
128 DCHECK_LE(crossfade_size_, input_step); 336
129 DCHECK_LE(crossfade_size_, output_step); 337 if (!IsQueueFull())
130 338 request_read_cb_.Run();
131 uint32 bytes_written = 0; 339 }
132 uint32 bytes_left_to_output = length; 340
133 uint8* output_ptr = dest; 341 void AudioRendererAlgorithmBase::OutputCrossfadedFrame(
134 342 uint8* outtro, const uint8* intro) {
135 // TODO(vrk): The while loop and if test below are lame! We are requiring the 343 DCHECK_LE(index_into_window_, window_size_);
136 // client to provide us with enough data to output only complete crossfaded 344 DCHECK(!muted_);
137 // windows. Instead, we should output as much data as we can, and add state to 345
138 // keep track of what point in the crossfade we are at. 346 switch (bytes_per_channel_) {
139 // This is also the cause of crbug.com/108239. 347 case 4:
140 while (bytes_left_to_output >= output_step) { 348 CrossfadeFrame(reinterpret_cast<int32*>(outtro),
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 You can change this to CrossfadeFrame<int32>(outtr
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 I tried and failed at this! It compiles, it looks
141 // If there is not enough data buffered to complete an iteration of the 349 reinterpret_cast<const int32*>(intro));
142 // loop, mute the remaining and break. 350 break;
143 if (bytes_buffered() < window_size_) { 351 case 2:
144 bytes_written += MuteBuffer(output_ptr, bytes_left_to_output); 352 CrossfadeFrame(reinterpret_cast<int16*>(outtro),
145 break; 353 reinterpret_cast<const int16*>(intro));
146 } 354 break;
147 355 case 1:
148 // Copy |output_step| bytes into destination buffer. 356 CrossfadeFrame(outtro, intro);
149 uint32 copied = CopyFromAudioBuffer(output_ptr, output_step); 357 break;
150 DCHECK_EQ(copied, output_step); 358 default:
151 output_ptr += output_step; 359 NOTREACHED() << "Unsupported audio bit depth in crossfade.";
152 bytes_written += copied; 360 }
153 bytes_left_to_output -= copied; 361 }
154 362
155 // Copy the |crossfade_size_| bytes leading up to the next window that will 363 template <class Type>
156 // be played into an intermediate buffer. This will be used to crossfade 364 void AudioRendererAlgorithmBase::CrossfadeFrame(
157 // from the current window to the next. 365 Type* outtro, const Type* intro) {
158 AdvanceBufferPosition(input_step - crossfade_size_); 366 uint32 frames_in_crossfade = bytes_in_crossfade_ / bytes_per_frame_;
159 scoped_array<uint8> next_window_intro(new uint8[crossfade_size_]); 367 float crossfade_ratio =
160 uint32 bytes_copied = 368 static_cast<float>(crossfade_frame_number_) / frames_in_crossfade;
161 CopyFromAudioBuffer(next_window_intro.get(), crossfade_size_); 369 for (int channel = 0; channel < channels_; ++channel) {
162 DCHECK_EQ(bytes_copied, crossfade_size_); 370 *outtro = (*outtro) * (1.0 - crossfade_ratio) + (*intro) * crossfade_ratio;
163 AdvanceBufferPosition(crossfade_size_); 371 outtro++;
acolwell GONE FROM CHROMIUM 2012/02/22 07:51:40 nit: *outtro++ = ... *intro++
vrk (LEFT CHROMIUM) 2012/02/23 20:33:06 I don't think I can do that, since I want to incre
164 372 intro++;
165 // Prepare pointers to end of the current window and the start of the next 373 }
166 // window. 374 crossfade_frame_number_++;
167 uint8* start_of_outro = output_ptr - crossfade_size_;
168 const uint8* start_of_intro = next_window_intro.get();
169
170 // Do crossfade!
171 Crossfade(crossfade_size_, channels_, bytes_per_channel_,
172 start_of_intro, start_of_outro);
173 }
174
175 return bytes_written;
176 }
177
178 uint32 AudioRendererAlgorithmBase::MuteBuffer(uint8* dest, uint32 length) {
179 DCHECK_NE(playback_rate_, 0.0);
180 // Note: This may not play at the speed requested as we can only consume as
181 // much data as we have, and audio timestamps drive the pipeline clock.
182 //
183 // Furthermore, we won't end up scaling the very last bit of audio, but
184 // we're talking about <8ms of audio data.
185
186 // Cap the |input_step| by the amount of bytes buffered.
187 uint32 input_step =
188 std::min(static_cast<uint32>(length * playback_rate_), bytes_buffered());
189 uint32 output_step = input_step / playback_rate_;
190 AlignToSampleBoundary(&input_step);
191 AlignToSampleBoundary(&output_step);
192
193 DCHECK_LE(output_step, length);
194 if (output_step > length) {
195 LOG(ERROR) << "OLA: output_step (" << output_step << ") calculated to "
196 << "be larger than destination length (" << length << ")";
197 output_step = length;
198 }
199
200 memset(dest, 0, output_step);
201 AdvanceBufferPosition(input_step);
202 return output_step;
203 } 375 }
204 376
205 void AudioRendererAlgorithmBase::SetPlaybackRate(float new_rate) { 377 void AudioRendererAlgorithmBase::SetPlaybackRate(float new_rate) {
206 DCHECK_GE(new_rate, 0.0); 378 DCHECK_GE(new_rate, 0.0);
207 playback_rate_ = new_rate; 379 playback_rate_ = new_rate;
208 } 380 }
209 381
210 void AudioRendererAlgorithmBase::AlignToSampleBoundary(uint32* value) { 382 void AudioRendererAlgorithmBase::AlignToFrameBoundary(uint32* value) {
211 (*value) -= ((*value) % (channels_ * bytes_per_channel_)); 383 (*value) -= ((*value) % bytes_per_frame_);
212 } 384 }
213 385
214 void AudioRendererAlgorithmBase::FlushBuffers() { 386 void AudioRendererAlgorithmBase::FlushBuffers() {
215 // Clear the queue of decoded packets (releasing the buffers). 387 // Clear the queue of decoded packets (releasing the buffers).
216 audio_buffer_.Clear(); 388 audio_buffer_.Clear();
217 request_read_cb_.Run(); 389 request_read_cb_.Run();
218 } 390 }
219 391
220 base::TimeDelta AudioRendererAlgorithmBase::GetTime() { 392 base::TimeDelta AudioRendererAlgorithmBase::GetTime() {
221 return audio_buffer_.current_time(); 393 return audio_buffer_.current_time();
222 } 394 }
223 395
224 void AudioRendererAlgorithmBase::EnqueueBuffer(Buffer* buffer_in) { 396 void AudioRendererAlgorithmBase::EnqueueBuffer(Buffer* buffer_in) {
225 // If we're at end of stream, |buffer_in| contains no data. 397 DCHECK(!buffer_in->IsEndOfStream());
226 if (!buffer_in->IsEndOfStream()) 398 audio_buffer_.Append(buffer_in);
227 audio_buffer_.Append(buffer_in); 399 needs_more_data_ = false;
228 400
229 // If we still don't have enough data, request more. 401 // If we still don't have enough data, request more.
230 if (!IsQueueFull()) 402 if (!IsQueueFull())
231 request_read_cb_.Run(); 403 request_read_cb_.Run();
232 } 404 }
233 405
406 bool AudioRendererAlgorithmBase::NeedsMoreData() {
407 return needs_more_data_;
408 }
409
234 bool AudioRendererAlgorithmBase::IsQueueEmpty() { 410 bool AudioRendererAlgorithmBase::IsQueueEmpty() {
235 return audio_buffer_.forward_bytes() == 0; 411 return audio_buffer_.forward_bytes() == 0;
236 } 412 }
237 413
238 bool AudioRendererAlgorithmBase::IsQueueFull() { 414 bool AudioRendererAlgorithmBase::IsQueueFull() {
239 return audio_buffer_.forward_bytes() >= audio_buffer_.forward_capacity(); 415 return audio_buffer_.forward_bytes() >= audio_buffer_.forward_capacity();
240 } 416 }
241 417
242 uint32 AudioRendererAlgorithmBase::QueueCapacity() { 418 uint32 AudioRendererAlgorithmBase::QueueCapacity() {
243 return audio_buffer_.forward_capacity(); 419 return audio_buffer_.forward_capacity();
244 } 420 }
245 421
246 void AudioRendererAlgorithmBase::IncreaseQueueCapacity() { 422 void AudioRendererAlgorithmBase::IncreaseQueueCapacity() {
247 audio_buffer_.set_forward_capacity( 423 audio_buffer_.set_forward_capacity(
248 std::min(2 * audio_buffer_.forward_capacity(), kMaxBufferSizeInBytes)); 424 std::min(2 * audio_buffer_.forward_capacity(), kMaxBufferSizeInBytes));
249 } 425 }
250 426
251 void AudioRendererAlgorithmBase::AdvanceBufferPosition(uint32 bytes) {
252 audio_buffer_.Seek(bytes);
253
254 if (!IsQueueFull())
255 request_read_cb_.Run();
256 }
257
258 uint32 AudioRendererAlgorithmBase::CopyFromAudioBuffer(
259 uint8* dest, uint32 bytes) {
260 return audio_buffer_.Peek(dest, bytes);
261 }
262
263 } // namespace media 427 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698