This source file includes following definitions.
- bytes_consumed_
- ProcessAudioPacket
- AudioPlayerCallback
- ResetQueue
- FillWithSamples
#include "remoting/client/audio_player.h"
#include <algorithm>
#include "base/logging.h"
#include "base/stl_util.h"
const int kChannels = 2;
const int kSampleSizeBytes = 2;
const int kMaxQueueLatencyMs = 150;
namespace remoting {
AudioPlayer::AudioPlayer()
: sampling_rate_(AudioPacket::SAMPLING_RATE_INVALID),
start_failed_(false),
queued_bytes_(0),
bytes_consumed_(0) {
}
AudioPlayer::~AudioPlayer() {
base::AutoLock auto_lock(lock_);
ResetQueue();
}
void AudioPlayer::ProcessAudioPacket(scoped_ptr<AudioPacket> packet) {
CHECK_EQ(1, packet->data_size());
DCHECK_EQ(AudioPacket::ENCODING_RAW, packet->encoding());
DCHECK_NE(AudioPacket::SAMPLING_RATE_INVALID, packet->sampling_rate());
DCHECK_EQ(kSampleSizeBytes, packet->bytes_per_sample());
DCHECK_EQ(static_cast<int>(kChannels), packet->channels());
DCHECK_EQ(packet->data(0).size() % (kChannels * kSampleSizeBytes), 0u);
if (start_failed_) {
return;
}
if (sampling_rate_ != packet->sampling_rate()) {
{
base::AutoLock auto_lock(lock_);
ResetQueue();
}
sampling_rate_ = packet->sampling_rate();
bool success = ResetAudioPlayer(sampling_rate_);
if (!success) {
start_failed_ = true;
return;
}
}
base::AutoLock auto_lock(lock_);
queued_bytes_ += packet->data(0).size();
queued_packets_.push_back(packet.release());
int max_buffer_size_ =
kMaxQueueLatencyMs * sampling_rate_ * kSampleSizeBytes * kChannels /
base::Time::kMillisecondsPerSecond;
while (queued_bytes_ > max_buffer_size_) {
queued_bytes_ -= queued_packets_.front()->data(0).size() - bytes_consumed_;
DCHECK_GE(queued_bytes_, 0);
delete queued_packets_.front();
queued_packets_.pop_front();
bytes_consumed_ = 0;
}
}
void AudioPlayer::AudioPlayerCallback(void* samples,
uint32 buffer_size,
void* data) {
AudioPlayer* audio_player = static_cast<AudioPlayer*>(data);
audio_player->FillWithSamples(samples, buffer_size);
}
void AudioPlayer::ResetQueue() {
lock_.AssertAcquired();
STLDeleteElements(&queued_packets_);
queued_bytes_ = 0;
bytes_consumed_ = 0;
}
void AudioPlayer::FillWithSamples(void* samples, uint32 buffer_size) {
base::AutoLock auto_lock(lock_);
const size_t bytes_needed = kChannels * kSampleSizeBytes *
GetSamplesPerFrame();
CHECK_EQ(buffer_size, bytes_needed);
char* next_sample = static_cast<char*>(samples);
size_t bytes_extracted = 0;
while (bytes_extracted < bytes_needed) {
if (queued_packets_.empty()) {
memset(next_sample, 0, bytes_needed - bytes_extracted);
return;
}
if (queued_packets_.front()->data(0).size() == bytes_consumed_) {
delete queued_packets_.front();
queued_packets_.pop_front();
bytes_consumed_ = 0;
continue;
}
const std::string& packet_data = queued_packets_.front()->data(0);
size_t bytes_to_copy = std::min(
packet_data.size() - bytes_consumed_,
bytes_needed - bytes_extracted);
memcpy(next_sample, packet_data.data() + bytes_consumed_, bytes_to_copy);
next_sample += bytes_to_copy;
bytes_consumed_ += bytes_to_copy;
bytes_extracted += bytes_to_copy;
queued_bytes_ -= bytes_to_copy;
DCHECK_GE(queued_bytes_, 0);
}
}
}