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

Unified Diff: content/renderer/media/webrtc_audio_capturer.cc

Issue 1780653002: Revert of MediaStream audio object graph untangling and clean-ups. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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 side-by-side diff with in-line comments
Download patch
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 9337756466598745357db83f5d09cca21061eaf4..9c56be0b705de454ef71eb6c08f1d841c900c098 100644
--- a/content/renderer/media/webrtc_audio_capturer.cc
+++ b/content/renderer/media/webrtc_audio_capturer.cc
@@ -24,6 +24,29 @@
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
@@ -33,10 +56,13 @@
: delegate_(track) {}
void Capture(const media::AudioBus& audio_bus,
- base::TimeTicks estimated_capture_time) {
+ base::TimeTicks estimated_capture_time,
+ bool force_report_nonzero_energy) {
base::AutoLock lock(lock_);
if (delegate_) {
- delegate_->Capture(audio_bus, estimated_capture_time);
+ delegate_->Capture(audio_bus,
+ estimated_capture_time,
+ force_report_nonzero_energy);
}
}
@@ -44,6 +70,13 @@
base::AutoLock lock(lock_);
if (delegate_)
delegate_->OnSetFormat(params);
+ }
+
+ void SetAudioProcessor(
+ const scoped_refptr<MediaStreamAudioProcessor>& processor) {
+ base::AutoLock lock(lock_);
+ if (delegate_)
+ delegate_->SetAudioProcessor(processor);
}
void Reset() {
@@ -91,14 +124,14 @@
};
// static
-scoped_ptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer(
+scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer(
int render_frame_id,
const StreamDeviceInfo& device_info,
const blink::WebMediaConstraints& constraints,
WebRtcAudioDeviceImpl* audio_device,
MediaStreamAudioSource* audio_source) {
- scoped_ptr<WebRtcAudioCapturer> capturer(new WebRtcAudioCapturer(
- render_frame_id, device_info, constraints, audio_device, audio_source));
+ scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer(
+ render_frame_id, device_info, constraints, audio_device, audio_source);
if (capturer->Initialize())
return capturer;
@@ -173,10 +206,27 @@
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);
+ AudioDeviceFactory::NewInputDevice(render_frame_id_),
+ channel_layout,
+ device_info_.device.input.sample_rate,
+ buffer_size_samples);
// Add the capturer to the WebRtcAudioDeviceImpl since it needs some hardware
// information from the capturer.
@@ -215,17 +265,8 @@
}
void WebRtcAudioCapturer::AddTrack(WebRtcLocalAudioTrack* track) {
- DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(track);
DVLOG(1) << "WebRtcAudioCapturer::AddTrack()";
-
- 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_);
@@ -270,7 +311,8 @@
void WebRtcAudioCapturer::SetCapturerSourceInternal(
const scoped_refptr<media::AudioCapturerSource>& source,
media::ChannelLayout channel_layout,
- int sample_rate) {
+ int sample_rate,
+ int buffer_size) {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << ","
<< "sample_rate=" << sample_rate << ")";
@@ -291,25 +333,23 @@
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,
- GetBufferSize(sample_rate));
+ channel_layout, sample_rate, 16, buffer_size);
params.set_effects(device_info_.device.input.effects);
- DCHECK(params.IsValid());
{
base::AutoLock auto_lock(lock_);
-
- // Notify the |audio_processor_| of the new format. We're doing this while
- // the lock is held only because the signaling thread might be calling
- // GetInputFormat(). Simultaneous reads from the audio thread are NOT the
- // concern here since the source is currently stopped (i.e., no audio
- // capture calls can be executing).
+ // Notify the |audio_processor_| of the new format.
audio_processor_->OnCaptureFormatChanged(params);
// Notify all tracks about the new format.
@@ -317,7 +357,7 @@
}
if (source.get())
- source->Initialize(params, this, device_info_.session_id);
+ source->Initialize(params, this, session_id());
Start();
}
@@ -353,7 +393,8 @@
// WebRtc native buffer size.
SetCapturerSourceInternal(AudioDeviceFactory::NewInputDevice(render_frame_id),
input_params.channel_layout(),
- input_params.sample_rate());
+ input_params.sample_rate(),
+ 0);
}
void WebRtcAudioCapturer::Start() {
@@ -466,28 +507,26 @@
tracks_.RetrieveAndClearTags(&tracks_to_notify_format);
}
- // Sanity-check the input audio format in debug builds. Then, notify the
- // tracks if the format has changed.
- //
- // Locking is not needed here to read the audio input/output parameters
- // because the audio processor format changes only occur while audio capture
- // is stopped.
DCHECK(audio_processor_->InputFormat().IsValid());
DCHECK_EQ(audio_source->channels(),
audio_processor_->InputFormat().channels());
DCHECK_EQ(audio_source->frames(),
audio_processor_->InputFormat().frames_per_buffer());
- if (!tracks_to_notify_format.empty()) {
- const media::AudioParameters& output_params =
- audio_processor_->OutputFormat();
- for (const auto& track : tracks_to_notify_format)
- track->OnSetFormat(output_params);
- }
-
- // 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();
+
+ // Notify the tracks on when the format changes. This will do nothing if
+ // |tracks_to_notify_format| is empty.
+ const media::AudioParameters& output_params =
+ audio_processor_->OutputFormat();
+ 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);
// Push the data to the processor for processing.
audio_processor_->PushCaptureData(
@@ -503,13 +542,13 @@
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);
+ for (const auto& track : tracks) {
+ track->Capture(*processed_data,
+ processed_data_capture_time,
+ force_report_nonzero_energy);
+ }
if (new_volume) {
SetVolume(new_volume);
@@ -524,9 +563,28 @@
WebRtcLogMessage("WAC::OnCaptureError: " + message);
}
-media::AudioParameters WebRtcAudioCapturer::GetInputFormat() const {
+media::AudioParameters WebRtcAudioCapturer::source_audio_parameters() const {
base::AutoLock auto_lock(lock_);
- return audio_processor_->InputFormat();
+ 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;
}
int WebRtcAudioCapturer::GetBufferSize(int sample_rate) const {
@@ -559,8 +617,10 @@
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());
+ SetCapturerSourceInternal(source,
+ params.channel_layout(),
+ params.sample_rate(),
+ 0);
}
} // namespace content
« no previous file with comments | « content/renderer/media/webrtc_audio_capturer.h ('k') | content/renderer/media/webrtc_audio_capturer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698