| Index: content/renderer/media/webrtc_audio_device_impl.cc
|
| diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc
|
| index 0a34cd323b807be47e28d408748e702d5f40f9db..a73884f7a35efb7d9a2866a94d0abf6260d72811 100644
|
| --- a/content/renderer/media/webrtc_audio_device_impl.cc
|
| +++ b/content/renderer/media/webrtc_audio_device_impl.cc
|
| @@ -27,7 +27,8 @@ WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
|
| initialized_(false),
|
| playing_(false),
|
| recording_(false),
|
| - microphone_volume_(0) {
|
| + microphone_volume_(0),
|
| + render_buffer_size_(0) {
|
| DVLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()";
|
| }
|
|
|
| @@ -121,11 +122,15 @@ void WebRtcAudioDeviceImpl::OnSetFormat(
|
| DVLOG(1) << "WebRtcAudioDeviceImpl::OnSetFormat()";
|
| }
|
|
|
| -void WebRtcAudioDeviceImpl::RenderData(uint8* audio_data,
|
| - int number_of_channels,
|
| - int number_of_frames,
|
| +void WebRtcAudioDeviceImpl::RenderData(media::AudioBus* audio_bus,
|
| + int sample_rate,
|
| int audio_delay_milliseconds) {
|
| - DCHECK_LE(number_of_frames, output_buffer_size());
|
| + if (!render_buffer_ ||
|
| + render_buffer_size_ != (audio_bus->frames() * audio_bus->channels())) {
|
| + render_buffer_size_ = audio_bus->frames() * audio_bus->channels();
|
| + render_buffer_.reset(new int16[render_buffer_size_]);
|
| + }
|
| +
|
| {
|
| base::AutoLock auto_lock(lock_);
|
| DCHECK(audio_transport_callback_);
|
| @@ -133,37 +138,42 @@ void WebRtcAudioDeviceImpl::RenderData(uint8* audio_data,
|
| output_delay_ms_ = audio_delay_milliseconds;
|
| }
|
|
|
| - const int channels = number_of_channels;
|
| - DCHECK_LE(channels, output_channels());
|
| -
|
| - int samples_per_sec = output_sample_rate();
|
| - int samples_per_10_msec = (samples_per_sec / 100);
|
| - int bytes_per_sample = output_audio_parameters_.bits_per_sample() / 8;
|
| + int samples_per_10_msec = (sample_rate / 100);
|
| + int bytes_per_sample = 2;
|
| const int bytes_per_10_msec =
|
| - channels * samples_per_10_msec * bytes_per_sample;
|
| -
|
| - uint32_t num_audio_samples = 0;
|
| - int accumulated_audio_samples = 0;
|
| + audio_bus->channels() * samples_per_10_msec * bytes_per_sample;
|
| + DCHECK_EQ(audio_bus->frames() % samples_per_10_msec, 0);
|
|
|
| // Get audio samples in blocks of 10 milliseconds from the registered
|
| // webrtc::AudioTransport source. Keep reading until our internal buffer
|
| // is full.
|
| - while (accumulated_audio_samples < number_of_frames) {
|
| + uint32_t num_audio_samples = 0;
|
| + int accumulated_audio_samples = 0;
|
| + int16* audio_data = render_buffer_.get();
|
| + while (accumulated_audio_samples < audio_bus->frames()) {
|
| // Get 10ms and append output to temporary byte buffer.
|
| audio_transport_callback_->NeedMorePlayData(samples_per_10_msec,
|
| bytes_per_sample,
|
| - channels,
|
| - samples_per_sec,
|
| + audio_bus->channels(),
|
| + sample_rate,
|
| audio_data,
|
| num_audio_samples);
|
| accumulated_audio_samples += num_audio_samples;
|
| audio_data += bytes_per_10_msec;
|
| }
|
| -}
|
|
|
| -void WebRtcAudioDeviceImpl::SetRenderFormat(const AudioParameters& params) {
|
| - DCHECK(thread_checker_.CalledOnValidThread());
|
| - output_audio_parameters_ = params;
|
| + // De-interleave each channel and convert to 32-bit floating-point
|
| + // with nominal range -1.0 -> +1.0 to match the callback format.
|
| + audio_bus->FromInterleaved(render_buffer_.get(),
|
| + audio_bus->frames(),
|
| + bytes_per_sample);
|
| +
|
| + // Pass the render data to the observers.
|
| + base::AutoLock auto_lock(lock_);
|
| + for (RenderDataObservers::const_iterator it = render_data_observers_.begin();
|
| + it != render_data_observers_.end(); ++it) {
|
| + (*it)->RenderData(audio_bus, sample_rate, audio_delay_milliseconds);
|
| + }
|
| }
|
|
|
| void WebRtcAudioDeviceImpl::RemoveAudioRenderer(WebRtcAudioRenderer* renderer) {
|
| @@ -369,7 +379,7 @@ int32_t WebRtcAudioDeviceImpl::MinMicrophoneVolume(uint32_t* min_volume) const {
|
|
|
| int32_t WebRtcAudioDeviceImpl::StereoPlayoutIsAvailable(bool* available) const {
|
| DCHECK(initialized_);
|
| - *available = (output_channels() == 2);
|
| + *available = renderer_ ? (renderer_->channels() == 2) : false;
|
| return 0;
|
| }
|
|
|
| @@ -412,7 +422,7 @@ int32_t WebRtcAudioDeviceImpl::RecordingSampleRate(
|
|
|
| int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate(
|
| uint32_t* samples_per_sec) const {
|
| - *samples_per_sec = static_cast<uint32_t>(output_sample_rate());
|
| + *samples_per_sec = renderer_ ? renderer_->sample_rate() : 0;
|
| return 0;
|
| }
|
|
|
| @@ -465,6 +475,23 @@ WebRtcAudioDeviceImpl::GetDefaultCapturer() const {
|
| return NULL;
|
| }
|
|
|
| +void WebRtcAudioDeviceImpl::AddRenderDataObserver(
|
| + WebRtcAudioRendererSource* observer) {
|
| + DCHECK(observer);
|
| + base::AutoLock auto_lock(lock_);
|
| + DCHECK(std::find(render_data_observers_.begin(),
|
| + render_data_observers_.end(),
|
| + observer) == render_data_observers_.end());
|
| + render_data_observers_.push_back(observer);
|
| +}
|
| +
|
| +void WebRtcAudioDeviceImpl::RemoveRenderDataObserver(
|
| + WebRtcAudioRendererSource* observer) {
|
| + DCHECK(observer);
|
| + base::AutoLock auto_lock(lock_);
|
| + render_data_observers_.remove(observer);
|
| +}
|
| +
|
| bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer(
|
| int* session_id,
|
| int* output_sample_rate,
|
|
|