Propagate arrival time inside NetEq

Bug: webrtc:341266986
Change-Id: I0fdd14e3fc5b09cbc9369497501f399464964211
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/352920
Commit-Queue: Lionel Koenig <lionelk@webrtc.org>
Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42414}
This commit is contained in:
Lionel Koenig 2024-05-27 11:22:27 +02:00 committed by WebRTC LUCI CQ
parent 79492bfe99
commit 5889cf5888
27 changed files with 267 additions and 132 deletions

View File

@ -23,6 +23,7 @@ rtc_source_set("neteq_api") {
"../../rtc_base:stringutils", "../../rtc_base:stringutils",
"../../system_wrappers:system_wrappers", "../../system_wrappers:system_wrappers",
"../audio_codecs:audio_codecs_api", "../audio_codecs:audio_codecs_api",
"../units:timestamp",
"//third_party/abseil-cpp/absl/types:optional", "//third_party/abseil-cpp/absl/types:optional",
] ]
} }

View File

@ -23,6 +23,7 @@
#include "api/audio_codecs/audio_format.h" #include "api/audio_codecs/audio_format.h"
#include "api/rtp_headers.h" #include "api/rtp_headers.h"
#include "api/scoped_refptr.h" #include "api/scoped_refptr.h"
#include "api/units/timestamp.h"
namespace webrtc { namespace webrtc {
@ -183,10 +184,20 @@ class NetEq {
virtual ~NetEq() {} virtual ~NetEq() {}
virtual int InsertPacket(const RTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> payload) {
// TODO: webrtc:343501093 - removed unused method.
return InsertPacket(rtp_header, payload,
/*receive_time=*/Timestamp::MinusInfinity());
}
// Inserts a new packet into NetEq. // Inserts a new packet into NetEq.
// Returns 0 on success, -1 on failure. // Returns 0 on success, -1 on failure.
virtual int InsertPacket(const RTPHeader& rtp_header, virtual int InsertPacket(const RTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> payload) = 0; rtc::ArrayView<const uint8_t> payload,
Timestamp receive_time) {
// TODO: webrtc:343501093 - Make this method pure virtual.
return InsertPacket(rtp_header, payload);
}
// Lets NetEq know that a packet arrived with an empty payload. This typically // Lets NetEq know that a packet arrived with an empty payload. This typically
// happens when empty packets are used for probing the network channel, and // happens when empty packets are used for probing the network channel, and

View File

@ -196,8 +196,8 @@ class ChannelReceive : public ChannelReceiveInterface,
private: private:
void ReceivePacket(const uint8_t* packet, void ReceivePacket(const uint8_t* packet,
size_t packet_length, size_t packet_length,
const RTPHeader& header) const RTPHeader& header,
RTC_RUN_ON(worker_thread_checker_); Timestamp receive_time) RTC_RUN_ON(worker_thread_checker_);
int ResendPackets(const uint16_t* sequence_numbers, int length); int ResendPackets(const uint16_t* sequence_numbers, int length);
void UpdatePlayoutTimestamp(bool rtcp, int64_t now_ms) void UpdatePlayoutTimestamp(bool rtcp, int64_t now_ms)
RTC_RUN_ON(worker_thread_checker_); RTC_RUN_ON(worker_thread_checker_);
@ -205,7 +205,8 @@ class ChannelReceive : public ChannelReceiveInterface,
int GetRtpTimestampRateHz() const; int GetRtpTimestampRateHz() const;
void OnReceivedPayloadData(rtc::ArrayView<const uint8_t> payload, void OnReceivedPayloadData(rtc::ArrayView<const uint8_t> payload,
const RTPHeader& rtpHeader) const RTPHeader& rtpHeader,
Timestamp receive_time)
RTC_RUN_ON(worker_thread_checker_); RTC_RUN_ON(worker_thread_checker_);
void InitFrameTransformerDelegate( void InitFrameTransformerDelegate(
@ -254,7 +255,6 @@ class ChannelReceive : public ChannelReceiveInterface,
AudioSinkInterface* audio_sink_ = nullptr; AudioSinkInterface* audio_sink_ = nullptr;
AudioLevel _outputAudioLevel; AudioLevel _outputAudioLevel;
Clock* const clock_;
RemoteNtpTimeEstimator ntp_estimator_ RTC_GUARDED_BY(ts_stats_lock_); RemoteNtpTimeEstimator ntp_estimator_ RTC_GUARDED_BY(ts_stats_lock_);
// Timestamp of the audio pulled from NetEq. // Timestamp of the audio pulled from NetEq.
@ -320,7 +320,8 @@ class ChannelReceive : public ChannelReceiveInterface,
void ChannelReceive::OnReceivedPayloadData( void ChannelReceive::OnReceivedPayloadData(
rtc::ArrayView<const uint8_t> payload, rtc::ArrayView<const uint8_t> payload,
const RTPHeader& rtpHeader) { const RTPHeader& rtpHeader,
Timestamp receive_time) {
if (!playing_) { if (!playing_) {
// Avoid inserting into NetEQ when we are not playing. Count the // Avoid inserting into NetEQ when we are not playing. Count the
// packet as discarded. // packet as discarded.
@ -335,7 +336,7 @@ void ChannelReceive::OnReceivedPayloadData(
// the SourceTracker from updating RtpSource information. // the SourceTracker from updating RtpSource information.
if (source_tracker_) { if (source_tracker_) {
RtpPacketInfos::vector_type packet_vector = { RtpPacketInfos::vector_type packet_vector = {
RtpPacketInfo(rtpHeader, clock_->CurrentTime())}; RtpPacketInfo(rtpHeader, receive_time)};
source_tracker_->OnFrameDelivered(RtpPacketInfos(packet_vector)); source_tracker_->OnFrameDelivered(RtpPacketInfos(packet_vector));
} }
@ -343,7 +344,7 @@ void ChannelReceive::OnReceivedPayloadData(
} }
// Push the incoming payload (parsed and ready for decoding) into the ACM // Push the incoming payload (parsed and ready for decoding) into the ACM
if (acm_receiver_.InsertPacket(rtpHeader, payload) != 0) { if (acm_receiver_.InsertPacket(rtpHeader, payload, receive_time) != 0) {
RTC_DLOG(LS_ERROR) << "ChannelReceive::OnReceivedPayloadData() unable to " RTC_DLOG(LS_ERROR) << "ChannelReceive::OnReceivedPayloadData() unable to "
"push data to the ACM"; "push data to the ACM";
return; return;
@ -372,7 +373,9 @@ void ChannelReceive::InitFrameTransformerDelegate(
receive_audio_callback = [this](rtc::ArrayView<const uint8_t> packet, receive_audio_callback = [this](rtc::ArrayView<const uint8_t> packet,
const RTPHeader& header) { const RTPHeader& header) {
RTC_DCHECK_RUN_ON(&worker_thread_checker_); RTC_DCHECK_RUN_ON(&worker_thread_checker_);
OnReceivedPayloadData(packet, header); // TODO(lionelk): Get the receive time.
OnReceivedPayloadData(packet, header,
/*receive_time=*/Timestamp::MinusInfinity());
}; };
frame_transformer_delegate_ = frame_transformer_delegate_ =
rtc::make_ref_counted<ChannelReceiveFrameTransformerDelegate>( rtc::make_ref_counted<ChannelReceiveFrameTransformerDelegate>(
@ -545,7 +548,6 @@ ChannelReceive::ChannelReceive(
jitter_buffer_fast_playout, jitter_buffer_fast_playout,
jitter_buffer_min_delay_ms)), jitter_buffer_min_delay_ms)),
_outputAudioLevel(), _outputAudioLevel(),
clock_(clock),
ntp_estimator_(clock), ntp_estimator_(clock),
playout_timestamp_rtp_(0), playout_timestamp_rtp_(0),
playout_delay_ms_(0), playout_delay_ms_(0),
@ -663,12 +665,14 @@ void ChannelReceive::OnRtpPacket(const RtpPacketReceived& packet) {
rtc::saturated_cast<uint32_t>(packet_copy.payload_type_frequency()), rtc::saturated_cast<uint32_t>(packet_copy.payload_type_frequency()),
header.extension.absolute_capture_time); header.extension.absolute_capture_time);
ReceivePacket(packet_copy.data(), packet_copy.size(), header); ReceivePacket(packet_copy.data(), packet_copy.size(), header,
packet.arrival_time());
} }
void ChannelReceive::ReceivePacket(const uint8_t* packet, void ChannelReceive::ReceivePacket(const uint8_t* packet,
size_t packet_length, size_t packet_length,
const RTPHeader& header) { const RTPHeader& header,
Timestamp receive_time) {
const uint8_t* payload = packet + header.headerLength; const uint8_t* payload = packet + header.headerLength;
RTC_DCHECK_GE(packet_length, header.headerLength); RTC_DCHECK_GE(packet_length, header.headerLength);
size_t payload_length = packet_length - header.headerLength; size_t payload_length = packet_length - header.headerLength;
@ -688,7 +692,8 @@ void ChannelReceive::ReceivePacket(const uint8_t* packet,
const FrameDecryptorInterface::Result decrypt_result = const FrameDecryptorInterface::Result decrypt_result =
frame_decryptor_->Decrypt( frame_decryptor_->Decrypt(
cricket::MEDIA_TYPE_AUDIO, csrcs, cricket::MEDIA_TYPE_AUDIO, csrcs,
/*additional_data=*/nullptr, /*additional_data=*/
nullptr,
rtc::ArrayView<const uint8_t>(payload, payload_data_length), rtc::ArrayView<const uint8_t>(payload, payload_data_length),
decrypted_audio_payload); decrypted_audio_payload);
@ -720,7 +725,7 @@ void ChannelReceive::ReceivePacket(const uint8_t* packet,
frame_transformer_delegate_->Transform(payload_data, header, remote_ssrc_, frame_transformer_delegate_->Transform(payload_data, header, remote_ssrc_,
mime_type.str()); mime_type.str());
} else { } else {
OnReceivedPayloadData(payload_data, header); OnReceivedPayloadData(payload_data, header, receive_time);
} }
} }

View File

@ -11,6 +11,7 @@
#include "audio/voip/audio_ingress.h" #include "audio/voip/audio_ingress.h"
#include <algorithm> #include <algorithm>
#include <ctime>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -50,7 +51,8 @@ AudioIngress::AudioIngress(
rtp_receive_statistics_(receive_statistics), rtp_receive_statistics_(receive_statistics),
rtp_rtcp_(rtp_rtcp), rtp_rtcp_(rtp_rtcp),
acm_receiver_(CreateAcmConfig(decoder_factory)), acm_receiver_(CreateAcmConfig(decoder_factory)),
ntp_estimator_(clock) {} ntp_estimator_(clock),
clock_(clock) {}
AudioIngress::~AudioIngress() = default; AudioIngress::~AudioIngress() = default;
@ -184,7 +186,8 @@ void AudioIngress::ReceivedRTPPacket(rtc::ArrayView<const uint8_t> rtp_packet) {
auto data_view = rtc::ArrayView<const uint8_t>(payload, payload_data_length); auto data_view = rtc::ArrayView<const uint8_t>(payload, payload_data_length);
// Push the incoming payload (parsed and ready for decoding) into the ACM. // Push the incoming payload (parsed and ready for decoding) into the ACM.
if (acm_receiver_.InsertPacket(header, data_view) != 0) { if (acm_receiver_.InsertPacket(header, data_view, clock_->CurrentTime()) !=
0) {
RTC_DLOG(LS_ERROR) << "AudioIngress::ReceivedRTPPacket() unable to " RTC_DLOG(LS_ERROR) << "AudioIngress::ReceivedRTPPacket() unable to "
"push data to the ACM"; "push data to the ACM";
} }

View File

@ -133,6 +133,8 @@ class AudioIngress : public AudioMixer::Source {
RemoteNtpTimeEstimator ntp_estimator_ RTC_GUARDED_BY(lock_); RemoteNtpTimeEstimator ntp_estimator_ RTC_GUARDED_BY(lock_);
Clock* clock_;
// For receiving RTP statistics, this tracks the sampling rate value // For receiving RTP statistics, this tracks the sampling rate value
// per payload type set when caller set via SetReceiveCodecs. // per payload type set when caller set via SetReceiveCodecs.
std::map<int, int> receive_codec_info_ RTC_GUARDED_BY(lock_); std::map<int, int> receive_codec_info_ RTC_GUARDED_BY(lock_);

View File

@ -47,6 +47,7 @@ rtc_library("audio_coding") {
"../../api/audio:audio_frame_api", "../../api/audio:audio_frame_api",
"../../api/audio_codecs:audio_codecs_api", "../../api/audio_codecs:audio_codecs_api",
"../../api/neteq:neteq_api", "../../api/neteq:neteq_api",
"../../api/units:timestamp",
"../../common_audio", "../../common_audio",
"../../common_audio:common_audio_c", "../../common_audio:common_audio_c",
"../../rtc_base:audio_format_to_string", "../../rtc_base:audio_format_to_string",
@ -712,6 +713,7 @@ rtc_library("neteq") {
"../../api/neteq:neteq_api", "../../api/neteq:neteq_api",
"../../api/neteq:neteq_controller_api", "../../api/neteq:neteq_controller_api",
"../../api/neteq:tick_timer", "../../api/neteq:tick_timer",
"../../api/units:timestamp",
"../../common_audio", "../../common_audio",
"../../common_audio:common_audio_c", "../../common_audio:common_audio_c",
"../../rtc_base:audio_format_to_string", "../../rtc_base:audio_format_to_string",
@ -784,6 +786,7 @@ rtc_library("neteq_tools_minimal") {
"../../api/neteq:custom_neteq_factory", "../../api/neteq:custom_neteq_factory",
"../../api/neteq:default_neteq_controller_factory", "../../api/neteq:default_neteq_controller_factory",
"../../api/neteq:neteq_api", "../../api/neteq:neteq_api",
"../../api/units:timestamp",
"../../rtc_base:buffer", "../../rtc_base:buffer",
"../../rtc_base:checks", "../../rtc_base:checks",
"../../rtc_base:copy_on_write_buffer", "../../rtc_base:copy_on_write_buffer",
@ -938,6 +941,7 @@ rtc_library("audio_coding_modules_tests_shared") {
"../../api/audio_codecs:builtin_audio_decoder_factory", "../../api/audio_codecs:builtin_audio_decoder_factory",
"../../api/audio_codecs:builtin_audio_encoder_factory", "../../api/audio_codecs:builtin_audio_encoder_factory",
"../../api/neteq:neteq_api", "../../api/neteq:neteq_api",
"../../api/units:timestamp",
"../../rtc_base:checks", "../../rtc_base:checks",
"../../rtc_base:digest", "../../rtc_base:digest",
"../../rtc_base:stringutils", "../../rtc_base:stringutils",
@ -1067,6 +1071,7 @@ if (rtc_include_tests) {
"../../api/audio_codecs/ilbc:audio_encoder_ilbc", "../../api/audio_codecs/ilbc:audio_encoder_ilbc",
"../../api/audio_codecs/opus:audio_decoder_opus", "../../api/audio_codecs/opus:audio_decoder_opus",
"../../api/audio_codecs/opus:audio_encoder_opus", "../../api/audio_codecs/opus:audio_encoder_opus",
"../../api/units:timestamp",
"../../common_audio", "../../common_audio",
"../../rtc_base:checks", "../../rtc_base:checks",
"../../rtc_base:logging", "../../rtc_base:logging",
@ -1356,6 +1361,7 @@ if (rtc_include_tests) {
":neteq_tools_minimal", ":neteq_tools_minimal",
"../../api/audio_codecs:builtin_audio_decoder_factory", "../../api/audio_codecs:builtin_audio_decoder_factory",
"../../api/neteq:neteq_api", "../../api/neteq:neteq_api",
"../../api/units:timestamp",
"../../rtc_base:checks", "../../rtc_base:checks",
"../../rtc_base:stringutils", "../../rtc_base:stringutils",
"../../system_wrappers", "../../system_wrappers",
@ -1684,6 +1690,7 @@ if (rtc_include_tests) {
"../../api/neteq:tick_timer", "../../api/neteq:tick_timer",
"../../api/neteq:tick_timer_unittest", "../../api/neteq:tick_timer_unittest",
"../../api/rtc_event_log", "../../api/rtc_event_log",
"../../api/units:timestamp",
"../../common_audio", "../../common_audio",
"../../common_audio:common_audio_c", "../../common_audio:common_audio_c",
"../../common_audio:mock_common_audio", "../../common_audio:mock_common_audio",

View File

@ -122,7 +122,8 @@ void AcmReceiveTestOldApi::Run() {
EXPECT_EQ(0, acm_receiver_->InsertPacket( EXPECT_EQ(0, acm_receiver_->InsertPacket(
packet->header(), packet->header(),
rtc::ArrayView<const uint8_t>( rtc::ArrayView<const uint8_t>(
packet->payload(), packet->payload_length_bytes()))) packet->payload(), packet->payload_length_bytes()),
clock_.CurrentTime()))
<< "Failure when inserting packet:" << std::endl << "Failure when inserting packet:" << std::endl
<< " PT = " << static_cast<int>(packet->header().payloadType) << " PT = " << static_cast<int>(packet->header().payloadType)
<< std::endl << std::endl

View File

@ -20,6 +20,7 @@
#include "api/audio/audio_frame.h" #include "api/audio/audio_frame.h"
#include "api/audio_codecs/audio_decoder.h" #include "api/audio_codecs/audio_decoder.h"
#include "api/neteq/neteq.h" #include "api/neteq/neteq.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/acm2/acm_resampler.h" #include "modules/audio_coding/acm2/acm_resampler.h"
#include "modules/audio_coding/acm2/call_statistics.h" #include "modules/audio_coding/acm2/call_statistics.h"
#include "modules/audio_coding/neteq/default_neteq_factory.h" #include "modules/audio_coding/neteq/default_neteq_factory.h"
@ -102,7 +103,8 @@ int AcmReceiver::last_output_sample_rate_hz() const {
} }
int AcmReceiver::InsertPacket(const RTPHeader& rtp_header, int AcmReceiver::InsertPacket(const RTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> incoming_payload) { rtc::ArrayView<const uint8_t> incoming_payload,
Timestamp receive_time) {
if (incoming_payload.empty()) { if (incoming_payload.empty()) {
neteq_->InsertEmptyPacket(rtp_header); neteq_->InsertEmptyPacket(rtp_header);
return 0; return 0;
@ -137,7 +139,7 @@ int AcmReceiver::InsertPacket(const RTPHeader& rtp_header,
} }
} // `mutex_` is released. } // `mutex_` is released.
if (neteq_->InsertPacket(rtp_header, incoming_payload) < 0) { if (neteq_->InsertPacket(rtp_header, incoming_payload, receive_time) < 0) {
RTC_LOG(LS_ERROR) << "AcmReceiver::InsertPacket " RTC_LOG(LS_ERROR) << "AcmReceiver::InsertPacket "
<< static_cast<int>(rtp_header.payloadType) << static_cast<int>(rtp_header.payloadType)
<< " Failed to insert packet"; << " Failed to insert packet";

View File

@ -28,6 +28,7 @@
#include "api/audio_codecs/audio_format.h" #include "api/audio_codecs/audio_format.h"
#include "api/neteq/neteq.h" #include "api/neteq/neteq.h"
#include "api/neteq/neteq_factory.h" #include "api/neteq/neteq_factory.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/acm2/acm_resampler.h" #include "modules/audio_coding/acm2/acm_resampler.h"
#include "modules/audio_coding/acm2/call_statistics.h" #include "modules/audio_coding/acm2/call_statistics.h"
#include "modules/audio_coding/include/audio_coding_module_typedefs.h" #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
@ -70,13 +71,15 @@ class AcmReceiver {
// information about payload type, sequence number, // information about payload type, sequence number,
// timestamp, SSRC and marker bit. // timestamp, SSRC and marker bit.
// - incoming_payload : Incoming audio payload. // - incoming_payload : Incoming audio payload.
// - length_payload : Length of incoming audio payload in bytes. // - receive_time : Timestamp when the packet has been seen on the
// network card.
// //
// Return value : 0 if OK. // Return value : 0 if OK.
// <0 if NetEq returned an error. // <0 if NetEq returned an error.
// //
int InsertPacket(const RTPHeader& rtp_header, int InsertPacket(const RTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> incoming_payload); rtc::ArrayView<const uint8_t> incoming_payload,
Timestamp receive_time = Timestamp::MinusInfinity());
// //
// Asks NetEq for 10 milliseconds of decoded audio. // Asks NetEq for 10 milliseconds of decoded audio.

View File

@ -16,6 +16,7 @@
#include "absl/types/optional.h" #include "absl/types/optional.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/codecs/cng/audio_encoder_cng.h" #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
#include "modules/audio_coding/include/audio_coding_module.h" #include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/neteq/tools/rtp_generator.h" #include "modules/audio_coding/neteq/tools/rtp_generator.h"
@ -119,7 +120,8 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback,
int ret_val = receiver_->InsertPacket( int ret_val = receiver_->InsertPacket(
rtp_header_, rtp_header_,
rtc::ArrayView<const uint8_t>(payload_data, payload_len_bytes)); rtc::ArrayView<const uint8_t>(payload_data, payload_len_bytes),
Timestamp::MinusInfinity());
if (ret_val < 0) { if (ret_val < 0) {
RTC_DCHECK_NOTREACHED(); RTC_DCHECK_NOTREACHED();
return -1; return -1;
@ -373,7 +375,8 @@ TEST_F(AcmReceiverTestOldApi, MAYBE_NetEqCalls) {
for (int num_calls = 0; num_calls < kNumNormalCalls; ++num_calls) { for (int num_calls = 0; num_calls < kNumNormalCalls; ++num_calls) {
const uint8_t kPayload[kPayloadSizeBytes] = {0}; const uint8_t kPayload[kPayloadSizeBytes] = {0};
ASSERT_EQ(0, receiver_->InsertPacket(rtp_header, kPayload)); ASSERT_EQ(0, receiver_->InsertPacket(rtp_header, kPayload,
Timestamp::MinusInfinity()));
++rtp_header.sequenceNumber; ++rtp_header.sequenceNumber;
rtp_header.timestamp += kFrameSizeSamples; rtp_header.timestamp += kFrameSizeSamples;
ASSERT_EQ(0, receiver_->GetAudio(-1, &audio_frame, &muted)); ASSERT_EQ(0, receiver_->GetAudio(-1, &audio_frame, &muted));

View File

@ -25,6 +25,7 @@
#include "api/audio_codecs/opus/audio_decoder_opus.h" #include "api/audio_codecs/opus/audio_decoder_opus.h"
#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h" #include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h"
#include "api/audio_codecs/opus/audio_encoder_opus.h" #include "api/audio_codecs/opus/audio_encoder_opus.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/acm2/acm_receive_test.h" #include "modules/audio_coding/acm2/acm_receive_test.h"
#include "modules/audio_coding/acm2/acm_send_test.h" #include "modules/audio_coding/acm2/acm_send_test.h"
#include "modules/audio_coding/codecs/cng/audio_encoder_cng.h" #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
@ -209,9 +210,10 @@ class AudioCodingModuleTestOldApi : public ::testing::Test {
virtual void InsertPacket() { virtual void InsertPacket() {
const uint8_t kPayload[kPayloadSizeBytes] = {0}; const uint8_t kPayload[kPayloadSizeBytes] = {0};
ASSERT_EQ(0, acm_receiver_->InsertPacket(rtp_header_, ASSERT_EQ(0, acm_receiver_->InsertPacket(
rtc::ArrayView<const uint8_t>( rtp_header_,
kPayload, kPayloadSizeBytes))); rtc::ArrayView<const uint8_t>(kPayload, kPayloadSizeBytes),
/*receive_time=*/Timestamp::MinusInfinity()));
rtp_utility_->Forward(&rtp_header_); rtp_utility_->Forward(&rtp_header_);
} }

View File

@ -193,11 +193,12 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config,
NetEqImpl::~NetEqImpl() = default; NetEqImpl::~NetEqImpl() = default;
int NetEqImpl::InsertPacket(const RTPHeader& rtp_header, int NetEqImpl::InsertPacket(const RTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> payload) { rtc::ArrayView<const uint8_t> payload,
Timestamp receive_time) {
rtc::MsanCheckInitialized(payload); rtc::MsanCheckInitialized(payload);
TRACE_EVENT0("webrtc", "NetEqImpl::InsertPacket"); TRACE_EVENT0("webrtc", "NetEqImpl::InsertPacket");
MutexLock lock(&mutex_); MutexLock lock(&mutex_);
if (InsertPacketInternal(rtp_header, payload) != 0) { if (InsertPacketInternal(rtp_header, payload, receive_time) != 0) {
return kFail; return kFail;
} }
return kOK; return kOK;
@ -464,13 +465,12 @@ NetEq::Operation NetEqImpl::last_operation_for_test() const {
// Methods below this line are private. // Methods below this line are private.
int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> payload) { rtc::ArrayView<const uint8_t> payload,
Timestamp receive_time) {
if (payload.empty()) { if (payload.empty()) {
RTC_LOG_F(LS_ERROR) << "payload is empty"; RTC_LOG_F(LS_ERROR) << "payload is empty";
return kInvalidPointer; return kInvalidPointer;
} }
Timestamp receive_time = clock_->CurrentTime();
stats_->ReceivedPacket(); stats_->ReceivedPacket();
PacketList packet_list; PacketList packet_list;

View File

@ -13,6 +13,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -24,6 +25,7 @@
#include "api/neteq/neteq_controller_factory.h" #include "api/neteq/neteq_controller_factory.h"
#include "api/neteq/tick_timer.h" #include "api/neteq/tick_timer.h"
#include "api/rtp_packet_info.h" #include "api/rtp_packet_info.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/neteq/audio_multi_vector.h" #include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "modules/audio_coding/neteq/expand_uma_logger.h" #include "modules/audio_coding/neteq/expand_uma_logger.h"
#include "modules/audio_coding/neteq/packet.h" #include "modules/audio_coding/neteq/packet.h"
@ -127,7 +129,8 @@ class NetEqImpl : public webrtc::NetEq {
// Inserts a new packet into NetEq. Returns 0 on success, -1 on failure. // Inserts a new packet into NetEq. Returns 0 on success, -1 on failure.
int InsertPacket(const RTPHeader& rtp_header, int InsertPacket(const RTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> payload) override; rtc::ArrayView<const uint8_t> payload,
Timestamp receive_time) override;
void InsertEmptyPacket(const RTPHeader& rtp_header) override; void InsertEmptyPacket(const RTPHeader& rtp_header) override;
@ -204,7 +207,8 @@ class NetEqImpl : public webrtc::NetEq {
// above. Returns 0 on success, otherwise an error code. // above. Returns 0 on success, otherwise an error code.
// TODO(hlundin): Merge this with InsertPacket above? // TODO(hlundin): Merge this with InsertPacket above?
int InsertPacketInternal(const RTPHeader& rtp_header, int InsertPacketInternal(const RTPHeader& rtp_header,
rtc::ArrayView<const uint8_t> payload) rtc::ArrayView<const uint8_t> payload,
Timestamp receive_time)
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns true if the payload type changed (this should be followed by // Returns true if the payload type changed (this should be followed by

View File

@ -194,7 +194,9 @@ class NetEqImplTest : public ::testing::Test {
kPayloadType, SdpAudioFormat("telephone-event", sample_rate_hz, 1))); kPayloadType, SdpAudioFormat("telephone-event", sample_rate_hz, 1)));
// Insert first packet. // Insert first packet.
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
// Pull audio once. // Pull audio once.
const size_t kMaxOutputSize = const size_t kMaxOutputSize =
@ -373,12 +375,14 @@ TEST_F(NetEqImplTest, InsertPacket) {
} }
// Insert first packet. // Insert first packet.
neteq_->InsertPacket(rtp_header, payload); neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime());
// Insert second packet. // Insert second packet.
rtp_header.timestamp += 160; rtp_header.timestamp += 160;
rtp_header.sequenceNumber += 1; rtp_header.sequenceNumber += 1;
neteq_->InsertPacket(rtp_header, payload); neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime());
} }
TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) { TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
@ -400,7 +404,9 @@ TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
// Insert packets. The buffer should not flush. // Insert packets. The buffer should not flush.
for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) { for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) {
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
rtp_header.timestamp += kPayloadLengthSamples; rtp_header.timestamp += kPayloadLengthSamples;
rtp_header.sequenceNumber += 1; rtp_header.sequenceNumber += 1;
EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer()); EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
@ -408,7 +414,9 @@ TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) {
// Insert one more packet and make sure the buffer got flushed. That is, it // Insert one more packet and make sure the buffer got flushed. That is, it
// should only hold one single packet. // should only hold one single packet.
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer()); EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer());
const Packet* test_packet = packet_buffer_->PeekNextPacket(); const Packet* test_packet = packet_buffer_->PeekNextPacket();
EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp); EXPECT_EQ(rtp_header.timestamp, test_packet->timestamp);
@ -494,7 +502,8 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
// Insert one packet. // Insert one packet.
clock_.AdvanceTimeMilliseconds(123456); clock_.AdvanceTimeMilliseconds(123456);
Timestamp expected_receive_time = clock_.CurrentTime(); Timestamp expected_receive_time = clock_.CurrentTime();
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload, expected_receive_time));
// Pull audio once. // Pull audio once.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
@ -588,7 +597,9 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
// Insert one packet. // Insert one packet.
clock_.AdvanceTimeMilliseconds(123456); clock_.AdvanceTimeMilliseconds(123456);
Timestamp expected_receive_time = clock_.CurrentTime(); Timestamp expected_receive_time = clock_.CurrentTime();
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
// Pull audio once. // Pull audio once.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
@ -618,14 +629,18 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
rtp_header.extension.set_audio_level(AudioLevel(/*voice_activity=*/false, 1)); rtp_header.extension.set_audio_level(AudioLevel(/*voice_activity=*/false, 1));
payload[0] = 1; payload[0] = 1;
clock_.AdvanceTimeMilliseconds(1000); clock_.AdvanceTimeMilliseconds(1000);
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
rtp_header.sequenceNumber += 2; rtp_header.sequenceNumber += 2;
rtp_header.timestamp += 2 * kPayloadLengthSamples; rtp_header.timestamp += 2 * kPayloadLengthSamples;
rtp_header.extension.set_audio_level(AudioLevel(/*voice_activity=*/false, 2)); rtp_header.extension.set_audio_level(AudioLevel(/*voice_activity=*/false, 2));
payload[0] = 2; payload[0] = 2;
clock_.AdvanceTimeMilliseconds(2000); clock_.AdvanceTimeMilliseconds(2000);
expected_receive_time = clock_.CurrentTime(); expected_receive_time = clock_.CurrentTime();
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
// Expect only the second packet to be decoded (the one with "2" as the first // Expect only the second packet to be decoded (the one with "2" as the first
// payload byte). // payload byte).
@ -684,7 +699,9 @@ TEST_F(NetEqImplTest, FirstPacketUnknown) {
// Insert one packet. Note that we have not registered any payload type, so // Insert one packet. Note that we have not registered any payload type, so
// this packet will be rejected. // this packet will be rejected.
EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kFail,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
// Pull audio once. // Pull audio once.
const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000);
@ -705,7 +722,9 @@ TEST_F(NetEqImplTest, FirstPacketUnknown) {
for (size_t i = 0; i < 10; ++i) { for (size_t i = 0; i < 10; ++i) {
rtp_header.sequenceNumber++; rtp_header.sequenceNumber++;
rtp_header.timestamp += kPayloadLengthSamples; rtp_header.timestamp += kPayloadLengthSamples;
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer()); EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer());
} }
@ -777,7 +796,8 @@ TEST_F(NetEqImplTest, InsertRedPayload) {
header.extension.set_audio_level(AudioLevel(/*voice_activity=*/false, 12)); header.extension.set_audio_level(AudioLevel(/*voice_activity=*/false, 12));
header.numCSRCs = 1; header.numCSRCs = 1;
header.arrOfCSRCs[0] = 123; header.arrOfCSRCs[0] = 123;
neteq_->InsertPacket(header, payload); neteq_->InsertPacket(header, payload,
/*receive_time=*/clock_.CurrentTime());
AudioFrame frame; AudioFrame frame;
bool muted; bool muted;
neteq_->GetAudio(&frame, &muted); neteq_->GetAudio(&frame, &muted);
@ -875,7 +895,9 @@ TEST_P(NetEqImplTestSampleRateParameter,
auto insert_packet = [&]() { auto insert_packet = [&]() {
rtp_header.sequenceNumber++; rtp_header.sequenceNumber++;
rtp_header.timestamp += kPayloadLengthSamples; rtp_header.timestamp += kPayloadLengthSamples;
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
}; };
// Insert 10 packets. // Insert 10 packets.
for (size_t i = 0; i < 10; ++i) { for (size_t i = 0; i < 10; ++i) {
@ -959,7 +981,9 @@ TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) {
auto insert_packet = [&]() { auto insert_packet = [&]() {
rtp_header.sequenceNumber++; rtp_header.sequenceNumber++;
rtp_header.timestamp += kPayloadLengthSamples; rtp_header.timestamp += kPayloadLengthSamples;
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
}; };
// Insert 10 packets. // Insert 10 packets.
for (size_t i = 0; i < 10; ++i) { for (size_t i = 0; i < 10; ++i) {
@ -1033,7 +1057,9 @@ TEST_P(NetEqImplTestSdpFormatParameter, GetNackListScaledTimestamp) {
rtp_header.sequenceNumber++; rtp_header.sequenceNumber++;
rtp_header.timestamp += kPayloadLengthSamples; rtp_header.timestamp += kPayloadLengthSamples;
if (!lost) if (!lost)
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
}; };
// Insert and decode 10 packets. // Insert and decode 10 packets.
@ -1122,7 +1148,9 @@ TEST_F(NetEqImplTest, CodecInternalCng) {
rtp_header.sequenceNumber += packets[i].sequence_number_delta; rtp_header.sequenceNumber += packets[i].sequence_number_delta;
rtp_header.timestamp += packets[i].timestamp_delta; rtp_header.timestamp += packets[i].timestamp_delta;
payload[0] = i; payload[0] = i;
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
// Pointee(x) verifies that first byte of the payload equals x, this makes // Pointee(x) verifies that first byte of the payload equals x, this makes
// it possible to verify that the correct payload is fed to Decode(). // it possible to verify that the correct payload is fed to Decode().
@ -1220,7 +1248,9 @@ TEST_F(NetEqImplTest, UnsupportedDecoder) {
// Insert one packet. // Insert one packet.
payload[0] = kFirstPayloadValue; // This will make Decode() fail. payload[0] = kFirstPayloadValue; // This will make Decode() fail.
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
// Insert another packet. // Insert another packet.
payload[0] = kSecondPayloadValue; // This will make Decode() successful. payload[0] = kSecondPayloadValue; // This will make Decode() successful.
@ -1228,7 +1258,9 @@ TEST_F(NetEqImplTest, UnsupportedDecoder) {
// The second timestamp needs to be at least 30 ms after the first to make // The second timestamp needs to be at least 30 ms after the first to make
// the second packet get decoded. // the second packet get decoded.
rtp_header.timestamp += 3 * kPayloadLengthSamples; rtp_header.timestamp += 3 * kPayloadLengthSamples;
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
AudioFrame output; AudioFrame output;
bool muted; bool muted;
@ -1281,7 +1313,9 @@ TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) {
// Insert packets until the buffer flushes. // Insert packets until the buffer flushes.
for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) { for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) {
EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer()); EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer());
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples); rtp_header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples);
++rtp_header.sequenceNumber; ++rtp_header.sequenceNumber;
} }
@ -1333,7 +1367,9 @@ TEST_F(NetEqImplTest, DecodedPayloadTooShort) {
SdpAudioFormat("L16", 8000, 1))); SdpAudioFormat("L16", 8000, 1)));
// Insert one packet. // Insert one packet.
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength()); EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength());
@ -1425,7 +1461,9 @@ TEST_F(NetEqImplTest, DecodingError) {
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
rtp_header.sequenceNumber += 1; rtp_header.sequenceNumber += 1;
rtp_header.timestamp += kFrameLengthSamples; rtp_header.timestamp += kFrameLengthSamples;
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
} }
// Pull audio. // Pull audio.
@ -1550,7 +1588,9 @@ TEST_F(NetEqImplTest, NotifyControllerOfReorderedPacket) {
EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType, EXPECT_TRUE(neteq_->RegisterPayloadType(kPayloadType,
SdpAudioFormat("l16", 8000, 1))); SdpAudioFormat("l16", 8000, 1)));
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
AudioFrame output; AudioFrame output;
bool muted; bool muted;
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted)); EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
@ -1572,7 +1612,9 @@ TEST_F(NetEqImplTest, NotifyControllerOfReorderedPacket) {
Field(&NetEqController::PacketArrivedInfo::main_timestamp, Field(&NetEqController::PacketArrivedInfo::main_timestamp,
rtp_header.timestamp)))); rtp_header.timestamp))));
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
} }
// When using a codec with 1000 channels, there should be no crashes. // When using a codec with 1000 channels, there should be no crashes.
@ -1626,7 +1668,8 @@ TEST_F(NetEqImplTest, NoCrashWith1000Channels) {
})); }));
// Insert first packet. // Insert first packet.
neteq_->InsertPacket(rtp_header, payload); neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime());
AudioFrame audio_frame; AudioFrame audio_frame;
bool muted; bool muted;
@ -1655,12 +1698,16 @@ TEST_F(NetEqImplTest, CngFirstThenSpeechWithNewSampleRate) {
header.payloadType = kCnPayloadType; header.payloadType = kCnPayloadType;
uint8_t payload[320] = {0}; uint8_t payload[320] = {0};
EXPECT_EQ(neteq_->InsertPacket(header, payload), NetEq::kOK); EXPECT_EQ(neteq_->InsertPacket(header, payload,
/*receive_time=*/clock_.CurrentTime()),
NetEq::kOK);
EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 0u); EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 0u);
header.payloadType = kSpeechPayloadType; header.payloadType = kSpeechPayloadType;
header.timestamp += 160; header.timestamp += 160;
EXPECT_EQ(neteq_->InsertPacket(header, payload), NetEq::kOK); EXPECT_EQ(neteq_->InsertPacket(header, payload,
/*receive_time=*/clock_.CurrentTime()),
NetEq::kOK);
// CN packet should be discarded, since it does not match the // CN packet should be discarded, since it does not match the
// new speech sample rate. // new speech sample rate.
EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 1u); EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 1u);
@ -1688,12 +1735,16 @@ TEST_F(NetEqImplTest, InsertPacketChangePayloadType) {
header.timestamp = 1234; header.timestamp = 1234;
uint8_t payload[160] = {0}; uint8_t payload[160] = {0};
EXPECT_EQ(neteq_->InsertPacket(header, payload), NetEq::kOK); EXPECT_EQ(neteq_->InsertPacket(header, payload,
/*receive_time=*/clock_.CurrentTime()),
NetEq::kOK);
EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 0u); EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 0u);
header.payloadType = kPcmaPayloadType; header.payloadType = kPcmaPayloadType;
header.timestamp += 80; header.timestamp += 80;
EXPECT_EQ(neteq_->InsertPacket(header, payload), NetEq::kOK); EXPECT_EQ(neteq_->InsertPacket(header, payload,
/*receive_time=*/clock_.CurrentTime()),
NetEq::kOK);
// The previous packet should be discarded since the codec changed. // The previous packet should be discarded since the codec changed.
EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 1u); EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 1u);
@ -1780,7 +1831,9 @@ class NetEqImplTest120ms : public NetEqImplTest {
rtp_header.ssrc = 15; rtp_header.ssrc = 15;
const size_t kPayloadLengthBytes = 1; // This can be arbitrary. const size_t kPayloadLengthBytes = 1; // This can be arbitrary.
uint8_t payload[kPayloadLengthBytes] = {0}; uint8_t payload[kPayloadLengthBytes] = {0};
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload)); EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header, payload,
/*receive_time=*/clock_.CurrentTime()));
sequence_number_++; sequence_number_++;
} }

View File

@ -238,7 +238,9 @@ class NetEqNetworkStatsTest {
kPayloadType, frame_size_samples_, &rtp_header_); kPayloadType, frame_size_samples_, &rtp_header_);
if (!Lost(next_send_time)) { if (!Lost(next_send_time)) {
static const uint8_t payload[kPayloadSizeByte] = {0}; static const uint8_t payload[kPayloadSizeByte] = {0};
ASSERT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header_, payload)); ASSERT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_header_, payload,
Timestamp::Millis(next_send_time)));
} }
} }
bool muted = true; bool muted = true;

View File

@ -18,6 +18,7 @@
#include "api/audio/audio_frame.h" #include "api/audio/audio_frame.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/neteq/neteq.h" #include "api/neteq/neteq.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
#include "modules/audio_coding/neteq/default_neteq_factory.h" #include "modules/audio_coding/neteq/default_neteq_factory.h"
#include "modules/audio_coding/neteq/tools/input_audio_file.h" #include "modules/audio_coding/neteq/tools/input_audio_file.h"
@ -109,7 +110,7 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> {
if (frame_size_samples_ * 2 != payload_size_bytes_) { if (frame_size_samples_ * 2 != payload_size_bytes_) {
return -1; return -1;
} }
int next_send_time = rtp_generator_mono_.GetRtpHeader( int next_send_time_ms = rtp_generator_mono_.GetRtpHeader(
kPayloadTypeMono, frame_size_samples_, &rtp_header_mono_); kPayloadTypeMono, frame_size_samples_, &rtp_header_mono_);
MakeMultiChannelInput(); MakeMultiChannelInput();
multi_payload_size_bytes_ = WebRtcPcm16b_Encode( multi_payload_size_bytes_ = WebRtcPcm16b_Encode(
@ -120,7 +121,7 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> {
} }
rtp_generator_.GetRtpHeader(kPayloadTypeMulti, frame_size_samples_, rtp_generator_.GetRtpHeader(kPayloadTypeMulti, frame_size_samples_,
&rtp_header_); &rtp_header_);
return next_send_time; return next_send_time_ms;
} }
virtual void MakeMultiChannelInput() { virtual void MakeMultiChannelInput() {
@ -151,32 +152,35 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> {
void RunTest(int num_loops) { void RunTest(int num_loops) {
// Get next input packets (mono and multi-channel). // Get next input packets (mono and multi-channel).
int next_send_time; int next_send_time_ms;
int next_arrival_time; int next_arrival_time_ms;
do { do {
next_send_time = GetNewPackets(); next_send_time_ms = GetNewPackets();
ASSERT_NE(-1, next_send_time); ASSERT_NE(-1, next_send_time_ms);
next_arrival_time = GetArrivalTime(next_send_time); next_arrival_time_ms = GetArrivalTime(next_send_time_ms);
} while (Lost()); // If lost, immediately read the next packet. } while (Lost()); // If lost, immediately read the next packet.
int time_now = 0; int time_now_ms = 0;
for (int k = 0; k < num_loops; ++k) { for (int k = 0; k < num_loops; ++k) {
while (time_now >= next_arrival_time) { while (time_now_ms >= next_arrival_time_ms) {
// Insert packet in mono instance. // Insert packet in mono instance.
ASSERT_EQ(NetEq::kOK, ASSERT_EQ(NetEq::kOK,
neteq_mono_->InsertPacket( neteq_mono_->InsertPacket(rtp_header_mono_,
rtp_header_mono_, rtc::ArrayView<const uint8_t>( rtc::ArrayView<const uint8_t>(
encoded_, payload_size_bytes_))); encoded_, payload_size_bytes_),
Timestamp::Millis(time_now_ms)));
// Insert packet in multi-channel instance. // Insert packet in multi-channel instance.
ASSERT_EQ(NetEq::kOK, neteq_->InsertPacket( ASSERT_EQ(NetEq::kOK,
rtp_header_, rtc::ArrayView<const uint8_t>( neteq_->InsertPacket(
encoded_multi_channel_, rtp_header_,
multi_payload_size_bytes_))); rtc::ArrayView<const uint8_t>(encoded_multi_channel_,
multi_payload_size_bytes_),
Timestamp::Millis(time_now_ms)));
// Get next input packets (mono and multi-channel). // Get next input packets (mono and multi-channel).
do { do {
next_send_time = GetNewPackets(); next_send_time_ms = GetNewPackets();
ASSERT_NE(-1, next_send_time); ASSERT_NE(-1, next_send_time_ms);
next_arrival_time = GetArrivalTime(next_send_time); next_arrival_time_ms = GetArrivalTime(next_send_time_ms);
} while (Lost()); // If lost, immediately read the next packet. } while (Lost()); // If lost, immediately read the next packet.
} }
// Get audio from mono instance. // Get audio from mono instance.
@ -197,7 +201,7 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> {
// Compare mono and multi-channel. // Compare mono and multi-channel.
ASSERT_NO_FATAL_FAILURE(VerifyOutput(output_size_samples_)); ASSERT_NO_FATAL_FAILURE(VerifyOutput(output_size_samples_));
time_now += kTimeStepMs; time_now_ms += kTimeStepMs;
clock_.AdvanceTimeMilliseconds(kTimeStepMs); clock_.AdvanceTimeMilliseconds(kTimeStepMs);
} }
} }

View File

@ -132,7 +132,7 @@ TEST_F(NetEqDecodingTestFaxMode, TestFrameWaitingTimeStatistics) {
rtp_info.ssrc = 0x1234; // Just an arbitrary SSRC. rtp_info.ssrc = 0x1234; // Just an arbitrary SSRC.
rtp_info.payloadType = 94; // PCM16b WB codec. rtp_info.payloadType = 94; // PCM16b WB codec.
rtp_info.markerBit = 0; rtp_info.markerBit = 0;
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
} }
// Pull out all data. // Pull out all data.
for (size_t i = 0; i < num_frames; ++i) { for (size_t i = 0; i < num_frames; ++i) {
@ -237,7 +237,8 @@ TEST_F(NetEqDecodingTest, UnknownPayloadType) {
RTPHeader rtp_info; RTPHeader rtp_info;
PopulateRtpInfo(0, 0, &rtp_info); PopulateRtpInfo(0, 0, &rtp_info);
rtp_info.payloadType = 1; // Not registered as a decoder. rtp_info.payloadType = 1; // Not registered as a decoder.
EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_info, payload)); EXPECT_EQ(NetEq::kFail,
neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
} }
#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
@ -252,7 +253,7 @@ TEST_F(NetEqDecodingTest, MAYBE_DecoderError) {
RTPHeader rtp_info; RTPHeader rtp_info;
PopulateRtpInfo(0, 0, &rtp_info); PopulateRtpInfo(0, 0, &rtp_info);
rtp_info.payloadType = 103; // iSAC, but the payload is invalid. rtp_info.payloadType = 103; // iSAC, but the payload is invalid.
EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
// Set all of `out_data_` to 1, and verify that it was set to 0 by the call // Set all of `out_data_` to 1, and verify that it was set to 0 by the call
// to GetAudio. // to GetAudio.
int16_t* out_frame_data = out_frame_.mutable_data(); int16_t* out_frame_data = out_frame_.mutable_data();
@ -340,8 +341,10 @@ class NetEqBgnTest : public NetEqDecodingTest {
WebRtcPcm16b_Encode(block.data(), block.size(), payload); WebRtcPcm16b_Encode(block.data(), block.size(), payload);
ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2); ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2);
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( ASSERT_EQ(0, neteq_->InsertPacket(
payload, enc_len_bytes))); rtp_info,
rtc::ArrayView<const uint8_t>(payload, enc_len_bytes),
clock_.CurrentTime()));
output.Reset(); output.Reset();
ASSERT_EQ(0, neteq_->GetAudio(&output, &muted)); ASSERT_EQ(0, neteq_->GetAudio(&output, &muted));
ASSERT_EQ(1u, output.num_channels_); ASSERT_EQ(1u, output.num_channels_);
@ -445,7 +448,7 @@ TEST_F(NetEqDecodingTest, DiscardDuplicateCng) {
bool muted; bool muted;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
PopulateRtpInfo(seq_no, timestamp, &rtp_info); PopulateRtpInfo(seq_no, timestamp, &rtp_info);
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
++seq_no; ++seq_no;
timestamp += kSamples; timestamp += kSamples;
@ -462,8 +465,10 @@ TEST_F(NetEqDecodingTest, DiscardDuplicateCng) {
size_t payload_len; size_t payload_len;
PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len);
// This is the first time this CNG packet is inserted. // This is the first time this CNG packet is inserted.
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( ASSERT_EQ(0,
payload, payload_len))); neteq_->InsertPacket(
rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len),
clock_.CurrentTime()));
// Pull audio once and make sure CNG is played. // Pull audio once and make sure CNG is played.
ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted)); ASSERT_EQ(0, neteq_->GetAudio(&out_frame_, &muted));
@ -476,8 +481,10 @@ TEST_F(NetEqDecodingTest, DiscardDuplicateCng) {
// Insert the same CNG packet again. Note that at this point it is old, since // Insert the same CNG packet again. Note that at this point it is old, since
// we have already decoded the first copy of it. // we have already decoded the first copy of it.
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( ASSERT_EQ(0,
payload, payload_len))); neteq_->InsertPacket(
rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len),
clock_.CurrentTime()));
// Pull audio until we have played `kCngPeriodMs` of CNG. Start at 10 ms since // Pull audio until we have played `kCngPeriodMs` of CNG. Start at 10 ms since
// we have already pulled out CNG once. // we have already pulled out CNG once.
@ -497,7 +504,7 @@ TEST_F(NetEqDecodingTest, DiscardDuplicateCng) {
// Insert speech again. // Insert speech again.
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
PopulateRtpInfo(seq_no, timestamp, &rtp_info); PopulateRtpInfo(seq_no, timestamp, &rtp_info);
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
++seq_no; ++seq_no;
timestamp += kSamples; timestamp += kSamples;
} }
@ -529,7 +536,8 @@ TEST_F(NetEqDecodingTest, CngFirst) {
PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len);
ASSERT_EQ(NetEq::kOK, ASSERT_EQ(NetEq::kOK,
neteq_->InsertPacket( neteq_->InsertPacket(
rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len))); rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len),
clock_.CurrentTime()));
++seq_no; ++seq_no;
timestamp += kCngPeriodSamples; timestamp += kCngPeriodSamples;
@ -545,7 +553,7 @@ TEST_F(NetEqDecodingTest, CngFirst) {
do { do {
ASSERT_LT(timeout_counter++, 20) << "Test timed out"; ASSERT_LT(timeout_counter++, 20) << "Test timed out";
PopulateRtpInfo(seq_no, timestamp, &rtp_info); PopulateRtpInfo(seq_no, timestamp, &rtp_info);
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
++seq_no; ++seq_no;
timestamp += kSamples; timestamp += kSamples;
@ -571,7 +579,7 @@ class NetEqDecodingTestWithMutedState : public NetEqDecodingTest {
uint8_t payload[kPayloadBytes] = {0}; uint8_t payload[kPayloadBytes] = {0};
RTPHeader rtp_info; RTPHeader rtp_info;
PopulateRtpInfo(0, rtp_timestamp, &rtp_info); PopulateRtpInfo(0, rtp_timestamp, &rtp_info);
EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
} }
void InsertCngPacket(uint32_t rtp_timestamp) { void InsertCngPacket(uint32_t rtp_timestamp) {
@ -580,8 +588,9 @@ class NetEqDecodingTestWithMutedState : public NetEqDecodingTest {
size_t payload_len; size_t payload_len;
PopulateCng(0, rtp_timestamp, &rtp_info, payload, &payload_len); PopulateCng(0, rtp_timestamp, &rtp_info, payload, &payload_len);
EXPECT_EQ(NetEq::kOK, EXPECT_EQ(NetEq::kOK,
neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( neteq_->InsertPacket(
payload, payload_len))); rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len),
clock_.CurrentTime()));
} }
bool GetAudioReturnMuted() { bool GetAudioReturnMuted() {
@ -791,8 +800,8 @@ TEST_F(NetEqDecodingTestTwoInstances, CompareMutedStateOnOff) {
uint8_t payload[kPayloadBytes] = {0}; uint8_t payload[kPayloadBytes] = {0};
RTPHeader rtp_info; RTPHeader rtp_info;
PopulateRtpInfo(0, 0, &rtp_info); PopulateRtpInfo(0, 0, &rtp_info);
EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
EXPECT_EQ(0, neteq2_->InsertPacket(rtp_info, payload)); EXPECT_EQ(0, neteq2_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
AudioFrame out_frame1, out_frame2; AudioFrame out_frame1, out_frame2;
bool muted; bool muted;
@ -815,8 +824,9 @@ TEST_F(NetEqDecodingTestTwoInstances, CompareMutedStateOnOff) {
// packet. // packet.
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
PopulateRtpInfo(0, kSamples * 1000 + kSamples * i, &rtp_info); PopulateRtpInfo(0, kSamples * 1000 + kSamples * i, &rtp_info);
EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
EXPECT_EQ(0, neteq2_->InsertPacket(rtp_info, payload)); EXPECT_EQ(0,
neteq2_->InsertPacket(rtp_info, payload, clock_.CurrentTime()));
} }
int counter = 0; int counter = 0;
@ -854,7 +864,7 @@ TEST_F(NetEqDecodingTest, TestConcealmentEvents) {
for (int j = 0; j < 10; j++) { for (int j = 0; j < 10; j++) {
rtp_info.sequenceNumber = seq_no++; rtp_info.sequenceNumber = seq_no++;
rtp_info.timestamp = rtp_info.sequenceNumber * kSamples; rtp_info.timestamp = rtp_info.sequenceNumber * kSamples;
neteq_->InsertPacket(rtp_info, payload); neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime());
neteq_->GetAudio(&out_frame_, &muted); neteq_->GetAudio(&out_frame_, &muted);
} }
@ -894,7 +904,7 @@ void NetEqDecodingTestFaxMode::TestJitterBufferDelay(bool apply_packet_loss) {
if (packets_sent < kNumPackets) { if (packets_sent < kNumPackets) {
rtp_info.sequenceNumber = packets_sent++; rtp_info.sequenceNumber = packets_sent++;
rtp_info.timestamp = rtp_info.sequenceNumber * kSamples; rtp_info.timestamp = rtp_info.sequenceNumber * kSamples;
neteq_->InsertPacket(rtp_info, payload); neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime());
} }
// Get packet. // Get packet.
@ -950,17 +960,17 @@ TEST_F(NetEqDecodingTestFaxMode, TestJitterBufferDelayWithAcceleration) {
const uint8_t payload[kPayloadBytes] = {0}; const uint8_t payload[kPayloadBytes] = {0};
int expected_target_delay = neteq_->TargetDelayMs() * kSamples; int expected_target_delay = neteq_->TargetDelayMs() * kSamples;
neteq_->InsertPacket(rtp_info, payload); neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime());
bool muted; bool muted;
neteq_->GetAudio(&out_frame_, &muted); neteq_->GetAudio(&out_frame_, &muted);
rtp_info.sequenceNumber += 1; rtp_info.sequenceNumber += 1;
rtp_info.timestamp += kSamples; rtp_info.timestamp += kSamples;
neteq_->InsertPacket(rtp_info, payload); neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime());
rtp_info.sequenceNumber += 1; rtp_info.sequenceNumber += 1;
rtp_info.timestamp += kSamples; rtp_info.timestamp += kSamples;
neteq_->InsertPacket(rtp_info, payload); neteq_->InsertPacket(rtp_info, payload, clock_.CurrentTime());
expected_target_delay += neteq_->TargetDelayMs() * 2 * kSamples; expected_target_delay += neteq_->TargetDelayMs() * 2 * kSamples;
// We have two packets in the buffer and kAccelerate operation will // We have two packets in the buffer and kAccelerate operation will

View File

@ -13,6 +13,7 @@
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/rtp_headers.h" #include "api/rtp_headers.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/neteq/default_neteq_factory.h" #include "modules/audio_coding/neteq/default_neteq_factory.h"
#include "modules/audio_coding/neteq/test/result_sink.h" #include "modules/audio_coding/neteq/test/result_sink.h"
#include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_builder.h"
@ -106,11 +107,11 @@ void NetEqDecodingTest::Process() {
// Ignore payload type 104 (iSAC-swb) if ISAC is not supported. // Ignore payload type 104 (iSAC-swb) if ISAC is not supported.
if (packet_->header().payloadType != 104) if (packet_->header().payloadType != 104)
#endif #endif
ASSERT_EQ( ASSERT_EQ(0, neteq_->InsertPacket(packet_->header(),
0, neteq_->InsertPacket( rtc::ArrayView<const uint8_t>(
packet_->header(), packet_->payload(),
rtc::ArrayView<const uint8_t>( packet_->payload_length_bytes()),
packet_->payload(), packet_->payload_length_bytes()))); clock_.CurrentTime()));
} }
// Get next packet. // Get next packet.
packet_ = rtp_source_->NextPacket(); packet_ = rtp_source_->NextPacket();
@ -239,7 +240,8 @@ void NetEqDecodingTest::WrapTest(uint16_t start_seq_no,
PopulateRtpInfo(seq_no, timestamp, &rtp_info); PopulateRtpInfo(seq_no, timestamp, &rtp_info);
if (drop_seq_numbers.find(seq_no) == drop_seq_numbers.end()) { if (drop_seq_numbers.find(seq_no) == drop_seq_numbers.end()) {
// This sequence number was not in the set to drop. Insert it. // This sequence number was not in the set to drop. Insert it.
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload,
Timestamp::Millis(t_ms)));
} }
NetEqNetworkStatistics network_stats; NetEqNetworkStatistics network_stats;
ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats));
@ -298,7 +300,8 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor,
uint8_t payload[kPayloadBytes] = {0}; uint8_t payload[kPayloadBytes] = {0};
RTPHeader rtp_info; RTPHeader rtp_info;
PopulateRtpInfo(seq_no, timestamp, &rtp_info); PopulateRtpInfo(seq_no, timestamp, &rtp_info);
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); ASSERT_EQ(
0, neteq_->InsertPacket(rtp_info, payload, Timestamp::Millis(t_ms)));
++seq_no; ++seq_no;
timestamp += kSamples; timestamp += kSamples;
next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor; next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor;
@ -325,8 +328,10 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor,
size_t payload_len; size_t payload_len;
RTPHeader rtp_info; RTPHeader rtp_info;
PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len);
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( ASSERT_EQ(
payload, payload_len))); 0, neteq_->InsertPacket(
rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len),
Timestamp::Millis(t_ms)));
++seq_no; ++seq_no;
timestamp += kCngPeriodSamples; timestamp += kCngPeriodSamples;
next_input_time_ms += static_cast<double>(kCngPeriodMs) * drift_factor; next_input_time_ms += static_cast<double>(kCngPeriodMs) * drift_factor;
@ -367,8 +372,10 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor,
size_t payload_len; size_t payload_len;
RTPHeader rtp_info; RTPHeader rtp_info;
PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len);
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( ASSERT_EQ(
payload, payload_len))); 0, neteq_->InsertPacket(
rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len),
Timestamp::Millis(t_ms)));
++seq_no; ++seq_no;
timestamp += kCngPeriodSamples; timestamp += kCngPeriodSamples;
next_input_time_ms += kCngPeriodMs * drift_factor; next_input_time_ms += kCngPeriodMs * drift_factor;
@ -384,7 +391,8 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor,
uint8_t payload[kPayloadBytes] = {0}; uint8_t payload[kPayloadBytes] = {0};
RTPHeader rtp_info; RTPHeader rtp_info;
PopulateRtpInfo(seq_no, timestamp, &rtp_info); PopulateRtpInfo(seq_no, timestamp, &rtp_info);
ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload)); ASSERT_EQ(
0, neteq_->InsertPacket(rtp_info, payload, Timestamp::Millis(t_ms)));
++seq_no; ++seq_no;
timestamp += kSamples; timestamp += kSamples;
next_input_time_ms += kFrameSizeMs * drift_factor; next_input_time_ms += kFrameSizeMs * drift_factor;

View File

@ -87,7 +87,8 @@ int64_t NetEqPerformanceTest::Run(int runtime_ms,
} }
if (!lost) { if (!lost) {
// Insert packet. // Insert packet.
int error = neteq->InsertPacket(rtp_header, input_payload); int error = neteq->InsertPacket(rtp_header, input_payload,
Timestamp::Millis(time_now_ms));
if (error != NetEq::kOK) if (error != NetEq::kOK)
return -1; return -1;
} }

View File

@ -16,6 +16,7 @@
#include "absl/flags/flag.h" #include "absl/flags/flag.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/neteq/default_neteq_factory.h" #include "modules/audio_coding/neteq/default_neteq_factory.h"
#include "modules/audio_coding/neteq/tools/neteq_quality_test.h" #include "modules/audio_coding/neteq/tools/neteq_quality_test.h"
#include "modules/audio_coding/neteq/tools/output_audio_file.h" #include "modules/audio_coding/neteq/tools/output_audio_file.h"
@ -415,7 +416,8 @@ int NetEqQualityTest::Transmit() {
if (!PacketLost()) { if (!PacketLost()) {
int ret = neteq_->InsertPacket( int ret = neteq_->InsertPacket(
rtp_header_, rtp_header_,
rtc::ArrayView<const uint8_t>(payload_.data(), payload_size_bytes_)); rtc::ArrayView<const uint8_t>(payload_.data(), payload_size_bytes_),
Timestamp::Millis(packet_input_time_ms));
if (ret != NetEq::kOK) if (ret != NetEq::kOK)
return -1; return -1;
Log() << "was sent."; Log() << "was sent.";

View File

@ -13,6 +13,7 @@
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include "api/units/timestamp.h"
#include "modules/audio_coding/neteq/default_neteq_factory.h" #include "modules/audio_coding/neteq/default_neteq_factory.h"
#include "modules/rtp_rtcp/source/byte_io.h" #include "modules/rtp_rtcp/source/byte_io.h"
#include "system_wrappers/include/clock.h" #include "system_wrappers/include/clock.h"
@ -114,7 +115,8 @@ NetEqTest::SimulationStepResult NetEqTest::RunToNextGetAudio() {
if (payload_data_length != 0) { if (payload_data_length != 0) {
int error = neteq_->InsertPacket( int error = neteq_->InsertPacket(
packet_data->header, packet_data->header,
rtc::ArrayView<const uint8_t>(packet_data->payload)); rtc::ArrayView<const uint8_t>(packet_data->payload),
Timestamp::Millis(time_now_ms));
if (error != NetEq::kOK && callbacks_.error_callback) { if (error != NetEq::kOK && callbacks_.error_callback) {
callbacks_.error_callback->OnInsertPacketError(*packet_data); callbacks_.error_callback->OnInsertPacketError(*packet_data);
} }

View File

@ -83,7 +83,8 @@ int32_t Channel::SendData(AudioFrameType frameType,
} }
status = _receiverACM->InsertPacket( status = _receiverACM->InsertPacket(
rtp_header, rtc::ArrayView<const uint8_t>(_payloadData, payloadDataSize)); rtp_header, rtc::ArrayView<const uint8_t>(_payloadData, payloadDataSize),
/*receive_time=*/Timestamp::MinusInfinity());
return status; return status;
} }

View File

@ -170,8 +170,10 @@ bool Receiver::IncomingPacket() {
} }
EXPECT_EQ(0, _acm_receiver->InsertPacket( EXPECT_EQ(0, _acm_receiver->InsertPacket(
_rtpHeader, rtc::ArrayView<const uint8_t>( _rtpHeader,
_incomingPayload, _realPayloadSizeBytes))); rtc::ArrayView<const uint8_t>(_incomingPayload,
_realPayloadSizeBytes),
/*receive_time=*/Timestamp::Millis(_nextTime)));
_realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload, _realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,
_payloadSizeBytes, &_nextTime); _payloadSizeBytes, &_nextTime);
if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) { if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) {

View File

@ -14,6 +14,7 @@
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/units/timestamp.h"
#include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_builder.h"
#include "test/gtest.h" #include "test/gtest.h"
#include "test/testsupport/file_utils.h" #include "test/testsupport/file_utils.h"
@ -58,9 +59,10 @@ bool ReceiverWithPacketLoss::IncomingPacket() {
} }
if (!PacketLost()) { if (!PacketLost()) {
_acm_receiver->InsertPacket( _acm_receiver->InsertPacket(_rtpHeader,
_rtpHeader, rtc::ArrayView<const uint8_t>(_incomingPayload, rtc::ArrayView<const uint8_t>(
_realPayloadSizeBytes)); _incomingPayload, _realPayloadSizeBytes),
Timestamp::Millis(_nextTime));
} }
packet_counter_++; packet_counter_++;
_realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload, _realPayloadSizeBytes = _rtpStream->Read(&_rtpHeader, _incomingPayload,

View File

@ -84,7 +84,8 @@ int32_t TestPack::SendData(AudioFrameType frame_type,
memcpy(payload_data_, payload_data, payload_size); memcpy(payload_data_, payload_data, payload_size);
status = receiver_acm_->InsertPacket( status = receiver_acm_->InsertPacket(
rtp_header, rtc::ArrayView<const uint8_t>(payload_data_, payload_size)); rtp_header, rtc::ArrayView<const uint8_t>(payload_data_, payload_size),
/*receive_time=*/Timestamp::MinusInfinity());
payload_size_ = payload_size; payload_size_ = payload_size;
timestamp_diff_ = timestamp - last_in_timestamp_; timestamp_diff_ = timestamp - last_in_timestamp_;

View File

@ -61,7 +61,8 @@ int32_t TestPackStereo::SendData(const AudioFrameType frame_type,
if (lost_packet_ == false) { if (lost_packet_ == false) {
status = receiver_acm_->InsertPacket( status = receiver_acm_->InsertPacket(
rtp_header, rtc::ArrayView<const uint8_t>(payload_data, payload_size)); rtp_header, rtc::ArrayView<const uint8_t>(payload_data, payload_size),
/*receive_time=*/Timestamp::MinusInfinity());
if (frame_type != AudioFrameType::kAudioFrameCN) { if (frame_type != AudioFrameType::kAudioFrameCN) {
payload_size_ = static_cast<int>(payload_size); payload_size_ = static_cast<int>(payload_size);

View File

@ -13,6 +13,7 @@
#include "api/audio/audio_frame.h" #include "api/audio/audio_frame.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/rtp_headers.h" #include "api/rtp_headers.h"
#include "api/units/timestamp.h"
#include "modules/audio_coding/acm2/acm_receiver.h" #include "modules/audio_coding/acm2/acm_receiver.h"
#include "modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
#include "modules/audio_coding/include/audio_coding_module.h" #include "modules/audio_coding/include/audio_coding_module.h"
@ -85,7 +86,8 @@ class TargetDelayTest : public ::testing::Test {
rtp_header_.sequenceNumber++; rtp_header_.sequenceNumber++;
ASSERT_EQ(0, receiver_.InsertPacket(rtp_header_, ASSERT_EQ(0, receiver_.InsertPacket(rtp_header_,
rtc::ArrayView<const uint8_t>( rtc::ArrayView<const uint8_t>(
payload_, kFrameSizeSamples * 2))); payload_, kFrameSizeSamples * 2),
Timestamp::MinusInfinity()));
} }
// Pull audio equivalent to the amount of audio in one RTP packet. // Pull audio equivalent to the amount of audio in one RTP packet.