Home | History | Annotate | Download | only in audio_sender
      1 // Copyright 2013 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/cast/audio_sender/audio_encoder.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/bind.h"
     10 #include "base/bind_helpers.h"
     11 #include "base/logging.h"
     12 #include "base/message_loop/message_loop.h"
     13 #include "base/sys_byteorder.h"
     14 #include "base/time/time.h"
     15 #include "media/base/audio_bus.h"
     16 #include "media/cast/cast_defines.h"
     17 #include "media/cast/cast_environment.h"
     18 #include "third_party/opus/src/include/opus.h"
     19 
     20 namespace media {
     21 namespace cast {
     22 
     23 void LogAudioEncodedEvent(CastEnvironment* const cast_environment,
     24                           const base::TimeTicks& recorded_time) {
     25   // TODO(mikhal): Resolve timestamp calculation for audio.
     26   cast_environment->Logging()->InsertFrameEvent(kAudioFrameEncoded,
     27       GetVideoRtpTimestamp(recorded_time), kFrameIdUnknown);
     28 }
     29 
     30 // Base class that handles the common problem of feeding one or more AudioBus'
     31 // data into a 10 ms buffer and then, once the buffer is full, encoding the
     32 // signal and emitting an EncodedAudioFrame via the FrameEncodedCallback.
     33 //
     34 // Subclasses complete the implementation by handling the actual encoding
     35 // details.
     36 class AudioEncoder::ImplBase {
     37  public:
     38   ImplBase(CastEnvironment* cast_environment,
     39            AudioCodec codec, int num_channels, int sampling_rate,
     40            const FrameEncodedCallback& callback)
     41       : cast_environment_(cast_environment),
     42         codec_(codec), num_channels_(num_channels),
     43         samples_per_10ms_(sampling_rate / 100),
     44         callback_(callback),
     45         buffer_fill_end_(0),
     46         frame_id_(0) {
     47     CHECK_GT(num_channels_, 0);
     48     CHECK_GT(samples_per_10ms_, 0);
     49     CHECK_EQ(sampling_rate % 100, 0);
     50     CHECK_LE(samples_per_10ms_ * num_channels_,
     51              EncodedAudioFrame::kMaxNumberOfSamples);
     52   }
     53 
     54   virtual ~ImplBase() {}
     55 
     56   void EncodeAudio(const AudioBus* audio_bus,
     57                    const base::TimeTicks& recorded_time,
     58                    const base::Closure& done_callback) {
     59     int src_pos = 0;
     60     while (src_pos < audio_bus->frames()) {
     61       const int num_samples_to_xfer =
     62           std::min(samples_per_10ms_ - buffer_fill_end_,
     63                    audio_bus->frames() - src_pos);
     64       DCHECK_EQ(audio_bus->channels(), num_channels_);
     65       TransferSamplesIntoBuffer(
     66           audio_bus, src_pos, buffer_fill_end_, num_samples_to_xfer);
     67       src_pos += num_samples_to_xfer;
     68       buffer_fill_end_ += num_samples_to_xfer;
     69 
     70       if (src_pos == audio_bus->frames()) {
     71         cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
     72                                     done_callback);
     73         // Note: |audio_bus| is now invalid..
     74       }
     75 
     76       if (buffer_fill_end_ == samples_per_10ms_) {
     77         scoped_ptr<EncodedAudioFrame> audio_frame(new EncodedAudioFrame());
     78         audio_frame->codec = codec_;
     79         audio_frame->frame_id = frame_id_++;
     80         audio_frame->samples = samples_per_10ms_;
     81         if (EncodeFromFilledBuffer(&audio_frame->data)) {
     82           // Compute an offset to determine the recorded time for the first
     83           // audio sample in the buffer.
     84           const base::TimeDelta buffer_time_offset =
     85               (buffer_fill_end_ - src_pos) *
     86               base::TimeDelta::FromMilliseconds(10) / samples_per_10ms_;
     87           // TODO(miu): Consider batching EncodedAudioFrames so we only post a
     88           // at most one task for each call to this method.
     89           cast_environment_->PostTask(
     90               CastEnvironment::MAIN, FROM_HERE,
     91               base::Bind(callback_, base::Passed(&audio_frame),
     92                          recorded_time - buffer_time_offset));
     93         }
     94         buffer_fill_end_ = 0;
     95       }
     96     }
     97   }
     98 
     99  protected:
    100   virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus,
    101                                          int source_offset,
    102                                          int buffer_fill_offset,
    103                                          int num_samples) = 0;
    104   virtual bool EncodeFromFilledBuffer(std::string* out) = 0;
    105 
    106   CastEnvironment* const cast_environment_;
    107   const AudioCodec codec_;
    108   const int num_channels_;
    109   const int samples_per_10ms_;
    110   const FrameEncodedCallback callback_;
    111 
    112  private:
    113   // In the case where a call to EncodeAudio() cannot completely fill the
    114   // buffer, this points to the position at which to populate data in a later
    115   // call.
    116   int buffer_fill_end_;
    117 
    118   // A counter used to label EncodedAudioFrames.
    119   uint32 frame_id_;
    120 
    121  private:
    122   DISALLOW_COPY_AND_ASSIGN(ImplBase);
    123 };
    124 
    125 class AudioEncoder::OpusImpl : public AudioEncoder::ImplBase {
    126  public:
    127   OpusImpl(CastEnvironment* cast_environment,
    128            int num_channels, int sampling_rate, int bitrate,
    129            const FrameEncodedCallback& callback)
    130       : ImplBase(cast_environment, kOpus, num_channels, sampling_rate,
    131                  callback),
    132         encoder_memory_(new uint8[opus_encoder_get_size(num_channels)]),
    133         opus_encoder_(reinterpret_cast<OpusEncoder*>(encoder_memory_.get())),
    134         buffer_(new float[num_channels * samples_per_10ms_]) {
    135     CHECK_EQ(opus_encoder_init(opus_encoder_, sampling_rate, num_channels,
    136                                OPUS_APPLICATION_AUDIO),
    137              OPUS_OK);
    138     if (bitrate <= 0) {
    139       // Note: As of 2013-10-31, the encoder in "auto bitrate" mode would use a
    140       // variable bitrate up to 102kbps for 2-channel, 48 kHz audio and a 10 ms
    141       // frame size.  The opus library authors may, of course, adjust this in
    142       // later versions.
    143       bitrate = OPUS_AUTO;
    144     }
    145     CHECK_EQ(opus_encoder_ctl(opus_encoder_, OPUS_SET_BITRATE(bitrate)),
    146              OPUS_OK);
    147   }
    148 
    149   virtual ~OpusImpl() {}
    150 
    151  private:
    152   virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus,
    153                                          int source_offset,
    154                                          int buffer_fill_offset,
    155                                          int num_samples) OVERRIDE {
    156     // Opus requires channel-interleaved samples in a single array.
    157     for (int ch = 0; ch < audio_bus->channels(); ++ch) {
    158       const float* src = audio_bus->channel(ch) + source_offset;
    159       const float* const src_end = src + num_samples;
    160       float* dest = buffer_.get() + buffer_fill_offset * num_channels_ + ch;
    161       for (; src < src_end; ++src, dest += num_channels_)
    162         *dest = *src;
    163     }
    164   }
    165 
    166   virtual bool EncodeFromFilledBuffer(std::string* out) OVERRIDE {
    167     out->resize(kOpusMaxPayloadSize);
    168     const opus_int32 result = opus_encode_float(
    169         opus_encoder_, buffer_.get(), samples_per_10ms_,
    170         reinterpret_cast<uint8*>(&out->at(0)), kOpusMaxPayloadSize);
    171     if (result > 1) {
    172       out->resize(result);
    173       return true;
    174     } else if (result < 0) {
    175       LOG(ERROR) << "Error code from opus_encode_float(): " << result;
    176       return false;
    177     } else {
    178       // Do nothing: The documentation says that a return value of zero or
    179       // one byte means the packet does not need to be transmitted.
    180       return false;
    181     }
    182   }
    183 
    184   const scoped_ptr<uint8[]> encoder_memory_;
    185   OpusEncoder* const opus_encoder_;
    186   const scoped_ptr<float[]> buffer_;
    187 
    188   // This is the recommended value, according to documentation in
    189   // third_party/opus/src/include/opus.h, so that the Opus encoder does not
    190   // degrade the audio due to memory constraints.
    191   //
    192   // Note: Whereas other RTP implementations do not, the cast library is
    193   // perfectly capable of transporting larger than MTU-sized audio frames.
    194   static const int kOpusMaxPayloadSize = 4000;
    195 
    196   DISALLOW_COPY_AND_ASSIGN(OpusImpl);
    197 };
    198 
    199 class AudioEncoder::Pcm16Impl : public AudioEncoder::ImplBase {
    200  public:
    201   Pcm16Impl(CastEnvironment* cast_environment,
    202             int num_channels, int sampling_rate,
    203             const FrameEncodedCallback& callback)
    204       : ImplBase(cast_environment, kPcm16, num_channels, sampling_rate,
    205                  callback),
    206         buffer_(new int16[num_channels * samples_per_10ms_]) {}
    207 
    208   virtual ~Pcm16Impl() {}
    209 
    210  private:
    211   virtual void TransferSamplesIntoBuffer(const AudioBus* audio_bus,
    212                                          int source_offset,
    213                                          int buffer_fill_offset,
    214                                          int num_samples) OVERRIDE {
    215     audio_bus->ToInterleavedPartial(
    216         source_offset, num_samples, sizeof(int16),
    217         buffer_.get() + buffer_fill_offset * num_channels_);
    218   }
    219 
    220   virtual bool EncodeFromFilledBuffer(std::string* out) OVERRIDE {
    221     // Output 16-bit PCM integers in big-endian byte order.
    222     out->resize(num_channels_ * samples_per_10ms_ * sizeof(int16));
    223     const int16* src = buffer_.get();
    224     const int16* const src_end = src + num_channels_ * samples_per_10ms_;
    225     uint16* dest = reinterpret_cast<uint16*>(&out->at(0));
    226     for (; src < src_end; ++src, ++dest)
    227       *dest = base::HostToNet16(*src);
    228     return true;
    229   }
    230 
    231  private:
    232   const scoped_ptr<int16[]> buffer_;
    233 
    234   DISALLOW_COPY_AND_ASSIGN(Pcm16Impl);
    235 };
    236 
    237 AudioEncoder::AudioEncoder(
    238     const scoped_refptr<CastEnvironment>& cast_environment,
    239     const AudioSenderConfig& audio_config,
    240     const FrameEncodedCallback& frame_encoded_callback)
    241     : cast_environment_(cast_environment) {
    242   // Note: It doesn't matter which thread constructs AudioEncoder, just so long
    243   // as all calls to InsertAudio() are by the same thread.
    244   insert_thread_checker_.DetachFromThread();
    245 
    246   switch (audio_config.codec) {
    247     case kOpus:
    248       impl_.reset(new OpusImpl(
    249           cast_environment, audio_config.channels, audio_config.frequency,
    250           audio_config.bitrate, frame_encoded_callback));
    251       break;
    252     case kPcm16:
    253       impl_.reset(new Pcm16Impl(
    254           cast_environment, audio_config.channels, audio_config.frequency,
    255           frame_encoded_callback));
    256       break;
    257     default:
    258       NOTREACHED() << "Unsupported or unspecified codec for audio encoder";
    259       break;
    260   }
    261 }
    262 
    263 AudioEncoder::~AudioEncoder() {}
    264 
    265 void AudioEncoder::InsertAudio(
    266     const AudioBus* audio_bus,
    267     const base::TimeTicks& recorded_time,
    268     const base::Closure& done_callback) {
    269   DCHECK(insert_thread_checker_.CalledOnValidThread());
    270   if (!impl_) {
    271     NOTREACHED();
    272     cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
    273                                 done_callback);
    274     return;
    275   }
    276   cast_environment_->PostTask(CastEnvironment::AUDIO_ENCODER, FROM_HERE,
    277       base::Bind(&AudioEncoder::EncodeAudio, this, audio_bus, recorded_time,
    278                  done_callback));
    279 }
    280 
    281 void AudioEncoder::EncodeAudio(
    282     const AudioBus* audio_bus,
    283     const base::TimeTicks& recorded_time,
    284     const base::Closure& done_callback) {
    285   DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::AUDIO_ENCODER));
    286   impl_->EncodeAudio(audio_bus, recorded_time, done_callback);
    287   cast_environment_->PostTask(CastEnvironment::MAIN, FROM_HERE,
    288       base::Bind(LogAudioEncodedEvent, cast_environment_, recorded_time));
    289 }
    290 
    291 }  // namespace cast
    292 }  // namespace media
    293