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 15 matching lines...) Expand all Loading... | |
26 #include "webrtc/modules/audio_coding/neteq/comfort_noise.h" | 26 #include "webrtc/modules/audio_coding/neteq/comfort_noise.h" |
27 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" | 27 #include "webrtc/modules/audio_coding/neteq/decision_logic.h" |
28 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" | 28 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" |
29 #include "webrtc/modules/audio_coding/neteq/defines.h" | 29 #include "webrtc/modules/audio_coding/neteq/defines.h" |
30 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" | 30 #include "webrtc/modules/audio_coding/neteq/delay_manager.h" |
31 #include "webrtc/modules/audio_coding/neteq/delay_peak_detector.h" | 31 #include "webrtc/modules/audio_coding/neteq/delay_peak_detector.h" |
32 #include "webrtc/modules/audio_coding/neteq/dtmf_buffer.h" | 32 #include "webrtc/modules/audio_coding/neteq/dtmf_buffer.h" |
33 #include "webrtc/modules/audio_coding/neteq/dtmf_tone_generator.h" | 33 #include "webrtc/modules/audio_coding/neteq/dtmf_tone_generator.h" |
34 #include "webrtc/modules/audio_coding/neteq/expand.h" | 34 #include "webrtc/modules/audio_coding/neteq/expand.h" |
35 #include "webrtc/modules/audio_coding/neteq/merge.h" | 35 #include "webrtc/modules/audio_coding/neteq/merge.h" |
36 #include "webrtc/modules/audio_coding/neteq/nack.h" | |
36 #include "webrtc/modules/audio_coding/neteq/normal.h" | 37 #include "webrtc/modules/audio_coding/neteq/normal.h" |
37 #include "webrtc/modules/audio_coding/neteq/packet_buffer.h" | 38 #include "webrtc/modules/audio_coding/neteq/packet_buffer.h" |
38 #include "webrtc/modules/audio_coding/neteq/packet.h" | 39 #include "webrtc/modules/audio_coding/neteq/packet.h" |
39 #include "webrtc/modules/audio_coding/neteq/payload_splitter.h" | 40 #include "webrtc/modules/audio_coding/neteq/payload_splitter.h" |
40 #include "webrtc/modules/audio_coding/neteq/post_decode_vad.h" | 41 #include "webrtc/modules/audio_coding/neteq/post_decode_vad.h" |
41 #include "webrtc/modules/audio_coding/neteq/preemptive_expand.h" | 42 #include "webrtc/modules/audio_coding/neteq/preemptive_expand.h" |
42 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" | 43 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" |
43 #include "webrtc/modules/audio_coding/neteq/timestamp_scaler.h" | 44 #include "webrtc/modules/audio_coding/neteq/timestamp_scaler.h" |
44 #include "webrtc/modules/interface/module_common_types.h" | 45 #include "webrtc/modules/interface/module_common_types.h" |
45 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" | 46 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
79 expand_factory_(expand_factory), | 80 expand_factory_(expand_factory), |
80 accelerate_factory_(accelerate_factory), | 81 accelerate_factory_(accelerate_factory), |
81 preemptive_expand_factory_(preemptive_expand_factory), | 82 preemptive_expand_factory_(preemptive_expand_factory), |
82 last_mode_(kModeNormal), | 83 last_mode_(kModeNormal), |
83 decoded_buffer_length_(kMaxFrameSize), | 84 decoded_buffer_length_(kMaxFrameSize), |
84 decoded_buffer_(new int16_t[decoded_buffer_length_]), | 85 decoded_buffer_(new int16_t[decoded_buffer_length_]), |
85 playout_timestamp_(0), | 86 playout_timestamp_(0), |
86 new_codec_(false), | 87 new_codec_(false), |
87 timestamp_(0), | 88 timestamp_(0), |
88 reset_decoder_(false), | 89 reset_decoder_(false), |
89 current_rtp_payload_type_(0xFF), // Invalid RTP payload type. | 90 current_rtp_payload_type_(0xFF), // Invalid RTP payload type. |
90 current_cng_rtp_payload_type_(0xFF), // Invalid RTP payload type. | 91 current_cng_rtp_payload_type_(0xFF), // Invalid RTP payload type. |
91 ssrc_(0), | 92 ssrc_(0), |
92 first_packet_(true), | 93 first_packet_(true), |
93 error_code_(0), | 94 error_code_(0), |
94 decoder_error_code_(0), | 95 decoder_error_code_(0), |
95 background_noise_mode_(config.background_noise_mode), | 96 background_noise_mode_(config.background_noise_mode), |
96 playout_mode_(config.playout_mode), | 97 playout_mode_(config.playout_mode), |
97 enable_fast_accelerate_(config.enable_fast_accelerate), | 98 enable_fast_accelerate_(config.enable_fast_accelerate), |
98 decoded_packet_sequence_number_(-1), | 99 nack_enabled_(false) { |
99 decoded_packet_timestamp_(0) { | |
100 LOG(LS_INFO) << "NetEq config: " << config.ToString(); | 100 LOG(LS_INFO) << "NetEq config: " << config.ToString(); |
101 int fs = config.sample_rate_hz; | 101 int fs = config.sample_rate_hz; |
102 if (fs != 8000 && fs != 16000 && fs != 32000 && fs != 48000) { | 102 if (fs != 8000 && fs != 16000 && fs != 32000 && fs != 48000) { |
103 LOG(LS_ERROR) << "Sample rate " << fs << " Hz not supported. " << | 103 LOG(LS_ERROR) << "Sample rate " << fs << " Hz not supported. " << |
104 "Changing to 8000 Hz."; | 104 "Changing to 8000 Hz."; |
105 fs = 8000; | 105 fs = 8000; |
106 } | 106 } |
107 fs_hz_ = fs; | 107 fs_hz_ = fs; |
108 fs_mult_ = fs / 8000; | 108 fs_mult_ = fs / 8000; |
109 output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_); | 109 output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 // Set to wait for new codec. | 398 // Set to wait for new codec. |
399 first_packet_ = true; | 399 first_packet_ = true; |
400 } | 400 } |
401 | 401 |
402 void NetEqImpl::PacketBufferStatistics(int* current_num_packets, | 402 void NetEqImpl::PacketBufferStatistics(int* current_num_packets, |
403 int* max_num_packets) const { | 403 int* max_num_packets) const { |
404 CriticalSectionScoped lock(crit_sect_.get()); | 404 CriticalSectionScoped lock(crit_sect_.get()); |
405 packet_buffer_->BufferStat(current_num_packets, max_num_packets); | 405 packet_buffer_->BufferStat(current_num_packets, max_num_packets); |
406 } | 406 } |
407 | 407 |
408 int NetEqImpl::DecodedRtpInfo(int* sequence_number, uint32_t* timestamp) const { | 408 void NetEqImpl::EnableNack(size_t max_nack_list_size) { |
409 RTC_CHECK_GT(max_nack_list_size, 0u); | |
410 // Ugly hack to get around the problem of passing static consts by reference. | |
411 const size_t kNackListSizeLimitLocal = Nack::kNackListSizeLimit; | |
412 RTC_CHECK_LE(max_nack_list_size, kNackListSizeLimitLocal); | |
413 | |
409 CriticalSectionScoped lock(crit_sect_.get()); | 414 CriticalSectionScoped lock(crit_sect_.get()); |
410 if (decoded_packet_sequence_number_ < 0) | 415 if (!nack_enabled_) { |
411 return -1; | 416 const int kNackThresholdPackets = 2; |
412 *sequence_number = decoded_packet_sequence_number_; | 417 nack_.reset(Nack::Create(kNackThresholdPackets)); |
413 *timestamp = decoded_packet_timestamp_; | 418 nack_enabled_ = true; |
414 return 0; | 419 nack_->UpdateSampleRate(fs_hz_); |
420 } | |
421 RTC_CHECK_EQ(nack_->SetMaxNackListSize(max_nack_list_size), 0); | |
minyue-webrtc
2015/10/27 14:35:08
why not make SetMaxNackListSize() a void and move
hlundin-webrtc
2015/10/28 15:03:36
Good idea. Done.
| |
422 } | |
423 | |
424 void NetEqImpl::DisableNack() { | |
425 CriticalSectionScoped lock(crit_sect_.get()); | |
426 nack_.reset(); | |
427 nack_enabled_ = false; | |
428 } | |
429 | |
430 std::vector<uint16_t> NetEqImpl::GetNackList(int64_t round_trip_time_ms) const { | |
431 RTC_CHECK_GE(round_trip_time_ms, 0); | |
minyue-webrtc
2015/10/27 14:35:08
is this necessary to crash?
hlundin-webrtc
2015/10/28 15:03:36
No, you are right. Changed to DCHECK. But I also m
| |
432 CriticalSectionScoped lock(crit_sect_.get()); | |
433 if (!nack_enabled_) { | |
434 return std::vector<uint16_t>(); | |
435 } | |
436 RTC_DCHECK(nack_.get()); | |
437 return nack_->GetNackList(round_trip_time_ms); | |
415 } | 438 } |
416 | 439 |
417 const SyncBuffer* NetEqImpl::sync_buffer_for_test() const { | 440 const SyncBuffer* NetEqImpl::sync_buffer_for_test() const { |
418 CriticalSectionScoped lock(crit_sect_.get()); | 441 CriticalSectionScoped lock(crit_sect_.get()); |
419 return sync_buffer_.get(); | 442 return sync_buffer_.get(); |
420 } | 443 } |
421 | 444 |
422 // Methods below this line are private. | 445 // Methods below this line are private. |
423 | 446 |
424 int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header, | 447 int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header, |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
604 decoder_database_->GetDecoder(main_header.payloadType); | 627 decoder_database_->GetDecoder(main_header.payloadType); |
605 assert(decoder); // Should always get a valid object, since we have | 628 assert(decoder); // Should always get a valid object, since we have |
606 // already checked that the payload types are known. | 629 // already checked that the payload types are known. |
607 decoder->IncomingPacket(packet_list.front()->payload, | 630 decoder->IncomingPacket(packet_list.front()->payload, |
608 packet_list.front()->payload_length, | 631 packet_list.front()->payload_length, |
609 packet_list.front()->header.sequenceNumber, | 632 packet_list.front()->header.sequenceNumber, |
610 packet_list.front()->header.timestamp, | 633 packet_list.front()->header.timestamp, |
611 receive_timestamp); | 634 receive_timestamp); |
612 } | 635 } |
613 | 636 |
637 if (nack_enabled_) { | |
638 RTC_DCHECK(nack_); | |
minyue-webrtc
2015/10/27 14:35:08
nack_.get()?
hlundin-webrtc
2015/10/28 15:03:36
Not needed. This expands "in the obvious way" thro
minyue-webrtc
2015/10/29 10:36:10
Ack, but we use get() elsewhere a lot, see line 43
hlundin-webrtc
2015/10/29 10:38:18
I know, but I'm trying to do better now. :)
kwiberg-webrtc
2015/10/29 10:46:01
+1
| |
639 if (update_sample_rate_and_channels) { | |
640 nack_->Reset(); | |
641 } | |
642 nack_->UpdateLastReceivedPacket(packet_list.front()->header.sequenceNumber, | |
643 packet_list.front()->header.timestamp); | |
644 } | |
645 | |
614 // Insert packets in buffer. | 646 // Insert packets in buffer. |
615 const size_t buffer_length_before_insert = | 647 const size_t buffer_length_before_insert = |
616 packet_buffer_->NumPacketsInBuffer(); | 648 packet_buffer_->NumPacketsInBuffer(); |
617 ret = packet_buffer_->InsertPacketList( | 649 ret = packet_buffer_->InsertPacketList( |
618 &packet_list, | 650 &packet_list, |
619 *decoder_database_, | 651 *decoder_database_, |
620 ¤t_rtp_payload_type_, | 652 ¤t_rtp_payload_type_, |
621 ¤t_cng_rtp_payload_type_); | 653 ¤t_cng_rtp_payload_type_); |
622 if (ret == PacketBuffer::kFlushed) { | 654 if (ret == PacketBuffer::kFlushed) { |
623 // Reset DSP timestamp etc. if packet buffer flushed. | 655 // Reset DSP timestamp etc. if packet buffer flushed. |
(...skipping 27 matching lines...) Expand all Loading... | |
651 // payload type of the hypothetically new send codec is not known. | 683 // payload type of the hypothetically new send codec is not known. |
652 const RTPHeader* rtp_header = packet_buffer_->NextRtpHeader(); | 684 const RTPHeader* rtp_header = packet_buffer_->NextRtpHeader(); |
653 assert(rtp_header); | 685 assert(rtp_header); |
654 int payload_type = rtp_header->payloadType; | 686 int payload_type = rtp_header->payloadType; |
655 AudioDecoder* decoder = decoder_database_->GetDecoder(payload_type); | 687 AudioDecoder* decoder = decoder_database_->GetDecoder(payload_type); |
656 assert(decoder); // Payloads are already checked to be valid. | 688 assert(decoder); // Payloads are already checked to be valid. |
657 const DecoderDatabase::DecoderInfo* decoder_info = | 689 const DecoderDatabase::DecoderInfo* decoder_info = |
658 decoder_database_->GetDecoderInfo(payload_type); | 690 decoder_database_->GetDecoderInfo(payload_type); |
659 assert(decoder_info); | 691 assert(decoder_info); |
660 if (decoder_info->fs_hz != fs_hz_ || | 692 if (decoder_info->fs_hz != fs_hz_ || |
661 decoder->Channels() != algorithm_buffer_->Channels()) | 693 decoder->Channels() != algorithm_buffer_->Channels()) { |
662 SetSampleRateAndChannels(decoder_info->fs_hz, decoder->Channels()); | 694 SetSampleRateAndChannels(decoder_info->fs_hz, decoder->Channels()); |
695 } | |
696 if (nack_enabled_) { | |
697 RTC_DCHECK(nack_); | |
698 // Update the sample rate even if the rate is not new, because of Reset(). | |
699 nack_->UpdateSampleRate(fs_hz_); | |
700 } | |
663 } | 701 } |
664 | 702 |
665 // TODO(hlundin): Move this code to DelayManager class. | 703 // TODO(hlundin): Move this code to DelayManager class. |
666 const DecoderDatabase::DecoderInfo* dec_info = | 704 const DecoderDatabase::DecoderInfo* dec_info = |
667 decoder_database_->GetDecoderInfo(main_header.payloadType); | 705 decoder_database_->GetDecoderInfo(main_header.payloadType); |
668 assert(dec_info); // Already checked that the payload type is known. | 706 assert(dec_info); // Already checked that the payload type is known. |
669 delay_manager_->LastDecoderType(dec_info->codec_type); | 707 delay_manager_->LastDecoderType(dec_info->codec_type); |
670 if (delay_manager_->last_pack_cng_or_dtmf() == 0) { | 708 if (delay_manager_->last_pack_cng_or_dtmf() == 0) { |
671 // Calculate the total speech length carried in each packet. | 709 // Calculate the total speech length carried in each packet. |
672 const size_t buffer_length_after_insert = | 710 const size_t buffer_length_after_insert = |
(...skipping 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1856 return -1; | 1894 return -1; |
1857 } | 1895 } |
1858 stats_.PacketsDiscarded(discard_count); | 1896 stats_.PacketsDiscarded(discard_count); |
1859 // Store waiting time in ms; packets->waiting_time is in "output blocks". | 1897 // Store waiting time in ms; packets->waiting_time is in "output blocks". |
1860 stats_.StoreWaitingTime(packet->waiting_time * kOutputSizeMs); | 1898 stats_.StoreWaitingTime(packet->waiting_time * kOutputSizeMs); |
1861 assert(packet->payload_length > 0); | 1899 assert(packet->payload_length > 0); |
1862 packet_list->push_back(packet); // Store packet in list. | 1900 packet_list->push_back(packet); // Store packet in list. |
1863 | 1901 |
1864 if (first_packet) { | 1902 if (first_packet) { |
1865 first_packet = false; | 1903 first_packet = false; |
1866 decoded_packet_sequence_number_ = prev_sequence_number = | 1904 if (nack_enabled_) { |
1867 packet->header.sequenceNumber; | 1905 RTC_DCHECK(nack_); |
1868 decoded_packet_timestamp_ = prev_timestamp = packet->header.timestamp; | 1906 // TODO(henrik.lundin): Should we update this for all decoded packets? |
1907 nack_->UpdateLastDecodedPacket(packet->header.sequenceNumber, | |
1908 packet->header.timestamp); | |
1909 } | |
1910 prev_sequence_number = packet->header.sequenceNumber; | |
1911 prev_timestamp = packet->header.timestamp; | |
1869 prev_payload_type = packet->header.payloadType; | 1912 prev_payload_type = packet->header.payloadType; |
1870 } | 1913 } |
1871 | 1914 |
1872 // Store number of extracted samples. | 1915 // Store number of extracted samples. |
1873 int packet_duration = 0; | 1916 int packet_duration = 0; |
1874 AudioDecoder* decoder = decoder_database_->GetDecoder( | 1917 AudioDecoder* decoder = decoder_database_->GetDecoder( |
1875 packet->header.payloadType); | 1918 packet->header.payloadType); |
1876 if (decoder) { | 1919 if (decoder) { |
1877 if (packet->sync_packet) { | 1920 if (packet->sync_packet) { |
1878 packet_duration = rtc::checked_cast<int>(decoder_frame_length_); | 1921 packet_duration = rtc::checked_cast<int>(decoder_frame_length_); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2026 | 2069 |
2027 void NetEqImpl::CreateDecisionLogic() { | 2070 void NetEqImpl::CreateDecisionLogic() { |
2028 decision_logic_.reset(DecisionLogic::Create(fs_hz_, output_size_samples_, | 2071 decision_logic_.reset(DecisionLogic::Create(fs_hz_, output_size_samples_, |
2029 playout_mode_, | 2072 playout_mode_, |
2030 decoder_database_.get(), | 2073 decoder_database_.get(), |
2031 *packet_buffer_.get(), | 2074 *packet_buffer_.get(), |
2032 delay_manager_.get(), | 2075 delay_manager_.get(), |
2033 buffer_level_filter_.get())); | 2076 buffer_level_filter_.get())); |
2034 } | 2077 } |
2035 } // namespace webrtc | 2078 } // namespace webrtc |
OLD | NEW |