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
20namespace media {
21namespace cast {
22
23void 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.
36class 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
125class 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
199class 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
237AudioEncoder::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
263AudioEncoder::~AudioEncoder() {}
264
265void 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
281void 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