 Chromium Code Reviews
 Chromium Code Reviews Issue 1334303005:
  Returning correct duration estimate on Opus DTX packets.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master
    
  
    Issue 1334303005:
  Returning correct duration estimate on Opus DTX packets.  (Closed) 
  Base URL: https://chromium.googlesource.com/external/webrtc.git@master| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 | 
| (...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 758 } | 758 } | 
| 759 case kRfc3389Cng: | 759 case kRfc3389Cng: | 
| 760 case kRfc3389CngNoPacket: { | 760 case kRfc3389CngNoPacket: { | 
| 761 return_value = DoRfc3389Cng(&packet_list, play_dtmf); | 761 return_value = DoRfc3389Cng(&packet_list, play_dtmf); | 
| 762 break; | 762 break; | 
| 763 } | 763 } | 
| 764 case kCodecInternalCng: { | 764 case kCodecInternalCng: { | 
| 765 // This handles the case when there is no transmission and the decoder | 765 // This handles the case when there is no transmission and the decoder | 
| 766 // should produce internal comfort noise. | 766 // should produce internal comfort noise. | 
| 767 // TODO(hlundin): Write test for codec-internal CNG. | 767 // TODO(hlundin): Write test for codec-internal CNG. | 
| 768 DoCodecInternalCng(); | 768 DoCodecInternalCng(decoded_buffer_.get(), length); | 
| 769 break; | 769 break; | 
| 770 } | 770 } | 
| 771 case kDtmf: { | 771 case kDtmf: { | 
| 772 // TODO(hlundin): Write test for this. | 772 // TODO(hlundin): Write test for this. | 
| 773 return_value = DoDtmf(dtmf_event, &play_dtmf); | 773 return_value = DoDtmf(dtmf_event, &play_dtmf); | 
| 774 break; | 774 break; | 
| 775 } | 775 } | 
| 776 case kAlternativePlc: { | 776 case kAlternativePlc: { | 
| 777 // TODO(hlundin): Write test for this. | 777 // TODO(hlundin): Write test for this. | 
| 778 DoAlternativePlc(false); | 778 DoAlternativePlc(false); | 
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1156 } | 1156 } | 
| 1157 | 1157 | 
| 1158 timestamp_ = end_timestamp; | 1158 timestamp_ = end_timestamp; | 
| 1159 return 0; | 1159 return 0; | 
| 1160 } | 1160 } | 
| 1161 | 1161 | 
| 1162 int NetEqImpl::Decode(PacketList* packet_list, Operations* operation, | 1162 int NetEqImpl::Decode(PacketList* packet_list, Operations* operation, | 
| 1163 int* decoded_length, | 1163 int* decoded_length, | 
| 1164 AudioDecoder::SpeechType* speech_type) { | 1164 AudioDecoder::SpeechType* speech_type) { | 
| 1165 *speech_type = AudioDecoder::kSpeech; | 1165 *speech_type = AudioDecoder::kSpeech; | 
| 1166 AudioDecoder* decoder = NULL; | 1166 | 
| 1167 // When packet_list is empty, we may be in kCodecInternalCng mode, and for | |
| 1168 // that we use current active decoder. | |
| 1169 AudioDecoder* decoder = decoder_database_->GetActiveDecoder(); | |
| 1170 | |
| 1167 if (!packet_list->empty()) { | 1171 if (!packet_list->empty()) { | 
| 1168 const Packet* packet = packet_list->front(); | 1172 const Packet* packet = packet_list->front(); | 
| 1169 uint8_t payload_type = packet->header.payloadType; | 1173 uint8_t payload_type = packet->header.payloadType; | 
| 1170 if (!decoder_database_->IsComfortNoise(payload_type)) { | 1174 if (!decoder_database_->IsComfortNoise(payload_type)) { | 
| 1171 decoder = decoder_database_->GetDecoder(payload_type); | 1175 decoder = decoder_database_->GetDecoder(payload_type); | 
| 1172 assert(decoder); | 1176 assert(decoder); | 
| 1173 if (!decoder) { | 1177 if (!decoder) { | 
| 1174 LOG(LS_WARNING) << "Unknown payload type " | 1178 LOG(LS_WARNING) << "Unknown payload type " | 
| 1175 << static_cast<int>(payload_type); | 1179 << static_cast<int>(payload_type); | 
| 1176 PacketBuffer::DeleteAllPackets(packet_list); | 1180 PacketBuffer::DeleteAllPackets(packet_list); | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1224 return 0; | 1228 return 0; | 
| 1225 } | 1229 } | 
| 1226 #endif | 1230 #endif | 
| 1227 | 1231 | 
| 1228 *decoded_length = 0; | 1232 *decoded_length = 0; | 
| 1229 // Update codec-internal PLC state. | 1233 // Update codec-internal PLC state. | 
| 1230 if ((*operation == kMerge) && decoder && decoder->HasDecodePlc()) { | 1234 if ((*operation == kMerge) && decoder && decoder->HasDecodePlc()) { | 
| 1231 decoder->DecodePlc(1, &decoded_buffer_[*decoded_length]); | 1235 decoder->DecodePlc(1, &decoded_buffer_[*decoded_length]); | 
| 1232 } | 1236 } | 
| 1233 | 1237 | 
| 1234 int return_value = DecodeLoop(packet_list, operation, decoder, | 1238 int return_value; | 
| 1235 decoded_length, speech_type); | 1239 if (*operation == kCodecInternalCng) { | 
| 1240 RTC_DCHECK(packet_list->empty()); | |
| 1241 return_value = DecodeCng(decoder, decoded_length, speech_type); | |
| 1242 } else { | |
| 1243 return_value = DecodeLoop(packet_list, *operation, decoder, | |
| 1244 decoded_length, speech_type); | |
| 1245 } | |
| 1236 | 1246 | 
| 1237 if (*decoded_length < 0) { | 1247 if (*decoded_length < 0) { | 
| 1238 // Error returned from the decoder. | 1248 // Error returned from the decoder. | 
| 1239 *decoded_length = 0; | 1249 *decoded_length = 0; | 
| 1240 sync_buffer_->IncreaseEndTimestamp( | 1250 sync_buffer_->IncreaseEndTimestamp( | 
| 1241 static_cast<uint32_t>(decoder_frame_length_)); | 1251 static_cast<uint32_t>(decoder_frame_length_)); | 
| 1242 int error_code = 0; | 1252 int error_code = 0; | 
| 1243 if (decoder) | 1253 if (decoder) | 
| 1244 error_code = decoder->ErrorCode(); | 1254 error_code = decoder->ErrorCode(); | 
| 1245 if (error_code != 0) { | 1255 if (error_code != 0) { | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1259 // since in this case, the we will increment the CNGplayedTS counter. | 1269 // since in this case, the we will increment the CNGplayedTS counter. | 
| 1260 // Increase with number of samples per channel. | 1270 // Increase with number of samples per channel. | 
| 1261 assert(*decoded_length == 0 || | 1271 assert(*decoded_length == 0 || | 
| 1262 (decoder && decoder->Channels() == sync_buffer_->Channels())); | 1272 (decoder && decoder->Channels() == sync_buffer_->Channels())); | 
| 1263 sync_buffer_->IncreaseEndTimestamp( | 1273 sync_buffer_->IncreaseEndTimestamp( | 
| 1264 *decoded_length / static_cast<int>(sync_buffer_->Channels())); | 1274 *decoded_length / static_cast<int>(sync_buffer_->Channels())); | 
| 1265 } | 1275 } | 
| 1266 return return_value; | 1276 return return_value; | 
| 1267 } | 1277 } | 
| 1268 | 1278 | 
| 1269 int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation, | 1279 int NetEqImpl::DecodeCng(AudioDecoder* decoder, int* decoded_length, | 
| 1280 AudioDecoder::SpeechType* speech_type) { | |
| 1281 RTC_DCHECK(decoder); | |
| 1282 int decode_length; | |
| 1283 while (*decoded_length < rtc::checked_cast<int>(output_size_samples_)) { | |
| 1284 decode_length = decoder->Decode( | |
| 1285 nullptr, 0, fs_hz_, decoded_buffer_length_ * sizeof(int16_t), | |
| 1286 decoded_buffer_.get(), speech_type); | |
| 1287 if (decode_length > 0) { | |
| 1288 *decoded_length += decode_length; | |
| 1289 LOG(LS_VERBOSE) << "Decoded " << decode_length << " CNG samples"; | |
| 1290 } else { | |
| 1291 // Error. | |
| 1292 LOG(LS_WARNING) << "Failed to decode CNG"; | |
| 1293 *decoded_length = -1; | |
| 1294 break; | |
| 1295 } | |
| 1296 } | |
| 1297 return 0; | |
| 1298 } | |
| 1299 | |
| 1300 int NetEqImpl::DecodeLoop(PacketList* packet_list, const Operations& operation, | |
| 1270 AudioDecoder* decoder, int* decoded_length, | 1301 AudioDecoder* decoder, int* decoded_length, | 
| 1271 AudioDecoder::SpeechType* speech_type) { | 1302 AudioDecoder::SpeechType* speech_type) { | 
| 1272 Packet* packet = NULL; | 1303 Packet* packet = NULL; | 
| 1273 if (!packet_list->empty()) { | 1304 if (!packet_list->empty()) { | 
| 1274 packet = packet_list->front(); | 1305 packet = packet_list->front(); | 
| 1275 } | 1306 } | 
| 1307 | |
| 1276 // Do decoding. | 1308 // Do decoding. | 
| 1277 while (packet && | 1309 while (packet && | 
| 1278 !decoder_database_->IsComfortNoise(packet->header.payloadType)) { | 1310 !decoder_database_->IsComfortNoise(packet->header.payloadType)) { | 
| 1279 assert(decoder); // At this point, we must have a decoder object. | 1311 assert(decoder); // At this point, we must have a decoder object. | 
| 1280 // The number of channels in the |sync_buffer_| should be the same as the | 1312 // The number of channels in the |sync_buffer_| should be the same as the | 
| 1281 // number decoder channels. | 1313 // number decoder channels. | 
| 1282 assert(sync_buffer_->Channels() == decoder->Channels()); | 1314 assert(sync_buffer_->Channels() == decoder->Channels()); | 
| 1283 assert(decoded_buffer_length_ >= kMaxFrameSize * decoder->Channels()); | 1315 assert(decoded_buffer_length_ >= kMaxFrameSize * decoder->Channels()); | 
| 1284 assert(*operation == kNormal || *operation == kAccelerate || | 1316 assert(operation == kNormal || operation == kAccelerate || | 
| 1285 *operation == kFastAccelerate || *operation == kMerge || | 1317 operation == kFastAccelerate || operation == kMerge || | 
| 1286 *operation == kPreemptiveExpand); | 1318 operation == kPreemptiveExpand); | 
| 1287 packet_list->pop_front(); | 1319 packet_list->pop_front(); | 
| 1288 size_t payload_length = packet->payload_length; | 1320 size_t payload_length = packet->payload_length; | 
| 1289 int decode_length; | 1321 int decode_length; | 
| 1290 if (packet->sync_packet) { | 1322 if (packet->sync_packet) { | 
| 1291 // Decode to silence with the same frame size as the last decode. | 1323 // Decode to silence with the same frame size as the last decode. | 
| 1292 LOG(LS_VERBOSE) << "Decoding sync-packet: " << | 1324 LOG(LS_VERBOSE) << "Decoding sync-packet: " << | 
| 1293 " ts=" << packet->header.timestamp << | 1325 " ts=" << packet->header.timestamp << | 
| 1294 ", sn=" << packet->header.sequenceNumber << | 1326 ", sn=" << packet->header.sequenceNumber << | 
| 1295 ", pt=" << static_cast<int>(packet->header.payloadType) << | 1327 ", pt=" << static_cast<int>(packet->header.payloadType) << | 
| 1296 ", ssrc=" << packet->header.ssrc << | 1328 ", ssrc=" << packet->header.ssrc << | 
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1636 } | 1668 } | 
| 1637 if (cn_return == ComfortNoise::kInternalError) { | 1669 if (cn_return == ComfortNoise::kInternalError) { | 
| 1638 decoder_error_code_ = comfort_noise_->internal_error_code(); | 1670 decoder_error_code_ = comfort_noise_->internal_error_code(); | 
| 1639 return kComfortNoiseErrorCode; | 1671 return kComfortNoiseErrorCode; | 
| 1640 } else if (cn_return == ComfortNoise::kUnknownPayloadType) { | 1672 } else if (cn_return == ComfortNoise::kUnknownPayloadType) { | 
| 1641 return kUnknownRtpPayloadType; | 1673 return kUnknownRtpPayloadType; | 
| 1642 } | 1674 } | 
| 1643 return 0; | 1675 return 0; | 
| 1644 } | 1676 } | 
| 1645 | 1677 | 
| 1646 void NetEqImpl::DoCodecInternalCng() { | 1678 void NetEqImpl::DoCodecInternalCng(const int16_t* decoded_buffer, | 
| 1647 int length = 0; | 1679 size_t decoded_length) { | 
| 1648 // TODO(hlundin): Will probably need a longer buffer for multi-channel. | 1680 assert(normal_.get()); | 
| 
hlundin-webrtc
2015/09/17 14:21:30
RTC_DCHECK
 
minyue-webrtc
2015/09/23 09:37:44
Done.
 | |
| 1649 int16_t decoded_buffer[kMaxFrameSize]; | |
| 1650 AudioDecoder* decoder = decoder_database_->GetActiveDecoder(); | |
| 1651 if (decoder) { | |
| 1652 const uint8_t* dummy_payload = NULL; | |
| 1653 AudioDecoder::SpeechType speech_type; | |
| 1654 length = decoder->Decode( | |
| 1655 dummy_payload, 0, fs_hz_, kMaxFrameSize * sizeof(int16_t), | |
| 1656 decoded_buffer, &speech_type); | |
| 1657 } | |
| 1658 assert(mute_factor_array_.get()); | 1681 assert(mute_factor_array_.get()); | 
| 1659 normal_->Process(decoded_buffer, length, last_mode_, mute_factor_array_.get(), | 1682 normal_->Process(decoded_buffer, decoded_length, last_mode_, | 
| 1660 algorithm_buffer_.get()); | 1683 mute_factor_array_.get(), algorithm_buffer_.get()); | 
| 1661 last_mode_ = kModeCodecInternalCng; | 1684 last_mode_ = kModeCodecInternalCng; | 
| 1662 expand_->Reset(); | 1685 expand_->Reset(); | 
| 1663 } | 1686 } | 
| 1664 | 1687 | 
| 1665 int NetEqImpl::DoDtmf(const DtmfEvent& dtmf_event, bool* play_dtmf) { | 1688 int NetEqImpl::DoDtmf(const DtmfEvent& dtmf_event, bool* play_dtmf) { | 
| 1666 // This block of the code and the block further down, handling |dtmf_switch| | 1689 // This block of the code and the block further down, handling |dtmf_switch| | 
| 1667 // are commented out. Otherwise playing out-of-band DTMF would fail in VoE | 1690 // are commented out. Otherwise playing out-of-band DTMF would fail in VoE | 
| 1668 // test, DtmfTest.ManualSuccessfullySendsOutOfBandTelephoneEvents. This is | 1691 // test, DtmfTest.ManualSuccessfullySendsOutOfBandTelephoneEvents. This is | 
| 1669 // equivalent to |dtmf_switch| always be false. | 1692 // equivalent to |dtmf_switch| always be false. | 
| 1670 // | 1693 // | 
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1993 | 2016 | 
| 1994 void NetEqImpl::CreateDecisionLogic() { | 2017 void NetEqImpl::CreateDecisionLogic() { | 
| 1995 decision_logic_.reset(DecisionLogic::Create(fs_hz_, output_size_samples_, | 2018 decision_logic_.reset(DecisionLogic::Create(fs_hz_, output_size_samples_, | 
| 1996 playout_mode_, | 2019 playout_mode_, | 
| 1997 decoder_database_.get(), | 2020 decoder_database_.get(), | 
| 1998 *packet_buffer_.get(), | 2021 *packet_buffer_.get(), | 
| 1999 delay_manager_.get(), | 2022 delay_manager_.get(), | 
| 2000 buffer_level_filter_.get())); | 2023 buffer_level_filter_.get())); | 
| 2001 } | 2024 } | 
| 2002 } // namespace webrtc | 2025 } // namespace webrtc | 
| OLD | NEW |