blob: 4184a98b2c1ac41b33af23608112a5b664765848 [file] [log] [blame]
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/filters/audio_renderer_algorithm_default.h"
#include "media/base/buffers.h"
#include "media/base/data_buffer.h"
namespace media {
AudioRendererAlgorithmDefault::AudioRendererAlgorithmDefault()
: data_offset_(0) {
}
AudioRendererAlgorithmDefault::~AudioRendererAlgorithmDefault() {
}
size_t AudioRendererAlgorithmDefault::FillBuffer(DataBuffer* buffer_out) {
size_t dest_written = 0;
if (playback_rate() == 0.0f) {
return 0;
}
if (playback_rate() == 1.0f) {
size_t dest_length = buffer_out->GetDataSize();
uint8* dest = buffer_out->GetWritableData(dest_length);
while (dest_length > 0 && !IsQueueEmpty()) {
scoped_refptr<Buffer> buffer = FrontQueue();
size_t data_length = buffer->GetDataSize() - data_offset_;
// Prevent writing past end of the buffer.
if (data_length > dest_length)
data_length = dest_length;
memcpy(dest, buffer->GetData() + data_offset_, data_length);
dest += data_length;
dest_length -= data_length;
dest_written += data_length;
data_offset_ += data_length;
// We should not have run over the end of the buffer.
DCHECK_GE(buffer->GetDataSize(), data_offset_);
// but if we've reached the end, dequeue it.
if (buffer->GetDataSize() - data_offset_ == 0) {
PopFrontQueue();
data_offset_ = 0;
}
}
} else {
// Mute (we will write to the whole buffer, so set |dest_written|
// to the requested size).
dest_written = buffer_out->GetDataSize();
memset(buffer_out->GetWritableData(dest_written), 0, dest_written);
// Discard any buffers that should be "used".
size_t scaled_dest_length_remaining =
static_cast<size_t>(dest_written * playback_rate());
while (scaled_dest_length_remaining > 0 && !IsQueueEmpty()) {
size_t data_length = FrontQueue()->GetDataSize() - data_offset_;
// Last buffer we need.
if (data_length > scaled_dest_length_remaining) {
data_offset_ += scaled_dest_length_remaining;
} else {
scaled_dest_length_remaining -= data_length;
PopFrontQueue();
data_offset_ = 0;
}
}
// If we ran out, don't report we used more than we did.
if (IsQueueEmpty()) {
dest_written -=
static_cast<size_t>(scaled_dest_length_remaining / playback_rate());
}
}
return dest_written;
}
} // namespace media