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.
5 #include "remoting/codec/audio_encoder_opus.h"
8 #include "base/logging.h"
10 #include "media/base/audio_bus.h"
11 #include "media/base/multi_channel_resampler.h"
12 #include "third_party/opus/src/include/opus.h"
18 // Output 160 kb/s bitrate.
19 const int kOutputBitrateBps
= 160 * 1024;
21 // Encoded buffer size.
22 const int kFrameDefaultBufferSize
= 4096;
24 // Maximum buffer size we'll allocate when encoding before giving up.
25 const int kMaxBufferSize
= 65536;
27 // Opus doesn't support 44100 sampling rate so we always resample to 48kHz.
28 const AudioPacket::SamplingRate kOpusSamplingRate
=
29 AudioPacket::SAMPLING_RATE_48000
;
31 // Opus supports frame sizes of 2.5, 5, 10, 20, 40 and 60 ms. We use 20 ms
32 // frames to balance latency and efficiency.
33 const int kFrameSizeMs
= 20;
35 // Number of samples per frame when using default sampling rate.
36 const int kFrameSamples
=
37 kOpusSamplingRate
* kFrameSizeMs
/ base::Time::kMillisecondsPerSecond
;
39 const AudioPacket::BytesPerSample kBytesPerSample
=
40 AudioPacket::BYTES_PER_SAMPLE_2
;
42 bool IsSupportedSampleRate(int rate
) {
43 return rate
== 44100 || rate
== 48000;
48 AudioEncoderOpus::AudioEncoderOpus()
50 channels_(AudioPacket::CHANNELS_STEREO
),
53 resampling_data_(NULL
),
54 resampling_data_size_(0),
55 resampling_data_pos_(0) {
58 AudioEncoderOpus::~AudioEncoderOpus() {
62 void AudioEncoderOpus::InitEncoder() {
65 encoder_
= opus_encoder_create(kOpusSamplingRate
, channels_
,
66 OPUS_APPLICATION_AUDIO
, &error
);
68 LOG(ERROR
) << "Failed to create OPUS encoder. Error code: " << error
;
72 opus_encoder_ctl(encoder_
, OPUS_SET_BITRATE(kOutputBitrateBps
));
74 frame_size_
= sampling_rate_
* kFrameSizeMs
/
75 base::Time::kMillisecondsPerSecond
;
77 if (sampling_rate_
!= kOpusSamplingRate
) {
78 resample_buffer_
.reset(
79 new char[kFrameSamples
* kBytesPerSample
* channels_
]);
80 resampler_
.reset(new media::MultiChannelResampler(
82 static_cast<double>(sampling_rate_
) / kOpusSamplingRate
,
83 base::Bind(&AudioEncoderOpus::FetchBytesToResample
,
84 base::Unretained(this))));
85 resampler_bus_
= media::AudioBus::Create(channels_
, kFrameSamples
);
88 // Drop leftover data because it's for different sampling rate.
89 leftover_samples_
= 0;
90 leftover_buffer_size_
=
91 frame_size_
+ media::SincResampler::kMaximumLookAheadSize
;
92 leftover_buffer_
.reset(
93 new int16
[leftover_buffer_size_
* channels_
]);
96 void AudioEncoderOpus::DestroyEncoder() {
98 opus_encoder_destroy(encoder_
);
105 bool AudioEncoderOpus::ResetForPacket(AudioPacket
* packet
) {
106 if (packet
->channels() != channels_
||
107 packet
->sampling_rate() != sampling_rate_
) {
110 channels_
= packet
->channels();
111 sampling_rate_
= packet
->sampling_rate();
113 if (channels_
<= 0 || channels_
> 2 ||
114 !IsSupportedSampleRate(sampling_rate_
)) {
115 LOG(WARNING
) << "Unsupported OPUS parameters: "
116 << channels_
<< " channels with "
117 << sampling_rate_
<< " samples per second.";
124 return encoder_
!= NULL
;
127 void AudioEncoderOpus::FetchBytesToResample(int resampler_frame_delay
,
128 media::AudioBus
* audio_bus
) {
129 DCHECK(resampling_data_
);
130 int samples_left
= (resampling_data_size_
- resampling_data_pos_
) /
131 kBytesPerSample
/ channels_
;
132 DCHECK_LE(audio_bus
->frames(), samples_left
);
133 audio_bus
->FromInterleaved(
134 resampling_data_
+ resampling_data_pos_
,
135 audio_bus
->frames(), kBytesPerSample
);
136 resampling_data_pos_
+= audio_bus
->frames() * kBytesPerSample
* channels_
;
137 DCHECK_LE(resampling_data_pos_
, static_cast<int>(resampling_data_size_
));
140 scoped_ptr
<AudioPacket
> AudioEncoderOpus::Encode(
141 scoped_ptr
<AudioPacket
> packet
) {
142 DCHECK_EQ(AudioPacket::ENCODING_RAW
, packet
->encoding());
143 DCHECK_EQ(1, packet
->data_size());
144 DCHECK_EQ(kBytesPerSample
, packet
->bytes_per_sample());
146 if (!ResetForPacket(packet
.get())) {
147 LOG(ERROR
) << "Encoder initialization failed";
148 return scoped_ptr
<AudioPacket
>();
151 int samples_in_packet
= packet
->data(0).size() / kBytesPerSample
/ channels_
;
152 const int16
* next_sample
=
153 reinterpret_cast<const int16
*>(packet
->data(0).data());
155 // Create a new packet of encoded data.
156 scoped_ptr
<AudioPacket
> encoded_packet(new AudioPacket());
157 encoded_packet
->set_encoding(AudioPacket::ENCODING_OPUS
);
158 encoded_packet
->set_sampling_rate(kOpusSamplingRate
);
159 encoded_packet
->set_channels(channels_
);
161 int prefetch_samples
=
162 resampler_
.get() ? media::SincResampler::kMaximumLookAheadSize
: 0;
163 int samples_wanted
= frame_size_
+ prefetch_samples
;
165 while (leftover_samples_
+ samples_in_packet
>= samples_wanted
) {
166 const int16
* pcm_buffer
= NULL
;
168 // Combine the packet with the leftover samples, if any.
169 if (leftover_samples_
> 0) {
170 pcm_buffer
= leftover_buffer_
.get();
171 int samples_to_copy
= samples_wanted
- leftover_samples_
;
172 memcpy(leftover_buffer_
.get() + leftover_samples_
* channels_
,
173 next_sample
, samples_to_copy
* kBytesPerSample
* channels_
);
175 pcm_buffer
= next_sample
;
178 // Resample data if necessary.
179 int samples_consumed
= 0;
180 if (resampler_
.get()) {
181 resampling_data_
= reinterpret_cast<const char*>(pcm_buffer
);
182 resampling_data_pos_
= 0;
183 resampling_data_size_
= samples_wanted
* channels_
* kBytesPerSample
;
184 resampler_
->Resample(resampler_bus_
.get(), kFrameSamples
);
185 resampling_data_
= NULL
;
186 samples_consumed
= resampling_data_pos_
/ channels_
/ kBytesPerSample
;
188 resampler_bus_
->ToInterleaved(kFrameSamples
, kBytesPerSample
,
189 resample_buffer_
.get());
190 pcm_buffer
= reinterpret_cast<int16
*>(resample_buffer_
.get());
192 samples_consumed
= frame_size_
;
195 // Initialize output buffer.
196 std::string
* data
= encoded_packet
->add_data();
197 data
->resize(kFrameSamples
* kBytesPerSample
* channels_
);
200 unsigned char* buffer
=
201 reinterpret_cast<unsigned char*>(string_as_array(data
));
202 int result
= opus_encode(encoder_
, pcm_buffer
, kFrameSamples
,
203 buffer
, data
->length());
205 LOG(ERROR
) << "opus_encode() failed with error code: " << result
;
206 return scoped_ptr
<AudioPacket
>();
209 DCHECK_LE(result
, static_cast<int>(data
->length()));
210 data
->resize(result
);
212 // Cleanup leftover buffer.
213 if (samples_consumed
>= leftover_samples_
) {
214 samples_consumed
-= leftover_samples_
;
215 leftover_samples_
= 0;
216 next_sample
+= samples_consumed
* channels_
;
217 samples_in_packet
-= samples_consumed
;
219 leftover_samples_
-= samples_consumed
;
220 memmove(leftover_buffer_
.get(),
221 leftover_buffer_
.get() + samples_consumed
* channels_
,
222 leftover_samples_
* channels_
* kBytesPerSample
);
226 // Store the leftover samples.
227 if (samples_in_packet
> 0) {
228 DCHECK_LE(leftover_samples_
+ samples_in_packet
, leftover_buffer_size_
);
229 memmove(leftover_buffer_
.get() + leftover_samples_
* channels_
,
230 next_sample
, samples_in_packet
* kBytesPerSample
* channels_
);
231 leftover_samples_
+= samples_in_packet
;
234 // Return NULL if there's nothing in the packet.
235 if (encoded_packet
->data_size() == 0)
236 return scoped_ptr
<AudioPacket
>();
238 return encoded_packet
.Pass();
241 } // namespace remoting