Home | History | Annotate | Download | only in client
      1 // Copyright (c) 2012 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 "remoting/client/audio_player.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/logging.h"
     10 #include "base/stl_util.h"
     11 
     12 // The number of channels in the audio stream (only supporting stereo audio
     13 // for now).
     14 const int kChannels = 2;
     15 const int kSampleSizeBytes = 2;
     16 
     17 // If queue grows bigger than 150ms we start dropping packets.
     18 const int kMaxQueueLatencyMs = 150;
     19 
     20 namespace remoting {
     21 
     22 AudioPlayer::AudioPlayer()
     23     : sampling_rate_(AudioPacket::SAMPLING_RATE_INVALID),
     24       start_failed_(false),
     25       queued_bytes_(0),
     26       bytes_consumed_(0) {
     27 }
     28 
     29 AudioPlayer::~AudioPlayer() {
     30   base::AutoLock auto_lock(lock_);
     31   ResetQueue();
     32 }
     33 
     34 void AudioPlayer::ProcessAudioPacket(scoped_ptr<AudioPacket> packet) {
     35   CHECK_EQ(1, packet->data_size());
     36   DCHECK_EQ(AudioPacket::ENCODING_RAW, packet->encoding());
     37   DCHECK_NE(AudioPacket::SAMPLING_RATE_INVALID, packet->sampling_rate());
     38   DCHECK_EQ(kSampleSizeBytes, packet->bytes_per_sample());
     39   DCHECK_EQ(static_cast<int>(kChannels), packet->channels());
     40   DCHECK_EQ(packet->data(0).size() % (kChannels * kSampleSizeBytes), 0u);
     41 
     42   // No-op if the Pepper player won't start.
     43   if (start_failed_) {
     44     return;
     45   }
     46 
     47   // Start the Pepper audio player if this is the first packet.
     48   if (sampling_rate_ != packet->sampling_rate()) {
     49     // Drop all packets currently in the queue, since they are sampled at the
     50     // wrong rate.
     51     {
     52       base::AutoLock auto_lock(lock_);
     53       ResetQueue();
     54     }
     55 
     56     sampling_rate_ = packet->sampling_rate();
     57     bool success = ResetAudioPlayer(sampling_rate_);
     58     if (!success) {
     59       start_failed_ = true;
     60       return;
     61     }
     62   }
     63 
     64   base::AutoLock auto_lock(lock_);
     65 
     66   queued_bytes_ += packet->data(0).size();
     67   queued_packets_.push_back(packet.release());
     68 
     69   int max_buffer_size_ =
     70       kMaxQueueLatencyMs * sampling_rate_ * kSampleSizeBytes * kChannels /
     71       base::Time::kMillisecondsPerSecond;
     72   while (queued_bytes_ > max_buffer_size_) {
     73     queued_bytes_ -= queued_packets_.front()->data(0).size() - bytes_consumed_;
     74     DCHECK_GE(queued_bytes_, 0);
     75     delete queued_packets_.front();
     76     queued_packets_.pop_front();
     77     bytes_consumed_ = 0;
     78   }
     79 }
     80 
     81 // static
     82 void AudioPlayer::AudioPlayerCallback(void* samples,
     83                                       uint32 buffer_size,
     84                                       void* data) {
     85   AudioPlayer* audio_player = static_cast<AudioPlayer*>(data);
     86   audio_player->FillWithSamples(samples, buffer_size);
     87 }
     88 
     89 void AudioPlayer::ResetQueue() {
     90   lock_.AssertAcquired();
     91   STLDeleteElements(&queued_packets_);
     92   queued_bytes_ = 0;
     93   bytes_consumed_ = 0;
     94 }
     95 
     96 void AudioPlayer::FillWithSamples(void* samples, uint32 buffer_size) {
     97   base::AutoLock auto_lock(lock_);
     98 
     99   const size_t bytes_needed = kChannels * kSampleSizeBytes *
    100       GetSamplesPerFrame();
    101 
    102   // Make sure we don't overrun the buffer.
    103   CHECK_EQ(buffer_size, bytes_needed);
    104 
    105   char* next_sample = static_cast<char*>(samples);
    106   size_t bytes_extracted = 0;
    107 
    108   while (bytes_extracted < bytes_needed) {
    109     // Check if we've run out of samples for this packet.
    110     if (queued_packets_.empty()) {
    111       memset(next_sample, 0, bytes_needed - bytes_extracted);
    112       return;
    113     }
    114 
    115     // Pop off the packet if we've already consumed all its bytes.
    116     if (queued_packets_.front()->data(0).size() == bytes_consumed_) {
    117       delete queued_packets_.front();
    118       queued_packets_.pop_front();
    119       bytes_consumed_ = 0;
    120       continue;
    121     }
    122 
    123     const std::string& packet_data = queued_packets_.front()->data(0);
    124     size_t bytes_to_copy = std::min(
    125         packet_data.size() - bytes_consumed_,
    126         bytes_needed - bytes_extracted);
    127     memcpy(next_sample, packet_data.data() + bytes_consumed_, bytes_to_copy);
    128 
    129     next_sample += bytes_to_copy;
    130     bytes_consumed_ += bytes_to_copy;
    131     bytes_extracted += bytes_to_copy;
    132     queued_bytes_ -= bytes_to_copy;
    133     DCHECK_GE(queued_bytes_, 0);
    134   }
    135 }
    136 
    137 }  // namespace remoting
    138