diff --git a/webrtc/modules/BUILD.gn b/webrtc/modules/BUILD.gn index 5514bf73ec..ccc681c02f 100644 --- a/webrtc/modules/BUILD.gn +++ b/webrtc/modules/BUILD.gn @@ -270,7 +270,6 @@ if (rtc_include_tests) { "audio_coding/acm2/audio_coding_module_unittest_oldapi.cc", "audio_coding/acm2/call_statistics_unittest.cc", "audio_coding/acm2/codec_manager_unittest.cc", - "audio_coding/acm2/initial_delay_manager_unittest.cc", "audio_coding/acm2/rent_a_codec_unittest.cc", "audio_coding/codecs/audio_decoder_factory_unittest.cc", "audio_coding/codecs/cng/audio_encoder_cng_unittest.cc", diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn index c59dfa2067..1d16202d72 100644 --- a/webrtc/modules/audio_coding/BUILD.gn +++ b/webrtc/modules/audio_coding/BUILD.gn @@ -92,8 +92,6 @@ rtc_static_library("audio_coding") { "acm2/call_statistics.h", "acm2/codec_manager.cc", "acm2/codec_manager.h", - "acm2/initial_delay_manager.cc", - "acm2/initial_delay_manager.h", "include/audio_coding_module.h", "include/audio_coding_module_typedefs.h", ] diff --git a/webrtc/modules/audio_coding/acm2/acm_receiver.h b/webrtc/modules/audio_coding/acm2/acm_receiver.h index 94f15a25dc..06946f41d8 100644 --- a/webrtc/modules/audio_coding/acm2/acm_receiver.h +++ b/webrtc/modules/audio_coding/acm2/acm_receiver.h @@ -24,7 +24,6 @@ #include "webrtc/engine_configurations.h" #include "webrtc/modules/audio_coding/acm2/acm_resampler.h" #include "webrtc/modules/audio_coding/acm2/call_statistics.h" -#include "webrtc/modules/audio_coding/acm2/initial_delay_manager.h" #include "webrtc/modules/audio_coding/include/audio_coding_module.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" #include "webrtc/modules/include/module_common_types.h" diff --git a/webrtc/modules/audio_coding/acm2/initial_delay_manager.cc b/webrtc/modules/audio_coding/acm2/initial_delay_manager.cc deleted file mode 100644 index 0c31b83eb3..0000000000 --- a/webrtc/modules/audio_coding/acm2/initial_delay_manager.cc +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/acm2/initial_delay_manager.h" - -namespace webrtc { - -namespace acm2 { - -InitialDelayManager::InitialDelayManager(int initial_delay_ms, - int late_packet_threshold) - : last_packet_type_(kUndefinedPacket), - last_receive_timestamp_(0), - timestamp_step_(0), - audio_payload_type_(kInvalidPayloadType), - initial_delay_ms_(initial_delay_ms), - buffered_audio_ms_(0), - buffering_(true), - playout_timestamp_(0), - late_packet_threshold_(late_packet_threshold) { - last_packet_rtp_info_.header.payloadType = kInvalidPayloadType; - last_packet_rtp_info_.header.ssrc = 0; - last_packet_rtp_info_.header.sequenceNumber = 0; - last_packet_rtp_info_.header.timestamp = 0; -} - -void InitialDelayManager::UpdateLastReceivedPacket( - const WebRtcRTPHeader& rtp_info, - uint32_t receive_timestamp, - PacketType type, - bool new_codec, - int sample_rate_hz, - SyncStream* sync_stream) { - assert(sync_stream); - - // If payload of audio packets is changing |new_codec| has to be true. - assert(!(!new_codec && type == kAudioPacket && - rtp_info.header.payloadType != audio_payload_type_)); - - // Just shorthands. - const RTPHeader* current_header = &rtp_info.header; - RTPHeader* last_header = &last_packet_rtp_info_.header; - - // Don't do anything if getting DTMF. The chance of DTMF in applications where - // initial delay is required is very low (we don't know of any). This avoids a - // lot of corner cases. The effect of ignoring DTMF packet is minimal. Note - // that DTMFs are inserted into NetEq just not accounted here. - if (type == kAvtPacket || - (last_packet_type_ != kUndefinedPacket && - !IsNewerSequenceNumber(current_header->sequenceNumber, - last_header->sequenceNumber))) { - sync_stream->num_sync_packets = 0; - return; - } - - // Either if it is a new packet or the first packet record and set variables. - if (new_codec || - last_packet_rtp_info_.header.payloadType == kInvalidPayloadType) { - timestamp_step_ = 0; - if (type == kAudioPacket) - audio_payload_type_ = rtp_info.header.payloadType; - else - audio_payload_type_ = kInvalidPayloadType; // Invalid. - - RecordLastPacket(rtp_info, receive_timestamp, type); - sync_stream->num_sync_packets = 0; - buffered_audio_ms_ = 0; - buffering_ = true; - - // If |buffering_| is set then |playout_timestamp_| should have correct - // value. - UpdatePlayoutTimestamp(*current_header, sample_rate_hz); - return; - } - - uint32_t timestamp_increase = current_header->timestamp - - last_header->timestamp; - - // |timestamp_increase| is invalid if this is the first packet. The effect is - // that |buffered_audio_ms_| is not increased. - if (last_packet_type_ == kUndefinedPacket) { - timestamp_increase = 0; - } - - if (buffering_) { - buffered_audio_ms_ += timestamp_increase * 1000 / sample_rate_hz; - - // A timestamp that reflects the initial delay, while buffering. - UpdatePlayoutTimestamp(*current_header, sample_rate_hz); - - if (buffered_audio_ms_ >= initial_delay_ms_) - buffering_ = false; - } - - if (current_header->sequenceNumber == last_header->sequenceNumber + 1) { - // Two consecutive audio packets, the previous packet-type is audio, so we - // can update |timestamp_step_|. - if (last_packet_type_ == kAudioPacket) - timestamp_step_ = timestamp_increase; - RecordLastPacket(rtp_info, receive_timestamp, type); - sync_stream->num_sync_packets = 0; - return; - } - - uint16_t packet_gap = current_header->sequenceNumber - - last_header->sequenceNumber - 1; - - // For smooth transitions leave a gap between audio and sync packets. - sync_stream->num_sync_packets = last_packet_type_ == kSyncPacket ? - packet_gap - 1 : packet_gap - 2; - - // Do nothing if we haven't received any audio packet. - if (sync_stream->num_sync_packets > 0 && - audio_payload_type_ != kInvalidPayloadType) { - if (timestamp_step_ == 0) { - // Make an estimate for |timestamp_step_| if it is not updated, yet. - assert(packet_gap > 0); - timestamp_step_ = timestamp_increase / (packet_gap + 1); - } - sync_stream->timestamp_step = timestamp_step_; - - // Build the first sync-packet based on the current received packet. - memcpy(&sync_stream->rtp_info, &rtp_info, sizeof(rtp_info)); - sync_stream->rtp_info.header.payloadType = audio_payload_type_; - - uint16_t sequence_number_update = sync_stream->num_sync_packets + 1; - uint32_t timestamp_update = timestamp_step_ * sequence_number_update; - - // Rewind sequence number and timestamps. This will give a more accurate - // description of the missing packets. - // - // Note that we leave a gap between the last packet in sync-stream and the - // current received packet, so it should be compensated for in the following - // computation of timestamps and sequence number. - sync_stream->rtp_info.header.sequenceNumber -= sequence_number_update; - sync_stream->receive_timestamp = receive_timestamp - timestamp_update; - sync_stream->rtp_info.header.timestamp -= timestamp_update; - sync_stream->rtp_info.header.payloadType = audio_payload_type_; - } else { - sync_stream->num_sync_packets = 0; - } - - RecordLastPacket(rtp_info, receive_timestamp, type); - return; -} - -void InitialDelayManager::RecordLastPacket(const WebRtcRTPHeader& rtp_info, - uint32_t receive_timestamp, - PacketType type) { - last_packet_type_ = type; - last_receive_timestamp_ = receive_timestamp; - memcpy(&last_packet_rtp_info_, &rtp_info, sizeof(rtp_info)); -} - -void InitialDelayManager::LatePackets( - uint32_t timestamp_now, SyncStream* sync_stream) { - assert(sync_stream); - sync_stream->num_sync_packets = 0; - - // If there is no estimate of timestamp increment, |timestamp_step_|, then - // we cannot estimate the number of late packets. - // If the last packet has been CNG, estimating late packets is not meaningful, - // as a CNG packet is on unknown length. - // We can set a higher threshold if the last packet is CNG and continue - // execution, but this is how ACM1 code was written. - if (timestamp_step_ <= 0 || - last_packet_type_ == kCngPacket || - last_packet_type_ == kUndefinedPacket || - audio_payload_type_ == kInvalidPayloadType) // No audio packet received. - return; - - int num_late_packets = (timestamp_now - last_receive_timestamp_) / - timestamp_step_; - - if (num_late_packets < late_packet_threshold_) - return; - - int sync_offset = 1; // One gap at the end of the sync-stream. - if (last_packet_type_ != kSyncPacket) { - ++sync_offset; // One more gap at the beginning of the sync-stream. - --num_late_packets; - } - uint32_t timestamp_update = sync_offset * timestamp_step_; - - sync_stream->num_sync_packets = num_late_packets; - if (num_late_packets == 0) - return; - - // Build the first sync-packet in the sync-stream. - memcpy(&sync_stream->rtp_info, &last_packet_rtp_info_, - sizeof(last_packet_rtp_info_)); - - // Increase sequence number and timestamps. - sync_stream->rtp_info.header.sequenceNumber += sync_offset; - sync_stream->rtp_info.header.timestamp += timestamp_update; - sync_stream->receive_timestamp = last_receive_timestamp_ + timestamp_update; - sync_stream->timestamp_step = timestamp_step_; - - // Sync-packets have audio payload-type. - sync_stream->rtp_info.header.payloadType = audio_payload_type_; - - uint16_t sequence_number_update = num_late_packets + sync_offset - 1; - timestamp_update = sequence_number_update * timestamp_step_; - - // Fake the last RTP, assuming the caller will inject the whole sync-stream. - last_packet_rtp_info_.header.timestamp += timestamp_update; - last_packet_rtp_info_.header.sequenceNumber += sequence_number_update; - last_packet_rtp_info_.header.payloadType = audio_payload_type_; - last_receive_timestamp_ += timestamp_update; - - last_packet_type_ = kSyncPacket; - return; -} - -bool InitialDelayManager::GetPlayoutTimestamp(uint32_t* playout_timestamp) { - if (!buffering_) { - return false; - } - *playout_timestamp = playout_timestamp_; - return true; -} - -void InitialDelayManager::DisableBuffering() { - buffering_ = false; -} - -void InitialDelayManager::UpdatePlayoutTimestamp( - const RTPHeader& current_header, int sample_rate_hz) { - playout_timestamp_ = current_header.timestamp - static_cast( - initial_delay_ms_ * sample_rate_hz / 1000); -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/acm2/initial_delay_manager.h b/webrtc/modules/audio_coding/acm2/initial_delay_manager.h deleted file mode 100644 index a73141adc6..0000000000 --- a/webrtc/modules/audio_coding/acm2/initial_delay_manager.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_INITIAL_DELAY_MANAGER_H_ -#define WEBRTC_MODULES_AUDIO_CODING_ACM2_INITIAL_DELAY_MANAGER_H_ - -#include "webrtc/modules/include/module_common_types.h" - -namespace webrtc { - -namespace acm2 { - -class InitialDelayManager { - public: - enum PacketType { - kUndefinedPacket, kCngPacket, kAvtPacket, kAudioPacket, kSyncPacket }; - - // Specifies a stream of sync-packets. - struct SyncStream { - SyncStream() - : num_sync_packets(0), - receive_timestamp(0), - timestamp_step(0) { - memset(&rtp_info, 0, sizeof(rtp_info)); - } - - int num_sync_packets; - - // RTP header of the first sync-packet in the sequence. - WebRtcRTPHeader rtp_info; - - // Received timestamp of the first sync-packet in the sequence. - uint32_t receive_timestamp; - - // Samples per packet. - uint32_t timestamp_step; - }; - - InitialDelayManager(int initial_delay_ms, int late_packet_threshold); - - // Update with the last received RTP header, |header|, and received timestamp, - // |received_timestamp|. |type| indicates the packet type. If codec is changed - // since the last time |new_codec| should be true. |sample_rate_hz| is the - // decoder's sampling rate in Hz. |header| has a field to store sampling rate - // but we are not sure if that is properly set at the send side, and |header| - // is declared constant in the caller of this function - // (AcmReceiver::InsertPacket()). |sync_stream| contains information required - // to generate a stream of sync packets. - void UpdateLastReceivedPacket(const WebRtcRTPHeader& header, - uint32_t receive_timestamp, - PacketType type, - bool new_codec, - int sample_rate_hz, - SyncStream* sync_stream); - - // Based on the last received timestamp and given the current timestamp, - // sequence of late (or perhaps missing) packets is computed. - void LatePackets(uint32_t timestamp_now, SyncStream* sync_stream); - - // Get playout timestamp. - // Returns true if the timestamp is valid (when buffering), otherwise false. - bool GetPlayoutTimestamp(uint32_t* playout_timestamp); - - // True if buffered audio is less than the given initial delay (specified at - // the constructor). Buffering might be disabled by the client of this class. - bool buffering() { return buffering_; } - - // Disable buffering in the class. - void DisableBuffering(); - - // True if any packet received for buffering. - bool PacketBuffered() { return last_packet_type_ != kUndefinedPacket; } - - private: - static const uint8_t kInvalidPayloadType = 0xFF; - - // Update playout timestamps. While buffering, this is about - // |initial_delay_ms| millisecond behind the latest received timestamp. - void UpdatePlayoutTimestamp(const RTPHeader& current_header, - int sample_rate_hz); - - // Record an RTP headr and related parameter - void RecordLastPacket(const WebRtcRTPHeader& rtp_info, - uint32_t receive_timestamp, - PacketType type); - - PacketType last_packet_type_; - WebRtcRTPHeader last_packet_rtp_info_; - uint32_t last_receive_timestamp_; - uint32_t timestamp_step_; - uint8_t audio_payload_type_; - const int initial_delay_ms_; - int buffered_audio_ms_; - bool buffering_; - - // During the initial phase where packets are being accumulated and silence - // is played out, |playout_ts| is a timestamp which is equal to - // |initial_delay_ms_| milliseconds earlier than the most recently received - // RTP timestamp. - uint32_t playout_timestamp_; - - // If the number of late packets exceed this value (computed based on current - // timestamp and last received timestamp), sequence of sync-packets is - // specified. - const int late_packet_threshold_; -}; - -} // namespace acm2 - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_INITIAL_DELAY_MANAGER_H_ diff --git a/webrtc/modules/audio_coding/acm2/initial_delay_manager_unittest.cc b/webrtc/modules/audio_coding/acm2/initial_delay_manager_unittest.cc deleted file mode 100644 index bf2850d0ec..0000000000 --- a/webrtc/modules/audio_coding/acm2/initial_delay_manager_unittest.cc +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include - -#include - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/acm2/initial_delay_manager.h" - -namespace webrtc { - -namespace acm2 { - -namespace { - -const uint8_t kAudioPayloadType = 0; -const uint8_t kCngPayloadType = 1; -const uint8_t kAvtPayloadType = 2; - -const int kSamplingRateHz = 16000; -const int kInitDelayMs = 200; -const int kFrameSizeMs = 20; -const uint32_t kTimestampStep = kFrameSizeMs * kSamplingRateHz / 1000; -const int kLatePacketThreshold = 5; - -void InitRtpInfo(WebRtcRTPHeader* rtp_info) { - memset(rtp_info, 0, sizeof(*rtp_info)); - rtp_info->header.markerBit = false; - rtp_info->header.payloadType = kAudioPayloadType; - rtp_info->header.sequenceNumber = 1234; - rtp_info->header.timestamp = 0xFFFFFFFD; // Close to wrap around. - rtp_info->header.ssrc = 0x87654321; // Arbitrary. - rtp_info->header.numCSRCs = 0; // Arbitrary. - rtp_info->header.paddingLength = 0; - rtp_info->header.headerLength = sizeof(RTPHeader); - rtp_info->header.payload_type_frequency = kSamplingRateHz; - rtp_info->header.extension.absoluteSendTime = 0; - rtp_info->header.extension.transmissionTimeOffset = 0; - rtp_info->frameType = kAudioFrameSpeech; -} - -void ForwardRtpHeader(int n, - WebRtcRTPHeader* rtp_info, - uint32_t* rtp_receive_timestamp) { - rtp_info->header.sequenceNumber += n; - rtp_info->header.timestamp += n * kTimestampStep; - *rtp_receive_timestamp += n * kTimestampStep; -} - -void NextRtpHeader(WebRtcRTPHeader* rtp_info, - uint32_t* rtp_receive_timestamp) { - ForwardRtpHeader(1, rtp_info, rtp_receive_timestamp); -} - -} // namespace - -class InitialDelayManagerTest : public ::testing::Test { - protected: - InitialDelayManagerTest() - : manager_(new InitialDelayManager(kInitDelayMs, kLatePacketThreshold)), - rtp_receive_timestamp_(1111) { } // Arbitrary starting point. - - virtual void SetUp() { - ASSERT_TRUE(manager_.get() != NULL); - InitRtpInfo(&rtp_info_); - } - - void GetNextRtpHeader(WebRtcRTPHeader* rtp_info, - uint32_t* rtp_receive_timestamp) const { - memcpy(rtp_info, &rtp_info_, sizeof(*rtp_info)); - *rtp_receive_timestamp = rtp_receive_timestamp_; - NextRtpHeader(rtp_info, rtp_receive_timestamp); - } - - std::unique_ptr manager_; - WebRtcRTPHeader rtp_info_; - uint32_t rtp_receive_timestamp_; -}; - -TEST_F(InitialDelayManagerTest, Init) { - EXPECT_TRUE(manager_->buffering()); - EXPECT_FALSE(manager_->PacketBuffered()); - manager_->DisableBuffering(); - EXPECT_FALSE(manager_->buffering()); - InitialDelayManager::SyncStream sync_stream; - - // Call before any packet inserted. - manager_->LatePackets(0x6789ABCD, &sync_stream); // Arbitrary but large - // receive timestamp. - EXPECT_EQ(0, sync_stream.num_sync_packets); - - // Insert non-audio packets, a CNG and DTMF. - rtp_info_.header.payloadType = kCngPayloadType; - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kCngPacket, false, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); - ForwardRtpHeader(5, &rtp_info_, &rtp_receive_timestamp_); - rtp_info_.header.payloadType = kAvtPayloadType; - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAvtPacket, false, - kSamplingRateHz, &sync_stream); - // Gap in sequence numbers but no audio received, sync-stream should be empty. - EXPECT_EQ(0, sync_stream.num_sync_packets); - manager_->LatePackets(0x45678987, &sync_stream); // Large arbitrary receive - // timestamp. - // |manager_| has no estimate of timestamp-step and has not received any - // audio packet. - EXPECT_EQ(0, sync_stream.num_sync_packets); - - - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - rtp_info_.header.payloadType = kAudioPayloadType; - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); - - // Call LatePAcket() after only one packet inserted. - manager_->LatePackets(0x6789ABCD, &sync_stream); // Arbitrary but large - // receive timestamp. - EXPECT_EQ(0, sync_stream.num_sync_packets); - - // Gap in timestamp, but this packet is also flagged as "new," therefore, - // expecting empty sync-stream. - ForwardRtpHeader(5, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); -} - -TEST_F(InitialDelayManagerTest, MissingPacket) { - InitialDelayManager::SyncStream sync_stream; - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Third packet, missing packets start from here. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - - // First sync-packet in sync-stream is one after the above packet. - WebRtcRTPHeader expected_rtp_info; - uint32_t expected_receive_timestamp; - GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp); - - const int kNumMissingPackets = 10; - ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets); - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); - EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step); - EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp); -} - -// There hasn't been any consecutive packets to estimate timestamp-step. -TEST_F(InitialDelayManagerTest, MissingPacketEstimateTimestamp) { - InitialDelayManager::SyncStream sync_stream; - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet, missing packets start here. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - - // First sync-packet in sync-stream is one after the above. - WebRtcRTPHeader expected_rtp_info; - uint32_t expected_receive_timestamp; - GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp); - - const int kNumMissingPackets = 10; - ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets); - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); -} - -TEST_F(InitialDelayManagerTest, MissingPacketWithCng) { - InitialDelayManager::SyncStream sync_stream; - - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet as CNG. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - rtp_info_.header.payloadType = kCngPayloadType; - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kCngPacket, false, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Audio packet after CNG. Missing packets start from this packet. - rtp_info_.header.payloadType = kAudioPayloadType; - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - - // Timestamps are increased higher than regular packet. - const uint32_t kCngTimestampStep = 5 * kTimestampStep; - rtp_info_.header.timestamp += kCngTimestampStep; - rtp_receive_timestamp_ += kCngTimestampStep; - - // First sync-packet in sync-stream is the one after the above packet. - WebRtcRTPHeader expected_rtp_info; - uint32_t expected_receive_timestamp; - GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp); - - const int kNumMissingPackets = 10; - ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets); - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); - EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step); - EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp); -} - -TEST_F(InitialDelayManagerTest, LatePacket) { - InitialDelayManager::SyncStream sync_stream; - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Timestamp increment for 10ms; - const uint32_t kTimestampStep10Ms = kSamplingRateHz / 100; - - // 10 ms after the second packet is inserted. - uint32_t timestamp_now = rtp_receive_timestamp_ + kTimestampStep10Ms; - - // Third packet, late packets start from this packet. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - - // First sync-packet in sync-stream, which is one after the above packet. - WebRtcRTPHeader expected_rtp_info; - uint32_t expected_receive_timestamp; - GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp); - - const int kLatePacketThreshold = 5; - - int expected_num_late_packets = kLatePacketThreshold - 1; - for (int k = 0; k < 2; ++k) { - for (int n = 1; n < kLatePacketThreshold * kFrameSizeMs / 10; ++n) { - manager_->LatePackets(timestamp_now, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets) << - "try " << k << " loop number " << n; - timestamp_now += kTimestampStep10Ms; - } - manager_->LatePackets(timestamp_now, &sync_stream); - - EXPECT_EQ(expected_num_late_packets, sync_stream.num_sync_packets) << - "try " << k; - EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step) << - "try " << k; - EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp) << - "try " << k; - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); - - timestamp_now += kTimestampStep10Ms; - - // |manger_| assumes the |sync_stream| obtained by LatePacket() is fully - // injected. The last injected packet is sync-packet, therefore, there will - // not be any gap between sync stream of this and the next iteration. - ForwardRtpHeader(sync_stream.num_sync_packets, &expected_rtp_info, - &expected_receive_timestamp); - expected_num_late_packets = kLatePacketThreshold; - } - - // Test "no-gap" for missing packet after late packet. - // |expected_rtp_info| is the expected sync-packet if any packet is missing. - memcpy(&rtp_info_, &expected_rtp_info, sizeof(rtp_info_)); - rtp_receive_timestamp_ = expected_receive_timestamp; - - int kNumMissingPackets = 3; // Arbitrary. - ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - - // Note that there is one packet gap between the last sync-packet and the - // latest inserted packet. - EXPECT_EQ(kNumMissingPackets - 1, sync_stream.num_sync_packets); - EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step); - EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp); - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); -} - -TEST_F(InitialDelayManagerTest, NoLatePacketAfterCng) { - InitialDelayManager::SyncStream sync_stream; - - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet as CNG. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - rtp_info_.header.payloadType = kCngPayloadType; - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kCngPacket, false, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Forward the time more then |kLatePacketThreshold| packets. - uint32_t timestamp_now = rtp_receive_timestamp_ + kTimestampStep * (3 + - kLatePacketThreshold); - - manager_->LatePackets(timestamp_now, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); -} - -TEST_F(InitialDelayManagerTest, BufferingAudio) { - InitialDelayManager::SyncStream sync_stream; - - // Very first packet is not counted in calculation of buffered audio. - for (int n = 0; n < kInitDelayMs / kFrameSizeMs; ++n) { - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, - n == 0, kSamplingRateHz, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); - EXPECT_TRUE(manager_->buffering()); - const uint32_t expected_playout_timestamp = rtp_info_.header.timestamp - - kInitDelayMs * kSamplingRateHz / 1000; - uint32_t actual_playout_timestamp = 0; - EXPECT_TRUE(manager_->GetPlayoutTimestamp(&actual_playout_timestamp)); - EXPECT_EQ(expected_playout_timestamp, actual_playout_timestamp); - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - } - - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, - false, kSamplingRateHz, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); - EXPECT_FALSE(manager_->buffering()); -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/audio_coding.gypi b/webrtc/modules/audio_coding/audio_coding.gypi index cb318ec777..0ed3e08034 100644 --- a/webrtc/modules/audio_coding/audio_coding.gypi +++ b/webrtc/modules/audio_coding/audio_coding.gypi @@ -180,8 +180,6 @@ 'acm2/call_statistics.h', 'acm2/codec_manager.cc', 'acm2/codec_manager.h', - 'acm2/initial_delay_manager.cc', - 'acm2/initial_delay_manager.h', 'include/audio_coding_module.h', 'include/audio_coding_module_typedefs.h', ],