1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_buffer_converter.h"
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <cmath>
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/logging.h"
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_buffer.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_bus.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_decoder_config.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_timestamp_helper.h"
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/buffers.h"
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/sinc_resampler.h"
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/vector_math.h"
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace media {
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Is the config presented by |buffer| a config change from |params|?
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstatic bool IsConfigChange(const AudioParameters& params,
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                           const scoped_refptr<AudioBuffer>& buffer) {
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return buffer->sample_rate() != params.sample_rate() ||
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         buffer->channel_count() != params.channels() ||
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         buffer->channel_layout() != params.channel_layout();
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
28effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochAudioBufferConverter::AudioBufferConverter(const AudioParameters& output_params)
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    : output_params_(output_params),
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      input_params_(output_params),
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      last_input_buffer_offset_(0),
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      input_frames_(0),
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      buffered_input_frames_(0.0),
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      io_sample_rate_ratio_(1.0),
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      timestamp_helper_(output_params_.sample_rate()),
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      is_flushing_(false) {}
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
38effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochAudioBufferConverter::~AudioBufferConverter() {}
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AudioBufferConverter::AddInput(const scoped_refptr<AudioBuffer>& buffer) {
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // On EOS flush any remaining buffered data.
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (buffer->end_of_stream()) {
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    Flush();
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    queued_outputs_.push_back(buffer);
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // We'll need a new |audio_converter_| if there was a config change.
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (IsConfigChange(input_params_, buffer))
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ResetConverter(buffer);
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Pass straight through if there's no work to be done.
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!audio_converter_) {
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    queued_outputs_.push_back(buffer);
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (timestamp_helper_.base_timestamp() == kNoTimestamp())
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    timestamp_helper_.SetBaseTimestamp(buffer->timestamp());
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  queued_inputs_.push_back(buffer);
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_frames_ += buffer->frame_count();
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ConvertIfPossible();
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool AudioBufferConverter::HasNextBuffer() { return !queued_outputs_.empty(); }
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_refptr<AudioBuffer> AudioBufferConverter::GetNextBuffer() {
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(!queued_outputs_.empty());
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_refptr<AudioBuffer> out = queued_outputs_.front();
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  queued_outputs_.pop_front();
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return out;
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AudioBufferConverter::Reset() {
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  audio_converter_.reset();
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  queued_inputs_.clear();
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  queued_outputs_.clear();
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  timestamp_helper_.SetBaseTimestamp(kNoTimestamp());
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_params_ = output_params_;
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_frames_ = 0;
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffered_input_frames_ = 0.0;
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  last_input_buffer_offset_ = 0;
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AudioBufferConverter::ResetTimestampState() {
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  Flush();
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  timestamp_helper_.SetBaseTimestamp(kNoTimestamp());
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochdouble AudioBufferConverter::ProvideInput(AudioBus* audio_bus,
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                          base::TimeDelta buffer_delay) {
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(is_flushing_ || input_frames_ >= audio_bus->frames());
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int requested_frames_left = audio_bus->frames();
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int dest_index = 0;
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  while (requested_frames_left > 0 && !queued_inputs_.empty()) {
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_refptr<AudioBuffer> input_buffer = queued_inputs_.front();
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    int frames_to_read =
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        std::min(requested_frames_left,
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                 input_buffer->frame_count() - last_input_buffer_offset_);
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    input_buffer->ReadFrames(
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        frames_to_read, last_input_buffer_offset_, dest_index, audio_bus);
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    last_input_buffer_offset_ += frames_to_read;
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (last_input_buffer_offset_ == input_buffer->frame_count()) {
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // We've consumed all the frames in |input_buffer|.
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      queued_inputs_.pop_front();
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      last_input_buffer_offset_ = 0;
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    requested_frames_left -= frames_to_read;
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    dest_index += frames_to_read;
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // If we're flushing, zero any extra space, otherwise we should always have
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // enough data to completely fulfill the request.
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (is_flushing_ && requested_frames_left > 0) {
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    audio_bus->ZeroFramesPartial(audio_bus->frames() - requested_frames_left,
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 requested_frames_left);
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } else {
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK_EQ(requested_frames_left, 0);
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_frames_ -= audio_bus->frames() - requested_frames_left;
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_GE(input_frames_, 0);
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffered_input_frames_ += audio_bus->frames() - requested_frames_left;
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Full volume.
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return 1.0;
135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AudioBufferConverter::ResetConverter(
138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const scoped_refptr<AudioBuffer>& buffer) {
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  Flush();
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  audio_converter_.reset();
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  input_params_.Reset(
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      input_params_.format(),
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      buffer->channel_layout(),
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      buffer->channel_count(),
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      buffer->sample_rate(),
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      input_params_.bits_per_sample(),
1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // If resampling is needed and the FIFO disabled, the AudioConverter will
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // always request SincResampler::kDefaultRequestSize frames.  Otherwise it
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // will use the output frame size.
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      buffer->sample_rate() == output_params_.sample_rate()
1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          ? output_params_.frames_per_buffer()
1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          : SincResampler::kDefaultRequestSize);
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  io_sample_rate_ratio_ = static_cast<double>(input_params_.sample_rate()) /
155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          output_params_.sample_rate();
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // If |buffer| matches |output_params_| we don't need an AudioConverter at
158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // all, and can early-out here.
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!IsConfigChange(output_params_, buffer))
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Note: The FIFO is disabled to avoid extraneous memcpy().
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  audio_converter_.reset(
164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      new AudioConverter(input_params_, output_params_, true));
165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  audio_converter_->AddInput(this);
166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AudioBufferConverter::ConvertIfPossible() {
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(audio_converter_);
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int request_frames = 0;
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (is_flushing_) {
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // If we're flushing we want to convert *everything* even if this means
175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // we'll have to pad some silence in ProvideInput().
176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    request_frames =
177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        ceil((buffered_input_frames_ + input_frames_) / io_sample_rate_ratio_);
178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } else {
179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // How many calls to ProvideInput() we can satisfy completely.
180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    int chunks = input_frames_ / input_params_.frames_per_buffer();
181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // How many output frames that corresponds to:
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    request_frames = chunks * audio_converter_->ChunkSize();
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!request_frames)
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_refptr<AudioBuffer> output_buffer =
190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      AudioBuffer::CreateBuffer(kSampleFormatPlanarF32,
191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                output_params_.channel_layout(),
192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                output_params_.channels(),
193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                output_params_.sample_rate(),
194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                request_frames);
195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<AudioBus> output_bus =
196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      AudioBus::CreateWrapper(output_buffer->channel_count());
197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  int frames_remaining = request_frames;
199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // The AudioConverter wants requests of a fixed size, so we'll slide an
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // AudioBus of that size across the |output_buffer|.
202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  while (frames_remaining != 0) {
203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // It's important that this is a multiple of AudioBus::kChannelAlignment in
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // all requests except for the last, otherwise downstream SIMD optimizations
205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // will crash on unaligned data.
206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const int frames_this_iteration = std::min(
207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        static_cast<int>(SincResampler::kDefaultRequestSize), frames_remaining);
208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const int offset_into_buffer =
209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        output_buffer->frame_count() - frames_remaining;
210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Wrap the portion of the AudioBuffer in an AudioBus so the AudioConverter
212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // can fill it.
213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    output_bus->set_frames(frames_this_iteration);
214effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    for (int ch = 0; ch < output_buffer->channel_count(); ++ch) {
215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      output_bus->SetChannelData(
216effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          ch,
217effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          reinterpret_cast<float*>(output_buffer->channel_data()[ch]) +
218effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch              offset_into_buffer);
219effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
220effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Do the actual conversion.
222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    audio_converter_->Convert(output_bus.get());
223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    frames_remaining -= frames_this_iteration;
224effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    buffered_input_frames_ -= frames_this_iteration * io_sample_rate_ratio_;
225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
226effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
227effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Compute the timestamp.
228effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  output_buffer->set_timestamp(timestamp_helper_.GetTimestamp());
229effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  timestamp_helper_.AddFrames(request_frames);
230effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  queued_outputs_.push_back(output_buffer);
232effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
233effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AudioBufferConverter::Flush() {
235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!audio_converter_)
236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return;
237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  is_flushing_ = true;
238effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ConvertIfPossible();
239effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  is_flushing_ = false;
240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  audio_converter_->Reset();
241effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_EQ(input_frames_, 0);
242effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_EQ(last_input_buffer_offset_, 0);
243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_LT(buffered_input_frames_, 1.0);
244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(queued_inputs_.empty());
245effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffered_input_frames_ = 0.0;
246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}  // namespace media
249