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