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

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

Issue 9826028: Rename AudioRendererBase and AudioRendererAlgorithmBase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Unit tests were somehow unadded Created 8 years, 8 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
« no previous file with comments | « media/filters/audio_renderer_impl.h ('k') | media/filters/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_base.h" 5 #include "media/filters/audio_renderer_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "media/base/filter_host.h" 13 #include "media/base/filter_host.h"
14 #include "media/audio/audio_util.h" 14 #include "media/audio/audio_util.h"
15 15
16 namespace media { 16 namespace media {
17 17
18 AudioRendererBase::AudioRendererBase(media::AudioRendererSink* sink) 18 AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink)
19 : state_(kUninitialized), 19 : state_(kUninitialized),
20 pending_read_(false), 20 pending_read_(false),
21 received_end_of_stream_(false), 21 received_end_of_stream_(false),
22 rendered_end_of_stream_(false), 22 rendered_end_of_stream_(false),
23 bytes_per_frame_(0), 23 bytes_per_frame_(0),
24 bytes_per_second_(0), 24 bytes_per_second_(0),
25 stopped_(false), 25 stopped_(false),
26 sink_(sink), 26 sink_(sink),
27 is_initialized_(false), 27 is_initialized_(false),
28 read_cb_(base::Bind(&AudioRendererBase::DecodedAudioReady, 28 read_cb_(base::Bind(&AudioRendererImpl::DecodedAudioReady,
29 base::Unretained(this))) { 29 base::Unretained(this))) {
30 } 30 }
31 31
32 AudioRendererBase::~AudioRendererBase() { 32 AudioRendererImpl::~AudioRendererImpl() {
33 // Stop() should have been called and |algorithm_| should have been destroyed. 33 // Stop() should have been called and |algorithm_| should have been destroyed.
34 DCHECK(state_ == kUninitialized || state_ == kStopped); 34 DCHECK(state_ == kUninitialized || state_ == kStopped);
35 DCHECK(!algorithm_.get()); 35 DCHECK(!algorithm_.get());
36 } 36 }
37 37
38 void AudioRendererBase::Play(const base::Closure& callback) { 38 void AudioRendererImpl::Play(const base::Closure& callback) {
39 { 39 {
40 base::AutoLock auto_lock(lock_); 40 base::AutoLock auto_lock(lock_);
41 DCHECK_EQ(kPaused, state_); 41 DCHECK_EQ(kPaused, state_);
42 state_ = kPlaying; 42 state_ = kPlaying;
43 callback.Run(); 43 callback.Run();
44 } 44 }
45 45
46 if (stopped_) 46 if (stopped_)
47 return; 47 return;
48 48
49 if (GetPlaybackRate() != 0.0f) { 49 if (GetPlaybackRate() != 0.0f) {
50 DoPlay(); 50 DoPlay();
51 } else { 51 } else {
52 DoPause(); 52 DoPause();
53 } 53 }
54 } 54 }
55 55
56 void AudioRendererBase::DoPlay() { 56 void AudioRendererImpl::DoPlay() {
57 earliest_end_time_ = base::Time::Now(); 57 earliest_end_time_ = base::Time::Now();
58 DCHECK(sink_.get()); 58 DCHECK(sink_.get());
59 sink_->Play(); 59 sink_->Play();
60 } 60 }
61 61
62 void AudioRendererBase::Pause(const base::Closure& callback) { 62 void AudioRendererImpl::Pause(const base::Closure& callback) {
63 { 63 {
64 base::AutoLock auto_lock(lock_); 64 base::AutoLock auto_lock(lock_);
65 DCHECK(state_ == kPlaying || state_ == kUnderflow || 65 DCHECK(state_ == kPlaying || state_ == kUnderflow ||
66 state_ == kRebuffering); 66 state_ == kRebuffering);
67 pause_cb_ = callback; 67 pause_cb_ = callback;
68 state_ = kPaused; 68 state_ = kPaused;
69 69
70 // Pause only when we've completed our pending read. 70 // Pause only when we've completed our pending read.
71 if (!pending_read_) { 71 if (!pending_read_) {
72 pause_cb_.Run(); 72 pause_cb_.Run();
73 pause_cb_.Reset(); 73 pause_cb_.Reset();
74 } 74 }
75 } 75 }
76 76
77 if (stopped_) 77 if (stopped_)
78 return; 78 return;
79 79
80 DoPause(); 80 DoPause();
81 } 81 }
82 82
83 void AudioRendererBase::DoPause() { 83 void AudioRendererImpl::DoPause() {
84 DCHECK(sink_.get()); 84 DCHECK(sink_.get());
85 sink_->Pause(false); 85 sink_->Pause(false);
86 } 86 }
87 87
88 void AudioRendererBase::Flush(const base::Closure& callback) { 88 void AudioRendererImpl::Flush(const base::Closure& callback) {
89 decoder_->Reset(callback); 89 decoder_->Reset(callback);
90 } 90 }
91 91
92 void AudioRendererBase::Stop(const base::Closure& callback) { 92 void AudioRendererImpl::Stop(const base::Closure& callback) {
93 if (!stopped_) { 93 if (!stopped_) {
94 DCHECK(sink_.get()); 94 DCHECK(sink_.get());
95 sink_->Stop(); 95 sink_->Stop();
96 96
97 stopped_ = true; 97 stopped_ = true;
98 } 98 }
99 { 99 {
100 base::AutoLock auto_lock(lock_); 100 base::AutoLock auto_lock(lock_);
101 state_ = kStopped; 101 state_ = kStopped;
102 algorithm_.reset(NULL); 102 algorithm_.reset(NULL);
103 time_cb_.Reset(); 103 time_cb_.Reset();
104 underflow_cb_.Reset(); 104 underflow_cb_.Reset();
105 } 105 }
106 if (!callback.is_null()) { 106 if (!callback.is_null()) {
107 callback.Run(); 107 callback.Run();
108 } 108 }
109 } 109 }
110 110
111 void AudioRendererBase::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { 111 void AudioRendererImpl::Seek(base::TimeDelta time, const PipelineStatusCB& cb) {
112 base::AutoLock auto_lock(lock_); 112 base::AutoLock auto_lock(lock_);
113 DCHECK_EQ(kPaused, state_); 113 DCHECK_EQ(kPaused, state_);
114 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 114 DCHECK(!pending_read_) << "Pending read must complete before seeking";
115 DCHECK(pause_cb_.is_null()); 115 DCHECK(pause_cb_.is_null());
116 DCHECK(seek_cb_.is_null()); 116 DCHECK(seek_cb_.is_null());
117 state_ = kSeeking; 117 state_ = kSeeking;
118 seek_cb_ = cb; 118 seek_cb_ = cb;
119 seek_timestamp_ = time; 119 seek_timestamp_ = time;
120 120
121 // Throw away everything and schedule our reads. 121 // Throw away everything and schedule our reads.
122 audio_time_buffered_ = base::TimeDelta(); 122 audio_time_buffered_ = base::TimeDelta();
123 received_end_of_stream_ = false; 123 received_end_of_stream_ = false;
124 rendered_end_of_stream_ = false; 124 rendered_end_of_stream_ = false;
125 125
126 // |algorithm_| will request more reads. 126 // |algorithm_| will request more reads.
127 algorithm_->FlushBuffers(); 127 algorithm_->FlushBuffers();
128 128
129 if (stopped_) 129 if (stopped_)
130 return; 130 return;
131 131
132 DoSeek(); 132 DoSeek();
133 } 133 }
134 134
135 void AudioRendererBase::DoSeek() { 135 void AudioRendererImpl::DoSeek() {
136 earliest_end_time_ = base::Time::Now(); 136 earliest_end_time_ = base::Time::Now();
137 137
138 // Pause and flush the stream when we seek to a new location. 138 // Pause and flush the stream when we seek to a new location.
139 sink_->Pause(true); 139 sink_->Pause(true);
140 } 140 }
141 141
142 void AudioRendererBase::Initialize(const scoped_refptr<AudioDecoder>& decoder, 142 void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder,
143 const PipelineStatusCB& init_cb, 143 const PipelineStatusCB& init_cb,
144 const base::Closure& underflow_cb, 144 const base::Closure& underflow_cb,
145 const TimeCB& time_cb) { 145 const TimeCB& time_cb) {
146 DCHECK(decoder); 146 DCHECK(decoder);
147 DCHECK(!init_cb.is_null()); 147 DCHECK(!init_cb.is_null());
148 DCHECK(!underflow_cb.is_null()); 148 DCHECK(!underflow_cb.is_null());
149 DCHECK(!time_cb.is_null()); 149 DCHECK(!time_cb.is_null());
150 DCHECK_EQ(kUninitialized, state_); 150 DCHECK_EQ(kUninitialized, state_);
151 decoder_ = decoder; 151 decoder_ = decoder;
152 underflow_cb_ = underflow_cb; 152 underflow_cb_ = underflow_cb;
153 time_cb_ = time_cb; 153 time_cb_ = time_cb;
154 154
155 // Create a callback so our algorithm can request more reads. 155 // Create a callback so our algorithm can request more reads.
156 base::Closure cb = base::Bind(&AudioRendererBase::ScheduleRead_Locked, this); 156 base::Closure cb = base::Bind(&AudioRendererImpl::ScheduleRead_Locked, this);
157 157
158 // Construct the algorithm. 158 // Construct the algorithm.
159 algorithm_.reset(new AudioRendererAlgorithmBase()); 159 algorithm_.reset(new AudioRendererAlgorithm());
160 160
161 // Initialize our algorithm with media properties, initial playback rate, 161 // Initialize our algorithm with media properties, initial playback rate,
162 // and a callback to request more reads from the data source. 162 // and a callback to request more reads from the data source.
163 ChannelLayout channel_layout = decoder_->channel_layout(); 163 ChannelLayout channel_layout = decoder_->channel_layout();
164 int channels = ChannelLayoutToChannelCount(channel_layout); 164 int channels = ChannelLayoutToChannelCount(channel_layout);
165 int bits_per_channel = decoder_->bits_per_channel(); 165 int bits_per_channel = decoder_->bits_per_channel();
166 int sample_rate = decoder_->samples_per_second(); 166 int sample_rate = decoder_->samples_per_second();
167 // TODO(vrk): Add method to AudioDecoder to compute bytes per frame. 167 // TODO(vrk): Add method to AudioDecoder to compute bytes per frame.
168 bytes_per_frame_ = channels * bits_per_channel / 8; 168 bytes_per_frame_ = channels * bits_per_channel / 8;
169 169
(...skipping 23 matching lines...) Expand all
193 sink_->Initialize(audio_parameters_, this); 193 sink_->Initialize(audio_parameters_, this);
194 194
195 sink_->Start(); 195 sink_->Start();
196 is_initialized_ = true; 196 is_initialized_ = true;
197 197
198 // Finally, execute the start callback. 198 // Finally, execute the start callback.
199 state_ = kPaused; 199 state_ = kPaused;
200 init_cb.Run(PIPELINE_OK); 200 init_cb.Run(PIPELINE_OK);
201 } 201 }
202 202
203 bool AudioRendererBase::HasEnded() { 203 bool AudioRendererImpl::HasEnded() {
204 base::AutoLock auto_lock(lock_); 204 base::AutoLock auto_lock(lock_);
205 DCHECK(!rendered_end_of_stream_ || algorithm_->NeedsMoreData()); 205 DCHECK(!rendered_end_of_stream_ || algorithm_->NeedsMoreData());
206 206
207 return received_end_of_stream_ && rendered_end_of_stream_; 207 return received_end_of_stream_ && rendered_end_of_stream_;
208 } 208 }
209 209
210 void AudioRendererBase::ResumeAfterUnderflow(bool buffer_more_audio) { 210 void AudioRendererImpl::ResumeAfterUnderflow(bool buffer_more_audio) {
211 base::AutoLock auto_lock(lock_); 211 base::AutoLock auto_lock(lock_);
212 if (state_ == kUnderflow) { 212 if (state_ == kUnderflow) {
213 if (buffer_more_audio) 213 if (buffer_more_audio)
214 algorithm_->IncreaseQueueCapacity(); 214 algorithm_->IncreaseQueueCapacity();
215 215
216 state_ = kRebuffering; 216 state_ = kRebuffering;
217 } 217 }
218 } 218 }
219 219
220 void AudioRendererBase::SetVolume(float volume) { 220 void AudioRendererImpl::SetVolume(float volume) {
221 if (stopped_) 221 if (stopped_)
222 return; 222 return;
223 sink_->SetVolume(volume); 223 sink_->SetVolume(volume);
224 } 224 }
225 225
226 void AudioRendererBase::DecodedAudioReady(scoped_refptr<Buffer> buffer) { 226 void AudioRendererImpl::DecodedAudioReady(scoped_refptr<Buffer> buffer) {
227 base::AutoLock auto_lock(lock_); 227 base::AutoLock auto_lock(lock_);
228 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying || 228 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying ||
229 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); 229 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped);
230 230
231 CHECK(pending_read_); 231 CHECK(pending_read_);
232 pending_read_ = false; 232 pending_read_ = false;
233 233
234 if (buffer && buffer->IsEndOfStream()) { 234 if (buffer && buffer->IsEndOfStream()) {
235 received_end_of_stream_ = true; 235 received_end_of_stream_ = true;
236 236
(...skipping 30 matching lines...) Expand all
267 case kUnderflow: 267 case kUnderflow:
268 case kRebuffering: 268 case kRebuffering:
269 if (buffer && !buffer->IsEndOfStream()) 269 if (buffer && !buffer->IsEndOfStream())
270 algorithm_->EnqueueBuffer(buffer); 270 algorithm_->EnqueueBuffer(buffer);
271 return; 271 return;
272 case kStopped: 272 case kStopped:
273 return; 273 return;
274 } 274 }
275 } 275 }
276 276
277 void AudioRendererBase::SignalEndOfStream() { 277 void AudioRendererImpl::SignalEndOfStream() {
278 DCHECK(received_end_of_stream_); 278 DCHECK(received_end_of_stream_);
279 if (!rendered_end_of_stream_) { 279 if (!rendered_end_of_stream_) {
280 rendered_end_of_stream_ = true; 280 rendered_end_of_stream_ = true;
281 host()->NotifyEnded(); 281 host()->NotifyEnded();
282 } 282 }
283 } 283 }
284 284
285 void AudioRendererBase::ScheduleRead_Locked() { 285 void AudioRendererImpl::ScheduleRead_Locked() {
286 lock_.AssertAcquired(); 286 lock_.AssertAcquired();
287 if (pending_read_ || state_ == kPaused) 287 if (pending_read_ || state_ == kPaused)
288 return; 288 return;
289 pending_read_ = true; 289 pending_read_ = true;
290 decoder_->Read(read_cb_); 290 decoder_->Read(read_cb_);
291 } 291 }
292 292
293 void AudioRendererBase::SetPlaybackRate(float playback_rate) { 293 void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
294 DCHECK_LE(0.0f, playback_rate); 294 DCHECK_LE(0.0f, playback_rate);
295 295
296 if (!stopped_) { 296 if (!stopped_) {
297 // Notify sink of new playback rate. 297 // Notify sink of new playback rate.
298 sink_->SetPlaybackRate(playback_rate); 298 sink_->SetPlaybackRate(playback_rate);
299 299
300 // We have two cases here: 300 // We have two cases here:
301 // Play: GetPlaybackRate() == 0.0 && playback_rate != 0.0 301 // Play: GetPlaybackRate() == 0.0 && playback_rate != 0.0
302 // Pause: GetPlaybackRate() != 0.0 && playback_rate == 0.0 302 // Pause: GetPlaybackRate() != 0.0 && playback_rate == 0.0
303 if (GetPlaybackRate() == 0.0f && playback_rate != 0.0f) { 303 if (GetPlaybackRate() == 0.0f && playback_rate != 0.0f) {
304 DoPlay(); 304 DoPlay();
305 } else if (GetPlaybackRate() != 0.0f && playback_rate == 0.0f) { 305 } else if (GetPlaybackRate() != 0.0f && playback_rate == 0.0f) {
306 // Pause is easy, we can always pause. 306 // Pause is easy, we can always pause.
307 DoPause(); 307 DoPause();
308 } 308 }
309 } 309 }
310 310
311 base::AutoLock auto_lock(lock_); 311 base::AutoLock auto_lock(lock_);
312 algorithm_->SetPlaybackRate(playback_rate); 312 algorithm_->SetPlaybackRate(playback_rate);
313 } 313 }
314 314
315 float AudioRendererBase::GetPlaybackRate() { 315 float AudioRendererImpl::GetPlaybackRate() {
316 base::AutoLock auto_lock(lock_); 316 base::AutoLock auto_lock(lock_);
317 return algorithm_->playback_rate(); 317 return algorithm_->playback_rate();
318 } 318 }
319 319
320 bool AudioRendererBase::IsBeforeSeekTime(const scoped_refptr<Buffer>& buffer) { 320 bool AudioRendererImpl::IsBeforeSeekTime(const scoped_refptr<Buffer>& buffer) {
321 return (state_ == kSeeking) && buffer && !buffer->IsEndOfStream() && 321 return (state_ == kSeeking) && buffer && !buffer->IsEndOfStream() &&
322 (buffer->GetTimestamp() + buffer->GetDuration()) < seek_timestamp_; 322 (buffer->GetTimestamp() + buffer->GetDuration()) < seek_timestamp_;
323 } 323 }
324 324
325 int AudioRendererBase::Render(const std::vector<float*>& audio_data, 325 int AudioRendererImpl::Render(const std::vector<float*>& audio_data,
326 int number_of_frames, 326 int number_of_frames,
327 int audio_delay_milliseconds) { 327 int audio_delay_milliseconds) {
328 if (stopped_ || GetPlaybackRate() == 0.0f) { 328 if (stopped_ || GetPlaybackRate() == 0.0f) {
329 // Output silence if stopped. 329 // Output silence if stopped.
330 for (size_t i = 0; i < audio_data.size(); ++i) 330 for (size_t i = 0; i < audio_data.size(); ++i)
331 memset(audio_data[i], 0, sizeof(float) * number_of_frames); 331 memset(audio_data[i], 0, sizeof(float) * number_of_frames);
332 return 0; 332 return 0;
333 } 333 }
334 334
335 // Adjust the playback delay. 335 // Adjust the playback delay.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 if (frames_filled < number_of_frames) { 367 if (frames_filled < number_of_frames) {
368 int frames_to_zero = number_of_frames - frames_filled; 368 int frames_to_zero = number_of_frames - frames_filled;
369 memset(audio_data[channel_index] + frames_filled, 369 memset(audio_data[channel_index] + frames_filled,
370 0, 370 0,
371 sizeof(float) * frames_to_zero); 371 sizeof(float) * frames_to_zero);
372 } 372 }
373 } 373 }
374 return frames_filled; 374 return frames_filled;
375 } 375 }
376 376
377 uint32 AudioRendererBase::FillBuffer(uint8* dest, 377 uint32 AudioRendererImpl::FillBuffer(uint8* dest,
378 uint32 requested_frames, 378 uint32 requested_frames,
379 const base::TimeDelta& playback_delay) { 379 const base::TimeDelta& playback_delay) {
380 // The |audio_time_buffered_| is the ending timestamp of the last frame 380 // The |audio_time_buffered_| is the ending timestamp of the last frame
381 // buffered at the audio device. |playback_delay| is the amount of time 381 // buffered at the audio device. |playback_delay| is the amount of time
382 // buffered at the audio device. The current time can be computed by their 382 // buffered at the audio device. The current time can be computed by their
383 // difference. 383 // difference.
384 base::TimeDelta current_time = audio_time_buffered_ - playback_delay; 384 base::TimeDelta current_time = audio_time_buffered_ - playback_delay;
385 385
386 size_t frames_written = 0; 386 size_t frames_written = 0;
387 base::Closure underflow_cb; 387 base::Closure underflow_cb;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 current_time > host()->GetTime())) { 444 current_time > host()->GetTime())) {
445 time_cb_.Run(current_time, audio_time_buffered_); 445 time_cb_.Run(current_time, audio_time_buffered_);
446 } 446 }
447 447
448 if (!underflow_cb.is_null()) 448 if (!underflow_cb.is_null())
449 underflow_cb.Run(); 449 underflow_cb.Run();
450 450
451 return frames_written; 451 return frames_written;
452 } 452 }
453 453
454 void AudioRendererBase::UpdateEarliestEndTime(int bytes_filled, 454 void AudioRendererImpl::UpdateEarliestEndTime(int bytes_filled,
455 base::TimeDelta request_delay, 455 base::TimeDelta request_delay,
456 base::Time time_now) { 456 base::Time time_now) {
457 if (bytes_filled != 0) { 457 if (bytes_filled != 0) {
458 base::TimeDelta predicted_play_time = ConvertToDuration(bytes_filled); 458 base::TimeDelta predicted_play_time = ConvertToDuration(bytes_filled);
459 float playback_rate = GetPlaybackRate(); 459 float playback_rate = GetPlaybackRate();
460 if (playback_rate != 1.0f) { 460 if (playback_rate != 1.0f) {
461 predicted_play_time = base::TimeDelta::FromMicroseconds( 461 predicted_play_time = base::TimeDelta::FromMicroseconds(
462 static_cast<int64>(ceil(predicted_play_time.InMicroseconds() * 462 static_cast<int64>(ceil(predicted_play_time.InMicroseconds() *
463 playback_rate))); 463 playback_rate)));
464 } 464 }
465 earliest_end_time_ = 465 earliest_end_time_ =
466 std::max(earliest_end_time_, 466 std::max(earliest_end_time_,
467 time_now + request_delay + predicted_play_time); 467 time_now + request_delay + predicted_play_time);
468 } 468 }
469 } 469 }
470 470
471 base::TimeDelta AudioRendererBase::ConvertToDuration(int bytes) { 471 base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) {
472 if (bytes_per_second_) { 472 if (bytes_per_second_) {
473 return base::TimeDelta::FromMicroseconds( 473 return base::TimeDelta::FromMicroseconds(
474 base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_); 474 base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_);
475 } 475 }
476 return base::TimeDelta(); 476 return base::TimeDelta();
477 } 477 }
478 478
479 void AudioRendererBase::OnRenderError() { 479 void AudioRendererImpl::OnRenderError() {
480 host()->DisableAudioRenderer(); 480 host()->DisableAudioRenderer();
481 } 481 }
482 482
483 } // namespace media 483 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/audio_renderer_impl.h ('k') | media/filters/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698