diff --git a/modules/rtp_rtcp/include/rtp_receiver.h b/modules/rtp_rtcp/include/rtp_receiver.h index 8931d78d02..9738116a1a 100644 --- a/modules/rtp_rtcp/include/rtp_receiver.h +++ b/modules/rtp_rtcp/include/rtp_receiver.h @@ -79,8 +79,17 @@ class RtpReceiver { virtual bool IncomingRtpPacket(const RTPHeader& rtp_header, const uint8_t* payload, size_t payload_length, - PayloadUnion payload_specific, - bool in_order) = 0; + PayloadUnion payload_specific) = 0; + // TODO(nisse): Deprecated version, delete as soon as downstream + // applications are updated. + bool IncomingRtpPacket(const RTPHeader& rtp_header, + const uint8_t* payload, + size_t payload_length, + PayloadUnion payload_specific, + bool in_order /* Ignored */) { + return IncomingRtpPacket(rtp_header, payload, payload_length, + payload_specific); + } // Gets the RTP timestamp and the corresponding monotonic system // time for the most recent in-order packet. Returns true on diff --git a/modules/rtp_rtcp/source/rtp_receiver_impl.cc b/modules/rtp_rtcp/source/rtp_receiver_impl.cc index a47aa15ba7..792e08b151 100644 --- a/modules/rtp_rtcp/source/rtp_receiver_impl.cc +++ b/modules/rtp_rtcp/source/rtp_receiver_impl.cc @@ -20,6 +20,7 @@ #include "common_types.h" // NOLINT(build/include) #include "modules/audio_coding/codecs/audio_format_conversion.h" +#include "modules/include/module_common_types.h" #include "modules/rtp_rtcp/include/rtp_payload_registry.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtp_receiver_strategy.h" @@ -27,6 +28,26 @@ namespace webrtc { +namespace { +bool InOrderPacket(rtc::Optional latest_sequence_number, + uint16_t current_sequence_number) { + if (!latest_sequence_number) + return true; + + // We need to distinguish between a late or retransmitted packet, + // and a sequence number discontinuity. + if (IsNewerSequenceNumber(current_sequence_number, *latest_sequence_number)) { + return true; + } else { + // If we have a restart of the remote side this packet is still in order. + return !IsNewerSequenceNumber( + current_sequence_number, + *latest_sequence_number - kDefaultMaxReorderingThreshold); + } +} + +} // namespace + using RtpUtility::Payload; // Only return the sources in the last 10 seconds. @@ -142,12 +163,10 @@ int32_t RtpReceiverImpl::Energy( return rtp_media_receiver_->Energy(array_of_energy); } -bool RtpReceiverImpl::IncomingRtpPacket( - const RTPHeader& rtp_header, - const uint8_t* payload, - size_t payload_length, - PayloadUnion payload_specific, - bool in_order) { +bool RtpReceiverImpl::IncomingRtpPacket(const RTPHeader& rtp_header, + const uint8_t* payload, + size_t payload_length, + PayloadUnion payload_specific) { // Trigger our callbacks. CheckSSRCChanged(rtp_header); @@ -186,13 +205,18 @@ bool RtpReceiverImpl::IncomingRtpPacket( { rtc::CritScope lock(&critical_section_rtp_receiver_); - if (in_order) { - if (last_received_timestamp_ != rtp_header.timestamp) { - last_received_timestamp_ = rtp_header.timestamp; - last_received_frame_time_ms_ = clock_->TimeInMilliseconds(); - } + // TODO(nisse): Do not rely on InOrderPacket for recovered packets, when + // packet is passed as RtpPacketReceived and that information is available. + // We should ideally never record timestamps for retransmitted or recovered + // packets. + if (InOrderPacket(last_received_sequence_number_, + rtp_header.sequenceNumber)) { + last_received_sequence_number_.emplace(rtp_header.sequenceNumber); + last_received_timestamp_ = rtp_header.timestamp; + last_received_frame_time_ms_ = clock_->TimeInMilliseconds(); } } + return true; } @@ -237,7 +261,7 @@ std::vector RtpReceiverImpl::GetSources() const { bool RtpReceiverImpl::GetLatestTimestamps(uint32_t* timestamp, int64_t* receive_time_ms) const { rtc::CritScope lock(&critical_section_rtp_receiver_); - if (last_received_frame_time_ms_ < 0) + if (!last_received_sequence_number_) return false; *timestamp = last_received_timestamp_; diff --git a/modules/rtp_rtcp/source/rtp_receiver_impl.h b/modules/rtp_rtcp/source/rtp_receiver_impl.h index 92570292ad..cd6b619ff0 100644 --- a/modules/rtp_rtcp/source/rtp_receiver_impl.h +++ b/modules/rtp_rtcp/source/rtp_receiver_impl.h @@ -16,6 +16,7 @@ #include #include +#include "api/optional.h" #include "modules/rtp_rtcp/include/rtp_receiver.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtp_receiver_strategy.h" @@ -45,8 +46,7 @@ class RtpReceiverImpl : public RtpReceiver { bool IncomingRtpPacket(const RTPHeader& rtp_header, const uint8_t* payload, size_t payload_length, - PayloadUnion payload_specific, - bool in_order) override; + PayloadUnion payload_specific) override; bool GetLatestTimestamps(uint32_t* timestamp, int64_t* receive_time_ms) const override; @@ -95,6 +95,9 @@ class RtpReceiverImpl : public RtpReceiver { uint32_t current_remote_csrc_[kRtpCsrcSize] RTC_GUARDED_BY( critical_section_rtp_receiver_); + // Sequence number and timestamps for the latest in-order packet. + rtc::Optional last_received_sequence_number_ + RTC_GUARDED_BY(critical_section_rtp_receiver_); uint32_t last_received_timestamp_ RTC_GUARDED_BY(critical_section_rtp_receiver_); int64_t last_received_frame_time_ms_ diff --git a/modules/rtp_rtcp/source/rtp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtp_receiver_unittest.cc index c8c936232d..3d23b50c50 100644 --- a/modules/rtp_rtcp/source/rtp_receiver_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_receiver_unittest.cc @@ -34,7 +34,6 @@ const uint32_t kSsrc1 = 123; const uint32_t kSsrc2 = 124; const uint32_t kCsrc1 = 111; const uint32_t kCsrc2 = 222; -const bool kInOrder = true; static uint32_t rtp_timestamp(int64_t time_ms) { return static_cast(time_ms * kTestRate / 1000); @@ -90,7 +89,7 @@ TEST_F(RtpReceiverTest, GetSources) { AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}}; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); auto sources = rtp_receiver_->GetSources(); // One SSRC source and two CSRC sources. EXPECT_THAT(sources, UnorderedElementsAre( @@ -102,7 +101,7 @@ TEST_F(RtpReceiverTest, GetSources) { // contributing source object with same source id and updated timestamp. fake_clock_.AdvanceTimeMilliseconds(1); EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); sources = rtp_receiver_->GetSources(); now_ms = fake_clock_.TimeInMilliseconds(); EXPECT_THAT(sources, UnorderedElementsAre( @@ -141,7 +140,7 @@ TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) { AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}}; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); auto sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre( RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC))); @@ -153,7 +152,7 @@ TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) { header.ssrc = kSsrc2; header.timestamp = rtp_timestamp(now_ms); EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre( RtpSource(prev_time_ms, kSsrc1, RtpSourceType::SSRC), @@ -167,7 +166,7 @@ TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) { prev_time_ms = now_ms; now_ms = fake_clock_.TimeInMilliseconds(); EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre( RtpSource(prev_time_ms, kSsrc2, RtpSourceType::SSRC), @@ -177,7 +176,7 @@ TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) { fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs); now_ms = fake_clock_.TimeInMilliseconds(); EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre( RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC))); @@ -197,9 +196,8 @@ TEST_F(RtpReceiverTest, GetSourcesRemoveOutdatedSource) { for (size_t i = 0; i < kSourceListSize; ++i) { header.ssrc = i; header.arrOfCSRCs[0] = (i + 1); - EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, - sizeof(kTestPayload), - payload_specific, !kInOrder)); + EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( + header, kTestPayload, sizeof(kTestPayload), payload_specific)); } RtpSource source(0, 0, RtpSourceType::SSRC); @@ -237,7 +235,7 @@ TEST_F(RtpReceiverTest, GetSourcesRemoveOutdatedSource) { header.ssrc = kSsrc1; header.arrOfCSRCs[0] = kCsrc1; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); auto rtp_receiver_impl = static_cast(rtp_receiver_.get()); auto ssrc_sources = rtp_receiver_impl->ssrc_sources_for_testing(); ASSERT_EQ(1u, ssrc_sources.size()); @@ -268,7 +266,7 @@ TEST_F(RtpReceiverTest, GetSourcesContainsAudioLevelExtension) { AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}}; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); auto sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre(RtpSource( time1_ms, kSsrc1, RtpSourceType::SSRC, 10))); @@ -283,7 +281,7 @@ TEST_F(RtpReceiverTest, GetSourcesContainsAudioLevelExtension) { header.extension.audioLevel = 20; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre( @@ -300,7 +298,7 @@ TEST_F(RtpReceiverTest, GetSourcesContainsAudioLevelExtension) { header.extension.audioLevel = 30; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre( @@ -321,7 +319,7 @@ TEST_F(RtpReceiverTest, AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}}; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); auto sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre(RtpSource( time1_ms, kSsrc1, RtpSourceType::SSRC, 10))); @@ -334,10 +332,141 @@ TEST_F(RtpReceiverTest, header.extension.hasAudioLevel = false; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder)); + header, kTestPayload, sizeof(kTestPayload), payload_specific)); sources = rtp_receiver_->GetSources(); EXPECT_THAT(sources, UnorderedElementsAre( RtpSource(time2_ms, kSsrc1, RtpSourceType::SSRC))); } +TEST_F(RtpReceiverTest, UpdatesTimestampsIfAndOnlyIfPacketArrivesInOrder) { + RTPHeader header; + int64_t time1_ms = fake_clock_.TimeInMilliseconds(); + header.payloadType = kPcmuPayloadType; + header.ssrc = kSsrc1; + header.timestamp = rtp_timestamp(time1_ms); + header.extension.hasAudioLevel = true; + header.extension.audioLevel = 10; + header.sequenceNumber = 0xfff0; + + const PayloadUnion payload_specific{ + AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}}; + uint32_t latest_timestamp; + int64_t latest_receive_time_ms; + + // No packet received yet. + EXPECT_FALSE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + // Initial packet + const uint32_t timestamp_1 = header.timestamp; + const int64_t receive_time_1 = fake_clock_.TimeInMilliseconds(); + EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( + header, kTestPayload, sizeof(kTestPayload), payload_specific)); + EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + EXPECT_EQ(latest_timestamp, timestamp_1); + EXPECT_EQ(latest_receive_time_ms, receive_time_1); + + // Late packet, timestamp not recorded. + fake_clock_.AdvanceTimeMilliseconds(10); + header.timestamp -= 900; + header.sequenceNumber -= 2; + + EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( + header, kTestPayload, sizeof(kTestPayload), payload_specific)); + EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + EXPECT_EQ(latest_timestamp, timestamp_1); + EXPECT_EQ(latest_receive_time_ms, receive_time_1); + + // New packet, still late, no wraparound. + fake_clock_.AdvanceTimeMilliseconds(10); + header.timestamp += 1800; + header.sequenceNumber += 1; + + EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( + header, kTestPayload, sizeof(kTestPayload), payload_specific)); + EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + EXPECT_EQ(latest_timestamp, timestamp_1); + EXPECT_EQ(latest_receive_time_ms, receive_time_1); + + // New packet, new timestamp recorded + fake_clock_.AdvanceTimeMilliseconds(10); + header.timestamp += 900; + header.sequenceNumber += 2; + const uint32_t timestamp_2 = header.timestamp; + const int64_t receive_time_2 = fake_clock_.TimeInMilliseconds(); + const uint16_t seqno_2 = header.sequenceNumber; + + EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( + header, kTestPayload, sizeof(kTestPayload), payload_specific)); + EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + EXPECT_EQ(latest_timestamp, timestamp_2); + EXPECT_EQ(latest_receive_time_ms, receive_time_2); + + // New packet, timestamp wraps around + fake_clock_.AdvanceTimeMilliseconds(10); + header.timestamp += 900; + header.sequenceNumber += 20; + const uint32_t timestamp_3 = header.timestamp; + const int64_t receive_time_3 = fake_clock_.TimeInMilliseconds(); + EXPECT_LT(header.sequenceNumber, seqno_2); // Wrap-around + + EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( + header, kTestPayload, sizeof(kTestPayload), payload_specific)); + EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + EXPECT_EQ(latest_timestamp, timestamp_3); + EXPECT_EQ(latest_receive_time_ms, receive_time_3); +} + +TEST_F(RtpReceiverTest, UpdatesTimestampsWhenStreamResets) { + RTPHeader header; + int64_t time1_ms = fake_clock_.TimeInMilliseconds(); + header.payloadType = kPcmuPayloadType; + header.ssrc = kSsrc1; + header.timestamp = rtp_timestamp(time1_ms); + header.extension.hasAudioLevel = true; + header.extension.audioLevel = 10; + header.sequenceNumber = 0xfff0; + + const PayloadUnion payload_specific{ + AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}}; + uint32_t latest_timestamp; + int64_t latest_receive_time_ms; + + // No packet received yet. + EXPECT_FALSE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + // Initial packet + const uint32_t timestamp_1 = header.timestamp; + const int64_t receive_time_1 = fake_clock_.TimeInMilliseconds(); + const uint16_t seqno_1 = header.sequenceNumber; + EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( + header, kTestPayload, sizeof(kTestPayload), payload_specific)); + EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + EXPECT_EQ(latest_timestamp, timestamp_1); + EXPECT_EQ(latest_receive_time_ms, receive_time_1); + + // Packet with far in the past seqno, but unlikely to be a wrap-around. + // Treated as a seqno discontinuity, and timestamp is recorded. + fake_clock_.AdvanceTimeMilliseconds(10); + header.timestamp += 900; + header.sequenceNumber = 0x9000; + + const uint32_t timestamp_2 = header.timestamp; + const int64_t receive_time_2 = fake_clock_.TimeInMilliseconds(); + const uint16_t seqno_2 = header.sequenceNumber; + EXPECT_LT(seqno_1 - seqno_2, 0x8000); // In the past. + + EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( + header, kTestPayload, sizeof(kTestPayload), payload_specific)); + EXPECT_TRUE(rtp_receiver_->GetLatestTimestamps(&latest_timestamp, + &latest_receive_time_ms)); + EXPECT_EQ(latest_timestamp, timestamp_2); + EXPECT_EQ(latest_receive_time_ms, receive_time_2); +} + } // namespace webrtc diff --git a/modules/rtp_rtcp/test/testAPI/test_api.cc b/modules/rtp_rtcp/test/testAPI/test_api.cc index c247fc704a..e2afa42856 100644 --- a/modules/rtp_rtcp/test/testAPI/test_api.cc +++ b/modules/rtp_rtcp/test/testAPI/test_api.cc @@ -58,7 +58,7 @@ bool LoopBackTransport::SendRtp(const uint8_t* data, const size_t payload_length = len - header.headerLength; receive_statistics_->IncomingPacket(header, len, false); return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, - pl->typeSpecific, true); + pl->typeSpecific); } bool LoopBackTransport::SendRtcp(const uint8_t* data, size_t len) { diff --git a/modules/rtp_rtcp/test/testAPI/test_api_video.cc b/modules/rtp_rtcp/test/testAPI/test_api_video.cc index 26964fdba5..63b78514dc 100644 --- a/modules/rtp_rtcp/test/testAPI/test_api_video.cc +++ b/modules/rtp_rtcp/test/testAPI/test_api_video.cc @@ -171,7 +171,7 @@ TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) { const uint8_t* payload = padding_packet + header.headerLength; const size_t payload_length = packet_size - header.headerLength; EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket( - header, payload, payload_length, pl->typeSpecific, true)); + header, payload, payload_length, pl->typeSpecific)); EXPECT_EQ(0u, receiver_->payload_size()); EXPECT_EQ(payload_length, receiver_->rtp_header().header.paddingLength); } diff --git a/video/rtp_video_stream_receiver.cc b/video/rtp_video_stream_receiver.cc index 2b1b05eb2c..aecdfe3386 100644 --- a/video/rtp_video_stream_receiver.cc +++ b/video/rtp_video_stream_receiver.cc @@ -280,8 +280,7 @@ void RtpVideoStreamReceiver::OnRecoveredPacket(const uint8_t* rtp_packet, RTPHeader header; packet.GetHeader(&header); - bool in_order = IsPacketInOrder(header); - ReceivePacket(rtp_packet, rtp_packet_length, header, in_order); + ReceivePacket(rtp_packet, rtp_packet_length, header); } // TODO(pbos): Remove as soon as audio can handle a changing payload type @@ -339,7 +338,7 @@ void RtpVideoStreamReceiver::OnRtpPacket(const RtpPacketReceived& packet) { // TODO(nisse): Why isn't this done for recovered packets? rtp_payload_registry_.SetIncomingPayloadType(header); } - ReceivePacket(packet.data(), packet.size(), header, in_order); + ReceivePacket(packet.data(), packet.size(), header); // Update receive statistics after ReceivePacket. // Receive statistics will be reset if the payload type changes (make sure // that the first packet is included in the stats). @@ -443,8 +442,7 @@ void RtpVideoStreamReceiver::RemoveSecondarySink( void RtpVideoStreamReceiver::ReceivePacket(const uint8_t* packet, size_t packet_length, - const RTPHeader& header, - bool in_order) { + const RTPHeader& header) { if (rtp_payload_registry_.IsRed(header)) { ParseAndHandleEncapsulatingHeader(packet, packet_length, header); return; @@ -456,7 +454,7 @@ void RtpVideoStreamReceiver::ReceivePacket(const uint8_t* packet, rtp_payload_registry_.PayloadTypeToPayload(header.payloadType); if (pl) { rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, - pl->typeSpecific, in_order); + pl->typeSpecific); } } diff --git a/video/rtp_video_stream_receiver.h b/video/rtp_video_stream_receiver.h index 25ea486752..90e8200c53 100644 --- a/video/rtp_video_stream_receiver.h +++ b/video/rtp_video_stream_receiver.h @@ -154,8 +154,7 @@ class RtpVideoStreamReceiver : public RtpData, bool AddReceiveCodec(const VideoCodec& video_codec); void ReceivePacket(const uint8_t* packet, size_t packet_length, - const RTPHeader& header, - bool in_order); + const RTPHeader& header); // Parses and handles for instance RTX and RED headers. // This function assumes that it's being called from only one thread. void ParseAndHandleEncapsulatingHeader(const uint8_t* packet, diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc index c3c06a0b32..19873f1c17 100644 --- a/voice_engine/channel.cc +++ b/voice_engine/channel.cc @@ -595,7 +595,8 @@ bool Channel::OnRecoveredPacket(const uint8_t* rtp_packet, rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType); if (header.payload_type_frequency < 0) return false; - return ReceivePacket(rtp_packet, rtp_packet_length, header, false); + // TODO(nisse): Pass RtpPacketReceived with |recovered()| true. + return ReceivePacket(rtp_packet, rtp_packet_length, header); } AudioMixer::Source::AudioFrameInfo Channel::GetAudioFrameWithInfo( @@ -1148,14 +1149,13 @@ void Channel::OnRtpPacket(const RtpPacketReceived& packet) { header, packet.size(), IsPacketRetransmitted(header, in_order)); rtp_payload_registry_->SetIncomingPayloadType(header); - ReceivePacket(packet.data(), packet.size(), header, in_order); + ReceivePacket(packet.data(), packet.size(), header); } } bool Channel::ReceivePacket(const uint8_t* packet, size_t packet_length, - const RTPHeader& header, - bool in_order) { + const RTPHeader& header) { const uint8_t* payload = packet + header.headerLength; assert(packet_length >= header.headerLength); size_t payload_length = packet_length - header.headerLength; @@ -1165,7 +1165,7 @@ bool Channel::ReceivePacket(const uint8_t* packet, return false; } return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length, - pl->typeSpecific, in_order); + pl->typeSpecific); } bool Channel::IsPacketInOrder(const RTPHeader& header) const { diff --git a/voice_engine/channel.h b/voice_engine/channel.h index 9221115fc1..9a79b2b828 100644 --- a/voice_engine/channel.h +++ b/voice_engine/channel.h @@ -341,8 +341,7 @@ class Channel bool ReceivePacket(const uint8_t* packet, size_t packet_length, - const RTPHeader& header, - bool in_order); + const RTPHeader& header); bool IsPacketInOrder(const RTPHeader& header) const; bool IsPacketRetransmitted(const RTPHeader& header, bool in_order) const; int ResendPackets(const uint16_t* sequence_numbers, int length);