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

Side by Side Diff: webrtc/modules/audio_coding/main/acm2/acm_receiver.cc

Issue 1410073006: ACM: Move NACK functionality inside NetEq (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 5 years, 1 month 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 unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/main/acm2/acm_receiver.h ('k') | webrtc/modules/audio_coding/main/acm2/nack.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698