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"
9 #include "base/time/time.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 // Opus doesn't support 44100 sampling rate so we always resample to 48kHz.
22 const AudioPacket::SamplingRate kOpusSamplingRate
=
23 AudioPacket::SAMPLING_RATE_48000
;
25 // Opus supports frame sizes of 2.5, 5, 10, 20, 40 and 60 ms. We use 20 ms
26 // frames to balance latency and efficiency.
27 const int kFrameSizeMs
= 20;
29 // Number of samples per frame when using default sampling rate.
30 const int kFrameSamples
=
31 kOpusSamplingRate
* kFrameSizeMs
/ base::Time::kMillisecondsPerSecond
;
33 const AudioPacket::BytesPerSample kBytesPerSample
=
34 AudioPacket::BYTES_PER_SAMPLE_2
;
36 bool IsSupportedSampleRate(int rate
) {
37 return rate
== 44100 || rate
== 48000;
42 AudioEncoderOpus::AudioEncoderOpus()
44 channels_(AudioPacket::CHANNELS_STEREO
),
47 resampling_data_(NULL
),
48 resampling_data_size_(0),
49 resampling_data_pos_(0) {
52 AudioEncoderOpus::~AudioEncoderOpus() {
56 void AudioEncoderOpus::InitEncoder() {
59 encoder_
= opus_encoder_create(kOpusSamplingRate
, channels_
,
60 OPUS_APPLICATION_AUDIO
, &error
);
62 LOG(ERROR
) << "Failed to create OPUS encoder. Error code: " << error
;
66 opus_encoder_ctl(encoder_
, OPUS_SET_BITRATE(kOutputBitrateBps
));
68 frame_size_
= sampling_rate_
* kFrameSizeMs
/
69 base::Time::kMillisecondsPerSecond
;
71 if (sampling_rate_
!= kOpusSamplingRate
) {
72 resample_buffer_
.reset(
73 new char[kFrameSamples
* kBytesPerSample
* channels_
]);
74 // TODO(sergeyu): Figure out the right buffer size to use per packet instead
75 // of using media::SincResampler::kDefaultRequestSize.
76 resampler_
.reset(new media::MultiChannelResampler(
78 static_cast<double>(sampling_rate_
) / kOpusSamplingRate
,
79 media::SincResampler::kDefaultRequestSize
,
80 base::Bind(&AudioEncoderOpus::FetchBytesToResample
,
81 base::Unretained(this))));
82 resampler_bus_
= media::AudioBus::Create(channels_
, kFrameSamples
);
85 // Drop leftover data because it's for different sampling rate.
86 leftover_samples_
= 0;
87 leftover_buffer_size_
=
88 frame_size_
+ media::SincResampler::kDefaultRequestSize
;
89 leftover_buffer_
.reset(
90 new int16
[leftover_buffer_size_
* channels_
]);
93 void AudioEncoderOpus::DestroyEncoder() {
95 opus_encoder_destroy(encoder_
);
102 bool AudioEncoderOpus::ResetForPacket(AudioPacket
* packet
) {
103 if (packet
->channels() != channels_
||
104 packet
->sampling_rate() != sampling_rate_
) {
107 channels_
= packet
->channels();
108 sampling_rate_
= packet
->sampling_rate();
110 if (channels_
<= 0 || channels_
> 2 ||
111 !IsSupportedSampleRate(sampling_rate_
)) {
112 LOG(WARNING
) << "Unsupported OPUS parameters: "
113 << channels_
<< " channels with "
114 << sampling_rate_
<< " samples per second.";
121 return encoder_
!= NULL
;
124 void AudioEncoderOpus::FetchBytesToResample(int resampler_frame_delay
,
125 media::AudioBus
* audio_bus
) {
126 DCHECK(resampling_data_
);
127 int samples_left
= (resampling_data_size_
- resampling_data_pos_
) /
128 kBytesPerSample
/ channels_
;
129 DCHECK_LE(audio_bus
->frames(), samples_left
);
130 audio_bus
->FromInterleaved(
131 resampling_data_
+ resampling_data_pos_
,
132 audio_bus
->frames(), kBytesPerSample
);
133 resampling_data_pos_
+= audio_bus
->frames() * kBytesPerSample
* channels_
;
134 DCHECK_LE(resampling_data_pos_
, static_cast<int>(resampling_data_size_
));
137 int AudioEncoderOpus::GetBitrate() {
138 return kOutputBitrateBps
;
141 scoped_ptr
<AudioPacket
> AudioEncoderOpus::Encode(
142 scoped_ptr
<AudioPacket
> packet
) {
143 DCHECK_EQ(AudioPacket::ENCODING_RAW
, packet
->encoding());
144 DCHECK_EQ(1, packet
->data_size());
145 DCHECK_EQ(kBytesPerSample
, packet
->bytes_per_sample());
147 if (!ResetForPacket(packet
.get())) {
148 LOG(ERROR
) << "Encoder initialization failed";
152 int samples_in_packet
= packet
->data(0).size() / kBytesPerSample
/ channels_
;
153 const int16
* next_sample
=
154 reinterpret_cast<const int16
*>(packet
->data(0).data());
156 // Create a new packet of encoded data.
157 scoped_ptr
<AudioPacket
> encoded_packet(new AudioPacket());
158 encoded_packet
->set_encoding(AudioPacket::ENCODING_OPUS
);
159 encoded_packet
->set_sampling_rate(kOpusSamplingRate
);
160 encoded_packet
->set_channels(channels_
);
162 int prefetch_samples
=
163 resampler_
.get() ? media::SincResampler::kDefaultRequestSize
: 0;
164 int samples_wanted
= frame_size_
+ prefetch_samples
;
166 while (leftover_samples_
+ samples_in_packet
>= samples_wanted
) {
167 const int16
* pcm_buffer
= NULL
;
169 // Combine the packet with the leftover samples, if any.
170 if (leftover_samples_
> 0) {
171 pcm_buffer
= leftover_buffer_
.get();
172 int samples_to_copy
= samples_wanted
- leftover_samples_
;
173 memcpy(leftover_buffer_
.get() + leftover_samples_
* channels_
,
174 next_sample
, samples_to_copy
* kBytesPerSample
* channels_
);
176 pcm_buffer
= next_sample
;
179 // Resample data if necessary.
180 int samples_consumed
= 0;
181 if (resampler_
.get()) {
182 resampling_data_
= reinterpret_cast<const char*>(pcm_buffer
);
183 resampling_data_pos_
= 0;
184 resampling_data_size_
= samples_wanted
* channels_
* kBytesPerSample
;
185 resampler_
->Resample(kFrameSamples
, resampler_bus_
.get());
186 resampling_data_
= NULL
;
187 samples_consumed
= resampling_data_pos_
/ channels_
/ kBytesPerSample
;
189 resampler_bus_
->ToInterleaved(kFrameSamples
, kBytesPerSample
,
190 resample_buffer_
.get());
191 pcm_buffer
= reinterpret_cast<int16
*>(resample_buffer_
.get());
193 samples_consumed
= frame_size_
;
196 // Initialize output buffer.
197 std::string
* data
= encoded_packet
->add_data();
198 data
->resize(kFrameSamples
* kBytesPerSample
* channels_
);
201 unsigned char* buffer
=
202 reinterpret_cast<unsigned char*>(string_as_array(data
));
203 int result
= opus_encode(encoder_
, pcm_buffer
, kFrameSamples
,
204 buffer
, data
->length());
206 LOG(ERROR
) << "opus_encode() failed with error code: " << result
;
210 DCHECK_LE(result
, static_cast<int>(data
->length()));
211 data
->resize(result
);
213 // Cleanup leftover buffer.
214 if (samples_consumed
>= leftover_samples_
) {
215 samples_consumed
-= leftover_samples_
;
216 leftover_samples_
= 0;
217 next_sample
+= samples_consumed
* channels_
;
218 samples_in_packet
-= samples_consumed
;
220 leftover_samples_
-= samples_consumed
;
221 memmove(leftover_buffer_
.get(),
222 leftover_buffer_
.get() + samples_consumed
* channels_
,
223 leftover_samples_
* channels_
* kBytesPerSample
);
227 // Store the leftover samples.
228 if (samples_in_packet
> 0) {
229 DCHECK_LE(leftover_samples_
+ samples_in_packet
, leftover_buffer_size_
);
230 memmove(leftover_buffer_
.get() + leftover_samples_
* channels_
,
231 next_sample
, samples_in_packet
* kBytesPerSample
* channels_
);
232 leftover_samples_
+= samples_in_packet
;
235 // Return NULL if there's nothing in the packet.
236 if (encoded_packet
->data_size() == 0)
239 return encoded_packet
.Pass();
242 } // namespace remoting