Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "media/base/audio_push_fifo.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 namespace media { | |
| 10 | |
| 11 AudioPushFifo::AudioPushFifo(const OutputCallback& callback) | |
| 12 : callback_(callback), output_frames_(0) { | |
| 13 DCHECK(!callback_.is_null()); | |
| 14 } | |
| 15 | |
| 16 AudioPushFifo::~AudioPushFifo() {} | |
| 17 | |
| 18 void AudioPushFifo::Reset(int frames_per_buffer) { | |
| 19 DCHECK_GT(frames_per_buffer, 0); | |
| 20 | |
| 21 audio_queue_.reset(); | |
|
xjz
2016/02/23 22:03:02
Is it possible that there are still pending packet
miu
2016/02/23 23:32:33
Yes. As Dale suggested, I've added a Flush() meth
| |
| 22 queued_frames_ = 0; | |
| 23 | |
| 24 output_frames_ = frames_per_buffer; | |
| 25 } | |
| 26 | |
| 27 void AudioPushFifo::Push(const AudioBus& input_bus) { | |
| 28 DCHECK_GT(output_frames_, 0); | |
| 29 | |
| 30 // Fast path: No buffering required. | |
| 31 if ((queued_frames_ == 0) && (input_bus.frames() == output_frames_)) { | |
| 32 callback_.Run(input_bus, 0); | |
| 33 return; | |
| 34 } | |
| 35 | |
| 36 // Lazy-create the |audio_queue_| if needed. | |
| 37 if (!audio_queue_ || audio_queue_->channels() != input_bus.channels()) | |
|
DaleCurtis
2016/02/23 20:34:26
Do you want to document that channel changes will
miu
2016/02/23 23:32:33
Done. In header comments for Push() method.
| |
| 38 audio_queue_ = AudioBus::Create(input_bus.channels(), output_frames_); | |
| 39 | |
| 40 // Start with a frame offset that refers to the position of the first sample | |
| 41 // in |audio_queue_| relative to the first sample in |input_bus|. | |
| 42 int frame_offset = -queued_frames_; | |
| 43 | |
| 44 // Repeatedly fill up |audio_queue_| with more sample frames from |input_bus| | |
| 45 // and deliver batches until all sample frames in |input_bus| have been | |
| 46 // consumed. | |
| 47 int input_offset = 0; | |
| 48 do { | |
| 49 // Attempt to fill |audio_queue_| completely. | |
| 50 const int frames_to_enqueue = | |
| 51 std::min(static_cast<int>(input_bus.frames() - input_offset), | |
| 52 output_frames_ - queued_frames_); | |
| 53 if (frames_to_enqueue > 0) { | |
| 54 DVLOG(2) << "Enqueuing " << frames_to_enqueue << " frames."; | |
| 55 input_bus.CopyPartialFramesTo(input_offset, frames_to_enqueue, | |
| 56 queued_frames_, audio_queue_.get()); | |
| 57 queued_frames_ += frames_to_enqueue; | |
| 58 input_offset += frames_to_enqueue; | |
| 59 } | |
| 60 | |
| 61 // If |audio_queue_| has been filled completely, deliver the re-buffered | |
| 62 // audio to the consumer. | |
| 63 if (queued_frames_ == output_frames_) { | |
| 64 DVLOG(2) << "Delivering another " << queued_frames_ << " frames."; | |
| 65 callback_.Run(*audio_queue_, frame_offset); | |
| 66 frame_offset += output_frames_; | |
| 67 queued_frames_ = 0; | |
| 68 } else { | |
| 69 // Not enough frames queued-up yet to deliver more frames. | |
| 70 } | |
| 71 } while (input_offset < input_bus.frames()); | |
| 72 } | |
| 73 | |
| 74 } // namespace media | |
| OLD | NEW |