Chromium Code Reviews| 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 |