Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(867)

Unified Diff: webrtc/modules/audio_coding/neteq/neteq_impl.cc

Issue 1334303005: Returning correct duration estimate on Opus DTX packets. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: fixing a silly mistake in unittest Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_coding/neteq/neteq_impl.cc
diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
index 02e9324eee94eebda50b810c530e57da2f270179..7c049b0152bb030aef6098d27142f050498caa74 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc
@@ -765,7 +765,7 @@ int NetEqImpl::GetAudioInternal(size_t max_length,
// This handles the case when there is no transmission and the decoder
// should produce internal comfort noise.
// TODO(hlundin): Write test for codec-internal CNG.
- DoCodecInternalCng();
+ DoCodecInternalCng(decoded_buffer_.get(), length);
break;
}
case kDtmf: {
@@ -1163,7 +1163,11 @@ int NetEqImpl::Decode(PacketList* packet_list, Operations* operation,
int* decoded_length,
AudioDecoder::SpeechType* speech_type) {
*speech_type = AudioDecoder::kSpeech;
- AudioDecoder* decoder = NULL;
+
+ // When packet_list is empty, we may be in kCodecInternalCng mode, and for
+ // that we use current active decoder.
+ AudioDecoder* decoder = decoder_database_->GetActiveDecoder();
+
if (!packet_list->empty()) {
const Packet* packet = packet_list->front();
uint8_t payload_type = packet->header.payloadType;
@@ -1231,8 +1235,14 @@ int NetEqImpl::Decode(PacketList* packet_list, Operations* operation,
decoder->DecodePlc(1, &decoded_buffer_[*decoded_length]);
}
- int return_value = DecodeLoop(packet_list, operation, decoder,
- decoded_length, speech_type);
+ int return_value;
+ if (*operation == kCodecInternalCng) {
+ RTC_DCHECK(packet_list->empty());
+ return_value = DecodeCng(decoder, decoded_length, speech_type);
+ } else {
+ return_value = DecodeLoop(packet_list, *operation, decoder,
+ decoded_length, speech_type);
+ }
if (*decoded_length < 0) {
// Error returned from the decoder.
@@ -1266,13 +1276,45 @@ int NetEqImpl::Decode(PacketList* packet_list, Operations* operation,
return return_value;
}
-int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation,
+int NetEqImpl::DecodeCng(AudioDecoder* decoder, int* decoded_length,
+ AudioDecoder::SpeechType* speech_type) {
+ if (!decoder) {
+ // This happens when active decoder is not defined.
+ *decoded_length = -1;
+ return 0;
+ }
+
+ while (*decoded_length < rtc::checked_cast<int>(output_size_samples_)) {
+ const int length = decoder->Decode(
+ nullptr, 0, fs_hz_,
+ (decoded_buffer_length_ - *decoded_length) * sizeof(int16_t),
+ &decoded_buffer_[*decoded_length], speech_type);
+ if (length > 0) {
+ *decoded_length += length;
+ LOG(LS_VERBOSE) << "Decoded " << length << " CNG samples";
+ } else {
+ // Error.
+ LOG(LS_WARNING) << "Failed to decode CNG";
+ *decoded_length = -1;
+ break;
+ }
+ if (*decoded_length > static_cast<int>(decoded_buffer_length_)) {
+ // Guard against overflow.
+ LOG(LS_WARNING) << "Decoded too much CNG.";
+ return kDecodedTooMuch;
+ }
+ }
+ return 0;
+}
+
+int NetEqImpl::DecodeLoop(PacketList* packet_list, const Operations& operation,
AudioDecoder* decoder, int* decoded_length,
AudioDecoder::SpeechType* speech_type) {
Packet* packet = NULL;
if (!packet_list->empty()) {
packet = packet_list->front();
}
+
// Do decoding.
while (packet &&
!decoder_database_->IsComfortNoise(packet->header.payloadType)) {
@@ -1281,9 +1323,9 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation,
// number decoder channels.
assert(sync_buffer_->Channels() == decoder->Channels());
assert(decoded_buffer_length_ >= kMaxFrameSize * decoder->Channels());
- assert(*operation == kNormal || *operation == kAccelerate ||
- *operation == kFastAccelerate || *operation == kMerge ||
- *operation == kPreemptiveExpand);
+ assert(operation == kNormal || operation == kAccelerate ||
+ operation == kFastAccelerate || operation == kMerge ||
+ operation == kPreemptiveExpand);
packet_list->pop_front();
size_t payload_length = packet->payload_length;
int decode_length;
@@ -1643,21 +1685,12 @@ int NetEqImpl::DoRfc3389Cng(PacketList* packet_list, bool play_dtmf) {
return 0;
}
-void NetEqImpl::DoCodecInternalCng() {
- int length = 0;
- // TODO(hlundin): Will probably need a longer buffer for multi-channel.
- int16_t decoded_buffer[kMaxFrameSize];
- AudioDecoder* decoder = decoder_database_->GetActiveDecoder();
- if (decoder) {
- const uint8_t* dummy_payload = NULL;
- AudioDecoder::SpeechType speech_type;
- length = decoder->Decode(
- dummy_payload, 0, fs_hz_, kMaxFrameSize * sizeof(int16_t),
- decoded_buffer, &speech_type);
- }
- assert(mute_factor_array_.get());
- normal_->Process(decoded_buffer, length, last_mode_, mute_factor_array_.get(),
- algorithm_buffer_.get());
+void NetEqImpl::DoCodecInternalCng(const int16_t* decoded_buffer,
+ size_t decoded_length) {
+ RTC_DCHECK(normal_.get());
+ RTC_DCHECK(mute_factor_array_.get());
+ normal_->Process(decoded_buffer, decoded_length, last_mode_,
+ mute_factor_array_.get(), algorithm_buffer_.get());
last_mode_ = kModeCodecInternalCng;
expand_->Reset();
}
« no previous file with comments | « webrtc/modules/audio_coding/neteq/neteq_impl.h ('k') | webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698