Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / main / acm2 / acm_opus.cc
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include "webrtc/modules/audio_coding/main/acm2/acm_opus.h"
12
13 #ifdef WEBRTC_CODEC_OPUS
14 #include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
15 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
16 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
17 #include "webrtc/system_wrappers/interface/trace.h"
18 #endif
19
20 namespace webrtc {
21
22 namespace acm2 {
23
24 #ifndef WEBRTC_CODEC_OPUS
25
26 ACMOpus::ACMOpus(int16_t /* codec_id */)
27     : encoder_inst_ptr_(NULL),
28       sample_freq_(0),
29       bitrate_(0),
30       channels_(1) {
31   return;
32 }
33
34 ACMOpus::~ACMOpus() {
35   return;
36 }
37
38 int16_t ACMOpus::InternalEncode(uint8_t* /* bitstream */,
39                                 int16_t* /* bitstream_len_byte */) {
40   return -1;
41 }
42
43 int16_t ACMOpus::InternalInitEncoder(WebRtcACMCodecParams* /* codec_params */) {
44   return -1;
45 }
46
47 ACMGenericCodec* ACMOpus::CreateInstance(void) {
48   return NULL;
49 }
50
51 int16_t ACMOpus::InternalCreateEncoder() {
52   return -1;
53 }
54
55 void ACMOpus::DestructEncoderSafe() {
56   return;
57 }
58
59 void ACMOpus::InternalDestructEncoderInst(void* /* ptr_inst */) {
60   return;
61 }
62
63 int16_t ACMOpus::SetBitRateSafe(const int32_t /*rate*/) {
64   return -1;
65 }
66
67 #else  //===================== Actual Implementation =======================
68
69 ACMOpus::ACMOpus(int16_t codec_id)
70     : encoder_inst_ptr_(NULL),
71       sample_freq_(32000),  // Default sampling frequency.
72       bitrate_(20000),  // Default bit-rate.
73       channels_(1) {  // Default mono
74   codec_id_ = codec_id;
75   // Opus has internal DTX, but we dont use it for now.
76   has_internal_dtx_ = false;
77
78   if (codec_id_ != ACMCodecDB::kOpus) {
79     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
80                  "Wrong codec id for Opus.");
81     sample_freq_ = -1;
82     bitrate_ = -1;
83   }
84   return;
85 }
86
87 ACMOpus::~ACMOpus() {
88   if (encoder_inst_ptr_ != NULL) {
89     WebRtcOpus_EncoderFree(encoder_inst_ptr_);
90     encoder_inst_ptr_ = NULL;
91   }
92 }
93
94 int16_t ACMOpus::InternalEncode(uint8_t* bitstream,
95                                 int16_t* bitstream_len_byte) {
96   // Call Encoder.
97   *bitstream_len_byte = WebRtcOpus_Encode(encoder_inst_ptr_,
98                                           &in_audio_[in_audio_ix_read_],
99                                           frame_len_smpl_,
100                                           MAX_PAYLOAD_SIZE_BYTE, bitstream);
101   // Check for error reported from encoder.
102   if (*bitstream_len_byte < 0) {
103     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
104                  "InternalEncode: Encode error for Opus");
105     *bitstream_len_byte = 0;
106     return -1;
107   }
108
109   // Increment the read index. This tells the caller how far
110   // we have gone forward in reading the audio buffer.
111   in_audio_ix_read_ += frame_len_smpl_ * channels_;
112
113   return *bitstream_len_byte;
114 }
115
116 int16_t ACMOpus::InternalInitEncoder(WebRtcACMCodecParams* codec_params) {
117   int16_t ret;
118   if (encoder_inst_ptr_ != NULL) {
119     WebRtcOpus_EncoderFree(encoder_inst_ptr_);
120     encoder_inst_ptr_ = NULL;
121   }
122   ret = WebRtcOpus_EncoderCreate(&encoder_inst_ptr_,
123                                  codec_params->codec_inst.channels);
124   // Store number of channels.
125   channels_ = codec_params->codec_inst.channels;
126
127   if (ret < 0) {
128     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
129                  "Encoder creation failed for Opus");
130     return ret;
131   }
132   ret = WebRtcOpus_SetBitRate(encoder_inst_ptr_,
133                               codec_params->codec_inst.rate);
134   if (ret < 0) {
135     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
136                  "Setting initial bitrate failed for Opus");
137     return ret;
138   }
139
140   // Store bitrate.
141   bitrate_ = codec_params->codec_inst.rate;
142
143   // TODO(tlegrand): Remove this code when we have proper APIs to set the
144   // complexity at a higher level.
145 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) || defined(WEBRTC_ARCH_ARM)
146   // If we are on Android, iOS and/or ARM, use a lower complexity setting as
147   // default, to save encoder complexity.
148   const int kOpusComplexity5 = 5;
149   WebRtcOpus_SetComplexity(encoder_inst_ptr_, kOpusComplexity5);
150   if (ret < 0) {
151      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
152                   "Setting complexity failed for Opus");
153      return ret;
154    }
155 #endif
156
157   return 0;
158 }
159
160 ACMGenericCodec* ACMOpus::CreateInstance(void) {
161   return NULL;
162 }
163
164 int16_t ACMOpus::InternalCreateEncoder() {
165   // Real encoder will be created in InternalInitEncoder.
166   return 0;
167 }
168
169 void ACMOpus::DestructEncoderSafe() {
170   if (encoder_inst_ptr_) {
171     WebRtcOpus_EncoderFree(encoder_inst_ptr_);
172     encoder_inst_ptr_ = NULL;
173   }
174 }
175
176 void ACMOpus::InternalDestructEncoderInst(void* ptr_inst) {
177   if (ptr_inst != NULL) {
178     WebRtcOpus_EncoderFree(static_cast<OpusEncInst*>(ptr_inst));
179   }
180   return;
181 }
182
183 int16_t ACMOpus::SetBitRateSafe(const int32_t rate) {
184   if (rate < 6000 || rate > 510000) {
185     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
186                  "SetBitRateSafe: Invalid rate Opus");
187     return -1;
188   }
189
190   bitrate_ = rate;
191
192   // Ask the encoder for the new rate.
193   if (WebRtcOpus_SetBitRate(encoder_inst_ptr_, bitrate_) >= 0) {
194     encoder_params_.codec_inst.rate = bitrate_;
195     return 0;
196   }
197
198   return -1;
199 }
200
201 #endif  // WEBRTC_CODEC_OPUS
202
203 }  // namespace acm2
204
205 }  // namespace webrtc