Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / remoting / codec / audio_encoder_opus.cc
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.
4
5 #include "remoting/codec/audio_encoder_opus.h"
6
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"
13
14 namespace remoting {
15
16 namespace {
17
18 // Output 160 kb/s bitrate.
19 const int kOutputBitrateBps = 160 * 1024;
20
21 // Opus doesn't support 44100 sampling rate so we always resample to 48kHz.
22 const AudioPacket::SamplingRate kOpusSamplingRate =
23     AudioPacket::SAMPLING_RATE_48000;
24
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;
28
29 // Number of samples per frame when using default sampling rate.
30 const int kFrameSamples =
31     kOpusSamplingRate * kFrameSizeMs / base::Time::kMillisecondsPerSecond;
32
33 const AudioPacket::BytesPerSample kBytesPerSample =
34     AudioPacket::BYTES_PER_SAMPLE_2;
35
36 bool IsSupportedSampleRate(int rate) {
37   return rate == 44100 || rate == 48000;
38 }
39
40 }  // namespace
41
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) {
50 }
51
52 AudioEncoderOpus::~AudioEncoderOpus() {
53   DestroyEncoder();
54 }
55
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;
64   }
65
66   opus_encoder_ctl(encoder_, OPUS_SET_BITRATE(kOutputBitrateBps));
67
68   frame_size_ = sampling_rate_ * kFrameSizeMs /
69       base::Time::kMillisecondsPerSecond;
70
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);
83   }
84
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_]);
91 }
92
93 void AudioEncoderOpus::DestroyEncoder() {
94   if (encoder_) {
95     opus_encoder_destroy(encoder_);
96     encoder_ = NULL;
97   }
98
99   resampler_.reset();
100 }
101
102 bool AudioEncoderOpus::ResetForPacket(AudioPacket* packet) {
103   if (packet->channels() != channels_ ||
104       packet->sampling_rate() != sampling_rate_) {
105     DestroyEncoder();
106
107     channels_ = packet->channels();
108     sampling_rate_ = packet->sampling_rate();
109
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;
116     }
117
118     InitEncoder();
119   }
120
121   return encoder_ != NULL;
122 }
123
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_));
135 }
136
137 scoped_ptr<AudioPacket> AudioEncoderOpus::Encode(
138     scoped_ptr<AudioPacket> packet) {
139   DCHECK_EQ(AudioPacket::ENCODING_RAW, packet->encoding());
140   DCHECK_EQ(1, packet->data_size());
141   DCHECK_EQ(kBytesPerSample, packet->bytes_per_sample());
142
143   if (!ResetForPacket(packet.get())) {
144     LOG(ERROR) << "Encoder initialization failed";
145     return nullptr;
146   }
147
148   int samples_in_packet = packet->data(0).size() / kBytesPerSample / channels_;
149   const int16* next_sample =
150       reinterpret_cast<const int16*>(packet->data(0).data());
151
152   // Create a new packet of encoded data.
153   scoped_ptr<AudioPacket> encoded_packet(new AudioPacket());
154   encoded_packet->set_encoding(AudioPacket::ENCODING_OPUS);
155   encoded_packet->set_sampling_rate(kOpusSamplingRate);
156   encoded_packet->set_channels(channels_);
157
158   int prefetch_samples =
159       resampler_.get() ? media::SincResampler::kDefaultRequestSize : 0;
160   int samples_wanted = frame_size_ + prefetch_samples;
161
162   while (leftover_samples_ + samples_in_packet >= samples_wanted) {
163     const int16* pcm_buffer = NULL;
164
165     // Combine the packet with the leftover samples, if any.
166     if (leftover_samples_ > 0) {
167       pcm_buffer = leftover_buffer_.get();
168       int samples_to_copy = samples_wanted - leftover_samples_;
169       memcpy(leftover_buffer_.get() + leftover_samples_ * channels_,
170              next_sample, samples_to_copy * kBytesPerSample * channels_);
171     } else {
172       pcm_buffer = next_sample;
173     }
174
175     // Resample data if necessary.
176     int samples_consumed = 0;
177     if (resampler_.get()) {
178       resampling_data_ = reinterpret_cast<const char*>(pcm_buffer);
179       resampling_data_pos_ = 0;
180       resampling_data_size_ = samples_wanted * channels_ * kBytesPerSample;
181       resampler_->Resample(kFrameSamples, resampler_bus_.get());
182       resampling_data_ = NULL;
183       samples_consumed = resampling_data_pos_ / channels_ / kBytesPerSample;
184
185       resampler_bus_->ToInterleaved(kFrameSamples, kBytesPerSample,
186                                     resample_buffer_.get());
187       pcm_buffer = reinterpret_cast<int16*>(resample_buffer_.get());
188     } else {
189       samples_consumed = frame_size_;
190     }
191
192     // Initialize output buffer.
193     std::string* data = encoded_packet->add_data();
194     data->resize(kFrameSamples * kBytesPerSample * channels_);
195
196     // Encode.
197     unsigned char* buffer =
198         reinterpret_cast<unsigned char*>(string_as_array(data));
199     int result = opus_encode(encoder_, pcm_buffer, kFrameSamples,
200                              buffer, data->length());
201     if (result < 0) {
202       LOG(ERROR) << "opus_encode() failed with error code: " << result;
203       return nullptr;
204     }
205
206     DCHECK_LE(result, static_cast<int>(data->length()));
207     data->resize(result);
208
209     // Cleanup leftover buffer.
210     if (samples_consumed >= leftover_samples_) {
211       samples_consumed -= leftover_samples_;
212       leftover_samples_ = 0;
213       next_sample += samples_consumed * channels_;
214       samples_in_packet -= samples_consumed;
215     } else {
216       leftover_samples_ -= samples_consumed;
217       memmove(leftover_buffer_.get(),
218               leftover_buffer_.get() + samples_consumed * channels_,
219               leftover_samples_ * channels_ * kBytesPerSample);
220     }
221   }
222
223   // Store the leftover samples.
224   if (samples_in_packet > 0) {
225     DCHECK_LE(leftover_samples_ + samples_in_packet, leftover_buffer_size_);
226     memmove(leftover_buffer_.get() + leftover_samples_ * channels_,
227             next_sample, samples_in_packet * kBytesPerSample * channels_);
228     leftover_samples_ += samples_in_packet;
229   }
230
231   // Return NULL if there's nothing in the packet.
232   if (encoded_packet->data_size() == 0)
233     return nullptr;
234
235   return encoded_packet.Pass();
236 }
237
238 }  // namespace remoting