Chromium Code Reviews| Index: content/renderer/media/webrtc_audio_capturer.cc |
| diff --git a/content/renderer/media/webrtc_audio_capturer.cc b/content/renderer/media/webrtc_audio_capturer.cc |
| index 9c56be0b705de454ef71eb6c08f1d841c900c098..ba5cc7cf0fa20e7157c2814fcedaecd61a418314 100644 |
| --- a/content/renderer/media/webrtc_audio_capturer.cc |
| +++ b/content/renderer/media/webrtc_audio_capturer.cc |
| @@ -24,29 +24,6 @@ |
| namespace content { |
| -namespace { |
| - |
| -// Audio buffer sizes are specified in milliseconds. |
| -const char kAudioLatency[] = "latencyMs"; |
| -const int kMinAudioLatencyMs = 0; |
| -const int kMaxAudioLatencyMs = 10000; |
| - |
| -// Method to check if any of the data in |audio_source| has energy. |
| -bool HasDataEnergy(const media::AudioBus& audio_source) { |
| - for (int ch = 0; ch < audio_source.channels(); ++ch) { |
| - const float* channel_ptr = audio_source.channel(ch); |
| - for (int frame = 0; frame < audio_source.frames(); ++frame) { |
| - if (channel_ptr[frame] != 0) |
| - return true; |
| - } |
| - } |
| - |
| - // All the data is zero. |
| - return false; |
| -} |
| - |
| -} // namespace |
| - |
| // Reference counted container of WebRtcLocalAudioTrack delegate. |
| // TODO(xians): Switch to MediaStreamAudioSinkOwner. |
| class WebRtcAudioCapturer::TrackOwner |
| @@ -56,13 +33,10 @@ class WebRtcAudioCapturer::TrackOwner |
| : delegate_(track) {} |
| void Capture(const media::AudioBus& audio_bus, |
| - base::TimeTicks estimated_capture_time, |
| - bool force_report_nonzero_energy) { |
| + base::TimeTicks estimated_capture_time) { |
| base::AutoLock lock(lock_); |
| if (delegate_) { |
| - delegate_->Capture(audio_bus, |
| - estimated_capture_time, |
| - force_report_nonzero_energy); |
| + delegate_->Capture(audio_bus, estimated_capture_time); |
| } |
| } |
| @@ -72,13 +46,6 @@ class WebRtcAudioCapturer::TrackOwner |
| delegate_->OnSetFormat(params); |
| } |
| - void SetAudioProcessor( |
| - const scoped_refptr<MediaStreamAudioProcessor>& processor) { |
| - base::AutoLock lock(lock_); |
| - if (delegate_) |
| - delegate_->SetAudioProcessor(processor); |
| - } |
| - |
| void Reset() { |
| base::AutoLock lock(lock_); |
| delegate_ = NULL; |
| @@ -124,14 +91,14 @@ class WebRtcAudioCapturer::TrackOwner |
| }; |
| // static |
| -scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer( |
| +scoped_ptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer( |
| int render_frame_id, |
| const StreamDeviceInfo& device_info, |
| const blink::WebMediaConstraints& constraints, |
| WebRtcAudioDeviceImpl* audio_device, |
| MediaStreamAudioSource* audio_source) { |
| - scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer( |
| - render_frame_id, device_info, constraints, audio_device, audio_source); |
| + scoped_ptr<WebRtcAudioCapturer> capturer(new WebRtcAudioCapturer( |
| + render_frame_id, device_info, constraints, audio_device, audio_source)); |
| if (capturer->Initialize()) |
| return capturer; |
| @@ -206,27 +173,10 @@ bool WebRtcAudioCapturer::Initialize() { |
| device_info_.device.input.sample_rate); |
| } |
| - // Initialize the buffer size to zero, which means it wasn't specified. |
| - // If it is out of range, we return it to zero. |
| - int buffer_size_ms = 0; |
| - int buffer_size_samples = 0; |
| - GetConstraintValueAsInteger(constraints_, kAudioLatency, &buffer_size_ms); |
| - if (buffer_size_ms < kMinAudioLatencyMs || |
| - buffer_size_ms > kMaxAudioLatencyMs) { |
| - DVLOG(1) << "Ignoring out of range buffer size " << buffer_size_ms; |
| - } else { |
| - buffer_size_samples = |
| - device_info_.device.input.sample_rate * buffer_size_ms / 1000; |
| - } |
| - DVLOG_IF(1, buffer_size_samples > 0) |
| - << "Custom audio buffer size: " << buffer_size_samples << " samples"; |
| - |
| // Create and configure the default audio capturing source. |
| SetCapturerSourceInternal( |
| - AudioDeviceFactory::NewInputDevice(render_frame_id_), |
| - channel_layout, |
| - device_info_.device.input.sample_rate, |
| - buffer_size_samples); |
| + AudioDeviceFactory::NewInputDevice(render_frame_id_), channel_layout, |
| + device_info_.device.input.sample_rate); |
| // Add the capturer to the WebRtcAudioDeviceImpl since it needs some hardware |
| // information from the capturer. |
| @@ -253,7 +203,8 @@ WebRtcAudioCapturer::WebRtcAudioCapturer( |
| volume_(0), |
| peer_connection_mode_(false), |
| audio_device_(audio_device), |
| - audio_source_(audio_source) { |
| + audio_source_(audio_source), |
| + weak_factory_(this) { |
| DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; |
| } |
| @@ -265,9 +216,20 @@ WebRtcAudioCapturer::~WebRtcAudioCapturer() { |
| } |
| void WebRtcAudioCapturer::AddTrack(WebRtcLocalAudioTrack* track) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| DCHECK(track); |
| DVLOG(1) << "WebRtcAudioCapturer::AddTrack()"; |
| + track->AddStopObserver(base::Bind(&WebRtcAudioCapturer::RemoveTrack, |
| + weak_factory_.GetWeakPtr(), track)); |
| + track->SetLevel(level_calculator_.level()); |
| + |
| + // The track only grabs stats from the audio processor. Stats are only |
| + // available if audio processing is turned on. Therefore, only provide the |
| + // track a reference if audio processing is turned on. |
| + if (audio_processor_->has_audio_processing()) |
| + track->SetAudioProcessor(audio_processor_); |
| + |
| { |
| base::AutoLock auto_lock(lock_); |
| // Verify that |track| is not already added to the list. |
| @@ -311,8 +273,7 @@ void WebRtcAudioCapturer::RemoveTrack(WebRtcLocalAudioTrack* track) { |
| void WebRtcAudioCapturer::SetCapturerSourceInternal( |
| const scoped_refptr<media::AudioCapturerSource>& source, |
| media::ChannelLayout channel_layout, |
| - int sample_rate, |
| - int buffer_size) { |
| + int sample_rate) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," |
| << "sample_rate=" << sample_rate << ")"; |
| @@ -333,19 +294,16 @@ void WebRtcAudioCapturer::SetCapturerSourceInternal( |
| if (old_source.get()) |
| old_source->Stop(); |
| - // If the buffer size is zero, it has not been specified. |
| - // We either default to 10ms, or use the hardware buffer size. |
| - if (buffer_size == 0) |
| - buffer_size = GetBufferSize(sample_rate); |
| - |
| // Dispatch the new parameters both to the sink(s) and to the new source, |
| // also apply the new |constraints|. |
| // The idea is to get rid of any dependency of the microphone parameters |
| // which would normally be used by default. |
| // bits_per_sample is always 16 for now. |
| media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| - channel_layout, sample_rate, 16, buffer_size); |
| + channel_layout, sample_rate, 16, |
| + GetBufferSize(sample_rate)); |
| params.set_effects(device_info_.device.input.effects); |
| + DCHECK(params.IsValid()); |
| { |
| base::AutoLock auto_lock(lock_); |
| @@ -357,7 +315,7 @@ void WebRtcAudioCapturer::SetCapturerSourceInternal( |
| } |
| if (source.get()) |
| - source->Initialize(params, this, session_id()); |
| + source->Initialize(params, this, device_info_.session_id); |
| Start(); |
| } |
| @@ -393,8 +351,7 @@ void WebRtcAudioCapturer::EnablePeerConnectionMode() { |
| // WebRtc native buffer size. |
| SetCapturerSourceInternal(AudioDeviceFactory::NewInputDevice(render_frame_id), |
| input_params.channel_layout(), |
| - input_params.sample_rate(), |
| - 0); |
| + input_params.sample_rate()); |
| } |
| void WebRtcAudioCapturer::Start() { |
| @@ -431,6 +388,10 @@ void WebRtcAudioCapturer::Stop() { |
| if (audio_device_) |
| audio_device_->RemoveAudioCapturer(this); |
| + // Invalidate the weak pointers since we don't need the tracks to call our |
| + // RemoveTrack() method when their Stop() method is called. |
| + weak_factory_.InvalidateWeakPtrs(); |
| + |
| for (TrackList::ItemList::const_iterator it = tracks.begin(); |
| it != tracks.end(); |
| ++it) { |
| @@ -517,16 +478,13 @@ void WebRtcAudioCapturer::Capture(const media::AudioBus* audio_source, |
| // |tracks_to_notify_format| is empty. |
| const media::AudioParameters& output_params = |
| audio_processor_->OutputFormat(); |
|
o1ka
2016/02/29 14:28:04
Should we be on the valid thread, see Line 427?
miu
2016/03/01 09:43:55
No. This is another case of #1 (in my last commen
o1ka
2016/03/01 14:18:59
Could you make a comment on this? Would be very he
miu
2016/03/02 01:12:50
Done. I also "grouped" this code with the DCHECKs
|
| - for (const auto& track : tracks_to_notify_format) { |
| + for (const auto& track : tracks_to_notify_format) |
| track->OnSetFormat(output_params); |
| - track->SetAudioProcessor(audio_processor_); |
| - } |
| - // Figure out if the pre-processed data has any energy or not, the |
| - // information will be passed to the track to force the calculator |
| - // to report energy in case the post-processed data is zeroed by the audio |
| - // processing. |
| - const bool force_report_nonzero_energy = HasDataEnergy(*audio_source); |
| + // Figure out if the pre-processed data has any energy or not. This |
| + // information will be passed to the level calculator to force it to report |
| + // energy in case the post-processed data is zeroed by the audio processing. |
| + const bool force_report_nonzero_energy = !audio_source->AreFramesZero(); |
| // Push the data to the processor for processing. |
| audio_processor_->PushCaptureData( |
| @@ -542,13 +500,13 @@ void WebRtcAudioCapturer::Capture(const media::AudioBus* audio_source, |
| current_volume, key_pressed, |
| &processed_data, &processed_data_audio_delay, &new_volume)) { |
| DCHECK(processed_data); |
| + |
| + level_calculator_.Calculate(*processed_data, force_report_nonzero_energy); |
| + |
| const base::TimeTicks processed_data_capture_time = |
| reference_clock_snapshot - processed_data_audio_delay; |
| - for (const auto& track : tracks) { |
| - track->Capture(*processed_data, |
| - processed_data_capture_time, |
| - force_report_nonzero_energy); |
| - } |
| + for (const auto& track : tracks) |
| + track->Capture(*processed_data, processed_data_capture_time); |
| if (new_volume) { |
| SetVolume(new_volume); |
| @@ -563,28 +521,9 @@ void WebRtcAudioCapturer::OnCaptureError(const std::string& message) { |
| WebRtcLogMessage("WAC::OnCaptureError: " + message); |
| } |
| -media::AudioParameters WebRtcAudioCapturer::source_audio_parameters() const { |
| +media::AudioParameters WebRtcAudioCapturer::GetInputFormat() const { |
| base::AutoLock auto_lock(lock_); |
| - return audio_processor_.get() ? audio_processor_->InputFormat() |
| - : media::AudioParameters(); |
| -} |
| - |
| -bool WebRtcAudioCapturer::GetPairedOutputParameters( |
| - int* session_id, |
| - int* output_sample_rate, |
| - int* output_frames_per_buffer) const { |
| - // Don't set output parameters unless all of them are valid. |
| - if (device_info_.session_id <= 0 || |
| - !device_info_.device.matched_output.sample_rate || |
| - !device_info_.device.matched_output.frames_per_buffer) |
| - return false; |
| - |
| - *session_id = device_info_.session_id; |
| - *output_sample_rate = device_info_.device.matched_output.sample_rate; |
| - *output_frames_per_buffer = |
| - device_info_.device.matched_output.frames_per_buffer; |
| - |
| - return true; |
| + return audio_processor_->InputFormat(); |
| } |
| int WebRtcAudioCapturer::GetBufferSize(int sample_rate) const { |
| @@ -617,10 +556,8 @@ void WebRtcAudioCapturer::SetCapturerSource( |
| const scoped_refptr<media::AudioCapturerSource>& source, |
| media::AudioParameters params) { |
| // Create a new audio stream as source which uses the new source. |
| - SetCapturerSourceInternal(source, |
| - params.channel_layout(), |
| - params.sample_rate(), |
| - 0); |
| + SetCapturerSourceInternal(source, params.channel_layout(), |
| + params.sample_rate()); |
| } |
| } // namespace content |