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.
5 #include "media/cast/audio_sender/audio_encoder.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"
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();
28 cast_environment
->Logging()->InsertFrameEvent(now
, kAudioFrameEncoded
,
29 GetVideoRtpTimestamp(recorded_time
), kFrameIdUnknown
);
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.
36 // Subclasses complete the implementation by handling the actual encoding
38 class AudioEncoder::ImplBase
{
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),
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
);
56 virtual ~ImplBase() {}
58 void EncodeAudio(const AudioBus
* audio_bus
,
59 const base::TimeTicks
& recorded_time
,
60 const base::Closure
& done_callback
) {
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
;
72 if (src_pos
== audio_bus
->frames()) {
73 cast_environment_
->PostTask(CastEnvironment::MAIN
, FROM_HERE
,
75 // Note: |audio_bus| is invalid once done_callback is invoked.
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
));
104 virtual void TransferSamplesIntoBuffer(const AudioBus
* audio_bus
,
106 int buffer_fill_offset
,
107 int num_samples
) = 0;
108 virtual bool EncodeFromFilledBuffer(std::string
* out
) = 0;
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_
;
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
120 int buffer_fill_end_
;
122 // A counter used to label EncodedAudioFrames.
126 DISALLOW_COPY_AND_ASSIGN(ImplBase
);
129 class AudioEncoder::OpusImpl
: public AudioEncoder::ImplBase
{
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
),
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
149 CHECK_EQ(opus_encoder_ctl(opus_encoder_
, OPUS_SET_BITRATE(bitrate
)),
153 virtual ~OpusImpl() {}
156 virtual void TransferSamplesIntoBuffer(const AudioBus
* audio_bus
,
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_
)
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
);
178 } else if (result
< 0) {
179 LOG(ERROR
) << "Error code from opus_encode_float(): " << result
;
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.
188 const scoped_ptr
<uint8
[]> encoder_memory_
;
189 OpusEncoder
* const opus_encoder_
;
190 const scoped_ptr
<float[]> buffer_
;
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.
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;
200 DISALLOW_COPY_AND_ASSIGN(OpusImpl
);
203 class AudioEncoder::Pcm16Impl
: public AudioEncoder::ImplBase
{
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_
]) {}
212 virtual ~Pcm16Impl() {}
215 virtual void TransferSamplesIntoBuffer(const AudioBus
* audio_bus
,
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_
);
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
);
236 const scoped_ptr
<int16
[]> buffer_
;
238 DISALLOW_COPY_AND_ASSIGN(Pcm16Impl
);
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();
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
));
256 case transport::kPcm16
:
257 impl_
.reset(new Pcm16Impl(
258 cast_environment
, audio_config
.channels
, audio_config
.frequency
,
259 frame_encoded_callback
));
262 NOTREACHED() << "Unsupported or unspecified codec for audio encoder";
267 AudioEncoder::~AudioEncoder() {}
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());
276 cast_environment_
->PostTask(CastEnvironment::MAIN
, FROM_HERE
,
280 cast_environment_
->PostTask(CastEnvironment::AUDIO_ENCODER
, FROM_HERE
,
281 base::Bind(&AudioEncoder::EncodeAudio
, this, audio_bus
, recorded_time
,
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
));