Index: content/renderer/media/webrtc_audio_renderer.cc |
diff --git a/content/renderer/media/webrtc_audio_renderer.cc b/content/renderer/media/webrtc_audio_renderer.cc |
index fb7a848910cabc5151d4b07d37eddbec323d7fd5..9187983773fc0dfcde351842ea0386c673fb1511 100644 |
--- a/content/renderer/media/webrtc_audio_renderer.cc |
+++ b/content/renderer/media/webrtc_audio_renderer.cc |
@@ -200,8 +200,9 @@ WebRtcAudioRenderer::WebRtcAudioRenderer( |
start_ref_count_(0), |
audio_delay_milliseconds_(0), |
fifo_delay_milliseconds_(0), |
- sample_rate_(sample_rate), |
- frames_per_buffer_(frames_per_buffer) { |
+ sink_params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
+ media::CHANNEL_LAYOUT_STEREO, sample_rate, 16, |
+ frames_per_buffer) { |
WebRtcLogMessage(base::StringPrintf( |
"WAR::WAR. source_render_view_id=%d" |
", session_id=%d, sample_rate=%d, frames_per_buffer=%d", |
@@ -214,7 +215,6 @@ WebRtcAudioRenderer::WebRtcAudioRenderer( |
WebRtcAudioRenderer::~WebRtcAudioRenderer() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK_EQ(state_, UNINITIALIZED); |
- buffer_.reset(); |
} |
bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) { |
@@ -226,20 +226,14 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) { |
DCHECK(!sink_.get()); |
DCHECK(!source_); |
- // Use stereo output on all platforms. |
- media::ChannelLayout channel_layout = media::CHANNEL_LAYOUT_STEREO; |
- |
- // TODO(tommi,henrika): Maybe we should just change |sample_rate_| to be |
- // immutable and change its value instead of using a temporary? |
- int sample_rate = sample_rate_; |
- DVLOG(1) << "Audio output hardware sample rate: " << sample_rate; |
- |
// WebRTC does not yet support higher rates than 96000 on the client side |
// and 48000 is the preferred sample rate. Therefore, if 192000 is detected, |
// we change the rate to 48000 instead. The consequence is that the native |
// layer will be opened up at 192kHz but WebRTC will provide data at 48kHz |
// which will then be resampled by the audio converted on the browser side |
// to match the native audio layer. |
+ int sample_rate = sink_params_.sample_rate(); |
+ DVLOG(1) << "Audio output hardware sample rate: " << sample_rate; |
if (sample_rate == 192000) { |
DVLOG(1) << "Resampling from 48000 to 192000 is required"; |
sample_rate = 48000; |
@@ -249,7 +243,8 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) { |
UMA_HISTOGRAM_ENUMERATION( |
"WebRTC.AudioOutputSampleRate", asr, media::kUnexpectedAudioSampleRate); |
} else { |
- UMA_HISTOGRAM_COUNTS("WebRTC.AudioOutputSampleRateUnexpected", sample_rate); |
+ UMA_HISTOGRAM_COUNTS("WebRTC.AudioOutputSampleRateUnexpected", |
+ sample_rate); |
} |
// Verify that the reported output hardware sample rate is supported |
@@ -267,50 +262,47 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) { |
// The WebRTC client only supports multiples of 10ms as buffer size where |
// 10ms is preferred for lowest possible delay. |
media::AudioParameters source_params; |
- int buffer_size = (sample_rate / 100); |
- DVLOG(1) << "Using WebRTC output buffer size: " << buffer_size; |
+ const int frames_per_10ms = (sample_rate / 100); |
+ DVLOG(1) << "Using WebRTC output buffer size: " << frames_per_10ms; |
- int channels = ChannelLayoutToChannelCount(channel_layout); |
source_params.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
- channel_layout, channels, 0, |
- sample_rate, 16, buffer_size); |
+ sink_params_.channel_layout(), sink_params_.channels(), 0, |
+ sample_rate, 16, frames_per_10ms); |
- // Set up audio parameters for the sink, i.e., the native audio output stream. |
+ // Update audio parameters for the sink, i.e., the native audio output stream. |
// We strive to open up using native parameters to achieve best possible |
// performance and to ensure that no FIFO is needed on the browser side to |
// match the client request. Any mismatch between the source and the sink is |
// taken care of in this class instead using a pull FIFO. |
- media::AudioParameters sink_params; |
- |
- // Use native output siz as default. |
- buffer_size = frames_per_buffer_; |
+ // Use native output size as default. |
+ int frames_per_buffer = sink_params_.frames_per_buffer(); |
#if defined(OS_ANDROID) |
// TODO(henrika): Keep tuning this scheme and espcicially for low-latency |
// cases. Might not be possible to come up with the perfect solution using |
// the render side only. |
- const int frames_per_10ms = (sample_rate / 100); |
- if (buffer_size < 2 * frames_per_10ms) { |
+ if (frames_per_buffer < 2 * frames_per_10ms) { |
// Examples of low-latency frame sizes and the resulting |buffer_size|: |
// Nexus 7 : 240 audio frames => 2*480 = 960 |
// Nexus 10 : 256 => 2*441 = 882 |
// Galaxy Nexus: 144 => 2*441 = 882 |
- buffer_size = 2 * frames_per_10ms; |
+ frames_per_buffer = 2 * frames_per_10ms; |
DVLOG(1) << "Low-latency output detected on Android"; |
} |
#endif |
- DVLOG(1) << "Using sink output buffer size: " << buffer_size; |
+ DVLOG(1) << "Using sink output buffer size: " << frames_per_buffer; |
- sink_params.Reset(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
- channel_layout, channels, 0, sample_rate, 16, buffer_size); |
+ sink_params_.Reset(sink_params_.format(), sink_params_.channel_layout(), |
+ sink_params_.channels(), 0, sample_rate, 16, |
+ frames_per_buffer); |
// Create a FIFO if re-buffering is required to match the source input with |
// the sink request. The source acts as provider here and the sink as |
// consumer. |
fifo_delay_milliseconds_ = 0; |
- if (source_params.frames_per_buffer() != sink_params.frames_per_buffer()) { |
+ if (source_params.frames_per_buffer() != sink_params_.frames_per_buffer()) { |
DVLOG(1) << "Rebuffering from " << source_params.frames_per_buffer() |
- << " to " << sink_params.frames_per_buffer(); |
+ << " to " << sink_params_.frames_per_buffer(); |
audio_fifo_.reset(new media::AudioPullFifo( |
source_params.channels(), |
source_params.frames_per_buffer(), |
@@ -318,23 +310,15 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) { |
&WebRtcAudioRenderer::SourceCallback, |
base::Unretained(this)))); |
- if (sink_params.frames_per_buffer() > source_params.frames_per_buffer()) { |
+ if (sink_params_.frames_per_buffer() > source_params.frames_per_buffer()) { |
int frame_duration_milliseconds = base::Time::kMillisecondsPerSecond / |
static_cast<double>(source_params.sample_rate()); |
- fifo_delay_milliseconds_ = (sink_params.frames_per_buffer() - |
+ fifo_delay_milliseconds_ = (sink_params_.frames_per_buffer() - |
source_params.frames_per_buffer()) * frame_duration_milliseconds; |
} |
} |
- // Allocate local audio buffers based on the parameters above. |
- // It is assumed that each audio sample contains 16 bits and each |
- // audio frame contains one or two audio samples depending on the |
- // number of channels. |
- buffer_.reset( |
- new int16[source_params.frames_per_buffer() * source_params.channels()]); |
- |
source_ = source; |
- source->SetRenderFormat(source_params); |
// Configure the audio rendering client and start rendering. |
sink_ = AudioDeviceFactory::NewOutputDevice( |
@@ -343,7 +327,7 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) { |
// TODO(tommi): Rename InitializeUnifiedStream to rather reflect association |
// with a session. |
DCHECK_GE(session_id_, 0); |
- sink_->InitializeUnifiedStream(sink_params, this, session_id_); |
+ sink_->InitializeUnifiedStream(sink_params_, this, session_id_); |
sink_->Start(); |
@@ -515,22 +499,13 @@ void WebRtcAudioRenderer::SourceCallback( |
// We need to keep render data for the |source_| regardless of |state_|, |
// otherwise the data will be buffered up inside |source_|. |
- source_->RenderData(reinterpret_cast<uint8*>(buffer_.get()), |
- audio_bus->channels(), audio_bus->frames(), |
+ source_->RenderData(audio_bus, sink_params_.sample_rate(), |
output_delay_milliseconds); |
// Avoid filling up the audio bus if we are not playing; instead |
// return here and ensure that the returned value in Render() is 0. |
- if (state_ != PLAYING) { |
+ if (state_ != PLAYING) |
audio_bus->Zero(); |
- return; |
- } |
- |
- // 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(buffer_.get(), |
- audio_bus->frames(), |
- sizeof(buffer_[0])); |
} |
void WebRtcAudioRenderer::UpdateSourceVolume( |