OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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/main/acm2/acm_receiver.h" | 11 #include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" |
12 | 12 |
13 #include <stdlib.h> // malloc | 13 #include <stdlib.h> // malloc |
14 | 14 |
15 #include <algorithm> // sort | 15 #include <algorithm> // sort |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
19 #include "webrtc/base/format_macros.h" | 19 #include "webrtc/base/format_macros.h" |
20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
21 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" | 21 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" |
22 #include "webrtc/common_types.h" | 22 #include "webrtc/common_types.h" |
23 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" | 23 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" |
24 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" | 24 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" |
25 #include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" | 25 #include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" |
26 #include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" | 26 #include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" |
27 #include "webrtc/modules/audio_coding/main/acm2/nack.h" | |
28 #include "webrtc/modules/audio_coding/neteq/include/neteq.h" | 27 #include "webrtc/modules/audio_coding/neteq/include/neteq.h" |
29 #include "webrtc/system_wrappers/include/clock.h" | 28 #include "webrtc/system_wrappers/include/clock.h" |
30 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 29 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
31 #include "webrtc/system_wrappers/include/tick_util.h" | 30 #include "webrtc/system_wrappers/include/tick_util.h" |
32 #include "webrtc/system_wrappers/include/trace.h" | 31 #include "webrtc/system_wrappers/include/trace.h" |
33 | 32 |
34 namespace webrtc { | 33 namespace webrtc { |
35 | 34 |
36 namespace acm2 { | 35 namespace acm2 { |
37 | 36 |
38 namespace { | 37 namespace { |
39 | 38 |
40 const int kNackThresholdPackets = 2; | |
41 | |
42 // |vad_activity_| field of |audio_frame| is set to |previous_audio_activity_| | 39 // |vad_activity_| field of |audio_frame| is set to |previous_audio_activity_| |
43 // before the call to this function. | 40 // before the call to this function. |
44 void SetAudioFrameActivityAndType(bool vad_enabled, | 41 void SetAudioFrameActivityAndType(bool vad_enabled, |
45 NetEqOutputType type, | 42 NetEqOutputType type, |
46 AudioFrame* audio_frame) { | 43 AudioFrame* audio_frame) { |
47 if (vad_enabled) { | 44 if (vad_enabled) { |
48 switch (type) { | 45 switch (type) { |
49 case kOutputNormal: { | 46 case kOutputNormal: { |
50 audio_frame->vad_activity_ = AudioFrame::kVadActive; | 47 audio_frame->vad_activity_ = AudioFrame::kVadActive; |
51 audio_frame->speech_type_ = AudioFrame::kNormalSpeech; | 48 audio_frame->speech_type_ = AudioFrame::kNormalSpeech; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 } // namespace | 120 } // namespace |
124 | 121 |
125 AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) | 122 AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) |
126 : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), | 123 : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), |
127 id_(config.id), | 124 id_(config.id), |
128 last_audio_decoder_(nullptr), | 125 last_audio_decoder_(nullptr), |
129 previous_audio_activity_(AudioFrame::kVadPassive), | 126 previous_audio_activity_(AudioFrame::kVadPassive), |
130 current_sample_rate_hz_(config.neteq_config.sample_rate_hz), | 127 current_sample_rate_hz_(config.neteq_config.sample_rate_hz), |
131 audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), | 128 audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), |
132 last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), | 129 last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), |
133 nack_(), | |
134 nack_enabled_(false), | |
135 neteq_(NetEq::Create(config.neteq_config)), | 130 neteq_(NetEq::Create(config.neteq_config)), |
136 vad_enabled_(true), | 131 vad_enabled_(true), |
137 clock_(config.clock), | 132 clock_(config.clock), |
138 resampled_last_output_frame_(true), | 133 resampled_last_output_frame_(true), |
139 av_sync_(false), | 134 av_sync_(false), |
140 initial_delay_manager_(), | 135 initial_delay_manager_(), |
141 missing_packets_sync_stream_(), | 136 missing_packets_sync_stream_(), |
142 late_packets_sync_stream_() { | 137 late_packets_sync_stream_() { |
143 assert(clock_); | 138 assert(clock_); |
144 | 139 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 packet_type = InitialDelayManager::kCngPacket; | 242 packet_type = InitialDelayManager::kCngPacket; |
248 } else if (decoder->acm_codec_id == | 243 } else if (decoder->acm_codec_id == |
249 *RentACodec::CodecIndexFromId(RentACodec::CodecId::kAVT)) { | 244 *RentACodec::CodecIndexFromId(RentACodec::CodecId::kAVT)) { |
250 packet_type = InitialDelayManager::kAvtPacket; | 245 packet_type = InitialDelayManager::kAvtPacket; |
251 } else { | 246 } else { |
252 if (decoder != last_audio_decoder_) { | 247 if (decoder != last_audio_decoder_) { |
253 // This is either the first audio packet or send codec is changed. | 248 // This is either the first audio packet or send codec is changed. |
254 // Therefore, either NetEq buffer is empty or will be flushed when this | 249 // Therefore, either NetEq buffer is empty or will be flushed when this |
255 // packet is inserted. | 250 // packet is inserted. |
256 new_codec = true; | 251 new_codec = true; |
257 | |
258 // Updating NACK'sampling rate is required, either first packet is | |
259 // received or codec is changed. Furthermore, reset is required if codec | |
260 // is changed (NetEq flushes its buffer so NACK should reset its list). | |
261 if (nack_enabled_) { | |
262 assert(nack_.get()); | |
263 nack_->Reset(); | |
264 nack_->UpdateSampleRate(sample_rate_hz); | |
265 } | |
266 last_audio_decoder_ = decoder; | 252 last_audio_decoder_ = decoder; |
267 } | 253 } |
268 packet_type = InitialDelayManager::kAudioPacket; | 254 packet_type = InitialDelayManager::kAudioPacket; |
269 } | 255 } |
270 | 256 |
271 if (nack_enabled_) { | |
272 assert(nack_.get()); | |
273 nack_->UpdateLastReceivedPacket(header->sequenceNumber, | |
274 header->timestamp); | |
275 } | |
276 | |
277 if (av_sync_) { | 257 if (av_sync_) { |
278 assert(initial_delay_manager_.get()); | 258 assert(initial_delay_manager_.get()); |
279 assert(missing_packets_sync_stream_.get()); | 259 assert(missing_packets_sync_stream_.get()); |
280 // This updates |initial_delay_manager_| and specifies an stream of | 260 // This updates |initial_delay_manager_| and specifies an stream of |
281 // sync-packets, if required to be inserted. We insert the sync-packets | 261 // sync-packets, if required to be inserted. We insert the sync-packets |
282 // when AcmReceiver lock is released and |decoder_lock_| is acquired. | 262 // when AcmReceiver lock is released and |decoder_lock_| is acquired. |
283 initial_delay_manager_->UpdateLastReceivedPacket( | 263 initial_delay_manager_->UpdateLastReceivedPacket( |
284 rtp_header, receive_timestamp, packet_type, new_codec, sample_rate_hz, | 264 rtp_header, receive_timestamp, packet_type, new_codec, sample_rate_hz, |
285 missing_packets_sync_stream_.get()); | 265 missing_packets_sync_stream_.get()); |
286 } | 266 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 // Always write the output to |audio_buffer_| first. | 317 // Always write the output to |audio_buffer_| first. |
338 if (neteq_->GetAudio(AudioFrame::kMaxDataSizeSamples, | 318 if (neteq_->GetAudio(AudioFrame::kMaxDataSizeSamples, |
339 audio_buffer_.get(), | 319 audio_buffer_.get(), |
340 &samples_per_channel, | 320 &samples_per_channel, |
341 &num_channels, | 321 &num_channels, |
342 &type) != NetEq::kOK) { | 322 &type) != NetEq::kOK) { |
343 LOG(LERROR) << "AcmReceiver::GetAudio - NetEq Failed."; | 323 LOG(LERROR) << "AcmReceiver::GetAudio - NetEq Failed."; |
344 return -1; | 324 return -1; |
345 } | 325 } |
346 | 326 |
347 // Update NACK. | |
348 int decoded_sequence_num = 0; | |
349 uint32_t decoded_timestamp = 0; | |
350 bool update_nack = nack_enabled_ && // Update NACK only if it is enabled. | |
351 neteq_->DecodedRtpInfo(&decoded_sequence_num, &decoded_timestamp); | |
352 if (update_nack) { | |
353 assert(nack_.get()); | |
354 nack_->UpdateLastDecodedPacket(decoded_sequence_num, decoded_timestamp); | |
355 } | |
356 | |
357 // NetEq always returns 10 ms of audio. | 327 // NetEq always returns 10 ms of audio. |
358 current_sample_rate_hz_ = static_cast<int>(samples_per_channel * 100); | 328 current_sample_rate_hz_ = static_cast<int>(samples_per_channel * 100); |
359 | 329 |
360 // Update if resampling is required. | 330 // Update if resampling is required. |
361 bool need_resampling = (desired_freq_hz != -1) && | 331 bool need_resampling = (desired_freq_hz != -1) && |
362 (current_sample_rate_hz_ != desired_freq_hz); | 332 (current_sample_rate_hz_ != desired_freq_hz); |
363 | 333 |
364 if (need_resampling && !resampled_last_output_frame_) { | 334 if (need_resampling && !resampled_last_output_frame_) { |
365 // Prime the resampler with the last frame. | 335 // Prime the resampler with the last frame. |
366 int16_t temp_output[AudioFrame::kMaxDataSizeSamples]; | 336 int16_t temp_output[AudioFrame::kMaxDataSizeSamples]; |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 const Decoder& decoder = it->second; | 603 const Decoder& decoder = it->second; |
634 memcpy(codec, &ACMCodecDB::database_[decoder.acm_codec_id], | 604 memcpy(codec, &ACMCodecDB::database_[decoder.acm_codec_id], |
635 sizeof(CodecInst)); | 605 sizeof(CodecInst)); |
636 codec->pltype = decoder.payload_type; | 606 codec->pltype = decoder.payload_type; |
637 codec->channels = decoder.channels; | 607 codec->channels = decoder.channels; |
638 codec->plfreq = decoder.sample_rate_hz; | 608 codec->plfreq = decoder.sample_rate_hz; |
639 return 0; | 609 return 0; |
640 } | 610 } |
641 | 611 |
642 int AcmReceiver::EnableNack(size_t max_nack_list_size) { | 612 int AcmReceiver::EnableNack(size_t max_nack_list_size) { |
643 // Don't do anything if |max_nack_list_size| is out of range. | 613 neteq_->EnableNack(max_nack_list_size); |
644 if (max_nack_list_size == 0 || max_nack_list_size > Nack::kNackListSizeLimit) | 614 return 0; |
645 return -1; | |
646 | |
647 CriticalSectionScoped lock(crit_sect_.get()); | |
648 if (!nack_enabled_) { | |
649 nack_.reset(Nack::Create(kNackThresholdPackets)); | |
650 nack_enabled_ = true; | |
651 | |
652 // Sampling rate might need to be updated if we change from disable to | |
653 // enable. Do it if the receive codec is valid. | |
654 if (last_audio_decoder_) { | |
655 nack_->UpdateSampleRate( | |
656 ACMCodecDB::database_[last_audio_decoder_->acm_codec_id].plfreq); | |
657 } | |
658 } | |
659 return nack_->SetMaxNackListSize(max_nack_list_size); | |
660 } | 615 } |
661 | 616 |
662 void AcmReceiver::DisableNack() { | 617 void AcmReceiver::DisableNack() { |
663 CriticalSectionScoped lock(crit_sect_.get()); | 618 neteq_->DisableNack(); |
664 nack_.reset(); // Memory is released. | |
665 nack_enabled_ = false; | |
666 } | 619 } |
667 | 620 |
668 std::vector<uint16_t> AcmReceiver::GetNackList( | 621 std::vector<uint16_t> AcmReceiver::GetNackList( |
669 int64_t round_trip_time_ms) const { | 622 int64_t round_trip_time_ms) const { |
670 CriticalSectionScoped lock(crit_sect_.get()); | 623 return neteq_->GetNackList(round_trip_time_ms); |
671 if (round_trip_time_ms < 0) { | |
672 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_, | |
673 "GetNackList: round trip time cannot be negative." | |
674 " round_trip_time_ms=%" PRId64, round_trip_time_ms); | |
675 } | |
676 if (nack_enabled_ && round_trip_time_ms >= 0) { | |
677 assert(nack_.get()); | |
678 return nack_->GetNackList(round_trip_time_ms); | |
679 } | |
680 std::vector<uint16_t> empty_list; | |
681 return empty_list; | |
682 } | 624 } |
683 | 625 |
684 void AcmReceiver::ResetInitialDelay() { | 626 void AcmReceiver::ResetInitialDelay() { |
685 { | 627 { |
686 CriticalSectionScoped lock(crit_sect_.get()); | 628 CriticalSectionScoped lock(crit_sect_.get()); |
687 av_sync_ = false; | 629 av_sync_ = false; |
688 initial_delay_manager_.reset(NULL); | 630 initial_delay_manager_.reset(NULL); |
689 missing_packets_sync_stream_.reset(NULL); | 631 missing_packets_sync_stream_.reset(NULL); |
690 late_packets_sync_stream_.reset(NULL); | 632 late_packets_sync_stream_.reset(NULL); |
691 } | 633 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 | 728 |
787 void AcmReceiver::GetDecodingCallStatistics( | 729 void AcmReceiver::GetDecodingCallStatistics( |
788 AudioDecodingCallStats* stats) const { | 730 AudioDecodingCallStats* stats) const { |
789 CriticalSectionScoped lock(crit_sect_.get()); | 731 CriticalSectionScoped lock(crit_sect_.get()); |
790 *stats = call_stats_.GetDecodingStatistics(); | 732 *stats = call_stats_.GetDecodingStatistics(); |
791 } | 733 } |
792 | 734 |
793 } // namespace acm2 | 735 } // namespace acm2 |
794 | 736 |
795 } // namespace webrtc | 737 } // namespace webrtc |
OLD | NEW |