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

Side by Side Diff: content/renderer/media/webrtc_audio_device_impl.cc

Issue 139303016: Feed the render data to MediaStreamAudioProcessor and used AudioBus in render callback (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed the win bots. Created 6 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/media/webrtc_audio_device_impl.h" 5 #include "content/renderer/media/webrtc_audio_device_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "base/win/windows_version.h" 10 #include "base/win/windows_version.h"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 } 114 }
115 115
116 return new_volume; 116 return new_volume;
117 } 117 }
118 118
119 void WebRtcAudioDeviceImpl::OnSetFormat( 119 void WebRtcAudioDeviceImpl::OnSetFormat(
120 const media::AudioParameters& params) { 120 const media::AudioParameters& params) {
121 DVLOG(1) << "WebRtcAudioDeviceImpl::OnSetFormat()"; 121 DVLOG(1) << "WebRtcAudioDeviceImpl::OnSetFormat()";
122 } 122 }
123 123
124 void WebRtcAudioDeviceImpl::RenderData(uint8* audio_data, 124 void WebRtcAudioDeviceImpl::RenderData(media::AudioBus* audio_bus,
125 int number_of_channels, 125 int sample_rate,
126 int number_of_frames,
127 int audio_delay_milliseconds) { 126 int audio_delay_milliseconds) {
128 DCHECK_LE(number_of_frames, output_buffer_size()); 127 render_buffer_.resize(audio_bus->frames() * audio_bus->channels());
128
129 { 129 {
130 base::AutoLock auto_lock(lock_); 130 base::AutoLock auto_lock(lock_);
131 DCHECK(audio_transport_callback_); 131 DCHECK(audio_transport_callback_);
132 // Store the reported audio delay locally. 132 // Store the reported audio delay locally.
133 output_delay_ms_ = audio_delay_milliseconds; 133 output_delay_ms_ = audio_delay_milliseconds;
134 } 134 }
135 135
136 const int channels = number_of_channels; 136 int samples_per_10_msec = (sample_rate / 100);
137 DCHECK_LE(channels, output_channels()); 137 int bytes_per_sample = sizeof(render_buffer_[0]);
138
139 int samples_per_sec = output_sample_rate();
140 int samples_per_10_msec = (samples_per_sec / 100);
141 int bytes_per_sample = output_audio_parameters_.bits_per_sample() / 8;
142 const int bytes_per_10_msec = 138 const int bytes_per_10_msec =
143 channels * samples_per_10_msec * bytes_per_sample; 139 audio_bus->channels() * samples_per_10_msec * bytes_per_sample;
144 140 DCHECK_EQ(audio_bus->frames() % samples_per_10_msec, 0);
145 uint32_t num_audio_samples = 0;
146 int accumulated_audio_samples = 0;
147 141
148 // Get audio samples in blocks of 10 milliseconds from the registered 142 // Get audio samples in blocks of 10 milliseconds from the registered
149 // webrtc::AudioTransport source. Keep reading until our internal buffer 143 // webrtc::AudioTransport source. Keep reading until our internal buffer
150 // is full. 144 // is full.
151 while (accumulated_audio_samples < number_of_frames) { 145 uint32_t num_audio_samples = 0;
146 int accumulated_audio_samples = 0;
147 int16* audio_data = &render_buffer_[0];
148 while (accumulated_audio_samples < audio_bus->frames()) {
152 // Get 10ms and append output to temporary byte buffer. 149 // Get 10ms and append output to temporary byte buffer.
153 audio_transport_callback_->NeedMorePlayData(samples_per_10_msec, 150 audio_transport_callback_->NeedMorePlayData(samples_per_10_msec,
154 bytes_per_sample, 151 bytes_per_sample,
155 channels, 152 audio_bus->channels(),
156 samples_per_sec, 153 sample_rate,
157 audio_data, 154 audio_data,
158 num_audio_samples); 155 num_audio_samples);
159 accumulated_audio_samples += num_audio_samples; 156 accumulated_audio_samples += num_audio_samples;
160 audio_data += bytes_per_10_msec; 157 audio_data += bytes_per_10_msec;
161 } 158 }
162 }
163 159
164 void WebRtcAudioDeviceImpl::SetRenderFormat(const AudioParameters& params) { 160 // De-interleave each channel and convert to 32-bit floating-point
165 DCHECK(thread_checker_.CalledOnValidThread()); 161 // with nominal range -1.0 -> +1.0 to match the callback format.
166 output_audio_parameters_ = params; 162 audio_bus->FromInterleaved(&render_buffer_[0],
163 audio_bus->frames(),
164 bytes_per_sample);
165
166 // Pass the render data to the observers.
tommi (sloooow) - chröme 2014/01/31 13:58:32 this is terminology again but are observers in thi
no longer working on chromium 2014/02/02 16:50:16 Yes, it is. I have already explained in the header
tommi (sloooow) - chröme 2014/02/04 14:39:14 Observers aren't participants, so this is not an o
167 base::AutoLock auto_lock(lock_);
168 for (RenderDataObservers::const_iterator it = render_data_observers_.begin();
169 it != render_data_observers_.end(); ++it) {
170 (*it)->RenderData(audio_bus, sample_rate, audio_delay_milliseconds);
171 }
167 } 172 }
168 173
169 void WebRtcAudioDeviceImpl::RemoveAudioRenderer(WebRtcAudioRenderer* renderer) { 174 void WebRtcAudioDeviceImpl::RemoveAudioRenderer(WebRtcAudioRenderer* renderer) {
170 DCHECK(thread_checker_.CalledOnValidThread()); 175 DCHECK(thread_checker_.CalledOnValidThread());
171 DCHECK_EQ(renderer, renderer_); 176 DCHECK_EQ(renderer, renderer_);
172 base::AutoLock auto_lock(lock_); 177 base::AutoLock auto_lock(lock_);
173 renderer_ = NULL; 178 renderer_ = NULL;
174 playing_ = false; 179 playing_ = false;
175 } 180 }
176 181
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 return 0; 367 return 0;
363 } 368 }
364 369
365 int32_t WebRtcAudioDeviceImpl::MinMicrophoneVolume(uint32_t* min_volume) const { 370 int32_t WebRtcAudioDeviceImpl::MinMicrophoneVolume(uint32_t* min_volume) const {
366 *min_volume = 0; 371 *min_volume = 0;
367 return 0; 372 return 0;
368 } 373 }
369 374
370 int32_t WebRtcAudioDeviceImpl::StereoPlayoutIsAvailable(bool* available) const { 375 int32_t WebRtcAudioDeviceImpl::StereoPlayoutIsAvailable(bool* available) const {
371 DCHECK(initialized_); 376 DCHECK(initialized_);
372 *available = (output_channels() == 2); 377 *available = renderer_ ? (renderer_->channels() == 2) : false;
tommi (sloooow) - chröme 2014/01/31 13:58:32 nit: can also do this *available = renderer_ && re
no longer working on chromium 2014/02/02 16:50:16 Done.
373 return 0; 378 return 0;
374 } 379 }
375 380
376 int32_t WebRtcAudioDeviceImpl::StereoRecordingIsAvailable( 381 int32_t WebRtcAudioDeviceImpl::StereoRecordingIsAvailable(
377 bool* available) const { 382 bool* available) const {
378 DCHECK(initialized_); 383 DCHECK(initialized_);
379 // TODO(xians): These kind of hardware methods do not make much sense since we 384 // TODO(xians): These kind of hardware methods do not make much sense since we
380 // support multiple sources. Remove or figure out new APIs for such methods. 385 // support multiple sources. Remove or figure out new APIs for such methods.
381 scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); 386 scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer());
382 if (!capturer.get()) 387 if (!capturer.get())
(...skipping 22 matching lines...) Expand all
405 if (!capturer.get()) 410 if (!capturer.get())
406 return -1; 411 return -1;
407 412
408 *samples_per_sec = static_cast<uint32_t>( 413 *samples_per_sec = static_cast<uint32_t>(
409 capturer->source_audio_parameters().sample_rate()); 414 capturer->source_audio_parameters().sample_rate());
410 return 0; 415 return 0;
411 } 416 }
412 417
413 int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate( 418 int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate(
414 uint32_t* samples_per_sec) const { 419 uint32_t* samples_per_sec) const {
415 *samples_per_sec = static_cast<uint32_t>(output_sample_rate()); 420 *samples_per_sec = renderer_ ? renderer_->sample_rate() : 0;
416 return 0; 421 return 0;
417 } 422 }
418 423
419 bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) { 424 bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) {
420 DCHECK(thread_checker_.CalledOnValidThread()); 425 DCHECK(thread_checker_.CalledOnValidThread());
421 DCHECK(renderer); 426 DCHECK(renderer);
422 427
423 base::AutoLock auto_lock(lock_); 428 base::AutoLock auto_lock(lock_);
424 if (renderer_.get()) 429 if (renderer_.get())
425 return false; 430 return false;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 // Use the last |capturer| which is from the latest getUserMedia call as 463 // Use the last |capturer| which is from the latest getUserMedia call as
459 // the default capture device. 464 // the default capture device.
460 for (CapturerList::const_reverse_iterator iter = capturers_.rbegin(); 465 for (CapturerList::const_reverse_iterator iter = capturers_.rbegin();
461 iter != capturers_.rend(); ++iter) { 466 iter != capturers_.rend(); ++iter) {
462 return *iter; 467 return *iter;
463 } 468 }
464 469
465 return NULL; 470 return NULL;
466 } 471 }
467 472
473 void WebRtcAudioDeviceImpl::AddRenderDataObserver(
474 WebRtcAudioRendererSource* observer) {
475 DCHECK(observer);
tommi (sloooow) - chröme 2014/01/31 13:58:32 nice to see the dchecks on observer and std::find.
476 base::AutoLock auto_lock(lock_);
477 DCHECK(std::find(render_data_observers_.begin(),
478 render_data_observers_.end(),
479 observer) == render_data_observers_.end());
480 render_data_observers_.push_back(observer);
481 }
482
483 void WebRtcAudioDeviceImpl::RemoveRenderDataObserver(
484 WebRtcAudioRendererSource* observer) {
485 DCHECK(observer);
486 base::AutoLock auto_lock(lock_);
487 render_data_observers_.remove(observer);
488 }
489
468 bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer( 490 bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer(
469 int* session_id, 491 int* session_id,
470 int* output_sample_rate, 492 int* output_sample_rate,
471 int* output_frames_per_buffer) { 493 int* output_frames_per_buffer) {
472 DCHECK(thread_checker_.CalledOnValidThread()); 494 DCHECK(thread_checker_.CalledOnValidThread());
473 // If there is no capturer or there are more than one open capture devices, 495 // If there is no capturer or there are more than one open capture devices,
474 // return false. 496 // return false.
475 if (capturers_.empty() || capturers_.size() > 1) 497 if (capturers_.empty() || capturers_.size() > 1)
476 return false; 498 return false;
477 499
478 return GetDefaultCapturer()->GetPairedOutputParameters( 500 return GetDefaultCapturer()->GetPairedOutputParameters(
479 session_id, output_sample_rate, output_frames_per_buffer); 501 session_id, output_sample_rate, output_frames_per_buffer);
480 } 502 }
481 503
482 } // namespace content 504 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698