OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h" | 11 #include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 #include <memory> | 14 #include <memory> |
15 #include <limits> | 15 #include <limits> |
16 #include <utility> | 16 #include <utility> |
17 | 17 |
18 namespace webrtc { | 18 namespace webrtc { |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 const int kMaxFrameSizeMs = 60; | 22 const int kMaxFrameSizeMs = 60; |
23 | 23 |
24 std::unique_ptr<CNG_enc_inst, CngInstDeleter> CreateCngInst( | |
25 int sample_rate_hz, | |
26 int sid_frame_interval_ms, | |
27 int num_cng_coefficients) { | |
28 CNG_enc_inst* ci; | |
29 RTC_CHECK_EQ(0, WebRtcCng_CreateEnc(&ci)); | |
30 std::unique_ptr<CNG_enc_inst, CngInstDeleter> cng_inst(ci); | |
31 RTC_CHECK_EQ(0, | |
32 WebRtcCng_InitEnc(cng_inst.get(), sample_rate_hz, | |
33 sid_frame_interval_ms, num_cng_coefficients)); | |
34 return cng_inst; | |
35 } | |
36 | |
37 } // namespace | 24 } // namespace |
38 | 25 |
39 AudioEncoderCng::Config::Config() = default; | 26 AudioEncoderCng::Config::Config() = default; |
40 | 27 |
41 // TODO(kwiberg): =default this when Visual Studio learns to handle it. | 28 // TODO(kwiberg): =default this when Visual Studio learns to handle it. |
42 AudioEncoderCng::Config::Config(Config&& c) | 29 AudioEncoderCng::Config::Config(Config&& c) |
43 : num_channels(c.num_channels), | 30 : num_channels(c.num_channels), |
44 payload_type(c.payload_type), | 31 payload_type(c.payload_type), |
45 speech_encoder(std::move(c.speech_encoder)), | 32 speech_encoder(std::move(c.speech_encoder)), |
46 vad_mode(c.vad_mode), | 33 vad_mode(c.vad_mode), |
(...skipping 21 matching lines...) Expand all Loading... | |
68 | 55 |
69 AudioEncoderCng::AudioEncoderCng(Config&& config) | 56 AudioEncoderCng::AudioEncoderCng(Config&& config) |
70 : speech_encoder_( | 57 : speech_encoder_( |
71 ([&] { RTC_CHECK(config.IsOk()) << "Invalid configuration."; }(), | 58 ([&] { RTC_CHECK(config.IsOk()) << "Invalid configuration."; }(), |
72 std::move(config.speech_encoder))), | 59 std::move(config.speech_encoder))), |
73 cng_payload_type_(config.payload_type), | 60 cng_payload_type_(config.payload_type), |
74 num_cng_coefficients_(config.num_cng_coefficients), | 61 num_cng_coefficients_(config.num_cng_coefficients), |
75 sid_frame_interval_ms_(config.sid_frame_interval_ms), | 62 sid_frame_interval_ms_(config.sid_frame_interval_ms), |
76 last_frame_active_(true), | 63 last_frame_active_(true), |
77 vad_(config.vad ? std::unique_ptr<Vad>(config.vad) | 64 vad_(config.vad ? std::unique_ptr<Vad>(config.vad) |
78 : CreateVad(config.vad_mode)) { | 65 : CreateVad(config.vad_mode)), |
79 cng_inst_ = CreateCngInst(SampleRateHz(), sid_frame_interval_ms_, | 66 cng_encoder_(new ComfortNoiseEncoder(SampleRateHz(), |
80 num_cng_coefficients_); | 67 sid_frame_interval_ms_, |
68 num_cng_coefficients_)) { | |
81 } | 69 } |
82 | 70 |
83 AudioEncoderCng::~AudioEncoderCng() = default; | 71 AudioEncoderCng::~AudioEncoderCng() = default; |
84 | 72 |
85 size_t AudioEncoderCng::MaxEncodedBytes() const { | 73 size_t AudioEncoderCng::MaxEncodedBytes() const { |
86 const size_t max_encoded_bytes_active = speech_encoder_->MaxEncodedBytes(); | 74 const size_t max_encoded_bytes_active = speech_encoder_->MaxEncodedBytes(); |
87 const size_t max_encoded_bytes_passive = | 75 const size_t max_encoded_bytes_passive = |
88 rtc::CheckedDivExact(kMaxFrameSizeMs, 10) * SamplesPer10msFrame(); | 76 rtc::CheckedDivExact(kMaxFrameSizeMs, 10) * SamplesPer10msFrame(); |
89 return std::max(max_encoded_bytes_active, max_encoded_bytes_passive); | 77 return std::max(max_encoded_bytes_active, max_encoded_bytes_passive); |
90 } | 78 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 rtp_timestamps_.begin() + frames_to_encode); | 168 rtp_timestamps_.begin() + frames_to_encode); |
181 return info; | 169 return info; |
182 } | 170 } |
183 | 171 |
184 void AudioEncoderCng::Reset() { | 172 void AudioEncoderCng::Reset() { |
185 speech_encoder_->Reset(); | 173 speech_encoder_->Reset(); |
186 speech_buffer_.clear(); | 174 speech_buffer_.clear(); |
187 rtp_timestamps_.clear(); | 175 rtp_timestamps_.clear(); |
188 last_frame_active_ = true; | 176 last_frame_active_ = true; |
189 vad_->Reset(); | 177 vad_->Reset(); |
190 cng_inst_ = CreateCngInst(SampleRateHz(), sid_frame_interval_ms_, | 178 cng_encoder_.reset( |
191 num_cng_coefficients_); | 179 new ComfortNoiseEncoder(SampleRateHz(), sid_frame_interval_ms_, |
180 num_cng_coefficients_)); | |
kwiberg-webrtc
2016/04/12 13:35:30
A small utility function in an anonymous namespace
ossu
2016/04/12 13:54:49
Actually, there's a Reset method in it right now,
| |
192 } | 181 } |
193 | 182 |
194 bool AudioEncoderCng::SetFec(bool enable) { | 183 bool AudioEncoderCng::SetFec(bool enable) { |
195 return speech_encoder_->SetFec(enable); | 184 return speech_encoder_->SetFec(enable); |
196 } | 185 } |
197 | 186 |
198 bool AudioEncoderCng::SetDtx(bool enable) { | 187 bool AudioEncoderCng::SetDtx(bool enable) { |
199 return speech_encoder_->SetDtx(enable); | 188 return speech_encoder_->SetDtx(enable); |
200 } | 189 } |
201 | 190 |
(...skipping 21 matching lines...) Expand all Loading... | |
223 const size_t samples_per_10ms_frame = SamplesPer10msFrame(); | 212 const size_t samples_per_10ms_frame = SamplesPer10msFrame(); |
224 const size_t bytes_to_encode = frames_to_encode * samples_per_10ms_frame; | 213 const size_t bytes_to_encode = frames_to_encode * samples_per_10ms_frame; |
225 AudioEncoder::EncodedInfo info; | 214 AudioEncoder::EncodedInfo info; |
226 | 215 |
227 encoded->AppendData(bytes_to_encode, [&] (rtc::ArrayView<uint8_t> encoded) { | 216 encoded->AppendData(bytes_to_encode, [&] (rtc::ArrayView<uint8_t> encoded) { |
228 for (size_t i = 0; i < frames_to_encode; ++i) { | 217 for (size_t i = 0; i < frames_to_encode; ++i) { |
229 // It's important not to pass &info.encoded_bytes directly to | 218 // It's important not to pass &info.encoded_bytes directly to |
230 // WebRtcCng_Encode(), since later loop iterations may return zero in | 219 // WebRtcCng_Encode(), since later loop iterations may return zero in |
231 // that value, in which case we don't want to overwrite any value from | 220 // that value, in which case we don't want to overwrite any value from |
232 // an earlier iteration. | 221 // an earlier iteration. |
233 size_t encoded_bytes_tmp = 0; | 222 int encoded_bytes_tmp = |
234 RTC_CHECK_GE( | 223 cng_encoder_->Encode( |
235 WebRtcCng_Encode(cng_inst_.get(), | 224 rtc::ArrayView<const int16_t>( |
236 &speech_buffer_[i * samples_per_10ms_frame], | 225 &speech_buffer_[i * samples_per_10ms_frame], |
237 samples_per_10ms_frame, encoded.data(), | 226 samples_per_10ms_frame), |
238 &encoded_bytes_tmp, force_sid), | 227 encoded, force_sid); |
239 0); | 228 RTC_CHECK_GE(encoded_bytes_tmp, 0); |
kwiberg-webrtc
2016/04/12 13:35:30
Use rtc::Optional<size_t> if you need to return an
ossu
2016/04/12 13:54:49
Yeah, Buffer is probably better. It's what we want
hlundin-webrtc
2016/04/13 07:05:23
I'm fine with using a Buffer as well. But bear in
kwiberg-webrtc
2016/04/14 09:42:47
Meaning its output length is a small constant? It
| |
240 if (encoded_bytes_tmp > 0) { | 229 if (encoded_bytes_tmp > 0) { |
241 RTC_CHECK(!output_produced); | 230 RTC_CHECK(!output_produced); |
242 info.encoded_bytes = encoded_bytes_tmp; | 231 info.encoded_bytes = encoded_bytes_tmp; |
243 output_produced = true; | 232 output_produced = true; |
244 force_sid = false; | 233 force_sid = false; |
245 } | 234 } |
246 } | 235 } |
247 | 236 |
248 return info.encoded_bytes; | 237 return info.encoded_bytes; |
249 }); | 238 }); |
(...skipping 25 matching lines...) Expand all Loading... | |
275 } | 264 } |
276 } | 265 } |
277 return info; | 266 return info; |
278 } | 267 } |
279 | 268 |
280 size_t AudioEncoderCng::SamplesPer10msFrame() const { | 269 size_t AudioEncoderCng::SamplesPer10msFrame() const { |
281 return rtc::CheckedDivExact(10 * SampleRateHz(), 1000); | 270 return rtc::CheckedDivExact(10 * SampleRateHz(), 1000); |
282 } | 271 } |
283 | 272 |
284 } // namespace webrtc | 273 } // namespace webrtc |
OLD | NEW |