Adding a payload type for RTX.

BUG=736
TEST=Modified RTP unittests.

Review URL: https://webrtc-codereview.appspot.com/1278004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3843 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2013-04-12 14:55:46 +00:00
parent b8e7f4cc97
commit 9f5ebb5251
17 changed files with 222 additions and 61 deletions

View File

@ -232,14 +232,18 @@ class RtpRtcp : public Module {
/*
* Turn on/off receiving RTX (RFC 4588) on a specific SSRC.
*/
virtual int32_t SetRTXReceiveStatus(const bool enable,
const uint32_t SSRC) = 0;
virtual int32_t SetRTXReceiveStatus(bool enable, uint32_t SSRC) = 0;
// Sets the payload type to expected for received RTX packets. Note
// that this doesn't enable RTX, only the payload type is set.
virtual void SetRtxReceivePayloadType(int payload_type) = 0;
/*
* Get status of receiving RTX (RFC 4588) on a specific SSRC.
*/
virtual int32_t RTXReceiveStatus(bool* enable,
uint32_t* SSRC) const = 0;
uint32_t* SSRC,
int* payloadType) const = 0;
/*
* called by the network module when we receive a packet
@ -416,15 +420,18 @@ class RtpRtcp : public Module {
/*
* Turn on/off sending RTX (RFC 4588) on a specific SSRC.
*/
virtual int32_t SetRTXSendStatus(const RtxMode mode,
const bool setSSRC,
const uint32_t SSRC) = 0;
virtual int32_t SetRTXSendStatus(RtxMode mode, bool set_ssrc,
uint32_t ssrc) = 0;
// Sets the payload type to use when sending RTX packets. Note that this
// doesn't enable RTX, only the payload type is set.
virtual void SetRtxSendPayloadType(int payload_type) = 0;
/*
* Get status of sending RTX (RFC 4588) on a specific SSRC.
*/
virtual int32_t RTXSendStatus(RtxMode* mode,
uint32_t* SSRC) const = 0;
virtual int32_t RTXSendStatus(RtxMode* mode, uint32_t* ssrc,
int* payloadType) const = 0;
/*
* sends kRtcpByeCode when going from true to false

View File

@ -113,6 +113,8 @@ enum RtxMode {
kRtxAll = 2 // Apply RTX to all packets (source + retransmissions).
};
const int kRtxHeaderSize = 2;
struct RTCPSenderInfo
{
uint32_t NTPseconds;

View File

@ -76,11 +76,14 @@ class MockRtpRtcp : public RtpRtcp {
MOCK_METHOD2(SetSSRCFilter,
int32_t(const bool enable, const uint32_t allowedSSRC));
MOCK_METHOD2(SetRTXReceiveStatus,
int32_t(const bool enable, const uint32_t SSRC));
MOCK_CONST_METHOD2(RTXReceiveStatus,
int32_t(bool* enable, uint32_t* SSRC));
int32_t(bool enable, uint32_t ssrc));
MOCK_CONST_METHOD3(RTXReceiveStatus,
int32_t(bool* enable, uint32_t* ssrc, int* payload_type));
MOCK_METHOD1(SetRtxReceivePayloadType,
void(int));
MOCK_METHOD2(IncomingPacket,
int32_t(const uint8_t* incomingPacket, const uint16_t packetLength));
int32_t(const WebRtc_UWord8* incomingPacket,
const WebRtc_UWord16 packetLength));
MOCK_METHOD4(IncomingAudioNTP,
int32_t(const uint32_t audioReceivedNTPsecs,
const uint32_t audioReceivedNTPfrac,
@ -128,10 +131,11 @@ class MockRtpRtcp : public RtpRtcp {
MOCK_METHOD1(SetCSRCStatus,
int32_t(const bool include));
MOCK_METHOD3(SetRTXSendStatus,
int32_t(const RtxMode mode, const bool setSSRC,
const uint32_t SSRC));
MOCK_CONST_METHOD2(RTXSendStatus,
int32_t(RtxMode* mode, uint32_t* SSRC));
int32_t(RtxMode mode, bool setSSRC, uint32_t ssrc));
MOCK_CONST_METHOD3(RTXSendStatus,
int32_t(RtxMode* mode, uint32_t* ssrc, int* payload_type));
MOCK_METHOD1(SetRtxSendPayloadType,
void(int));
MOCK_METHOD1(SetSendingStatus,
int32_t(const bool sending));
MOCK_CONST_METHOD0(Sending,

View File

@ -193,8 +193,10 @@ TEST_F(RtpRtcpRtxNackTest, RTCP) {
TEST_F(RtpRtcpRtxNackTest, RTXNack) {
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXReceiveStatus(true, kTestSsrc + 1));
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXSendStatus(kRtxRetransmitted,
true, kTestSsrc + 1));
rtp_rtcp_module_->SetRtxReceivePayloadType(119);
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXSendStatus(kRtxRetransmitted, true,
kTestSsrc + 1));
rtp_rtcp_module_->SetRtxSendPayloadType(119);
transport_.DropEveryNthPacket(10);
@ -251,8 +253,8 @@ TEST_F(RtpRtcpRtxNackTest, RTXNack) {
TEST_F(RtpRtcpRtxNackTest, RTXAllNoLoss) {
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXReceiveStatus(true, kTestSsrc + 1));
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXSendStatus(kRtxAll,
true, kTestSsrc + 1));
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXSendStatus(kRtxAll, true,
kTestSsrc + 1));
transport_.DropEveryNthPacket(0);
uint32_t timestamp = 3000;
@ -285,8 +287,7 @@ TEST_F(RtpRtcpRtxNackTest, RTXAllNoLoss) {
TEST_F(RtpRtcpRtxNackTest, RTXAllWithLoss) {
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXReceiveStatus(true, kTestSsrc + 1));
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXSendStatus(kRtxAll,
true,
EXPECT_EQ(0, rtp_rtcp_module_->SetRTXSendStatus(kRtxAll, true,
kTestSsrc + 1));
int loss = 10;

View File

@ -93,6 +93,10 @@ class RTPPayloadRegistry {
last_received_payload_type_ = last_received_payload_type;
}
int8_t last_received_media_payload_type() const {
return last_received_media_payload_type_;
};
private:
// Prunes the payload type map of the specific payload type, if it exists.
void DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(

View File

@ -94,7 +94,8 @@ RTPReceiver::RTPReceiver(const int32_t id,
nack_method_(kNackOff),
max_reordering_threshold_(kDefaultMaxReorderingThreshold),
rtx_(false),
ssrc_rtx_(0) {
ssrc_rtx_(0),
payload_type_rtx_(-1) {
assert(incoming_audio_messages_callback &&
incoming_messages_callback &&
incoming_payload_callback);
@ -288,17 +289,23 @@ int32_t RTPReceiver::SetNACKStatus(const NACKMethod method,
return 0;
}
void RTPReceiver::SetRTXStatus(const bool enable,
const uint32_t ssrc) {
void RTPReceiver::SetRTXStatus(bool enable, uint32_t ssrc) {
CriticalSectionScoped lock(critical_section_rtp_receiver_);
rtx_ = enable;
ssrc_rtx_ = ssrc;
}
void RTPReceiver::RTXStatus(bool* enable, uint32_t* ssrc) const {
void RTPReceiver::RTXStatus(bool* enable, uint32_t* ssrc,
int* payload_type) const {
CriticalSectionScoped lock(critical_section_rtp_receiver_);
*enable = rtx_;
*ssrc = ssrc_rtx_;
*payload_type = payload_type_rtx_;
}
void RTPReceiver::SetRtxPayloadType(int payload_type) {
CriticalSectionScoped cs(critical_section_rtp_receiver_);
payload_type_rtx_ = payload_type;
}
uint32_t RTPReceiver::SSRC() const {
@ -350,10 +357,23 @@ int32_t RTPReceiver::IncomingRTPPacket(
}
if (rtx_) {
if (ssrc_rtx_ == rtp_header->header.ssrc) {
// Sanity check.
if (rtp_header->header.headerLength + 2 > packet_length) {
// Sanity check, RTX packets has 2 extra header bytes.
if (rtp_header->header.headerLength + kRtxHeaderSize > packet_length) {
return -1;
}
// 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->header.payloadType &&
rtp_payload_registry_->last_received_media_payload_type() != -1) {
rtp_header->header.payloadType =
rtp_payload_registry_->last_received_media_payload_type();
} else {
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
"Incorrect RTX configuration, dropping packet.");
return -1;
}
}
rtp_header->header.ssrc = ssrc_;
rtp_header->header.sequenceNumber =
(packet[rtp_header->header.headerLength] << 8) +

View File

@ -141,9 +141,11 @@ class RTPReceiver : public Bitrate {
void GetHeaderExtensionMapCopy(RtpHeaderExtensionMap* map) const;
// RTX.
void SetRTXStatus(const bool enable, const uint32_t ssrc);
void SetRTXStatus(bool enable, uint32_t ssrc);
void RTXStatus(bool* enable, uint32_t* ssrc) const;
void RTXStatus(bool* enable, uint32_t* ssrc, int* payload_type) const;
void SetRtxPayloadType(int payload_type);
virtual int8_t REDPayloadType() const;
@ -234,6 +236,7 @@ class RTPReceiver : public Bitrate {
bool rtx_;
uint32_t ssrc_rtx_;
int payload_type_rtx_;
};
} // namespace webrtc

View File

@ -314,7 +314,7 @@ void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() {
bool do_callback = false;
// Do operations on members under lock but avoid making the
// ProcessDeadOrAlive() callback under the same lock.
// ProcessDeadOrAlive() callback under the same lock.
{
CriticalSectionScoped lock(critical_section_module_ptrs_.get());
if (dead_or_alive_active_) {
@ -325,7 +325,7 @@ void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() {
if (rtcp_receiver_.LastReceived() + 12000 > now)
RTCPalive = true;
do_callback = true;
}
}
@ -532,32 +532,38 @@ int32_t ModuleRtpRtcpImpl::RemoteCSRCs(
return rtp_receiver_->CSRCs(arr_of_csrc);
}
int32_t ModuleRtpRtcpImpl::SetRTXSendStatus(
const RtxMode mode,
const bool set_ssrc,
const uint32_t ssrc) {
int32_t ModuleRtpRtcpImpl::SetRTXSendStatus(RtxMode mode, bool set_ssrc,
uint32_t ssrc) {
rtp_sender_.SetRTXStatus(mode, set_ssrc, ssrc);
return 0;
}
int32_t ModuleRtpRtcpImpl::RTXSendStatus(RtxMode* mode, uint32_t* ssrc) const {
rtp_sender_.RTXStatus(mode, ssrc);
int32_t ModuleRtpRtcpImpl::RTXSendStatus(RtxMode* mode, uint32_t* ssrc,
int* payload_type) const {
rtp_sender_.RTXStatus(mode, ssrc, payload_type);
return 0;
}
int32_t ModuleRtpRtcpImpl::SetRTXReceiveStatus(
const bool enable,
const uint32_t ssrc) {
int32_t ModuleRtpRtcpImpl::SetRTXReceiveStatus(bool enable,
uint32_t ssrc) {
rtp_receiver_->SetRTXStatus(enable, ssrc);
return 0;
}
int32_t ModuleRtpRtcpImpl::RTXReceiveStatus(bool* enable,
uint32_t* ssrc) const {
rtp_receiver_->RTXStatus(enable, ssrc);
int32_t ModuleRtpRtcpImpl::RTXReceiveStatus(bool* enable, uint32_t* ssrc,
int* payload_type) const {
rtp_receiver_->RTXStatus(enable, ssrc, payload_type);
return 0;
}
void ModuleRtpRtcpImpl::SetRtxSendPayloadType(int payload_type) {
rtp_sender_.SetRtxPayloadType(payload_type);
}
void ModuleRtpRtcpImpl::SetRtxReceivePayloadType(int payload_type) {
rtp_receiver_->SetRtxPayloadType(payload_type);
}
// Called by the network module when we receive a packet.
int32_t ModuleRtpRtcpImpl::IncomingPacket(
const uint8_t* incoming_packet,

View File

@ -103,8 +103,10 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
virtual int32_t SetRTXReceiveStatus(const bool enable,
const uint32_t ssrc);
virtual int32_t RTXReceiveStatus(bool* enable,
uint32_t* ssrc) const;
virtual int32_t RTXReceiveStatus(bool* enable, uint32_t* ssrc,
int* payloadType) const;
virtual void SetRtxReceivePayloadType(int payload_type);
// Called by the network module when we receive a packet.
virtual int32_t IncomingPacket(const uint8_t* incoming_packet,
@ -161,7 +163,11 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
const bool set_ssrc,
const uint32_t ssrc);
virtual int32_t RTXSendStatus(RtxMode* mode, uint32_t* ssrc) const;
virtual int32_t RTXSendStatus(RtxMode* mode, uint32_t* ssrc,
int* payloadType) const;
virtual void SetRtxSendPayloadType(int payload_type);
// Sends kRtcpByeCode when going from true to false.
virtual int32_t SetSendingStatus(const bool sending);

View File

@ -58,7 +58,7 @@ RTPSender::RTPSender(const int32_t id, const bool audio, Clock *clock,
start_time_stamp_(0), ssrc_db_(*SSRCDatabase::GetSSRCDatabase()),
remote_ssrc_(0), sequence_number_forced_(false), ssrc_forced_(false),
time_stamp_(0), csrcs_(0), csrc_(), include_csrcs_(true),
rtx_(kRtxOff) {
rtx_(kRtxOff), payload_type_rtx_(-1) {
memset(nack_byte_count_times_, 0, sizeof(nack_byte_count_times_));
memset(nack_byte_count_, 0, sizeof(nack_byte_count_));
memset(csrc_, 0, sizeof(csrc_));
@ -255,8 +255,7 @@ uint16_t RTPSender::MaxPayloadLength() const {
uint16_t RTPSender::PacketOverHead() const { return packet_over_head_; }
void RTPSender::SetRTXStatus(const RtxMode mode, const bool set_ssrc,
const uint32_t ssrc) {
void RTPSender::SetRTXStatus(RtxMode mode, bool set_ssrc, uint32_t ssrc) {
CriticalSectionScoped cs(send_critsect_);
rtx_ = mode;
if (rtx_ != kRtxOff) {
@ -268,10 +267,18 @@ void RTPSender::SetRTXStatus(const RtxMode mode, const bool set_ssrc,
}
}
void RTPSender::RTXStatus(RtxMode* mode, uint32_t *SSRC) const {
void RTPSender::RTXStatus(RtxMode* mode, uint32_t* ssrc,
int* payload_type) const {
CriticalSectionScoped cs(send_critsect_);
*mode = rtx_;
*SSRC = ssrc_rtx_;
*ssrc = ssrc_rtx_;
*payload_type = payload_type_rtx_;
}
void RTPSender::SetRtxPayloadType(int payload_type) {
CriticalSectionScoped cs(send_critsect_);
payload_type_rtx_ = payload_type;
}
int32_t RTPSender::CheckPayloadType(const int8_t payload_type,
@ -1222,6 +1229,13 @@ void RTPSender::BuildRtxPacket(uint8_t* buffer, uint16_t* length,
// Add original RTP header.
memcpy(data_buffer_rtx, buffer, rtp_header.header.headerLength);
// Replace payload type, if a specific type is set for RTX.
if (payload_type_rtx_ != -1) {
data_buffer_rtx[1] = static_cast<uint8_t>(payload_type_rtx_);
if (rtp_header.header.markerBit)
data_buffer_rtx[1] |= kRtpMarkerBitMask;
}
// Replace sequence number.
uint8_t *ptr = data_buffer_rtx + 2;
ModuleRTPUtility::AssignUWord16ToBuffer(ptr, sequence_number_rtx_++);

View File

@ -174,10 +174,11 @@ class RTPSender : public Bitrate, public RTPSenderInterface {
bool ProcessNACKBitRate(const uint32_t now);
// RTX.
void SetRTXStatus(const RtxMode mode, const bool set_ssrc,
const uint32_t SSRC);
void SetRTXStatus(RtxMode mode, bool set_ssrc, uint32_t ssrc);
void RTXStatus(RtxMode* mode, uint32_t *SSRC) const;
void RTXStatus(RtxMode* mode, uint32_t* ssrc, int* payload_type) const;
void SetRtxPayloadType(int payloadType);
// Functions wrapping RTPSenderInterface.
virtual int32_t BuildRTPheader(
@ -310,6 +311,7 @@ class RTPSender : public Bitrate, public RTPSenderInterface {
bool include_csrcs_;
RtxMode rtx_;
uint32_t ssrc_rtx_;
int payload_type_rtx_;
};
} // namespace webrtc

View File

@ -111,24 +111,40 @@ TEST_F(RtpRtcpAPITest, RTCP) {
TEST_F(RtpRtcpAPITest, RTXSender) {
unsigned int ssrc = 0;
RtxMode rtx_mode = kRtxOff;
const int kRtxPayloadType = 119;
int payload_type = -1;
EXPECT_EQ(0, module->SetRTXSendStatus(kRtxRetransmitted, true, 1));
EXPECT_EQ(0, module->RTXSendStatus(&rtx_mode, &ssrc));
module->SetRtxSendPayloadType(kRtxPayloadType);
EXPECT_EQ(0, module->RTXSendStatus(&rtx_mode, &ssrc, &payload_type));
EXPECT_EQ(kRtxRetransmitted, rtx_mode);
EXPECT_EQ(1u, ssrc);
EXPECT_EQ(kRtxPayloadType, payload_type);
rtx_mode = kRtxOff;
EXPECT_EQ(0, module->SetRTXSendStatus(kRtxOff, true, 0));
EXPECT_EQ(0, module->RTXSendStatus(&rtx_mode, &ssrc));
payload_type = -1;
module->SetRtxSendPayloadType(kRtxPayloadType);
EXPECT_EQ(0, module->RTXSendStatus(&rtx_mode, &ssrc, &payload_type));
EXPECT_EQ(kRtxOff, rtx_mode);
EXPECT_EQ(kRtxPayloadType ,payload_type);
EXPECT_EQ(0, module->SetRTXSendStatus(kRtxRetransmitted, false, 1));
EXPECT_EQ(0, module->RTXSendStatus(&rtx_mode, &ssrc, &payload_type));
EXPECT_EQ(kRtxRetransmitted, rtx_mode);
EXPECT_EQ(kRtxPayloadType ,payload_type);
}
TEST_F(RtpRtcpAPITest, RTXReceiver) {
bool enable = false;
unsigned int ssrc = 0;
const int kRtxPayloadType = 119;
int payload_type = -1;
EXPECT_EQ(0, module->SetRTXReceiveStatus(true, 1));
EXPECT_EQ(0, module->RTXReceiveStatus(&enable, &ssrc));
module->SetRtxReceivePayloadType(kRtxPayloadType);
EXPECT_EQ(0, module->RTXReceiveStatus(&enable, &ssrc, &payload_type));
EXPECT_TRUE(enable);
EXPECT_EQ(1u, ssrc);
EXPECT_EQ(kRtxPayloadType ,payload_type);
EXPECT_EQ(0, module->SetRTXReceiveStatus(false, 0));
EXPECT_EQ(0, module->RTXReceiveStatus(&enable, &ssrc));
EXPECT_EQ(0, module->RTXReceiveStatus(&enable, &ssrc, &payload_type));
EXPECT_FALSE(enable);
EXPECT_EQ(kRtxPayloadType ,payload_type);
}

View File

@ -133,6 +133,14 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP {
virtual int GetRemoteCSRCs(const int video_channel,
unsigned int CSRCs[kRtpCsrcSize]) const = 0;
// This sets a specific payload type for the RTX stream. Note that this
// doesn't enable RTX, SetLocalSSRC must still be called to enable RTX.
virtual int SetRtxSendPayloadType(const int video_channel,
const uint8_t payload_type) = 0;
virtual int SetRtxReceivePayloadType(const int video_channel,
const uint8_t payload_type) = 0;
// This function enables manual initialization of the sequence number. The
// start sequence number is normally a random number.
virtual int SetStartSequenceNumber(const int video_channel,

View File

@ -973,8 +973,31 @@ int32_t ViEChannel::GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize]) {
return 0;
}
int32_t ViEChannel::SetStartSequenceNumber(
uint16_t sequence_number) {
int ViEChannel::SetRtxSendPayloadType(int payload_type) {
if (rtp_rtcp_->Sending()) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: already sending", __FUNCTION__);
return -1;
}
rtp_rtcp_->SetRtxSendPayloadType(payload_type);
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
it != simulcast_rtp_rtcp_.end(); it++) {
(*it)->SetRtxSendPayloadType(payload_type);
}
return 0;
}
void ViEChannel::SetRtxReceivePayloadType(int payload_type) {
rtp_rtcp_->SetRtxReceivePayloadType(payload_type);
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
it != simulcast_rtp_rtcp_.end(); it++) {
(*it)->SetRtxReceivePayloadType(payload_type);
}
}
int32_t ViEChannel::SetStartSequenceNumber(uint16_t sequence_number) {
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
__FUNCTION__);

View File

@ -139,6 +139,9 @@ class ViEChannel
// Gets the CSRC for the incoming stream.
int32_t GetRemoteCSRC(uint32_t CSRCs[kRtpCsrcSize]);
int SetRtxSendPayloadType(int payload_type);
void SetRtxReceivePayloadType(int payload_type);
// Sets the starting sequence number, must be called before StartSend.
int32_t SetStartSequenceNumber(uint16_t sequence_number);

View File

@ -233,6 +233,44 @@ int ViERTP_RTCPImpl::GetRemoteCSRCs(const int video_channel,
return 0;
}
int ViERTP_RTCPImpl::SetRtxSendPayloadType(const int video_channel,
const uint8_t payload_type) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (!vie_channel->SetRtxSendPayloadType(payload_type)) {
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetRtxReceivePayloadType(const int video_channel,
const uint8_t payload_type) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d)", __FUNCTION__, video_channel);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
vie_channel->SetRtxReceivePayloadType(payload_type);
return 0;
}
int ViERTP_RTCPImpl::SetStartSequenceNumber(const int video_channel,
uint16_t sequence_number) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,

View File

@ -39,6 +39,10 @@ class ViERTP_RTCPImpl
unsigned int& SSRC) const; // NOLINT
virtual int GetRemoteCSRCs(const int video_channel,
unsigned int CSRCs[kRtpCsrcSize]) const;
virtual int SetRtxSendPayloadType(const int video_channel,
const uint8_t payload_type);
virtual int SetRtxReceivePayloadType(const int video_channel,
const uint8_t payload_type);
virtual int SetStartSequenceNumber(const int video_channel,
uint16_t sequence_number);
virtual int SetRTCPStatus(const int video_channel,