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

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

Powered by Google App Engine
This is Rietveld 408576698