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 |