Adds support for combining RTX and FEC/RED.
This is accomplished by breaking out RTX and FEC/RED functionality from the RTP module and keeping track of the base payload type, that is the payload type received when not receiving RTX.
Enables retransmissions over RTX by default in the loopback test.
BUG=1811
TESTS=voe/vie_auto_test --automated and trybots.
R=mflodman@webrtc.org, pbos@webrtc.org, xians@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/2154004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@4692 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/interface/module_common_types.h b/modules/interface/module_common_types.h
index ec9b634..bc32b22 100644
--- a/modules/interface/module_common_types.h
+++ b/modules/interface/module_common_types.h
@@ -98,9 +98,7 @@
{
kRtpVideoNone,
kRtpVideoGeneric,
- kRtpVideoVp8,
- kRtpVideoFec,
- kRtpVideoI420
+ kRtpVideoVp8
};
struct RTPVideoHeader
{
diff --git a/modules/modules.gyp b/modules/modules.gyp
index bee2195..e575fae 100644
--- a/modules/modules.gyp
+++ b/modules/modules.gyp
@@ -166,11 +166,11 @@
'remote_bitrate_estimator/bitrate_estimator_unittest.cc',
'remote_bitrate_estimator/rtp_to_ntp_unittest.cc',
'rtp_rtcp/source/mock/mock_rtp_payload_strategy.h',
+ 'rtp_rtcp/source/fec_receiver_unittest.cc',
'rtp_rtcp/source/fec_test_helper.cc',
'rtp_rtcp/source/fec_test_helper.h',
'rtp_rtcp/source/nack_rtx_unittest.cc',
'rtp_rtcp/source/producer_fec_unittest.cc',
- 'rtp_rtcp/source/receiver_fec_unittest.cc',
'rtp_rtcp/source/receive_statistics_unittest.cc',
'rtp_rtcp/source/rtcp_format_remb_unittest.cc',
'rtp_rtcp/source/rtcp_sender_unittest.cc',
diff --git a/modules/rtp_rtcp/interface/fec_receiver.h b/modules/rtp_rtcp/interface/fec_receiver.h
new file mode 100644
index 0000000..97b200f
--- /dev/null
+++ b/modules/rtp_rtcp/interface/fec_receiver.h
@@ -0,0 +1,33 @@
+/*
+ * 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_RTP_RTCP_INTERFACE_FEC_RECEIVER_H_
+#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_FEC_RECEIVER_H_
+
+#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "webrtc/typedefs.h"
+
+namespace webrtc {
+
+class FecReceiver {
+ public:
+ static FecReceiver* Create(int32_t id, RtpData* callback);
+
+ virtual ~FecReceiver() {}
+
+ virtual int32_t AddReceivedRedPacket(const RTPHeader& rtp_header,
+ const uint8_t* incoming_rtp_packet,
+ int packet_length,
+ uint8_t ulpfec_payload_type) = 0;
+
+ virtual int32_t ProcessReceivedFec() = 0;
+};
+} // namespace webrtc
+#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_FEC_RECEIVER_H_
diff --git a/modules/rtp_rtcp/interface/receive_statistics.h b/modules/rtp_rtcp/interface/receive_statistics.h
index 2ea155f..707adaa 100644
--- a/modules/rtp_rtcp/interface/receive_statistics.h
+++ b/modules/rtp_rtcp/interface/receive_statistics.h
@@ -44,8 +44,17 @@
virtual void GetDataCounters(uint32_t* bytes_received,
uint32_t* packets_received) const = 0;
virtual uint32_t BitrateReceived() const = 0;
+
// Resets all statistics.
virtual void ResetStatistics() = 0;
+
+ // Returns true if the packet with RTP header |header| is likely to be a
+ // retransmitted packet, false otherwise.
+ virtual bool IsRetransmitOfOldPacket(const RTPHeader& header,
+ int min_rtt) const = 0;
+
+ // Returns true if |sequence_number| is received in order, false otherwise.
+ virtual bool IsPacketInOrder(uint16_t sequence_number) const = 0;
};
typedef std::map<uint32_t, StreamStatistician*> StatisticianMap;
@@ -58,7 +67,7 @@
// Updates the receive statistics with this packet.
virtual void IncomingPacket(const RTPHeader& rtp_header, size_t bytes,
- bool retransmitted, bool in_order) = 0;
+ bool retransmitted) = 0;
// Returns a map of all statisticians which have seen an incoming packet
// during the last two seconds.
@@ -66,16 +75,20 @@
// Returns a pointer to the statistician of an ssrc.
virtual StreamStatistician* GetStatistician(uint32_t ssrc) const = 0;
+
+ // Sets the max reordering threshold in number of packets.
+ virtual void SetMaxReorderingThreshold(int max_reordering_threshold) = 0;
};
class NullReceiveStatistics : public ReceiveStatistics {
public:
virtual void IncomingPacket(const RTPHeader& rtp_header, size_t bytes,
- bool retransmitted, bool in_order) OVERRIDE;
+ bool retransmitted) OVERRIDE;
virtual StatisticianMap GetActiveStatisticians() const OVERRIDE;
virtual StreamStatistician* GetStatistician(uint32_t ssrc) const OVERRIDE;
virtual int32_t TimeUntilNextProcess() OVERRIDE;
virtual int32_t Process() OVERRIDE;
+ virtual void SetMaxReorderingThreshold(int max_reordering_threshold) OVERRIDE;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/interface/rtp_payload_registry.h b/modules/rtp_rtcp/interface/rtp_payload_registry.h
index f5aca81..3ea4dcd 100644
--- a/modules/rtp_rtcp/interface/rtp_payload_registry.h
+++ b/modules/rtp_rtcp/interface/rtp_payload_registry.h
@@ -76,6 +76,26 @@
const uint32_t rate,
int8_t* payload_type) const;
+ void SetRtxStatus(bool enable, uint32_t ssrc);
+
+ bool RtxEnabled() const;
+
+ void SetRtxPayloadType(int payload_type);
+
+ bool IsRtx(const RTPHeader& header) const;
+
+ bool RestoreOriginalPacket(uint8_t** restored_packet,
+ const uint8_t* packet,
+ int* packet_length,
+ uint32_t original_ssrc,
+ const RTPHeader& header) const;
+
+ bool IsRed(const RTPHeader& header) const;
+
+ // Returns true if the media of this RTP packet is encapsulated within an
+ // extra header, such as RTX or RED.
+ bool IsEncapsulated(const RTPHeader& header) const;
+
bool GetPayloadSpecifics(uint8_t payload_type, PayloadUnion* payload) const;
int GetPayloadTypeFrequency(uint8_t payload_type) const;
@@ -85,22 +105,38 @@
ModuleRTPUtility::Payload*& payload) const;
void ResetLastReceivedPayloadTypes() {
+ CriticalSectionScoped cs(crit_sect_.get());
last_received_payload_type_ = -1;
last_received_media_payload_type_ = -1;
}
+ // This sets the payload type of the packets being received from the network
+ // on the media SSRC. For instance if packets are encapsulated with RED, this
+ // payload type will be the RED payload type.
+ void SetIncomingPayloadType(const RTPHeader& header);
+
// Returns true if the new media payload type has not changed.
bool ReportMediaPayloadType(uint8_t media_payload_type);
- int8_t red_payload_type() const { return red_payload_type_; }
+ int8_t red_payload_type() const {
+ CriticalSectionScoped cs(crit_sect_.get());
+ return red_payload_type_;
+ }
+ int8_t ulpfec_payload_type() const {
+ CriticalSectionScoped cs(crit_sect_.get());
+ return ulpfec_payload_type_;
+ }
int8_t last_received_payload_type() const {
+ CriticalSectionScoped cs(crit_sect_.get());
return last_received_payload_type_;
}
void set_last_received_payload_type(int8_t last_received_payload_type) {
+ CriticalSectionScoped cs(crit_sect_.get());
last_received_payload_type_ = last_received_payload_type;
}
int8_t last_received_media_payload_type() const {
+ CriticalSectionScoped cs(crit_sect_.get());
return last_received_media_payload_type_;
};
@@ -113,12 +149,20 @@
const uint8_t channels,
const uint32_t rate);
+ bool IsRtxInternal(const RTPHeader& header) const;
+
+ scoped_ptr<CriticalSectionWrapper> crit_sect_;
ModuleRTPUtility::PayloadTypeMap payload_type_map_;
int32_t id_;
scoped_ptr<RTPPayloadStrategy> rtp_payload_strategy_;
int8_t red_payload_type_;
+ int8_t ulpfec_payload_type_;
+ int8_t incoming_payload_type_;
int8_t last_received_payload_type_;
int8_t last_received_media_payload_type_;
+ bool rtx_;
+ int8_t payload_type_rtx_;
+ uint32_t ssrc_rtx_;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/interface/rtp_receiver.h b/modules/rtp_rtcp/interface/rtp_receiver.h
index 40145e4..d1f1a81 100644
--- a/modules/rtp_rtcp/interface/rtp_receiver.h
+++ b/modules/rtp_rtcp/interface/rtp_receiver.h
@@ -70,9 +70,9 @@
// Parses the media specific parts of an RTP packet and updates the receiver
// state. This for instance means that any changes in SSRC and payload type is
// detected and acted upon.
- virtual bool IncomingRtpPacket(RTPHeader* rtp_header,
- const uint8_t* incoming_rtp_packet,
- int incoming_rtp_packet_length,
+ virtual bool IncomingRtpPacket(const RTPHeader& rtp_header,
+ const uint8_t* payload,
+ int payload_length,
PayloadUnion payload_specific,
bool in_order) = 0;
@@ -80,8 +80,7 @@
virtual NACKMethod NACK() const = 0;
// Turn negative acknowledgement (NACK) requests on/off.
- virtual int32_t SetNACKStatus(const NACKMethod method,
- int max_reordering_threshold) = 0;
+ virtual void SetNACKStatus(const NACKMethod method) = 0;
// Returns the last received timestamp.
virtual uint32_t Timestamp() const = 0;
@@ -96,24 +95,6 @@
// Returns the current energy of the RTP stream received.
virtual int32_t Energy(uint8_t array_of_energy[kRtpCsrcSize]) const = 0;
-
- // Enable/disable RTX and set the SSRC to be used.
- virtual void SetRTXStatus(bool enable, uint32_t ssrc) = 0;
-
- // Returns the current RTX status and the SSRC and payload type used.
- virtual void RTXStatus(bool* enable, uint32_t* ssrc,
- int* payload_type) const = 0;
-
- // Sets the RTX payload type.
- virtual void SetRtxPayloadType(int payload_type) = 0;
-
- // Returns true if the packet with RTP header |header| is likely to be a
- // retransmitted packet, false otherwise.
- virtual bool RetransmitOfOldPacket(const RTPHeader& header, int jitter,
- int min_rtt) const = 0;
-
- // Returns true if |sequence_number| is received in order, false otherwise.
- virtual bool InOrderPacket(const uint16_t sequence_number) const = 0;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/interface/rtp_rtcp_defines.h b/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
index c56b71f..8ec9f0c 100644
--- a/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
+++ b/modules/rtp_rtcp/interface/rtp_rtcp_defines.h
@@ -277,17 +277,17 @@
const int frequency,
const uint8_t channels,
const uint32_t rate) OVERRIDE {
- return 0;
- }
+ return 0;
+ }
virtual void OnIncomingSSRCChanged(const int32_t id,
const uint32_t ssrc) OVERRIDE {}
- virtual void OnIncomingCSRCChanged(const int32_t id,
- const uint32_t CSRC,
- const bool added) OVERRIDE {}
+ virtual void OnIncomingCSRCChanged(const int32_t id,
+ const uint32_t CSRC,
+ const bool added) OVERRIDE {}
- virtual void ResetStatistics(uint32_t ssrc) OVERRIDE {}
+ virtual void ResetStatistics(uint32_t ssrc) OVERRIDE {}
};
// Null object version of RtpData.
diff --git a/modules/rtp_rtcp/source/receiver_fec.cc b/modules/rtp_rtcp/source/fec_receiver_impl.cc
similarity index 74%
rename from modules/rtp_rtcp/source/receiver_fec.cc
rename to modules/rtp_rtcp/source/fec_receiver_impl.cc
index e558fe7..0dc142f 100644
--- a/modules/rtp_rtcp/source/receiver_fec.cc
+++ b/modules/rtp_rtcp/source/fec_receiver_impl.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "webrtc/modules/rtp_rtcp/source/receiver_fec.h"
+#include "webrtc/modules/rtp_rtcp/source/fec_receiver_impl.h"
#include <assert.h>
@@ -20,33 +20,28 @@
// RFC 5109
namespace webrtc {
-ReceiverFEC::ReceiverFEC(const int32_t id, RtpData* callback)
+
+FecReceiver* FecReceiver::Create(int32_t id, RtpData* callback) {
+ return new FecReceiverImpl(id, callback);
+}
+
+FecReceiverImpl::FecReceiverImpl(const int32_t id, RtpData* callback)
: id_(id),
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
recovered_packet_callback_(callback),
- fec_(new ForwardErrorCorrection(id)),
- payload_type_fec_(-1) {}
+ fec_(new ForwardErrorCorrection(id)) {}
-ReceiverFEC::~ReceiverFEC() {
- // Clean up DecodeFEC()
+FecReceiverImpl::~FecReceiverImpl() {
while (!received_packet_list_.empty()) {
- ForwardErrorCorrection::ReceivedPacket* received_packet =
- received_packet_list_.front();
- delete received_packet;
+ delete received_packet_list_.front();
received_packet_list_.pop_front();
}
- assert(received_packet_list_.empty());
-
if (fec_ != NULL) {
fec_->ResetState(&recovered_packet_list_);
delete fec_;
}
}
-void ReceiverFEC::SetPayloadTypeFEC(const int8_t payload_type) {
- CriticalSectionScoped cs(crit_sect_.get());
- payload_type_fec_ = payload_type;
-}
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -75,17 +70,12 @@
// block length: 10 bits Length in bytes of the corresponding data
// block excluding header.
-int32_t ReceiverFEC::AddReceivedFECPacket(const WebRtcRTPHeader* rtp_header,
- const uint8_t* incoming_rtp_packet,
- const uint16_t payload_data_length,
- bool& FECpacket) {
+int32_t FecReceiverImpl::AddReceivedRedPacket(
+ const RTPHeader& header, const uint8_t* incoming_rtp_packet,
+ int packet_length, uint8_t ulpfec_payload_type) {
CriticalSectionScoped cs(crit_sect_.get());
-
- if (payload_type_fec_ == -1) {
- return -1;
- }
-
uint8_t REDHeaderLength = 1;
+ uint16_t payload_data_length = packet_length - header.headerLength;
// Add to list without RED header, aka a virtual RTP packet
// we remove the RED header
@@ -96,26 +86,19 @@
// get payload type from RED header
uint8_t payload_type =
- incoming_rtp_packet[rtp_header->header.headerLength] & 0x7f;
+ incoming_rtp_packet[header.headerLength] & 0x7f;
- // use the payload_type to decide if it's FEC or coded data
- if (payload_type_fec_ == payload_type) {
- received_packet->is_fec = true;
- FECpacket = true;
- } else {
- received_packet->is_fec = false;
- FECpacket = false;
- }
- received_packet->seq_num = rtp_header->header.sequenceNumber;
+ received_packet->is_fec = payload_type == ulpfec_payload_type;
+ received_packet->seq_num = header.sequenceNumber;
uint16_t blockLength = 0;
- if (incoming_rtp_packet[rtp_header->header.headerLength] & 0x80) {
+ if (incoming_rtp_packet[header.headerLength] & 0x80) {
// f bit set in RED header
REDHeaderLength = 4;
uint16_t timestamp_offset =
- (incoming_rtp_packet[rtp_header->header.headerLength + 1]) << 8;
+ (incoming_rtp_packet[header.headerLength + 1]) << 8;
timestamp_offset +=
- incoming_rtp_packet[rtp_header->header.headerLength + 2];
+ incoming_rtp_packet[header.headerLength + 2];
timestamp_offset = timestamp_offset >> 2;
if (timestamp_offset != 0) {
// |timestampOffset| should be 0. However, it's possible this is the first
@@ -127,11 +110,11 @@
}
blockLength =
- (0x03 & incoming_rtp_packet[rtp_header->header.headerLength + 2]) << 8;
- blockLength += (incoming_rtp_packet[rtp_header->header.headerLength + 3]);
+ (0x03 & incoming_rtp_packet[header.headerLength + 2]) << 8;
+ blockLength += (incoming_rtp_packet[header.headerLength + 3]);
// check next RED header
- if (incoming_rtp_packet[rtp_header->header.headerLength + 4] & 0x80) {
+ if (incoming_rtp_packet[header.headerLength + 4] & 0x80) {
// more than 2 blocks in packet not supported
delete received_packet;
assert(false);
@@ -152,7 +135,7 @@
// copy the RTP header
memcpy(received_packet->pkt->data, incoming_rtp_packet,
- rtp_header->header.headerLength);
+ header.headerLength);
// replace the RED payload type
received_packet->pkt->data[1] &= 0x80; // reset the payload
@@ -161,8 +144,8 @@
// copy the payload data
memcpy(
- received_packet->pkt->data + rtp_header->header.headerLength,
- incoming_rtp_packet + rtp_header->header.headerLength + REDHeaderLength,
+ received_packet->pkt->data + header.headerLength,
+ incoming_rtp_packet + header.headerLength + REDHeaderLength,
blockLength);
received_packet->pkt->length = blockLength;
@@ -171,11 +154,11 @@
second_received_packet->pkt = new ForwardErrorCorrection::Packet;
second_received_packet->is_fec = true;
- second_received_packet->seq_num = rtp_header->header.sequenceNumber;
+ second_received_packet->seq_num = header.sequenceNumber;
// copy the FEC payload data
memcpy(second_received_packet->pkt->data,
- incoming_rtp_packet + rtp_header->header.headerLength +
+ incoming_rtp_packet + header.headerLength +
REDHeaderLength + blockLength,
payload_data_length - REDHeaderLength - blockLength);
@@ -186,7 +169,7 @@
// everything behind the RED header
memcpy(
received_packet->pkt->data,
- incoming_rtp_packet + rtp_header->header.headerLength + REDHeaderLength,
+ incoming_rtp_packet + header.headerLength + REDHeaderLength,
payload_data_length - REDHeaderLength);
received_packet->pkt->length = payload_data_length - REDHeaderLength;
received_packet->ssrc =
@@ -195,7 +178,7 @@
} else {
// copy the RTP header
memcpy(received_packet->pkt->data, incoming_rtp_packet,
- rtp_header->header.headerLength);
+ header.headerLength);
// replace the RED payload type
received_packet->pkt->data[1] &= 0x80; // reset the payload
@@ -204,12 +187,12 @@
// copy the media payload data
memcpy(
- received_packet->pkt->data + rtp_header->header.headerLength,
- incoming_rtp_packet + rtp_header->header.headerLength + REDHeaderLength,
+ received_packet->pkt->data + header.headerLength,
+ incoming_rtp_packet + header.headerLength + REDHeaderLength,
payload_data_length - REDHeaderLength);
received_packet->pkt->length =
- rtp_header->header.headerLength + payload_data_length - REDHeaderLength;
+ header.headerLength + payload_data_length - REDHeaderLength;
}
if (received_packet->pkt->length == 0) {
@@ -225,7 +208,7 @@
return 0;
}
-int32_t ReceiverFEC::ProcessReceivedFEC() {
+int32_t FecReceiverImpl::ProcessReceivedFec() {
crit_sect_->Enter();
if (!received_packet_list_.empty()) {
// Send received media packet to VCM.
diff --git a/modules/rtp_rtcp/source/receiver_fec.h b/modules/rtp_rtcp/source/fec_receiver_impl.h
similarity index 64%
rename from modules/rtp_rtcp/source/receiver_fec.h
rename to modules/rtp_rtcp/source/fec_receiver_impl.h
index 653a93e..0342123 100644
--- a/modules/rtp_rtcp/source/receiver_fec.h
+++ b/modules/rtp_rtcp/source/fec_receiver_impl.h
@@ -8,11 +8,12 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVER_FEC_H_
-#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVER_FEC_H_
+#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_RECEIVER_IMPL_H_
+#define WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_RECEIVER_IMPL_H_
// This header is included to get the nested declaration of Packet structure.
+#include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
@@ -22,19 +23,17 @@
class CriticalSectionWrapper;
-class ReceiverFEC {
+class FecReceiverImpl : public FecReceiver {
public:
- ReceiverFEC(const int32_t id, RtpData* callback);
- virtual ~ReceiverFEC();
+ FecReceiverImpl(const int32_t id, RtpData* callback);
+ virtual ~FecReceiverImpl();
- int32_t AddReceivedFECPacket(const WebRtcRTPHeader* rtp_header,
- const uint8_t* incoming_rtp_packet,
- const uint16_t payload_data_length,
- bool& FECpacket);
+ virtual int32_t AddReceivedRedPacket(const RTPHeader& rtp_header,
+ const uint8_t* incoming_rtp_packet,
+ int packet_length,
+ uint8_t ulpfec_payload_type) OVERRIDE;
- int32_t ProcessReceivedFEC();
-
- void SetPayloadTypeFEC(const int8_t payload_type);
+ virtual int32_t ProcessReceivedFec() OVERRIDE;
private:
int id_;
@@ -46,8 +45,7 @@
// arrives. We should remove the list.
ForwardErrorCorrection::ReceivedPacketList received_packet_list_;
ForwardErrorCorrection::RecoveredPacketList recovered_packet_list_;
- int8_t payload_type_fec_;
};
} // namespace webrtc
-#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVER_FEC_H_
+#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FEC_RECEIVER_IMPL_H_
diff --git a/modules/rtp_rtcp/source/receiver_fec_unittest.cc b/modules/rtp_rtcp/source/fec_receiver_unittest.cc
similarity index 88%
rename from modules/rtp_rtcp/source/receiver_fec_unittest.cc
rename to modules/rtp_rtcp/source/fec_receiver_unittest.cc
index 981f237..2e8846c 100644
--- a/modules/rtp_rtcp/source/receiver_fec_unittest.cc
+++ b/modules/rtp_rtcp/source/fec_receiver_unittest.cc
@@ -14,9 +14,9 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
-#include "webrtc/modules/rtp_rtcp/source/receiver_fec.h"
using ::testing::_;
using ::testing::Args;
@@ -40,9 +40,8 @@
protected:
virtual void SetUp() {
fec_ = new ForwardErrorCorrection(0);
- receiver_fec_ = new ReceiverFEC(0, &rtp_data_callback_);
+ receiver_fec_ = FecReceiver::Create(0, &rtp_data_callback_);
generator_ = new FrameGenerator();
- receiver_fec_->SetPayloadTypeFEC(kFecPayloadType);
}
virtual void TearDown() {
@@ -83,27 +82,23 @@
void BuildAndAddRedMediaPacket(RtpPacket* packet) {
RtpPacket* red_packet = generator_->BuildMediaRedPacket(packet);
- bool is_fec = false;
- EXPECT_EQ(0, receiver_fec_->AddReceivedFECPacket(
- &red_packet->header, red_packet->data,
- red_packet->length - kRtpHeaderSize, is_fec));
+ EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket(
+ red_packet->header.header, red_packet->data,
+ red_packet->length, kFecPayloadType));
delete red_packet;
- EXPECT_FALSE(is_fec);
}
void BuildAndAddRedFecPacket(Packet* packet) {
RtpPacket* red_packet = generator_->BuildFecRedPacket(packet);
- bool is_fec = false;
- EXPECT_EQ(0, receiver_fec_->AddReceivedFECPacket(
- &red_packet->header, red_packet->data,
- red_packet->length - kRtpHeaderSize, is_fec));
+ EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket(
+ red_packet->header.header, red_packet->data,
+ red_packet->length, kFecPayloadType));
delete red_packet;
- EXPECT_TRUE(is_fec);
}
ForwardErrorCorrection* fec_;
MockRtpData rtp_data_callback_;
- ReceiverFEC* receiver_fec_;
+ FecReceiver* receiver_fec_;
FrameGenerator* generator_;
};
@@ -127,13 +122,13 @@
std::list<RtpPacket*>::iterator media_it = media_rtp_packets.begin();
BuildAndAddRedMediaPacket(*media_it);
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
// Drop one media packet.
std::list<Packet*>::iterator fec_it = fec_packets.begin();
BuildAndAddRedFecPacket(*fec_it);
++it;
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
DeletePackets(&media_packets);
}
@@ -152,12 +147,12 @@
std::list<Packet*>::iterator fec_it = fec_packets.begin();
BuildAndAddRedFecPacket(*fec_it);
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
++fec_it;
BuildAndAddRedFecPacket(*fec_it);
++it;
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
DeletePackets(&media_packets);
}
@@ -175,12 +170,12 @@
std::list<RtpPacket*>::iterator it = media_rtp_packets.begin();
BuildAndAddRedMediaPacket(media_rtp_packets.front());
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
// Drop one media packet.
BuildAndAddRedFecPacket(fec_packets.front());
++it;
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
DeletePackets(&media_packets);
}
@@ -199,11 +194,11 @@
std::list<RtpPacket*>::iterator it = media_rtp_packets.begin();
BuildAndAddRedMediaPacket(*it); // First frame: one packet.
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
++it;
BuildAndAddRedMediaPacket(*it); // First packet of second frame.
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
DeletePackets(&media_packets);
}
@@ -225,12 +220,12 @@
for (; it != media_rtp_packets.end(); ++it) {
BuildAndAddRedMediaPacket(*it);
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
}
BuildAndAddRedFecPacket(fec_packets.front());
it = media_rtp_packets.begin();
VerifyReconstructedMediaPacket(*it, 1);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
DeletePackets(&media_packets);
}
@@ -267,7 +262,7 @@
BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front());
EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
.Times(1).WillRepeatedly(Return(true));
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
delayed_fec = fec_packets.front();
// Fill the FEC decoder. No packets should be dropped.
@@ -282,14 +277,14 @@
BuildAndAddRedMediaPacket(*it);
EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
.Times(1).WillRepeatedly(Return(true));
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
}
// Add the delayed FEC packet. One packet should be reconstructed.
BuildAndAddRedFecPacket(delayed_fec);
EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
.Times(1).WillRepeatedly(Return(true));
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
DeletePackets(&media_packets_batch1);
DeletePackets(&media_packets_batch2);
@@ -311,7 +306,7 @@
BuildAndAddRedMediaPacket(media_rtp_packets_batch1.front());
EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
.Times(1).WillRepeatedly(Return(true));
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
delayed_fec = fec_packets.front();
// Fill the FEC decoder and force the last packet to be dropped.
@@ -326,7 +321,7 @@
BuildAndAddRedMediaPacket(*it);
EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
.Times(1).WillRepeatedly(Return(true));
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
}
// Add the delayed FEC packet. No packet should be reconstructed since the
@@ -334,7 +329,7 @@
BuildAndAddRedFecPacket(delayed_fec);
EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
.Times(0);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
DeletePackets(&media_packets_batch1);
DeletePackets(&media_packets_batch2);
@@ -358,7 +353,7 @@
BuildAndAddRedFecPacket(*it);
EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
.Times(0);
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
}
media_packets.insert(media_packets.end(), frame_media_packets.begin(),
frame_media_packets.end());
@@ -372,7 +367,7 @@
BuildAndAddRedMediaPacket(media_rtp_packets.front());
EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
.Times(1).WillRepeatedly(Return(true));
- EXPECT_EQ(0, receiver_fec_->ProcessReceivedFEC());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
DeletePackets(&media_packets);
}
diff --git a/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/modules/rtp_rtcp/source/nack_rtx_unittest.cc
index 56b49cc..3c87ebf 100644
--- a/modules/rtp_rtcp/source/nack_rtx_unittest.cc
+++ b/modules/rtp_rtcp/source/nack_rtx_unittest.cc
@@ -75,8 +75,7 @@
count_rtx_ssrc_(0),
rtp_payload_registry_(NULL),
rtp_receiver_(NULL),
- module_(NULL) {
- }
+ module_(NULL) {}
void SetSendModule(RtpRtcp* rtpRtcpModule,
RTPPayloadRegistry* rtp_payload_registry,
@@ -112,19 +111,33 @@
count_ < consecutive_drop_end_) {
return len;
}
+ int packet_length = len;
+ uint8_t restored_packet[1500];
+ uint8_t* restored_packet_ptr = restored_packet;
RTPHeader header;
scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
- if (!parser->Parse(static_cast<const uint8_t*>(data), len, &header)) {
+ if (!parser->Parse(ptr, len, &header)) {
return -1;
}
+ if (rtp_payload_registry_->IsRtx(header)) {
+ // Remove the RTX header and parse the original RTP header.
+ EXPECT_TRUE(rtp_payload_registry_->RestoreOriginalPacket(
+ &restored_packet_ptr, ptr, &packet_length, rtp_receiver_->SSRC(),
+ header));
+ if (!parser->Parse(restored_packet_ptr, packet_length, &header)) {
+ return -1;
+ }
+ }
+ restored_packet_ptr += header.headerLength;
+ packet_length -= header.headerLength;
PayloadUnion payload_specific;
if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
- &payload_specific)) {
+ &payload_specific)) {
return -1;
}
- if (!rtp_receiver_->IncomingRtpPacket(&header,
- static_cast<const uint8_t*>(data),
- len, payload_specific, true)) {
+ if (!rtp_receiver_->IncomingRtpPacket(header, restored_packet_ptr,
+ packet_length, payload_specific,
+ true)) {
return -1;
}
return len;
@@ -177,7 +190,7 @@
EXPECT_EQ(0, rtp_rtcp_module_->SetSSRC(kTestSsrc));
EXPECT_EQ(0, rtp_rtcp_module_->SetRTCPStatus(kRtcpCompound));
- EXPECT_EQ(0, rtp_receiver_->SetNACKStatus(kNackRtcp, 450));
+ rtp_receiver_->SetNACKStatus(kNackRtcp);
EXPECT_EQ(0, rtp_rtcp_module_->SetStorePacketsStatus(true, 600));
EXPECT_EQ(0, rtp_rtcp_module_->SetSendingStatus(true));
EXPECT_EQ(0, rtp_rtcp_module_->SetSequenceNumber(kTestSequenceNumber));
@@ -240,7 +253,7 @@
}
void RunRtxTest(RtxMode rtx_method, int loss) {
- rtp_receiver_->SetRTXStatus(true, kTestSsrc + 1);
+ rtp_payload_registry_.SetRtxStatus(true, kTestSsrc + 1);
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXSendStatus(rtx_method, true,
kTestSsrc + 1));
transport_.DropEveryNthPacket(loss);
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc
index c826938..cf18990 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc
@@ -10,6 +10,8 @@
#include "webrtc/modules/rtp_rtcp/source/receive_statistics_impl.h"
+#include <math.h>
+
#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
@@ -27,10 +29,12 @@
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
incoming_bitrate_(clock),
ssrc_(0),
+ max_reordering_threshold_(kDefaultMaxReorderingThreshold),
jitter_q4_(0),
jitter_max_q4_(0),
cumulative_loss_(0),
jitter_q4_transmission_time_offset_(0),
+ last_receive_time_ms_(0),
last_receive_time_secs_(0),
last_receive_time_frac_(0),
last_received_timestamp_(0),
@@ -69,9 +73,9 @@
void StreamStatisticianImpl::IncomingPacket(const RTPHeader& header,
size_t bytes,
- bool retransmitted,
- bool in_order) {
+ bool retransmitted) {
CriticalSectionScoped cs(crit_sect_.get());
+ bool in_order = InOrderPacketInternal(header.sequenceNumber);
ssrc_ = header.ssrc;
incoming_bitrate_.Update(bytes);
received_byte_count_ += bytes;
@@ -83,6 +87,7 @@
received_seq_max_ = header.sequenceNumber;
received_inorder_packet_count_ = 1;
clock_->CurrentNtp(last_receive_time_secs_, last_receive_time_frac_);
+ last_receive_time_ms_ = clock_->TimeInMilliseconds();
return;
}
@@ -96,8 +101,7 @@
received_inorder_packet_count_++;
// Wrong if we use RetransmitOfOldPacket.
- int32_t seq_diff =
- header.sequenceNumber - received_seq_max_;
+ int32_t seq_diff = header.sequenceNumber - received_seq_max_;
if (seq_diff < 0) {
// Wrap around detected.
received_seq_wraps_++;
@@ -147,6 +151,7 @@
last_received_timestamp_ = header.timestamp;
last_receive_time_secs_ = receive_time_secs;
last_receive_time_frac_ = receive_time_frac;
+ last_receive_time_ms_ = clock_->TimeInMilliseconds();
} else {
if (retransmitted) {
received_retransmitted_packets_++;
@@ -162,6 +167,12 @@
received_packet_overhead_ = (15 * received_packet_overhead_ + packet_oh) >> 4;
}
+void StreamStatisticianImpl::SetMaxReorderingThreshold(
+ int max_reordering_threshold) {
+ CriticalSectionScoped cs(crit_sect_.get());
+ max_reordering_threshold_ = max_reordering_threshold;
+}
+
bool StreamStatisticianImpl::GetStatistics(Statistics* statistics, bool reset) {
CriticalSectionScoped cs(crit_sect_.get());
if (received_seq_first_ == 0 && received_byte_count_ == 0) {
@@ -275,6 +286,62 @@
*frac = last_receive_time_frac_;
}
+bool StreamStatisticianImpl::IsRetransmitOfOldPacket(
+ const RTPHeader& header, int min_rtt) const {
+ CriticalSectionScoped cs(crit_sect_.get());
+ if (InOrderPacketInternal(header.sequenceNumber)) {
+ return false;
+ }
+ uint32_t frequency_khz = header.payload_type_frequency / 1000;
+ assert(frequency_khz > 0);
+
+ int64_t time_diff_ms = clock_->TimeInMilliseconds() -
+ last_receive_time_ms_;
+
+ // Diff in time stamp since last received in order.
+ uint32_t timestamp_diff = header.timestamp - last_received_timestamp_;
+ int32_t rtp_time_stamp_diff_ms = static_cast<int32_t>(timestamp_diff) /
+ frequency_khz;
+
+ int32_t max_delay_ms = 0;
+ if (min_rtt == 0) {
+ // Jitter standard deviation in samples.
+ float jitter_std = sqrt(static_cast<float>(jitter_q4_ >> 4));
+
+ // 2 times the standard deviation => 95% confidence.
+ // And transform to milliseconds by dividing by the frequency in kHz.
+ max_delay_ms = static_cast<int32_t>((2 * jitter_std) / frequency_khz);
+
+ // Min max_delay_ms is 1.
+ if (max_delay_ms == 0) {
+ max_delay_ms = 1;
+ }
+ } else {
+ max_delay_ms = (min_rtt / 3) + 1;
+ }
+ return time_diff_ms > rtp_time_stamp_diff_ms + max_delay_ms;
+}
+
+bool StreamStatisticianImpl::IsPacketInOrder(uint16_t sequence_number) const {
+ CriticalSectionScoped cs(crit_sect_.get());
+ return InOrderPacketInternal(sequence_number);
+}
+
+bool StreamStatisticianImpl::InOrderPacketInternal(
+ uint16_t sequence_number) const {
+ // First packet is always in order.
+ if (last_receive_time_ms_ == 0)
+ return true;
+
+ if (IsNewerSequenceNumber(sequence_number, received_seq_max_)) {
+ return true;
+ } else {
+ // If we have a restart of the remote side this packet is still in order.
+ return !IsNewerSequenceNumber(sequence_number, received_seq_max_ -
+ max_reordering_threshold_);
+ }
+}
+
ReceiveStatistics* ReceiveStatistics::Create(Clock* clock) {
return new ReceiveStatisticsImpl(clock);
}
@@ -292,8 +359,7 @@
}
void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
- size_t bytes, bool old_packet,
- bool in_order) {
+ size_t bytes, bool old_packet) {
CriticalSectionScoped cs(crit_sect_.get());
StatisticianImplMap::iterator it = statisticians_.find(header.ssrc);
if (it == statisticians_.end()) {
@@ -302,8 +368,7 @@
header.ssrc, new StreamStatisticianImpl(clock_)));
it = insert_result.first;
}
- statisticians_[header.ssrc]->IncomingPacket(header, bytes, old_packet,
- in_order);
+ statisticians_[header.ssrc]->IncomingPacket(header, bytes, old_packet);
}
void ReceiveStatisticsImpl::ChangeSsrc(uint32_t from_ssrc, uint32_t to_ssrc) {
@@ -342,6 +407,15 @@
return it->second;
}
+void ReceiveStatisticsImpl::SetMaxReorderingThreshold(
+ int max_reordering_threshold) {
+ CriticalSectionScoped cs(crit_sect_.get());
+ for (StatisticianImplMap::iterator it = statisticians_.begin();
+ it != statisticians_.end(); ++it) {
+ it->second->SetMaxReorderingThreshold(max_reordering_threshold);
+ }
+}
+
int32_t ReceiveStatisticsImpl::Process() {
CriticalSectionScoped cs(crit_sect_.get());
for (StatisticianImplMap::iterator it = statisticians_.begin();
@@ -362,8 +436,7 @@
void NullReceiveStatistics::IncomingPacket(const RTPHeader& rtp_header,
size_t bytes,
- bool retransmitted,
- bool in_order) {}
+ bool retransmitted) {}
StatisticianMap NullReceiveStatistics::GetActiveStatisticians() const {
return StatisticianMap();
@@ -374,6 +447,9 @@
return NULL;
}
+void NullReceiveStatistics::SetMaxReorderingThreshold(
+ int max_reordering_threshold) {}
+
int32_t NullReceiveStatistics::TimeUntilNextProcess() { return 0; }
int32_t NullReceiveStatistics::Process() { return 0; }
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.h b/modules/rtp_rtcp/source/receive_statistics_impl.h
index f963123..0af074c 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.h
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.h
@@ -34,17 +34,24 @@
uint32_t* packets_received) const OVERRIDE;
virtual uint32_t BitrateReceived() const OVERRIDE;
virtual void ResetStatistics() OVERRIDE;
+ virtual bool IsRetransmitOfOldPacket(const RTPHeader& header,
+ int min_rtt) const OVERRIDE;
+ virtual bool IsPacketInOrder(uint16_t sequence_number) const OVERRIDE;
void IncomingPacket(const RTPHeader& rtp_header, size_t bytes,
- bool retransmitted, bool in_order);
+ bool retransmitted);
+ void SetMaxReorderingThreshold(int max_reordering_threshold);
void ProcessBitrate();
virtual void LastReceiveTimeNtp(uint32_t* secs, uint32_t* frac) const;
private:
+ bool InOrderPacketInternal(uint16_t sequence_number) const;
+
Clock* clock_;
scoped_ptr<CriticalSectionWrapper> crit_sect_;
Bitrate incoming_bitrate_;
uint32_t ssrc_;
+ int max_reordering_threshold_; // In number of packets or sequence numbers.
// Stats on received RTP packets.
uint32_t jitter_q4_;
@@ -52,6 +59,7 @@
uint32_t cumulative_loss_;
uint32_t jitter_q4_transmission_time_offset_;
+ int64_t last_receive_time_ms_;
uint32_t last_receive_time_secs_;
uint32_t last_receive_time_frac_;
uint32_t last_received_timestamp_;
@@ -82,9 +90,10 @@
// Implement ReceiveStatistics.
virtual void IncomingPacket(const RTPHeader& header, size_t bytes,
- bool old_packet, bool in_order) OVERRIDE;
+ bool old_packet) OVERRIDE;
virtual StatisticianMap GetActiveStatisticians() const OVERRIDE;
virtual StreamStatistician* GetStatistician(uint32_t ssrc) const OVERRIDE;
+ virtual void SetMaxReorderingThreshold(int max_reordering_threshold) OVERRIDE;
// Implement Module.
virtual int32_t Process() OVERRIDE;
diff --git a/modules/rtp_rtcp/source/receive_statistics_unittest.cc b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
index a69e408..39c5c6d 100644
--- a/modules/rtp_rtcp/source/receive_statistics_unittest.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
@@ -43,14 +43,14 @@
};
TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
- receive_statistics_->IncomingPacket(header2_, kPacketSize2, false, true);
+ receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
++header2_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(100);
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
- receive_statistics_->IncomingPacket(header2_, kPacketSize2, false, true);
+ receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
++header2_.sequenceNumber;
StreamStatistician* statistician =
@@ -75,9 +75,9 @@
EXPECT_EQ(2u, statisticians.size());
// Add more incoming packets and verify that they are registered in both
// access methods.
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
- receive_statistics_->IncomingPacket(header2_, kPacketSize2, false, true);
+ receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
++header2_.sequenceNumber;
statisticians[kSsrc1]->GetDataCounters(&bytes_received, &packets_received);
@@ -98,10 +98,10 @@
}
TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(1000);
- receive_statistics_->IncomingPacket(header2_, kPacketSize2, false, true);
+ receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
++header2_.sequenceNumber;
StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians();
// Nothing should time out since only 1000 ms has passed since the first
@@ -118,7 +118,7 @@
statisticians = receive_statistics_->GetActiveStatisticians();
EXPECT_EQ(0u, statisticians.size());
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
++header1_.sequenceNumber;
// kSsrc1 should be active again and the data counters should have survived.
statisticians = receive_statistics_->GetActiveStatisticians();
diff --git a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index 6e05fd1..2f0dc7a 100644
--- a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -375,8 +375,8 @@
PayloadUnion payload_specific;
EXPECT_TRUE(rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
&payload_specific));
- receive_statistics_->IncomingPacket(header, packet_length, false, true);
- EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(&header, packet_, packet_length,
+ receive_statistics_->IncomingPacket(header, packet_length, false);
+ EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, packet_, packet_length,
payload_specific, true));
EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
diff --git a/modules/rtp_rtcp/source/rtp_payload_registry.cc b/modules/rtp_rtcp/source/rtp_payload_registry.cc
index b597b31..1c3b990 100644
--- a/modules/rtp_rtcp/source/rtp_payload_registry.cc
+++ b/modules/rtp_rtcp/source/rtp_payload_registry.cc
@@ -17,11 +17,17 @@
RTPPayloadRegistry::RTPPayloadRegistry(
const int32_t id,
RTPPayloadStrategy* rtp_payload_strategy)
- : id_(id),
+ : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
+ id_(id),
rtp_payload_strategy_(rtp_payload_strategy),
red_payload_type_(-1),
+ ulpfec_payload_type_(-1),
+ incoming_payload_type_(-1),
last_received_payload_type_(-1),
- last_received_media_payload_type_(-1) {}
+ last_received_media_payload_type_(-1),
+ rtx_(false),
+ payload_type_rtx_(-1),
+ ssrc_rtx_(0) {}
RTPPayloadRegistry::~RTPPayloadRegistry() {
while (!payload_type_map_.empty()) {
@@ -64,6 +70,8 @@
size_t payload_name_length = strlen(payload_name);
+ CriticalSectionScoped cs(crit_sect_.get());
+
ModuleRTPUtility::PayloadTypeMap::iterator it =
payload_type_map_.find(payload_type);
@@ -105,7 +113,12 @@
payload = new ModuleRTPUtility::Payload;
memset(payload, 0, sizeof(*payload));
payload->audio = false;
- payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
+ strncpy(payload->name, payload_name, RTP_PAYLOAD_NAME_SIZE - 1);
+ } else if (ModuleRTPUtility::StringCompare(payload_name, "ulpfec", 3)) {
+ ulpfec_payload_type_ = payload_type;
+ payload = new ModuleRTPUtility::Payload;
+ memset(payload, 0, sizeof(*payload));
+ payload->audio = false;
strncpy(payload->name, payload_name, RTP_PAYLOAD_NAME_SIZE - 1);
} else {
*created_new_payload = true;
@@ -123,6 +136,7 @@
int32_t RTPPayloadRegistry::DeRegisterReceivePayload(
const int8_t payload_type) {
+ CriticalSectionScoped cs(crit_sect_.get());
ModuleRTPUtility::PayloadTypeMap::iterator it =
payload_type_map_.find(payload_type);
@@ -139,6 +153,7 @@
// There can't be several codecs with the same rate, frequency and channels
// for audio codecs, but there can for video.
+// Always called from within a critical section.
void RTPPayloadRegistry::DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
const size_t payload_name_length,
@@ -186,6 +201,8 @@
}
size_t payload_name_length = strlen(payload_name);
+ CriticalSectionScoped cs(crit_sect_.get());
+
ModuleRTPUtility::PayloadTypeMap::const_iterator it =
payload_type_map_.begin();
@@ -226,8 +243,84 @@
return -1;
}
+void RTPPayloadRegistry::SetRtxStatus(bool enable, uint32_t ssrc) {
+ CriticalSectionScoped cs(crit_sect_.get());
+ rtx_ = enable;
+ ssrc_rtx_ = ssrc;
+}
+
+bool RTPPayloadRegistry::RtxEnabled() const {
+ CriticalSectionScoped cs(crit_sect_.get());
+ return rtx_;
+}
+
+bool RTPPayloadRegistry::IsRtx(const RTPHeader& header) const {
+ CriticalSectionScoped cs(crit_sect_.get());
+ return IsRtxInternal(header);
+}
+
+bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const {
+ return rtx_ && ssrc_rtx_ == header.ssrc;
+}
+
+bool RTPPayloadRegistry::RestoreOriginalPacket(uint8_t** restored_packet,
+ const uint8_t* packet,
+ int* packet_length,
+ uint32_t original_ssrc,
+ const RTPHeader& header) const {
+ if (kRtxHeaderSize + header.headerLength > *packet_length) {
+ return false;
+ }
+ const uint8_t* rtx_header = packet + header.headerLength;
+ uint16_t original_sequence_number = (rtx_header[0] << 8) + rtx_header[1];
+
+ // Copy the packet into the restored packet, except for the RTX header.
+ memcpy(*restored_packet, packet, header.headerLength);
+ memcpy(*restored_packet + header.headerLength,
+ packet + header.headerLength + kRtxHeaderSize,
+ *packet_length - header.headerLength - kRtxHeaderSize);
+ *packet_length -= kRtxHeaderSize;
+
+ // Replace the SSRC and the sequence number with the originals.
+ ModuleRTPUtility::AssignUWord16ToBuffer(*restored_packet + 2,
+ original_sequence_number);
+ ModuleRTPUtility::AssignUWord32ToBuffer(*restored_packet + 8, original_ssrc);
+
+ CriticalSectionScoped cs(crit_sect_.get());
+
+ if (payload_type_rtx_ != -1) {
+ if (header.payloadType == payload_type_rtx_ &&
+ incoming_payload_type_ != -1) {
+ (*restored_packet)[1] = static_cast<uint8_t>(incoming_payload_type_);
+ if (header.markerBit) {
+ (*restored_packet)[1] |= kRtpMarkerBitMask; // Marker bit is set.
+ }
+ } else {
+ WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
+ "Incorrect RTX configuration, dropping packet.");
+ return false;
+ }
+ }
+ return true;
+}
+
+void RTPPayloadRegistry::SetRtxPayloadType(int payload_type) {
+ CriticalSectionScoped cs(crit_sect_.get());
+ payload_type_rtx_ = payload_type;
+}
+
+bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const {
+ CriticalSectionScoped cs(crit_sect_.get());
+ return red_payload_type_ == header.payloadType;
+}
+
+bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const {
+ return IsRed(header) || IsRtx(header);
+}
+
bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type,
PayloadUnion* payload) const {
+ CriticalSectionScoped cs(crit_sect_.get());
ModuleRTPUtility::PayloadTypeMap::const_iterator it =
payload_type_map_.find(payload_type);
@@ -245,12 +338,14 @@
if (!PayloadTypeToPayload(payload_type, payload)) {
return -1;
}
+ CriticalSectionScoped cs(crit_sect_.get());
return rtp_payload_strategy_->GetPayloadTypeFrequency(*payload);
}
bool RTPPayloadRegistry::PayloadTypeToPayload(
const uint8_t payload_type,
ModuleRTPUtility::Payload*& payload) const {
+ CriticalSectionScoped cs(crit_sect_.get());
ModuleRTPUtility::PayloadTypeMap::const_iterator it =
payload_type_map_.find(payload_type);
@@ -264,8 +359,14 @@
return true;
}
-bool RTPPayloadRegistry::ReportMediaPayloadType(
- uint8_t media_payload_type) {
+void RTPPayloadRegistry::SetIncomingPayloadType(const RTPHeader& header) {
+ CriticalSectionScoped cs(crit_sect_.get());
+ if (!IsRtxInternal(header))
+ incoming_payload_type_ = header.payloadType;
+}
+
+bool RTPPayloadRegistry::ReportMediaPayloadType(uint8_t media_payload_type) {
+ CriticalSectionScoped cs(crit_sect_.get());
if (last_received_media_payload_type_ == media_payload_type) {
// Media type unchanged.
return true;
@@ -350,7 +451,7 @@
} else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
videoType = kRtpVideoGeneric;
} else if (ModuleRTPUtility::StringCompare(payloadName, "ULPFEC", 6)) {
- videoType = kRtpVideoFec;
+ videoType = kRtpVideoNone;
} else {
videoType = kRtpVideoGeneric;
}
diff --git a/modules/rtp_rtcp/source/rtp_receiver_audio.cc b/modules/rtp_rtcp/source/rtp_receiver_audio.cc
index 1596137..04cfe14 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_audio.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_audio.cc
@@ -183,8 +183,8 @@
int32_t RTPReceiverAudio::ParseRtpPacket(WebRtcRTPHeader* rtp_header,
const PayloadUnion& specific_payload,
bool is_red,
- const uint8_t* packet,
- uint16_t packet_length,
+ const uint8_t* payload,
+ uint16_t payload_length,
int64_t timestamp_ms,
bool is_first_packet) {
TRACE_EVENT2("webrtc_rtp", "Audio::ParseRtp",
@@ -198,13 +198,11 @@
rtp_header->type.Audio.arrOfEnergy,
rtp_header->type.Audio.numEnergy);
}
- const uint8_t* payload_data =
- ModuleRTPUtility::GetPayloadData(rtp_header->header, packet);
- const uint16_t payload_data_length =
- ModuleRTPUtility::GetPayloadDataLength(rtp_header->header, packet_length);
+ const uint16_t payload_data_length = payload_length -
+ rtp_header->header.paddingLength;
return ParseAudioCodecSpecific(rtp_header,
- payload_data,
+ payload,
payload_data_length,
specific_payload.Audio,
is_red);
@@ -384,6 +382,7 @@
}
}
}
+ // TODO(holmer): Break this out to have RED parsing handled generically.
if (is_red && !(payload_data[0] & 0x80)) {
// we recive only one frame packed in a RED packet remove the RED wrapper
rtp_header->header.payloadType = payload_data[0];
diff --git a/modules/rtp_rtcp/source/rtp_receiver_impl.cc b/modules/rtp_rtcp/source/rtp_receiver_impl.cc
index c3d1039..00fa2a4 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_impl.cc
@@ -82,11 +82,7 @@
last_received_timestamp_(0),
last_received_frame_time_ms_(0),
last_received_sequence_number_(0),
- nack_method_(kNackOff),
- max_reordering_threshold_(kDefaultMaxReorderingThreshold),
- rtx_(false),
- ssrc_rtx_(0),
- payload_type_rtx_(-1) {
+ nack_method_(kNackOff) {
assert(incoming_audio_messages_callback);
assert(incoming_messages_callback);
@@ -152,37 +148,9 @@
}
// Turn negative acknowledgment requests on/off.
-int32_t RtpReceiverImpl::SetNACKStatus(const NACKMethod method,
- int max_reordering_threshold) {
+void RtpReceiverImpl::SetNACKStatus(const NACKMethod method) {
CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
- if (max_reordering_threshold < 0) {
- return -1;
- } else if (method == kNackRtcp) {
- max_reordering_threshold_ = max_reordering_threshold;
- } else {
- max_reordering_threshold_ = kDefaultMaxReorderingThreshold;
- }
nack_method_ = method;
- return 0;
-}
-
-void RtpReceiverImpl::SetRTXStatus(bool enable, uint32_t ssrc) {
- CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
- rtx_ = enable;
- ssrc_rtx_ = ssrc;
-}
-
-void RtpReceiverImpl::RTXStatus(bool* enable, uint32_t* ssrc,
- int* payload_type) const {
- CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
- *enable = rtx_;
- *ssrc = ssrc_rtx_;
- *payload_type = payload_type_rtx_;
-}
-
-void RtpReceiverImpl::SetRtxPayloadType(int payload_type) {
- CriticalSectionScoped cs(critical_section_rtp_receiver_.get());
- payload_type_rtx_ = payload_type;
}
uint32_t RtpReceiverImpl::SSRC() const {
@@ -208,55 +176,21 @@
}
bool RtpReceiverImpl::IncomingRtpPacket(
- RTPHeader* rtp_header,
- const uint8_t* packet,
- int packet_length,
- PayloadUnion payload_specific,
- bool in_order) {
- // The rtp_header argument contains the parsed RTP header.
- int length = packet_length - rtp_header->paddingLength;
-
+ const RTPHeader& rtp_header,
+ const uint8_t* payload,
+ int payload_length,
+ PayloadUnion payload_specific,
+ bool in_order) {
// Sanity check.
- if ((length - rtp_header->headerLength) < 0) {
+ if (payload_length < 0) {
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
"%s invalid argument",
__FUNCTION__);
return false;
}
- {
- CriticalSectionScoped cs(critical_section_rtp_receiver_.get());
- // TODO(holmer): Make rtp_header const after RTX has been broken out.
- if (rtx_) {
- if (ssrc_rtx_ == rtp_header->ssrc) {
- // Sanity check, RTX packets has 2 extra header bytes.
- if (rtp_header->headerLength + kRtxHeaderSize > packet_length) {
- return false;
- }
- // If a specific RTX payload type is negotiated, set back to the media
- // payload type and treat it like a media packet from here.
- if (payload_type_rtx_ != -1) {
- if (payload_type_rtx_ == rtp_header->payloadType &&
- rtp_payload_registry_->last_received_media_payload_type() != -1) {
- rtp_header->payloadType =
- rtp_payload_registry_->last_received_media_payload_type();
- } else {
- WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
- "Incorrect RTX configuration, dropping packet.");
- return false;
- }
- }
- rtp_header->ssrc = ssrc_;
- rtp_header->sequenceNumber =
- (packet[rtp_header->headerLength] << 8) +
- packet[1 + rtp_header->headerLength];
- // Count the RTX header as part of the RTP
- rtp_header->headerLength += 2;
- }
- }
- }
int8_t first_payload_byte = 0;
- if (length > 0) {
- first_payload_byte = packet[rtp_header->headerLength];
+ if (payload_length > 0) {
+ first_payload_byte = payload[0];
}
// Trigger our callbacks.
CheckSSRCChanged(rtp_header);
@@ -269,7 +203,7 @@
is_red,
&payload_specific,
&should_reset_statistics) == -1) {
- if (length - rtp_header->headerLength == 0) {
+ if (payload_length == 0) {
// OK, keep-alive packet.
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_,
"%s received keepalive",
@@ -288,24 +222,23 @@
WebRtcRTPHeader webrtc_rtp_header;
memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header));
- webrtc_rtp_header.header = *rtp_header;
- CheckCSRC(&webrtc_rtp_header);
+ webrtc_rtp_header.header = rtp_header;
+ CheckCSRC(webrtc_rtp_header);
- uint16_t payload_data_length =
- ModuleRTPUtility::GetPayloadDataLength(*rtp_header, packet_length);
+ uint16_t payload_data_length = payload_length - rtp_header.paddingLength;
bool is_first_packet_in_frame = false;
bool is_first_packet = false;
{
CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
is_first_packet_in_frame =
- last_received_sequence_number_ + 1 == rtp_header->sequenceNumber &&
- Timestamp() != rtp_header->timestamp;
+ last_received_sequence_number_ + 1 == rtp_header.sequenceNumber &&
+ Timestamp() != rtp_header.timestamp;
is_first_packet = is_first_packet_in_frame || last_receive_time_ == 0;
}
int32_t ret_val = rtp_media_receiver_->ParseRtpPacket(
- &webrtc_rtp_header, payload_specific, is_red, packet, packet_length,
+ &webrtc_rtp_header, payload_specific, is_red, payload, payload_length,
clock_->TimeInMilliseconds(), is_first_packet);
if (ret_val < 0) {
@@ -319,73 +252,16 @@
last_received_payload_length_ = payload_data_length;
if (in_order) {
- if (last_received_timestamp_ != rtp_header->timestamp) {
- last_received_timestamp_ = rtp_header->timestamp;
+ if (last_received_timestamp_ != rtp_header.timestamp) {
+ last_received_timestamp_ = rtp_header.timestamp;
last_received_frame_time_ms_ = clock_->TimeInMilliseconds();
}
- last_received_sequence_number_ = rtp_header->sequenceNumber;
+ last_received_sequence_number_ = rtp_header.sequenceNumber;
}
}
return true;
}
-bool RtpReceiverImpl::RetransmitOfOldPacket(const RTPHeader& header,
- int jitter, int min_rtt) const {
- if (InOrderPacket(header.sequenceNumber)) {
- return false;
- }
-
- CriticalSectionScoped cs(critical_section_rtp_receiver_.get());
- uint32_t frequency_khz = header.payload_type_frequency / 1000;
- assert(frequency_khz > 0);
-
- int64_t time_diff_ms = clock_->TimeInMilliseconds() -
- last_receive_time_;
-
- // Diff in time stamp since last received in order.
- uint32_t timestamp_diff = header.timestamp - last_received_timestamp_;
- int32_t rtp_time_stamp_diff_ms = static_cast<int32_t>(timestamp_diff) /
- frequency_khz;
-
- int32_t max_delay_ms = 0;
- if (min_rtt == 0) {
- // Jitter standard deviation in samples.
- float jitter_std = sqrt(static_cast<float>(jitter));
-
- // 2 times the standard deviation => 95% confidence.
- // And transform to milliseconds by dividing by the frequency in kHz.
- max_delay_ms = static_cast<int32_t>((2 * jitter_std) / frequency_khz);
-
- // Min max_delay_ms is 1.
- if (max_delay_ms == 0) {
- max_delay_ms = 1;
- }
- } else {
- max_delay_ms = (min_rtt / 3) + 1;
- }
- if (time_diff_ms > rtp_time_stamp_diff_ms + max_delay_ms) {
- return true;
- }
- return false;
-}
-
-bool RtpReceiverImpl::InOrderPacket(const uint16_t sequence_number) const {
- CriticalSectionScoped cs(critical_section_rtp_receiver_.get());
-
- // First packet is always in order.
- if (last_receive_time_ == 0)
- return true;
-
- if (IsNewerSequenceNumber(sequence_number, last_received_sequence_number_)) {
- return true;
- } else {
- // If we have a restart of the remote side this packet is still in order.
- return !IsNewerSequenceNumber(sequence_number,
- last_received_sequence_number_ -
- max_reordering_threshold_);
- }
-}
-
TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() {
return rtp_media_receiver_->GetTelephoneEventHandler();
}
@@ -401,7 +277,7 @@
}
// Implementation note: must not hold critsect when called.
-void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader* rtp_header) {
+void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) {
bool new_ssrc = false;
bool re_initialize_decoder = false;
char payload_name[RTP_PAYLOAD_NAME_SIZE];
@@ -413,7 +289,7 @@
int8_t last_received_payload_type =
rtp_payload_registry_->last_received_payload_type();
- if (ssrc_ != rtp_header->ssrc ||
+ if (ssrc_ != rtp_header.ssrc ||
(last_received_payload_type == -1 && ssrc_ == 0)) {
// We need the payload_type_ to make the call if the remote SSRC is 0.
new_ssrc = true;
@@ -427,12 +303,12 @@
// Do we have a SSRC? Then the stream is restarted.
if (ssrc_ != 0) {
// Do we have the same codec? Then re-initialize coder.
- if (rtp_header->payloadType == last_received_payload_type) {
+ if (rtp_header.payloadType == last_received_payload_type) {
re_initialize_decoder = true;
Payload* payload;
if (!rtp_payload_registry_->PayloadTypeToPayload(
- rtp_header->payloadType, payload)) {
+ rtp_header.payloadType, payload)) {
return;
}
assert(payload);
@@ -444,24 +320,24 @@
}
}
}
- ssrc_ = rtp_header->ssrc;
+ ssrc_ = rtp_header.ssrc;
}
}
if (new_ssrc) {
// We need to get this to our RTCP sender and receiver.
// We need to do this outside critical section.
- cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->ssrc);
+ cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header.ssrc);
}
if (re_initialize_decoder) {
if (-1 == cb_rtp_feedback_->OnInitializeDecoder(
- id_, rtp_header->payloadType, payload_name,
- rtp_header->payload_type_frequency, channels, rate)) {
+ id_, rtp_header.payloadType, payload_name,
+ rtp_header.payload_type_frequency, channels, rate)) {
// New stream, same codec.
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
"Failed to create decoder for payload type:%d",
- rtp_header->payloadType);
+ rtp_header.payloadType);
}
}
}
@@ -474,7 +350,7 @@
// media_specific interface (such as CheckPayloadChange, possibly get/set
// last known payload).
int32_t RtpReceiverImpl::CheckPayloadChanged(
- const RTPHeader* rtp_header,
+ const RTPHeader& rtp_header,
const int8_t first_payload_byte,
bool& is_red,
PayloadUnion* specific_payload,
@@ -482,13 +358,15 @@
bool re_initialize_decoder = false;
char payload_name[RTP_PAYLOAD_NAME_SIZE];
- int8_t payload_type = rtp_header->payloadType;
+ int8_t payload_type = rtp_header.payloadType;
{
CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
int8_t last_received_payload_type =
rtp_payload_registry_->last_received_payload_type();
+ // TODO(holmer): Remove this code when RED parsing has been broken out from
+ // RtpReceiverAudio.
if (payload_type != last_received_payload_type) {
if (rtp_payload_registry_->red_payload_type() == payload_type) {
// Get the real codec payload type.
@@ -537,16 +415,11 @@
rtp_media_receiver_->GetLastMediaSpecificPayload(specific_payload);
if (!payload->audio) {
- if (VideoCodecType() == kRtpVideoFec) {
- // Only reset the decoder on media packets.
+ bool media_type_unchanged =
+ rtp_payload_registry_->ReportMediaPayloadType(payload_type);
+ if (media_type_unchanged) {
+ // Only reset the decoder if the media codec type has changed.
re_initialize_decoder = false;
- } else {
- bool media_type_unchanged =
- rtp_payload_registry_->ReportMediaPayloadType(payload_type);
- if (media_type_unchanged) {
- // Only reset the decoder if the media codec type has changed.
- re_initialize_decoder = false;
- }
}
}
if (re_initialize_decoder) {
@@ -569,7 +442,7 @@
}
// Implementation note: must not hold critsect when called.
-void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader* rtp_header) {
+void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader& rtp_header) {
int32_t num_csrcs_diff = 0;
uint32_t old_remote_csrc[kRtpCsrcSize];
uint8_t old_num_csrcs = 0;
@@ -578,7 +451,7 @@
CriticalSectionScoped lock(critical_section_rtp_receiver_.get());
if (!rtp_media_receiver_->ShouldReportCsrcChanges(
- rtp_header->header.payloadType)) {
+ rtp_header.header.payloadType)) {
return;
}
old_num_csrcs = num_csrcs_;
@@ -587,11 +460,11 @@
memcpy(old_remote_csrc, current_remote_csrc_,
num_csrcs_ * sizeof(uint32_t));
}
- const uint8_t num_csrcs = rtp_header->header.numCSRCs;
+ const uint8_t num_csrcs = rtp_header.header.numCSRCs;
if ((num_csrcs > 0) && (num_csrcs <= kRtpCsrcSize)) {
// Copy new.
memcpy(current_remote_csrc_,
- rtp_header->header.arrOfCSRCs,
+ rtp_header.header.arrOfCSRCs,
num_csrcs * sizeof(uint32_t));
}
if (num_csrcs > 0 || old_num_csrcs > 0) {
@@ -605,8 +478,8 @@
bool have_called_callback = false;
// Search for new CSRC in old array.
- for (uint8_t i = 0; i < rtp_header->header.numCSRCs; ++i) {
- const uint32_t csrc = rtp_header->header.arrOfCSRCs[i];
+ for (uint8_t i = 0; i < rtp_header.header.numCSRCs; ++i) {
+ const uint32_t csrc = rtp_header.header.arrOfCSRCs[i];
bool found_match = false;
for (uint8_t j = 0; j < old_num_csrcs; ++j) {
@@ -626,8 +499,8 @@
const uint32_t csrc = old_remote_csrc[i];
bool found_match = false;
- for (uint8_t j = 0; j < rtp_header->header.numCSRCs; ++j) {
- if (csrc == rtp_header->header.arrOfCSRCs[j]) {
+ for (uint8_t j = 0; j < rtp_header.header.numCSRCs; ++j) {
+ if (csrc == rtp_header.header.arrOfCSRCs[j]) {
found_match = true;
break;
}
diff --git a/modules/rtp_rtcp/source/rtp_receiver_impl.h b/modules/rtp_rtcp/source/rtp_receiver_impl.h
index bf3b925..c3a2fa1 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_impl.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_impl.h
@@ -46,16 +46,16 @@
int32_t DeRegisterReceivePayload(const int8_t payload_type);
bool IncomingRtpPacket(
- RTPHeader* rtp_header,
- const uint8_t* incoming_rtp_packet,
- int incoming_rtp_packet_length,
+ const RTPHeader& rtp_header,
+ const uint8_t* payload,
+ int payload_length,
PayloadUnion payload_specific,
bool in_order);
NACKMethod NACK() const;
// Turn negative acknowledgement requests on/off.
- int32_t SetNACKStatus(const NACKMethod method, int max_reordering_threshold);
+ void SetNACKStatus(const NACKMethod method);
// Returns the last received timestamp.
virtual uint32_t Timestamp() const;
@@ -74,19 +74,16 @@
void SetRtxPayloadType(int payload_type);
- virtual bool RetransmitOfOldPacket(const RTPHeader& header,
- int jitter, int min_rtt) const;
- bool InOrderPacket(const uint16_t sequence_number) const;
TelephoneEventHandler* GetTelephoneEventHandler();
private:
RtpVideoCodecTypes VideoCodecType() const;
- void CheckSSRCChanged(const RTPHeader* rtp_header);
- void CheckCSRC(const WebRtcRTPHeader* rtp_header);
- int32_t CheckPayloadChanged(const RTPHeader* rtp_header,
+ void CheckSSRCChanged(const RTPHeader& rtp_header);
+ void CheckCSRC(const WebRtcRTPHeader& rtp_header);
+ int32_t CheckPayloadChanged(const RTPHeader& rtp_header,
const int8_t first_payload_byte,
- bool& isRED,
+ bool& is_red,
PayloadUnion* payload,
bool* should_reset_statistics);
@@ -112,11 +109,6 @@
uint16_t last_received_sequence_number_;
NACKMethod nack_method_;
- int max_reordering_threshold_;
-
- bool rtx_;
- uint32_t ssrc_rtx_;
- int payload_type_rtx_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
diff --git a/modules/rtp_rtcp/source/rtp_receiver_strategy.h b/modules/rtp_rtcp/source/rtp_receiver_strategy.h
index 0681ac9..d8a2257 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_strategy.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_strategy.h
@@ -43,8 +43,8 @@
virtual int32_t ParseRtpPacket(WebRtcRTPHeader* rtp_header,
const PayloadUnion& specific_payload,
bool is_red,
- const uint8_t* packet,
- uint16_t packet_length,
+ const uint8_t* payload,
+ uint16_t payload_length,
int64_t timestamp_ms,
bool is_first_packet) = 0;
diff --git a/modules/rtp_rtcp/source/rtp_receiver_video.cc b/modules/rtp_rtcp/source/rtp_receiver_video.cc
index a47f7d3..6524080 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_video.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_video.cc
@@ -10,24 +10,17 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
-#include <math.h>
-
-#include <assert.h> // assert
-#include <string.h> // memcpy()
+#include <assert.h>
+#include <string.h>
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
-#include "webrtc/modules/rtp_rtcp/source/receiver_fec.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/system_wrappers/interface/trace_event.h"
namespace webrtc {
-uint32_t BitRateBPS(uint16_t x) {
- return (x & 0x3fff) * uint32_t(pow(10.0f, (2 + (x >> 14))));
-}
RTPReceiverStrategy* RTPReceiverStrategy::CreateVideoStrategy(
int32_t id, RtpData* data_callback) {
@@ -36,12 +29,9 @@
RTPReceiverVideo::RTPReceiverVideo(int32_t id, RtpData* data_callback)
: RTPReceiverStrategy(data_callback),
- id_(id),
- receive_fec_(NULL) {
-}
+ id_(id) {}
RTPReceiverVideo::~RTPReceiverVideo() {
- delete receive_fec_;
}
bool RTPReceiverVideo::ShouldReportCsrcChanges(
@@ -54,13 +44,6 @@
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
int8_t payload_type,
uint32_t frequency) {
- if (ModuleRTPUtility::StringCompare(payload_name, "ULPFEC", 6)) {
- // Enable FEC if not enabled.
- if (receive_fec_ == NULL) {
- receive_fec_ = new ReceiverFEC(id_, data_callback_);
- }
- receive_fec_->SetPayloadTypeFEC(payload_type);
- }
return 0;
}
@@ -68,25 +51,20 @@
WebRtcRTPHeader* rtp_header,
const PayloadUnion& specific_payload,
bool is_red,
- const uint8_t* packet,
- uint16_t packet_length,
+ const uint8_t* payload,
+ uint16_t payload_length,
int64_t timestamp_ms,
bool is_first_packet) {
TRACE_EVENT2("webrtc_rtp", "Video::ParseRtp",
"seqnum", rtp_header->header.sequenceNumber,
"timestamp", rtp_header->header.timestamp);
rtp_header->type.Video.codec = specific_payload.Video.videoCodecType;
- const uint8_t* payload_data =
- ModuleRTPUtility::GetPayloadData(rtp_header->header, packet);
- const uint16_t payload_data_length =
- ModuleRTPUtility::GetPayloadDataLength(rtp_header->header, packet_length);
+ const uint16_t payload_data_length = payload_length -
+ rtp_header->header.paddingLength;
return ParseVideoCodecSpecific(rtp_header,
- payload_data,
+ payload,
payload_data_length,
specific_payload.Video.videoCodecType,
- is_red,
- packet,
- packet_length,
timestamp_ms,
is_first_packet);
}
@@ -119,57 +97,31 @@
return 0;
}
-// we have no critext when calling this
-// we are not allowed to have any critsects when calling
-// CallbackOfReceivedPayloadData
+// We are not allowed to hold a critical section when calling this function.
int32_t RTPReceiverVideo::ParseVideoCodecSpecific(
WebRtcRTPHeader* rtp_header,
const uint8_t* payload_data,
uint16_t payload_data_length,
RtpVideoCodecTypes video_type,
- bool is_red,
- const uint8_t* incoming_rtp_packet,
- uint16_t incoming_rtp_packet_size,
int64_t now_ms,
bool is_first_packet) {
- int32_t ret_val = 0;
+ WEBRTC_TRACE(kTraceStream,
+ kTraceRtpRtcp,
+ id_,
+ "%s(timestamp:%u)",
+ __FUNCTION__,
+ rtp_header->header.timestamp);
- crit_sect_->Enter();
-
- if (is_red) {
- if (receive_fec_ == NULL) {
- crit_sect_->Leave();
- return -1;
- }
- crit_sect_->Leave();
- bool FECpacket = false;
- ret_val = receive_fec_->AddReceivedFECPacket(
- rtp_header, incoming_rtp_packet, payload_data_length, FECpacket);
- if (ret_val != -1) {
- ret_val = receive_fec_->ProcessReceivedFEC();
- }
-
- if (ret_val == 0 && FECpacket) {
- // Callback with the received FEC packet.
- // The normal packets are delivered after parsing.
- // This contains the original RTP packet header but with
- // empty payload and data length.
- rtp_header->frameType = kFrameEmpty;
- // We need this for the routing.
- rtp_header->type.Video.codec = video_type;
- // Pass the length of FEC packets so that they can be accounted for in
- // the bandwidth estimator.
- ret_val = data_callback_->OnReceivedPayloadData(
- NULL, payload_data_length, rtp_header);
- }
- } else {
- // will leave the crit_sect_ critsect
- ret_val = ParseVideoCodecSpecificSwitch(rtp_header,
- payload_data,
- payload_data_length,
- is_first_packet);
+ switch (rtp_header->type.Video.codec) {
+ case kRtpVideoGeneric:
+ rtp_header->type.Video.isFirstPacket = is_first_packet;
+ return ReceiveGenericCodec(rtp_header, payload_data, payload_data_length);
+ case kRtpVideoVp8:
+ return ReceiveVp8Codec(rtp_header, payload_data, payload_data_length);
+ case kRtpVideoNone:
+ break;
}
- return ret_val;
+ return -1;
}
int32_t RTPReceiverVideo::BuildRTPheader(
@@ -208,35 +160,6 @@
return rtp_header_length;
}
-int32_t RTPReceiverVideo::ParseVideoCodecSpecificSwitch(
- WebRtcRTPHeader* rtp_header,
- const uint8_t* payload_data,
- uint16_t payload_data_length,
- bool is_first_packet) {
- WEBRTC_TRACE(kTraceStream,
- kTraceRtpRtcp,
- id_,
- "%s(timestamp:%u)",
- __FUNCTION__,
- rtp_header->header.timestamp);
-
- // Critical section has already been taken.
- switch (rtp_header->type.Video.codec) {
- case kRtpVideoGeneric:
- rtp_header->type.Video.isFirstPacket = is_first_packet;
- return ReceiveGenericCodec(rtp_header, payload_data, payload_data_length);
- case kRtpVideoVp8:
- return ReceiveVp8Codec(rtp_header, payload_data, payload_data_length);
- case kRtpVideoFec:
- break;
- default:
- assert(false);
- }
- // Releasing the already taken critical section here.
- crit_sect_->Leave();
- return -1;
-}
-
int32_t RTPReceiverVideo::ReceiveVp8Codec(WebRtcRTPHeader* rtp_header,
const uint8_t* payload_data,
uint16_t payload_data_length) {
@@ -246,13 +169,16 @@
success = true;
parsed_packet.info.VP8.dataLength = 0;
} else {
+ uint32_t id = 0;
+ {
+ CriticalSectionScoped cs(crit_sect_.get());
+ id = id_;
+ }
ModuleRTPUtility::RTPPayloadParser rtp_payload_parser(
- kRtpVideoVp8, payload_data, payload_data_length, id_);
+ kRtpVideoVp8, payload_data, payload_data_length, id);
success = rtp_payload_parser.Parse(parsed_packet);
}
- // from here down we only work on local data
- crit_sect_->Leave();
if (!success) {
return -1;
@@ -315,8 +241,6 @@
rtp_header->type.Video.isFirstPacket =
(generic_header & RtpFormatVideoGeneric::kFirstPacketBit) != 0;
- crit_sect_->Leave();
-
if (data_callback_->OnReceivedPayloadData(
payload_data, payload_data_length, rtp_header) != 0) {
return -1;
diff --git a/modules/rtp_rtcp/source/rtp_receiver_video.h b/modules/rtp_rtcp/source/rtp_receiver_video.h
index 47639c8..ab69b40 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_video.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_video.h
@@ -19,10 +19,6 @@
#include "webrtc/typedefs.h"
namespace webrtc {
-class CriticalSectionWrapper;
-class ModuleRtpRtcpImpl;
-class ReceiverFEC;
-class RtpReceiver;
class RTPReceiverVideo : public RTPReceiverStrategy {
public:
@@ -65,12 +61,6 @@
void SetPacketOverHead(uint16_t packet_over_head);
protected:
- int32_t ParseVideoCodecSpecificSwitch(
- WebRtcRTPHeader* rtp_header,
- const uint8_t* payload_data,
- uint16_t payload_data_length,
- bool is_first_packet);
-
int32_t ReceiveGenericCodec(WebRtcRTPHeader* rtp_header,
const uint8_t* payload_data,
uint16_t payload_data_length);
@@ -88,16 +78,10 @@
const uint8_t* payload_data,
uint16_t payload_data_length,
RtpVideoCodecTypes video_type,
- bool is_red,
- const uint8_t* incoming_rtp_packet,
- uint16_t incoming_rtp_packet_size,
int64_t now_ms,
bool is_first_packet);
int32_t id_;
-
- // FEC
- ReceiverFEC* receive_fec_;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_rtcp.gypi b/modules/rtp_rtcp/source/rtp_rtcp.gypi
index 42b6580..bb612b3 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp.gypi
+++ b/modules/rtp_rtcp/source/rtp_rtcp.gypi
@@ -28,6 +28,7 @@
},
'sources': [
# Common
+ '../interface/fec_receiver.h',
'../interface/receive_statistics.h',
'../interface/rtp_header_parser.h',
'../interface/rtp_payload_registry.h',
@@ -36,6 +37,8 @@
'../interface/rtp_rtcp_defines.h',
'bitrate.cc',
'bitrate.h',
+ 'fec_receiver_impl.cc',
+ 'fec_receiver_impl.h',
'receive_statistics_impl.cc',
'receive_statistics_impl.h',
'rtp_header_parser.cc',
@@ -87,8 +90,6 @@
'rtp_receiver_video.h',
'rtp_sender_video.cc',
'rtp_sender_video.h',
- 'receiver_fec.cc',
- 'receiver_fec.h',
'video_codec_information.h',
'rtp_format_vp8.cc',
'rtp_format_vp8.h',
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index 6c9131f..83ee7f6 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -19,7 +19,6 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
-#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/typedefs.h"
@@ -41,6 +40,18 @@
using testing::_;
+const uint8_t* GetPayloadData(const RTPHeader& rtp_header,
+ const uint8_t* packet) {
+ return packet + rtp_header.headerLength;
+}
+
+uint16_t GetPayloadDataLength(const RTPHeader& rtp_header,
+ const uint16_t packet_length) {
+ uint16_t length = packet_length - rtp_header.headerLength -
+ rtp_header.paddingLength;
+ return static_cast<uint16_t>(length);
+}
+
class LoopbackTransportTest : public webrtc::Transport {
public:
LoopbackTransportTest()
@@ -464,13 +475,12 @@
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
- const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
+ const uint8_t* payload_data = GetPayloadData(rtp_header,
transport_.last_sent_packet_);
uint8_t generic_header = *payload_data++;
ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
- ModuleRTPUtility::GetPayloadDataLength(rtp_header,
- transport_.last_sent_packet_len_));
+ GetPayloadDataLength(rtp_header, transport_.last_sent_packet_len_));
EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
@@ -490,16 +500,14 @@
transport_.last_sent_packet_len_);
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
- payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
- transport_.last_sent_packet_);
+ payload_data = GetPayloadData(rtp_header, transport_.last_sent_packet_);
generic_header = *payload_data++;
EXPECT_FALSE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
- ModuleRTPUtility::GetPayloadDataLength(rtp_header,
- transport_.last_sent_packet_len_));
+ GetPayloadDataLength(rtp_header, transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
}
@@ -574,10 +582,10 @@
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
- const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
+ const uint8_t* payload_data = GetPayloadData(rtp_header,
transport_.last_sent_packet_);
- ASSERT_EQ(sizeof(payload), ModuleRTPUtility::GetPayloadDataLength(rtp_header,
+ ASSERT_EQ(sizeof(payload), GetPayloadDataLength(rtp_header,
transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
@@ -605,11 +613,11 @@
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
- const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
- transport_.last_sent_packet_);
+ const uint8_t* payload_data = GetPayloadData(rtp_header,
+ transport_.last_sent_packet_);
- ASSERT_EQ(sizeof(payload), ModuleRTPUtility::GetPayloadDataLength(rtp_header,
- transport_.last_sent_packet_len_));
+ ASSERT_EQ(sizeof(payload), GetPayloadDataLength(
+ rtp_header, transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
diff --git a/modules/rtp_rtcp/source/rtp_utility.cc b/modules/rtp_rtcp/source/rtp_utility.cc
index 409a177..bc0be8b 100644
--- a/modules/rtp_rtcp/source/rtp_utility.cc
+++ b/modules/rtp_rtcp/source/rtp_utility.cc
@@ -113,18 +113,6 @@
* Misc utility routines
*/
-const uint8_t* GetPayloadData(const RTPHeader& rtp_header,
- const uint8_t* packet) {
- return packet + rtp_header.headerLength;
-}
-
-uint16_t GetPayloadDataLength(const RTPHeader& rtp_header,
- const uint16_t packet_length) {
- uint16_t length = packet_length - rtp_header.paddingLength -
- rtp_header.headerLength;
- return static_cast<uint16_t>(length);
-}
-
#if defined(_WIN32)
bool StringCompare(const char* str1, const char* str2,
const uint32_t length) {
diff --git a/modules/rtp_rtcp/source/rtp_utility.h b/modules/rtp_rtcp/source/rtp_utility.h
index 72bbfa0..8002273 100644
--- a/modules/rtp_rtcp/source/rtp_utility.h
+++ b/modules/rtp_rtcp/source/rtp_utility.h
@@ -56,14 +56,6 @@
uint32_t pow2(uint8_t exp);
- // Returns a pointer to the payload data given a packet.
- const uint8_t* GetPayloadData(const RTPHeader& rtp_header,
- const uint8_t* packet);
-
- // Returns payload length given a packet.
- uint16_t GetPayloadDataLength(const RTPHeader& rtp_header,
- const uint16_t packet_length);
-
// Returns true if |newTimestamp| is older than |existingTimestamp|.
// |wrapped| will be set to true if there has been a wraparound between the
// two timestamps.
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.cc b/modules/rtp_rtcp/test/testAPI/test_api.cc
index 6789e04..78df647 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api.cc
@@ -110,11 +110,11 @@
EXPECT_FALSE(module->TMMBR());
EXPECT_EQ(kNackOff, rtp_receiver_->NACK());
- EXPECT_EQ(0, rtp_receiver_->SetNACKStatus(kNackRtcp, 450));
+ rtp_receiver_->SetNACKStatus(kNackRtcp);
EXPECT_EQ(kNackRtcp, rtp_receiver_->NACK());
}
-TEST_F(RtpRtcpAPITest, RTXSender) {
+TEST_F(RtpRtcpAPITest, RtxSender) {
unsigned int ssrc = 0;
RtxMode rtx_mode = kRtxOff;
const int kRtxPayloadType = 119;
@@ -138,19 +138,20 @@
EXPECT_EQ(kRtxPayloadType, payload_type);
}
-TEST_F(RtpRtcpAPITest, RTXReceiver) {
- bool enable = false;
- unsigned int ssrc = 0;
+TEST_F(RtpRtcpAPITest, RtxReceiver) {
+ const uint32_t kRtxSsrc = 1;
const int kRtxPayloadType = 119;
- int payload_type = -1;
- rtp_receiver_->SetRTXStatus(true, 1);
- rtp_receiver_->SetRtxPayloadType(kRtxPayloadType);
- rtp_receiver_->RTXStatus(&enable, &ssrc, &payload_type);
- EXPECT_TRUE(enable);
- EXPECT_EQ(1u, ssrc);
- EXPECT_EQ(kRtxPayloadType ,payload_type);
- rtp_receiver_->SetRTXStatus(false, 0);
- rtp_receiver_->RTXStatus(&enable, &ssrc, &payload_type);
- EXPECT_FALSE(enable);
- EXPECT_EQ(kRtxPayloadType ,payload_type);
+ rtp_payload_registry_->SetRtxStatus(true, kRtxSsrc);
+ rtp_payload_registry_->SetRtxPayloadType(kRtxPayloadType);
+ EXPECT_TRUE(rtp_payload_registry_->RtxEnabled());
+ RTPHeader rtx_header;
+ rtx_header.ssrc = kRtxSsrc;
+ rtx_header.payloadType = kRtxPayloadType;
+ EXPECT_TRUE(rtp_payload_registry_->IsRtx(rtx_header));
+ rtx_header.ssrc = 0;
+ EXPECT_FALSE(rtp_payload_registry_->IsRtx(rtx_header));
+ rtp_payload_registry_->SetRtxStatus(false, kRtxSsrc);
+ EXPECT_FALSE(rtp_payload_registry_->RtxEnabled());
+ rtx_header.ssrc = kRtxSsrc;
+ EXPECT_FALSE(rtp_payload_registry_->IsRtx(rtx_header));
}
diff --git a/modules/rtp_rtcp/test/testAPI/test_api.h b/modules/rtp_rtcp/test/testAPI/test_api.h
index 1a13ab9..8061ce0 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api.h
+++ b/modules/rtp_rtcp/test/testAPI/test_api.h
@@ -60,8 +60,8 @@
header.payloadType, &payload_specific)) {
return -1;
}
- receive_statistics_->IncomingPacket(header, len, false, true);
- if (!rtp_receiver_->IncomingRtpPacket(&header,
+ receive_statistics_->IncomingPacket(header, len, false);
+ if (!rtp_receiver_->IncomingRtpPacket(header,
static_cast<const uint8_t*>(data),
len, payload_specific, true)) {
return -1;
diff --git a/modules/rtp_rtcp/test/testAPI/test_api_video.cc b/modules/rtp_rtcp/test/testAPI/test_api_video.cc
index 6291a34..6f065d5 100644
--- a/modules/rtp_rtcp/test/testAPI/test_api_video.cc
+++ b/modules/rtp_rtcp/test/testAPI/test_api_video.cc
@@ -52,7 +52,7 @@
EXPECT_EQ(0, video_module_->SetRTCPStatus(kRtcpCompound));
EXPECT_EQ(0, video_module_->SetSSRC(test_ssrc_));
- EXPECT_EQ(0, rtp_receiver_->SetNACKStatus(kNackRtcp, 450));
+ rtp_receiver_->SetNACKStatus(kNackRtcp);
EXPECT_EQ(0, video_module_->SetStorePacketsStatus(true, 600));
EXPECT_EQ(0, video_module_->SetSendingStatus(true));
@@ -176,11 +176,13 @@
PayloadUnion payload_specific;
EXPECT_TRUE(rtp_payload_registry_.GetPayloadSpecifics(header.payloadType,
&payload_specific));
- EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(&header, padding_packet,
- packet_size,
+ const uint8_t* payload = padding_packet + header.headerLength;
+ const int payload_length = packet_size - header.headerLength;
+ EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, payload,
+ payload_length,
payload_specific, true));
EXPECT_EQ(0, receiver_->payload_size());
- EXPECT_EQ(packet_size - 12, receiver_->rtp_header().header.paddingLength);
+ EXPECT_EQ(payload_length, receiver_->rtp_header().header.paddingLength);
}
timestamp += 3000;
fake_clock.AdvanceTimeMilliseconds(33);
diff --git a/modules/video_coding/main/source/packet.cc b/modules/video_coding/main/source/packet.cc
index ad69418..61ef2ee 100644
--- a/modules/video_coding/main/source/packet.cc
+++ b/modules/video_coding/main/source/packet.cc
@@ -111,11 +111,6 @@
codec = kVideoCodecVP8;
break;
}
- case kRtpVideoI420:
- {
- codec = kVideoCodecI420;
- break;
- }
default:
{
codec = kVideoCodecUnknown;
diff --git a/modules/video_coding/main/test/mt_rx_tx_test.cc b/modules/video_coding/main/test/mt_rx_tx_test.cc
index 2c04388..5cad5d4 100644
--- a/modules/video_coding/main/test/mt_rx_tx_test.cc
+++ b/modules/video_coding/main/test/mt_rx_tx_test.cc
@@ -257,8 +257,7 @@
FecProtectionParams delta_params = protectionCallback.DeltaFecParameters();
FecProtectionParams key_params = protectionCallback.KeyFecParameters();
rtp->SetFecParameters(&delta_params, &key_params);
- rtp_receiver->SetNACKStatus(nackEnabled ? kNackRtcp : kNackOff,
- kMaxPacketAgeToNack);
+ rtp_receiver->SetNACKStatus(nackEnabled ? kNackRtcp : kNackOff);
vcm->SetChannelParameters(static_cast<uint32_t>(1000 * bitRate),
(uint8_t) lossRate, rttMS);
diff --git a/modules/video_coding/main/test/mt_test_common.cc b/modules/video_coding/main/test/mt_test_common.cc
index 0ec19af..779ef7a 100644
--- a/modules/video_coding/main/test/mt_test_common.cc
+++ b/modules/video_coding/main/test/mt_test_common.cc
@@ -102,7 +102,7 @@
header.payloadType, &payload_specific)) {
return -1;
}
- if (!rtp_receiver_->IncomingRtpPacket(&header, packet->data,
+ if (!rtp_receiver_->IncomingRtpPacket(header, packet->data,
packet->length, payload_specific,
true))
{
diff --git a/modules/video_coding/main/test/normal_test.cc b/modules/video_coding/main/test/normal_test.cc
index e0016bd..3000a1a 100644
--- a/modules/video_coding/main/test/normal_test.cc
+++ b/modules/video_coding/main/test/normal_test.cc
@@ -102,9 +102,6 @@
rtpInfo.type.Video.codecHeader.VP8.pictureId =
videoHdr->codecHeader.VP8.pictureId;
break;
- case kVideoCodecI420:
- rtpInfo.type.Video.codec = kRtpVideoI420;
- break;
default:
assert(false);
return -1;
diff --git a/modules/video_coding/main/test/rtp_player.cc b/modules/video_coding/main/test/rtp_player.cc
index c3fc7cc..6af4389 100644
--- a/modules/video_coding/main/test/rtp_player.cc
+++ b/modules/video_coding/main/test/rtp_player.cc
@@ -226,10 +226,7 @@
return -1;
}
- if (handler->rtp_module_->SetNACKStatus(kNackOff,
- kMaxPacketAgeToNack) < 0) {
- return -1;
- }
+ handler->rtp_module_->SetNACKStatus(kNackOff);
handler->rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset,
kDefaultTransmissionTimeOffsetExtensionId);
@@ -262,10 +259,8 @@
PayloadUnion payload_specific;
it->second->rtp_payload_registry_->GetPayloadSpecifics(
header.payloadType, &payload_specific);
- bool in_order =
- it->second->rtp_module_->InOrderPacket(header.sequenceNumber);
- it->second->rtp_module_->IncomingRtpPacket(&header, data, length,
- payload_specific, in_order);
+ it->second->rtp_module_->IncomingRtpPacket(header, data, length,
+ payload_specific, true);
}
}
}
diff --git a/modules/video_coding/main/test/test_callbacks.cc b/modules/video_coding/main/test/test_callbacks.cc
index e9939d6..8e96776 100644
--- a/modules/video_coding/main/test/test_callbacks.cc
+++ b/modules/video_coding/main/test/test_callbacks.cc
@@ -82,8 +82,6 @@
rtpInfo.type.Video.codecHeader.VP8.pictureId =
videoHdr->codecHeader.VP8.pictureId;
break;
- case webrtc::kRtpVideoI420:
- break;
default:
assert(false);
return -1;
@@ -308,7 +306,7 @@
header.payloadType, &payload_specific)) {
return -1;
}
- if (!rtp_receiver_->IncomingRtpPacket(&header, packet->data,
+ if (!rtp_receiver_->IncomingRtpPacket(header, packet->data,
packet->length, payload_specific,
true))
{
diff --git a/modules/video_coding/main/test/test_util.cc b/modules/video_coding/main/test/test_util.cc
index 6f694ab..09ad991 100644
--- a/modules/video_coding/main/test/test_util.cc
+++ b/modules/video_coding/main/test/test_util.cc
@@ -150,8 +150,6 @@
webrtc::RtpVideoCodecTypes ConvertCodecType(const char* plname) {
if (strncmp(plname,"VP8" , 3) == 0) {
return webrtc::kRtpVideoVp8;
- } else if (strncmp(plname,"I420" , 5) == 0) {
- return webrtc::kRtpVideoI420;
} else {
return webrtc::kRtpVideoNone; // Default value
}