diff options
author | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-21 19:36:51 +0000 |
---|---|---|
committer | xians@chromium.org <xians@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-21 19:36:51 +0000 |
commit | 18359a3aa881f0ba88edae325e3cf883f28e82d6 (patch) | |
tree | 6e5dcc2d4e1b2ea46e40fc027b8f95aca6861e20 /media/audio | |
parent | c2693b6468dec685495c6c01f631a75d67ce40de (diff) | |
download | chromium_src-18359a3aa881f0ba88edae325e3cf883f28e82d6.zip chromium_src-18359a3aa881f0ba88edae325e3cf883f28e82d6.tar.gz chromium_src-18359a3aa881f0ba88edae325e3cf883f28e82d6.tar.bz2 |
Switch the input code to use AudioBlockFifo.
It saves two memcpy and quite some intermedia AudioBus code.
Also, this CL corrects a mistake in https://codereview.chromium.org/389623002/ by using FromInterleavedPartial() instead of FromInterleaved().
BUG=393199
TEST=bots and webrtc loopback test: https://apprtc.appspot.com
Review URL: https://codereview.chromium.org/396263004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284477 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r-- | media/audio/mac/audio_low_latency_input_mac.cc | 53 | ||||
-rw-r--r-- | media/audio/mac/audio_low_latency_input_mac.h | 14 | ||||
-rw-r--r-- | media/audio/pulse/pulse_input.cc | 30 | ||||
-rw-r--r-- | media/audio/pulse/pulse_input.h | 10 |
4 files changed, 34 insertions, 73 deletions
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc index f0f6629..f1dbdf7 100644 --- a/media/audio/mac/audio_low_latency_input_mac.cc +++ b/media/audio/mac/audio_low_latency_input_mac.cc @@ -11,11 +11,13 @@ #include "base/mac/mac_logging.h" #include "media/audio/mac/audio_manager_mac.h" #include "media/base/audio_bus.h" -#include "media/base/audio_fifo.h" #include "media/base/data_buffer.h" namespace media { +// Number of blocks of buffers used in the |fifo_|. +const int kNumberOfBlocksBufferInFifo = 2; + static std::ostream& operator<<(std::ostream& os, const AudioStreamBasicDescription& format) { os << "sample rate : " << format.mSampleRate << std::endl @@ -44,8 +46,9 @@ AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager, started_(false), hardware_latency_frames_(0), number_of_channels_in_frame_(0), - audio_bus_(media::AudioBus::Create(input_params)), - audio_wrapper_(media::AudioBus::Create(input_params)) { + fifo_(input_params.channels(), + number_of_frames_, + kNumberOfBlocksBufferInFifo) { DCHECK(manager_); // Set up the desired (output) format specified by the client. @@ -494,43 +497,17 @@ OSStatus AUAudioInputStream::Provide(UInt32 number_of_frames, if (!audio_data) return kAudioUnitErr_InvalidElement; - if (number_of_frames != number_of_frames_) { - // Create a FIFO on the fly to handle any discrepancies in callback rates. - if (!fifo_) { - VLOG(1) << "Audio frame size changed from " << number_of_frames_ << " to " - << number_of_frames << "; adding FIFO to compensate."; - fifo_.reset(new AudioFifo( - format_.mChannelsPerFrame, number_of_frames_ + number_of_frames)); - } - - if (audio_wrapper_->frames() != static_cast<int>(number_of_frames)) { - audio_wrapper_ = media::AudioBus::Create(format_.mChannelsPerFrame, - number_of_frames); - } - } - - // Copy captured (and interleaved) data into deinterleaved audio bus. - audio_wrapper_->FromInterleaved( - audio_data, audio_wrapper_->frames(), format_.mBitsPerChannel / 8); - - // When FIFO does not kick in, data will be directly passed to the callback. - if (!fifo_) { - CHECK_EQ(audio_wrapper_->frames(), static_cast<int>(number_of_frames_)); - sink_->OnData( - this, audio_wrapper_.get(), capture_delay_bytes, normalized_volume); - return noErr; - } + // Copy captured (and interleaved) data into FIFO. + fifo_.Push(audio_data, number_of_frames, format_.mBitsPerChannel / 8); - // Compensate the audio delay caused by the FIFO. - capture_delay_bytes += fifo_->frames() * format_.mBytesPerFrame; - fifo_->Push(audio_wrapper_.get()); - if (fifo_->frames() >= static_cast<int>(number_of_frames_)) { - // Consume the audio from the FIFO. - fifo_->Consume(audio_bus_.get(), 0, audio_bus_->frames()); - DCHECK(fifo_->frames() < static_cast<int>(number_of_frames_)); + // Consume and deliver the data when the FIFO has a block of available data. + while (fifo_.available_blocks()) { + const AudioBus* audio_bus = fifo_.Consume(); + DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_)); - sink_->OnData( - this, audio_bus_.get(), capture_delay_bytes, normalized_volume); + // Compensate the audio delay caused by the FIFO. + capture_delay_bytes += fifo_.GetAvailableFrames() * format_.mBytesPerFrame; + sink_->OnData(this, audio_bus, capture_delay_bytes, normalized_volume); } return noErr; diff --git a/media/audio/mac/audio_low_latency_input_mac.h b/media/audio/mac/audio_low_latency_input_mac.h index 059cf1f..c8e43fa 100644 --- a/media/audio/mac/audio_low_latency_input_mac.h +++ b/media/audio/mac/audio_low_latency_input_mac.h @@ -45,11 +45,11 @@ #include "media/audio/agc_audio_stream.h" #include "media/audio/audio_io.h" #include "media/audio/audio_parameters.h" +#include "media/base/audio_block_fifo.h" namespace media { class AudioBus; -class AudioFifo; class AudioManagerMac; class DataBuffer; @@ -148,20 +148,12 @@ class AUAudioInputStream : public AgcAudioStream<AudioInputStream> { // when querying the volume of each channel. int number_of_channels_in_frame_; - // Dynamically allocated FIFO used to accumulates recorded data when - // CoreAudio delivers non-requested frame size of data. - scoped_ptr<media::AudioFifo> fifo_; + // FIFO used to accumulates recorded data. + media::AudioBlockFifo fifo_; // Used to defer Start() to workaround http://crbug.com/160920. base::CancelableClosure deferred_start_cb_; - // Audio bus used for storage of deinterleaved data for the OnData callback. - scoped_ptr<media::AudioBus> audio_bus_; - - // Audio bus used to convert interleaved data to deinterleaved data before - // storing data to FIFO or delivering data via OnData callback. - scoped_ptr<media::AudioBus> audio_wrapper_; - DISALLOW_COPY_AND_ASSIGN(AUAudioInputStream); }; diff --git a/media/audio/pulse/pulse_input.cc b/media/audio/pulse/pulse_input.cc index d5cb94ec..3509d27 100644 --- a/media/audio/pulse/pulse_input.cc +++ b/media/audio/pulse/pulse_input.cc @@ -9,13 +9,15 @@ #include "base/logging.h" #include "media/audio/pulse/audio_manager_pulse.h" #include "media/audio/pulse/pulse_util.h" -#include "media/base/seekable_buffer.h" namespace media { using pulse::AutoPulseLock; using pulse::WaitForOperationCompletion; +// Number of blocks of buffers used in the |fifo_|. +const int kNumberOfBlocksBufferInFifo = 2; + PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager, const std::string& device_name, const AudioParameters& params, @@ -28,6 +30,9 @@ PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager, channels_(0), volume_(0.0), stream_started_(false), + fifo_(params.channels(), + params.frames_per_buffer(), + kNumberOfBlocksBufferInFifo), pa_mainloop_(mainloop), pa_context_(context), handle_(NULL), @@ -35,7 +40,6 @@ PulseAudioInputStream::PulseAudioInputStream(AudioManagerPulse* audio_manager, DCHECK(mainloop); DCHECK(context); CHECK(params_.IsValid()); - audio_bus_ = AudioBus::Create(params_); } PulseAudioInputStream::~PulseAudioInputStream() { @@ -54,8 +58,6 @@ bool PulseAudioInputStream::Open() { DCHECK(handle_); - buffer_.reset(new media::SeekableBuffer(0, 2 * params_.GetBytesPerBuffer())); - audio_data_buffer_.reset(new uint8[params_.GetBytesPerBuffer()]); return true; } @@ -74,7 +76,7 @@ void PulseAudioInputStream::Start(AudioInputCallback* callback) { // Clean up the old buffer. pa_stream_drop(handle_); - buffer_->Clear(); + fifo_.Clear(); // Start the streaming. callback_ = callback; @@ -265,23 +267,19 @@ void PulseAudioInputStream::ReadData() { if (!data || length == 0) break; - buffer_->Append(reinterpret_cast<const uint8*>(data), length); + const int number_of_frames = length / params_.GetBytesPerFrame(); + fifo_.Push(data, number_of_frames, params_.bits_per_sample() / 8); // Checks if we still have data. pa_stream_drop(handle_); } while (pa_stream_readable_size(handle_) > 0); - int packet_size = params_.GetBytesPerBuffer(); - while (buffer_->forward_bytes() >= packet_size) { - buffer_->Read(audio_data_buffer_.get(), packet_size); - audio_bus_->FromInterleaved(audio_data_buffer_.get(), - audio_bus_->frames(), - params_.bits_per_sample() / 8); - callback_->OnData( - this, audio_bus_.get(), hardware_delay, normalized_volume); + while (fifo_.available_blocks()) { + const AudioBus* audio_bus = fifo_.Consume(); - if (buffer_->forward_bytes() < packet_size) - break; + // Compensate the audio delay caused by the FIFO. + hardware_delay += fifo_.GetAvailableFrames() * params_.GetBytesPerFrame(); + callback_->OnData(this, audio_bus, hardware_delay, normalized_volume); // TODO(xians): Remove once PPAPI is using circular buffers. DVLOG(1) << "OnData is being called consecutively, sleep 5ms to " diff --git a/media/audio/pulse/pulse_input.h b/media/audio/pulse/pulse_input.h index 7e64bb2..9f08379 100644 --- a/media/audio/pulse/pulse_input.h +++ b/media/audio/pulse/pulse_input.h @@ -12,6 +12,7 @@ #include "media/audio/audio_device_name.h" #include "media/audio/audio_io.h" #include "media/audio/audio_parameters.h" +#include "media/base/audio_block_fifo.h" struct pa_context; struct pa_source_info; @@ -21,7 +22,6 @@ struct pa_threaded_mainloop; namespace media { class AudioManagerPulse; -class SeekableBuffer; class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> { public: @@ -61,11 +61,7 @@ class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> { bool stream_started_; // Holds the data from the OS. - scoped_ptr<media::SeekableBuffer> buffer_; - - // Temporary storage for recorded data. It gets a packet of data from - // |buffer_| and deliver the data to OnData() callback. - scoped_ptr<uint8[]> audio_data_buffer_; + AudioBlockFifo fifo_; // PulseAudio API structs. pa_threaded_mainloop* pa_mainloop_; // Weak. @@ -75,8 +71,6 @@ class PulseAudioInputStream : public AgcAudioStream<AudioInputStream> { // Flag indicating the state of the context has been changed. bool context_state_changed_; - scoped_ptr<AudioBus> audio_bus_; - base::ThreadChecker thread_checker_; DISALLOW_COPY_AND_ASSIGN(PulseAudioInputStream); |