Revert of Remove OneClickSigninHelper since it is no longer used. (patchset #5 id...
[chromium-blink-merge.git] / remoting / codec / audio_encoder_opus.cc
blobab7582b8a900217f69273413eb93aa249a16a1c1
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"
7 #include "base/bind.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"
14 namespace remoting {
16 namespace {
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;
40 } // namespace
42 AudioEncoderOpus::AudioEncoderOpus()
43 : sampling_rate_(0),
44 channels_(AudioPacket::CHANNELS_STEREO),
45 encoder_(NULL),
46 frame_size_(0),
47 resampling_data_(NULL),
48 resampling_data_size_(0),
49 resampling_data_pos_(0) {
52 AudioEncoderOpus::~AudioEncoderOpus() {
53 DestroyEncoder();
56 void AudioEncoderOpus::InitEncoder() {
57 DCHECK(!encoder_);
58 int error;
59 encoder_ = opus_encoder_create(kOpusSamplingRate, channels_,
60 OPUS_APPLICATION_AUDIO, &error);
61 if (!encoder_) {
62 LOG(ERROR) << "Failed to create OPUS encoder. Error code: " << error;
63 return;
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(
77 channels_,
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() {
94 if (encoder_) {
95 opus_encoder_destroy(encoder_);
96 encoder_ = NULL;
99 resampler_.reset();
102 bool AudioEncoderOpus::ResetForPacket(AudioPacket* packet) {
103 if (packet->channels() != channels_ ||
104 packet->sampling_rate() != sampling_rate_) {
105 DestroyEncoder();
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.";
115 return false;
118 InitEncoder();
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";
149 return nullptr;
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_);
175 } else {
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());
192 } else {
193 samples_consumed = frame_size_;
196 // Initialize output buffer.
197 std::string* data = encoded_packet->add_data();
198 data->resize(kFrameSamples * kBytesPerSample * channels_);
200 // Encode.
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());
205 if (result < 0) {
206 LOG(ERROR) << "opus_encode() failed with error code: " << result;
207 return nullptr;
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;
219 } else {
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)
237 return nullptr;
239 return encoded_packet.Pass();
242 } // namespace remoting