Index: media/base/audio_block_fifo.cc |
diff --git a/media/base/audio_block_fifo.cc b/media/base/audio_block_fifo.cc |
index 4313cad7c75e9d891a600af0df552f082e094e59..be15fb11638729c914ba9293e092c9d5b0e140c7 100644 |
--- a/media/base/audio_block_fifo.cc |
+++ b/media/base/audio_block_fifo.cc |
@@ -27,38 +27,11 @@ AudioBlockFifo::~AudioBlockFifo() {} |
void AudioBlockFifo::Push(const void* source, |
int frames, |
int bytes_per_sample) { |
- DCHECK(source); |
- DCHECK_GT(frames, 0); |
- DCHECK_GT(bytes_per_sample, 0); |
- DCHECK_LT(available_blocks_, static_cast<int>(audio_blocks_.size())); |
- CHECK_LE(frames, GetUnfilledFrames()); |
- |
- const uint8_t* source_ptr = static_cast<const uint8_t*>(source); |
- int frames_to_push = frames; |
- while (frames_to_push) { |
- // Get the current write block. |
- AudioBus* current_block = audio_blocks_[write_block_]; |
- |
- // Figure out what segment sizes we need when adding the new content to |
- // the FIFO. |
- const int push_frames = |
- std::min(block_frames_ - write_pos_, frames_to_push); |
- |
- // Deinterleave the content to the FIFO and update the |write_pos_|. |
- current_block->FromInterleavedPartial( |
- source_ptr, write_pos_, push_frames, bytes_per_sample); |
- write_pos_ = (write_pos_ + push_frames) % block_frames_; |
- if (!write_pos_) { |
- // The current block is completely filled, increment |write_block_| and |
- // |available_blocks_|. |
- write_block_ = (write_block_ + 1) % audio_blocks_.size(); |
- ++available_blocks_; |
- } |
+ PushInternal(source, frames, bytes_per_sample); |
+} |
- source_ptr += push_frames * bytes_per_sample * channels_; |
- frames_to_push -= push_frames; |
- DCHECK_GE(frames_to_push, 0); |
- } |
+void AudioBlockFifo::PushSilence(int frames) { |
+ PushInternal(nullptr, frames, 0); |
} |
const AudioBus* AudioBlockFifo::Consume() { |
@@ -103,8 +76,7 @@ void AudioBlockFifo::IncreaseCapacity(int blocks) { |
return; |
std::rotate(audio_blocks_.begin() + read_block_, |
- audio_blocks_.begin() + original_size, |
- audio_blocks_.end()); |
+ audio_blocks_.begin() + original_size, audio_blocks_.end()); |
// Update the write pointer if it is on top of the new inserted blocks. |
if (write_block_ >= read_block_) |
@@ -117,4 +89,47 @@ void AudioBlockFifo::IncreaseCapacity(int blocks) { |
DCHECK_LT(write_block_, static_cast<int>(audio_blocks_.size())); |
} |
+void AudioBlockFifo::PushInternal(const void* source, |
+ int frames, |
+ int bytes_per_sample) { |
+ // |source| may be nullptr if bytes_per_sample is 0. In that case, |
+ // we inject silence. |
+ DCHECK((source && bytes_per_sample > 0) || (!source && !bytes_per_sample)); |
+ DCHECK_GT(frames, 0); |
+ DCHECK_LT(available_blocks_, static_cast<int>(audio_blocks_.size())); |
+ CHECK_LE(frames, GetUnfilledFrames()); |
+ |
+ const uint8_t* source_ptr = static_cast<const uint8_t*>(source); |
+ int frames_to_push = frames; |
+ while (frames_to_push) { |
+ // Get the current write block. |
+ AudioBus* current_block = audio_blocks_[write_block_]; |
+ |
+ // Figure out what segment sizes we need when adding the new content to |
+ // the FIFO. |
+ const int push_frames = |
+ std::min(block_frames_ - write_pos_, frames_to_push); |
+ |
+ if (source) { |
+ // Deinterleave the content to the FIFO and update the |write_pos_|. |
+ current_block->FromInterleavedPartial(source_ptr, write_pos_, push_frames, |
+ bytes_per_sample); |
+ } else { |
+ current_block->ZeroFramesPartial(write_pos_, push_frames); |
+ } |
+ write_pos_ = (write_pos_ + push_frames) % block_frames_; |
+ if (!write_pos_) { |
+ // The current block is completely filled, increment |write_block_| and |
+ // |available_blocks_|. |
+ write_block_ = (write_block_ + 1) % audio_blocks_.size(); |
+ ++available_blocks_; |
+ } |
+ |
+ if (source_ptr) |
+ source_ptr += push_frames * bytes_per_sample * channels_; |
+ frames_to_push -= push_frames; |
+ DCHECK_GE(frames_to_push, 0); |
+ } |
+} |
+ |
} // namespace media |