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 29 matching lines...) Expand all Loading... | |
40 #include "webrtc/modules/audio_coding/neteq/packet_buffer.h" | 40 #include "webrtc/modules/audio_coding/neteq/packet_buffer.h" |
41 #include "webrtc/modules/audio_coding/neteq/packet.h" | 41 #include "webrtc/modules/audio_coding/neteq/packet.h" |
42 #include "webrtc/modules/audio_coding/neteq/payload_splitter.h" | 42 #include "webrtc/modules/audio_coding/neteq/payload_splitter.h" |
43 #include "webrtc/modules/audio_coding/neteq/post_decode_vad.h" | 43 #include "webrtc/modules/audio_coding/neteq/post_decode_vad.h" |
44 #include "webrtc/modules/audio_coding/neteq/preemptive_expand.h" | 44 #include "webrtc/modules/audio_coding/neteq/preemptive_expand.h" |
45 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" | 45 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" |
46 #include "webrtc/modules/audio_coding/neteq/tick_timer.h" | 46 #include "webrtc/modules/audio_coding/neteq/tick_timer.h" |
47 #include "webrtc/modules/audio_coding/neteq/timestamp_scaler.h" | 47 #include "webrtc/modules/audio_coding/neteq/timestamp_scaler.h" |
48 #include "webrtc/modules/include/module_common_types.h" | 48 #include "webrtc/modules/include/module_common_types.h" |
49 | 49 |
50 // Modify the code to obtain backwards bit-exactness. Once bit-exactness is no | |
51 // longer required, this #define should be removed (and the code that it | |
52 // enables). | |
53 #define LEGACY_BITEXACT | |
54 | |
55 namespace webrtc { | 50 namespace webrtc { |
56 | 51 |
57 NetEqImpl::Dependencies::Dependencies( | 52 NetEqImpl::Dependencies::Dependencies( |
58 const NetEq::Config& config, | 53 const NetEq::Config& config, |
59 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) | 54 const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory) |
60 : tick_timer(new TickTimer), | 55 : tick_timer(new TickTimer), |
61 buffer_level_filter(new BufferLevelFilter), | 56 buffer_level_filter(new BufferLevelFilter), |
62 decoder_database(new DecoderDatabase(decoder_factory)), | 57 decoder_database(new DecoderDatabase(decoder_factory)), |
63 delay_peak_detector(new DelayPeakDetector(tick_timer.get())), | 58 delay_peak_detector(new DelayPeakDetector(tick_timer.get())), |
64 delay_manager(new DelayManager(config.max_packets_in_buffer, | 59 delay_manager(new DelayManager(config.max_packets_in_buffer, |
(...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1138 // The only valid reason to get kUndefined is that new_codec_ is set. | 1133 // The only valid reason to get kUndefined is that new_codec_ is set. |
1139 assert(new_codec_); | 1134 assert(new_codec_); |
1140 if (*play_dtmf && !header) { | 1135 if (*play_dtmf && !header) { |
1141 timestamp_ = dtmf_event->timestamp; | 1136 timestamp_ = dtmf_event->timestamp; |
1142 } else { | 1137 } else { |
1143 if (!header) { | 1138 if (!header) { |
1144 LOG(LS_ERROR) << "Packet missing where it shouldn't."; | 1139 LOG(LS_ERROR) << "Packet missing where it shouldn't."; |
1145 return -1; | 1140 return -1; |
1146 } | 1141 } |
1147 timestamp_ = header->timestamp; | 1142 timestamp_ = header->timestamp; |
1148 if (*operation == kRfc3389CngNoPacket | 1143 if (*operation == kRfc3389CngNoPacket && |
1149 #ifndef LEGACY_BITEXACT | 1144 decoder_database_->IsComfortNoise(header->payloadType)) { |
1150 // Without this check, it can happen that a non-CNG packet is sent to | |
1151 // the CNG decoder as if it was a SID frame. This is clearly a bug, | |
1152 // but is kept for now to maintain bit-exactness with the test | |
1153 // vectors. | |
1154 && decoder_database_->IsComfortNoise(header->payloadType) | |
1155 #endif | |
1156 ) { | |
1157 // Change decision to CNG packet, since we do have a CNG packet, but it | 1145 // Change decision to CNG packet, since we do have a CNG packet, but it |
1158 // was considered too early to use. Now, use it anyway. | 1146 // was considered too early to use. Now, use it anyway. |
1159 *operation = kRfc3389Cng; | 1147 *operation = kRfc3389Cng; |
1160 } else if (*operation != kRfc3389Cng) { | 1148 } else if (*operation != kRfc3389Cng) { |
minyue-webrtc
2016/07/07 15:22:05
is "else if (*operation != kRfc3389Cng)" still val
ossu
2016/07/08 09:08:26
Hmm, this looks weird. If operation is CngNoPacket
minyue-webrtc
2016/07/08 12:36:25
Ah, I see. The original code did not capture all c
| |
1161 *operation = kNormal; | 1149 *operation = kNormal; |
1162 } | 1150 } |
1163 } | 1151 } |
1164 // Adjust |sync_buffer_| timestamp before setting |end_timestamp| to the | 1152 // Adjust |sync_buffer_| timestamp before setting |end_timestamp| to the |
1165 // new value. | 1153 // new value. |
1166 sync_buffer_->IncreaseEndTimestamp(timestamp_ - end_timestamp); | 1154 sync_buffer_->IncreaseEndTimestamp(timestamp_ - end_timestamp); |
1167 end_timestamp = timestamp_; | 1155 end_timestamp = timestamp_; |
1168 new_codec_ = false; | 1156 new_codec_ = false; |
1169 decision_logic_->SoftReset(); | 1157 decision_logic_->SoftReset(); |
1170 buffer_level_filter_->Reset(); | 1158 buffer_level_filter_->Reset(); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1365 decoder->Reset(); | 1353 decoder->Reset(); |
1366 | 1354 |
1367 // Reset comfort noise decoder. | 1355 // Reset comfort noise decoder. |
1368 ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder(); | 1356 ComfortNoiseDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder(); |
1369 if (cng_decoder) | 1357 if (cng_decoder) |
1370 cng_decoder->Reset(); | 1358 cng_decoder->Reset(); |
1371 | 1359 |
1372 reset_decoder_ = false; | 1360 reset_decoder_ = false; |
1373 } | 1361 } |
1374 | 1362 |
1375 #ifdef LEGACY_BITEXACT | |
1376 // Due to a bug in old SignalMCU, it could happen that CNG operation was | |
1377 // decided, but a speech packet was provided. The speech packet will be used | |
1378 // to update the comfort noise decoder, as if it was a SID frame, which is | |
1379 // clearly wrong. | |
1380 if (*operation == kRfc3389Cng) { | |
minyue-webrtc
2016/07/07 15:22:05
is it still possible to run in here?
though it is
ossu
2016/07/08 09:08:26
Hmm, maybe. If we did, we'd call DecodeLoop() belo
| |
1381 return 0; | |
1382 } | |
1383 #endif | |
1384 | |
1385 *decoded_length = 0; | 1363 *decoded_length = 0; |
1386 // Update codec-internal PLC state. | 1364 // Update codec-internal PLC state. |
1387 if ((*operation == kMerge) && decoder && decoder->HasDecodePlc()) { | 1365 if ((*operation == kMerge) && decoder && decoder->HasDecodePlc()) { |
1388 decoder->DecodePlc(1, &decoded_buffer_[*decoded_length]); | 1366 decoder->DecodePlc(1, &decoded_buffer_[*decoded_length]); |
1389 } | 1367 } |
1390 | 1368 |
1391 int return_value; | 1369 int return_value; |
1392 if (*operation == kCodecInternalCng) { | 1370 if (*operation == kCodecInternalCng) { |
1393 RTC_DCHECK(packet_list->empty()); | 1371 RTC_DCHECK(packet_list->empty()); |
1394 return_value = DecodeCng(decoder, decoded_length, speech_type); | 1372 return_value = DecodeCng(decoder, decoded_length, speech_type); |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1769 return 0; | 1747 return 0; |
1770 } | 1748 } |
1771 | 1749 |
1772 int NetEqImpl::DoRfc3389Cng(PacketList* packet_list, bool play_dtmf) { | 1750 int NetEqImpl::DoRfc3389Cng(PacketList* packet_list, bool play_dtmf) { |
1773 if (!packet_list->empty()) { | 1751 if (!packet_list->empty()) { |
1774 // Must have exactly one SID frame at this point. | 1752 // Must have exactly one SID frame at this point. |
1775 assert(packet_list->size() == 1); | 1753 assert(packet_list->size() == 1); |
1776 Packet* packet = packet_list->front(); | 1754 Packet* packet = packet_list->front(); |
1777 packet_list->pop_front(); | 1755 packet_list->pop_front(); |
1778 if (!decoder_database_->IsComfortNoise(packet->header.payloadType)) { | 1756 if (!decoder_database_->IsComfortNoise(packet->header.payloadType)) { |
1779 #ifdef LEGACY_BITEXACT | |
minyue-webrtc
2016/07/07 15:22:05
is it still possible to run in here?
though it is
ossu
2016/07/08 09:08:26
Well, we do return other types of errors, e.g. kUn
| |
1780 // This can happen due to a bug in GetDecision. Change the payload type | |
1781 // to a CNG type, and move on. Note that this means that we are in fact | |
1782 // sending a non-CNG payload to the comfort noise decoder for decoding. | |
1783 // Clearly wrong, but will maintain bit-exactness with legacy. | |
1784 if (fs_hz_ == 8000) { | |
1785 packet->header.payloadType = | |
1786 decoder_database_->GetRtpPayloadType(NetEqDecoder::kDecoderCNGnb); | |
1787 } else if (fs_hz_ == 16000) { | |
1788 packet->header.payloadType = | |
1789 decoder_database_->GetRtpPayloadType(NetEqDecoder::kDecoderCNGwb); | |
1790 } else if (fs_hz_ == 32000) { | |
1791 packet->header.payloadType = decoder_database_->GetRtpPayloadType( | |
1792 NetEqDecoder::kDecoderCNGswb32kHz); | |
1793 } else if (fs_hz_ == 48000) { | |
1794 packet->header.payloadType = decoder_database_->GetRtpPayloadType( | |
1795 NetEqDecoder::kDecoderCNGswb48kHz); | |
1796 } | |
1797 assert(decoder_database_->IsComfortNoise(packet->header.payloadType)); | |
1798 #else | |
1799 LOG(LS_ERROR) << "Trying to decode non-CNG payload as CNG."; | 1757 LOG(LS_ERROR) << "Trying to decode non-CNG payload as CNG."; |
1800 return kOtherError; | 1758 return kOtherError; |
1801 #endif | |
1802 } | 1759 } |
1803 // UpdateParameters() deletes |packet|. | 1760 // UpdateParameters() deletes |packet|. |
1804 if (comfort_noise_->UpdateParameters(packet) == | 1761 if (comfort_noise_->UpdateParameters(packet) == |
1805 ComfortNoise::kInternalError) { | 1762 ComfortNoise::kInternalError) { |
1806 algorithm_buffer_->Zeros(output_size_samples_); | 1763 algorithm_buffer_->Zeros(output_size_samples_); |
1807 return -comfort_noise_->internal_error_code(); | 1764 return -comfort_noise_->internal_error_code(); |
1808 } | 1765 } |
1809 } | 1766 } |
1810 int cn_return = comfort_noise_->Generate(output_size_samples_, | 1767 int cn_return = comfort_noise_->Generate(output_size_samples_, |
1811 algorithm_buffer_.get()); | 1768 algorithm_buffer_.get()); |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2166 } | 2123 } |
2167 } | 2124 } |
2168 | 2125 |
2169 void NetEqImpl::CreateDecisionLogic() { | 2126 void NetEqImpl::CreateDecisionLogic() { |
2170 decision_logic_.reset(DecisionLogic::Create( | 2127 decision_logic_.reset(DecisionLogic::Create( |
2171 fs_hz_, output_size_samples_, playout_mode_, decoder_database_.get(), | 2128 fs_hz_, output_size_samples_, playout_mode_, decoder_database_.get(), |
2172 *packet_buffer_.get(), delay_manager_.get(), buffer_level_filter_.get(), | 2129 *packet_buffer_.get(), delay_manager_.get(), buffer_level_filter_.get(), |
2173 tick_timer_.get())); | 2130 tick_timer_.get())); |
2174 } | 2131 } |
2175 } // namespace webrtc | 2132 } // namespace webrtc |
OLD | NEW |