Breaking out RTP header parsing from the RTP module.

This is the first step in order to move bandwidth estimation closer to the network. The goal is to have RTP header parsing and bandwidth estimation before voice and video engine, and have a joint estimate for audio and video.

Moving bandwidth estimation before the RTP module is also required for RTX.

TEST=vie_auto_test, voe_auto_test, trybots.
BUG=1811
R=andresp@webrtc.org, henrika@webrtc.org, mflodman@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4129 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2013-05-29 12:12:51 +00:00
parent 1ecee9a15a
commit a5cb98cbbd
37 changed files with 515 additions and 380 deletions

View File

@ -27,25 +27,26 @@
namespace webrtc { namespace webrtc {
struct RTPHeader
{
bool markerBit;
uint8_t payloadType;
uint16_t sequenceNumber;
uint32_t timestamp;
uint32_t ssrc;
uint8_t numCSRCs;
uint32_t arrOfCSRCs[kRtpCsrcSize];
uint8_t paddingLength;
uint16_t headerLength;
};
struct RTPHeaderExtension struct RTPHeaderExtension
{ {
int32_t transmissionTimeOffset; int32_t transmissionTimeOffset;
uint32_t absoluteSendTime; uint32_t absoluteSendTime;
}; };
struct RTPHeader
{
bool markerBit;
uint8_t payloadType;
uint16_t sequenceNumber;
uint32_t timestamp;
uint32_t ssrc;
uint8_t numCSRCs;
uint32_t arrOfCSRCs[kRtpCsrcSize];
uint8_t paddingLength;
uint16_t headerLength;
RTPHeaderExtension extension;
};
struct RTPAudioHeader struct RTPAudioHeader
{ {
uint8_t numEnergy; // number of valid entries in arrOfEnergy uint8_t numEnergy; // number of valid entries in arrOfEnergy
@ -122,7 +123,6 @@ struct WebRtcRTPHeader
RTPHeader header; RTPHeader header;
FrameType frameType; FrameType frameType;
RTPTypeHeader type; RTPTypeHeader type;
RTPHeaderExtension extension;
}; };
class RTPFragmentationHeader class RTPFragmentationHeader

View File

@ -142,7 +142,7 @@ void RemoteBitrateEstimatorMultiStream::IncomingPacket(
const WebRtcRTPHeader& header) { const WebRtcRTPHeader& header) {
uint32_t ssrc = header.header.ssrc; uint32_t ssrc = header.header.ssrc;
uint32_t rtp_timestamp = header.header.timestamp + uint32_t rtp_timestamp = header.header.timestamp +
header.extension.transmissionTimeOffset; header.header.extension.transmissionTimeOffset;
CriticalSectionScoped cs(crit_sect_.get()); CriticalSectionScoped cs(crit_sect_.get());
incoming_bitrate_.Update(payload_size, arrival_time_ms); incoming_bitrate_.Update(payload_size, arrival_time_ms);
// Add this stream to the map of streams if it doesn't already exist. // Add this stream to the map of streams if it doesn't already exist.

View File

@ -89,7 +89,7 @@ void RemoteBitrateEstimatorSingleStream::IncomingPacket(
const WebRtcRTPHeader& header) { const WebRtcRTPHeader& header) {
uint32_t ssrc = header.header.ssrc; uint32_t ssrc = header.header.ssrc;
uint32_t rtp_timestamp = header.header.timestamp + uint32_t rtp_timestamp = header.header.timestamp +
header.extension.transmissionTimeOffset; header.header.extension.transmissionTimeOffset;
CriticalSectionScoped cs(crit_sect_.get()); CriticalSectionScoped cs(crit_sect_.get());
SsrcOveruseDetectorMap::iterator it = overuse_detectors_.find(ssrc); SsrcOveruseDetectorMap::iterator it = overuse_detectors_.find(ssrc);
if (it == overuse_detectors_.end()) { if (it == overuse_detectors_.end()) {

View File

@ -227,7 +227,7 @@ void RemoteBitrateEstimatorTest::IncomingPacket(uint32_t ssrc,
memset(&header, 0, sizeof(header)); memset(&header, 0, sizeof(header));
header.header.ssrc = ssrc; header.header.ssrc = ssrc;
header.header.timestamp = rtp_timestamp; header.header.timestamp = rtp_timestamp;
header.extension.absoluteSendTime = absolute_send_time; header.header.extension.absoluteSendTime = absolute_send_time;
bitrate_estimator_->IncomingPacket(arrival_time, payload_size, header); bitrate_estimator_->IncomingPacket(arrival_time, payload_size, header);
} }

View File

@ -0,0 +1,43 @@
/*
* 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_RTP_HEADER_PARSER_H_
#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_HEADER_PARSER_H_
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
#include "webrtc/typedefs.h"
namespace webrtc {
struct RTPHeader;
class RtpHeaderParser {
public:
static RtpHeaderParser* Create();
virtual ~RtpHeaderParser() {}
// Returns true if the packet is an RTCP packet, false otherwise.
static bool IsRtcp(const uint8_t* packet, int length);
// Parses the packet and stores the parsed packet in |header|. Returns true on
// success, false otherwise.
// This method is thread-safe in the sense that it can parse multiple packets
// at once.
virtual bool Parse(const uint8_t* packet, int length,
RTPHeader* header) const = 0;
// Registers an RTP header extension and binds it to |id|.
virtual bool RegisterRtpHeaderExtension(RTPExtensionType type,
uint8_t id) = 0;
// De-registers an RTP header extension.
virtual bool DeregisterRtpHeaderExtension(RTPExtensionType type) = 0;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RTP_HEADER_PARSER_H_

View File

@ -163,18 +163,6 @@ class RtpRtcp : public Module {
virtual int32_t DeRegisterReceivePayload( virtual int32_t DeRegisterReceivePayload(
const int8_t payloadType) = 0; const int8_t payloadType) = 0;
/*
* (De)register RTP header extension type and id.
*
* return -1 on failure else 0
*/
virtual int32_t RegisterReceiveRtpHeaderExtension(
const RTPExtensionType type,
const uint8_t id) = 0;
virtual int32_t DeregisterReceiveRtpHeaderExtension(
const RTPExtensionType type) = 0;
/* /*
* Get last received remote timestamp * Get last received remote timestamp
*/ */
@ -250,11 +238,16 @@ class RtpRtcp : public Module {
* *
* incomingPacket - incoming packet buffer * incomingPacket - incoming packet buffer
* packetLength - length of incoming buffer * packetLength - length of incoming buffer
* parsed_rtp_header - the parsed RTP header
* *
* return -1 on failure else 0 * return -1 on failure else 0
*/ */
virtual int32_t IncomingPacket(const uint8_t* incomingPacket, virtual int32_t IncomingRtpPacket(const uint8_t* incomingPacket,
const uint16_t packetLength) = 0; const uint16_t packetLength,
const RTPHeader& parsed_rtp_header) = 0;
virtual int32_t IncomingRtcpPacket(const uint8_t* incoming_packet,
uint16_t incoming_packet_length) = 0;
/************************************************************************** /**************************************************************************
* *

View File

@ -57,10 +57,6 @@ class MockRtpRtcp : public RtpRtcp {
int32_t(const VideoCodec& videoCodec, int8_t* plType)); int32_t(const VideoCodec& videoCodec, int8_t* plType));
MOCK_METHOD1(DeRegisterReceivePayload, MOCK_METHOD1(DeRegisterReceivePayload,
int32_t(const int8_t payloadType)); int32_t(const int8_t payloadType));
MOCK_METHOD2(RegisterReceiveRtpHeaderExtension,
int32_t(const RTPExtensionType type, const uint8_t id));
MOCK_METHOD1(DeregisterReceiveRtpHeaderExtension,
int32_t(const RTPExtensionType type));
MOCK_CONST_METHOD0(RemoteTimestamp, MOCK_CONST_METHOD0(RemoteTimestamp,
uint32_t()); uint32_t());
MOCK_CONST_METHOD0(LocalTimeOfRemoteTimeStamp, MOCK_CONST_METHOD0(LocalTimeOfRemoteTimeStamp,
@ -81,8 +77,11 @@ class MockRtpRtcp : public RtpRtcp {
int32_t(bool* enable, uint32_t* ssrc, int* payload_type)); int32_t(bool* enable, uint32_t* ssrc, int* payload_type));
MOCK_METHOD1(SetRtxReceivePayloadType, MOCK_METHOD1(SetRtxReceivePayloadType,
void(int)); void(int));
MOCK_METHOD2(IncomingPacket, MOCK_METHOD3(IncomingRtpPacket,
int32_t(const uint8_t* incomingPacket, const uint16_t packetLength)); int32_t(const uint8_t* incomingPacket, const uint16_t packetLength,
const webrtc::RTPHeader& header));
MOCK_METHOD2(IncomingRtcpPacket,
int32_t(const uint8_t* incomingPacket, uint16_t packetLength));
MOCK_METHOD4(IncomingAudioNTP, MOCK_METHOD4(IncomingAudioNTP,
int32_t(const uint32_t audioReceivedNTPsecs, int32_t(const uint32_t audioReceivedNTPsecs,
const uint32_t audioReceivedNTPfrac, const uint32_t audioReceivedNTPfrac,

View File

@ -15,8 +15,10 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/common_types.h" #include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
using namespace webrtc; using namespace webrtc;
@ -87,14 +89,20 @@ class RtxLoopBackTransport : public webrtc::Transport {
count_ < consecutive_drop_end_) { count_ < consecutive_drop_end_) {
return len; return len;
} }
if (module_->IncomingPacket((const uint8_t*)data, len) == 0) { RTPHeader header;
return len; scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
if (!parser->Parse(static_cast<const uint8_t*>(data), len, &header)) {
return -1;
} }
return -1; if (module_->IncomingRtpPacket(static_cast<const uint8_t*>(data), len,
header) < 0) {
return -1;
}
return len;
} }
virtual int SendRTCPPacket(int channel, const void *data, int len) { virtual int SendRTCPPacket(int channel, const void *data, int len) {
if (module_->IncomingPacket((const uint8_t*)data, len) == 0) { if (module_->IncomingRtcpPacket((const uint8_t*)data, len) == 0) {
return len; return len;
} }
return -1; return -1;

View File

@ -252,7 +252,7 @@ int ReceiverFEC::ParseAndReceivePacket(
WebRtcRTPHeader header; WebRtcRTPHeader header;
memset(&header, 0, sizeof(header)); memset(&header, 0, sizeof(header));
ModuleRTPUtility::RTPHeaderParser parser(packet->data, packet->length); ModuleRTPUtility::RTPHeaderParser parser(packet->data, packet->length);
if (!parser.Parse(header)) { if (!parser.Parse(header.header)) {
return -1; return -1;
} }
if (owner_->ReceiveRecoveredPacketCallback( if (owner_->ReceiveRecoveredPacketCallback(

View File

@ -16,13 +16,14 @@
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "common_types.h" #include "webrtc/common_types.h"
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h" #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "modules/rtp_rtcp/source/rtcp_receiver.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "modules/rtp_rtcp/source/rtcp_sender.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
#include "modules/rtp_rtcp/source/rtp_utility.h" #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h" #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
namespace webrtc { namespace webrtc {
@ -353,7 +354,11 @@ TEST_F(RtcpSenderTest, TestCompound) {
EXPECT_EQ(0, rtp_rtcp_impl_->RegisterReceivePayload(codec_inst)); EXPECT_EQ(0, rtp_rtcp_impl_->RegisterReceivePayload(codec_inst));
// Make sure RTP packet has been received. // Make sure RTP packet has been received.
EXPECT_EQ(0, rtp_rtcp_impl_->IncomingPacket(packet_, packet_length)); scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
RTPHeader header;
EXPECT_TRUE(parser->Parse(packet_, packet_length, &header));
EXPECT_EQ(0, rtp_rtcp_impl_->IncomingRtpPacket(packet_, packet_length,
header));
EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true)); EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound)); EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc {
class RtpHeaderParserImpl : public RtpHeaderParser {
public:
RtpHeaderParserImpl();
virtual ~RtpHeaderParserImpl() {}
virtual bool Parse(const uint8_t* packet, int length,
RTPHeader* header) const;
virtual bool RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
virtual bool DeregisterRtpHeaderExtension(RTPExtensionType type);
private:
scoped_ptr<CriticalSectionWrapper> critical_section_;
RtpHeaderExtensionMap rtp_header_extension_map_;
};
RtpHeaderParser* RtpHeaderParser::Create() {
return new RtpHeaderParserImpl;
}
RtpHeaderParserImpl::RtpHeaderParserImpl()
: critical_section_(CriticalSectionWrapper::CreateCriticalSection()) {}
bool RtpHeaderParser::IsRtcp(const uint8_t* packet, int length) {
ModuleRTPUtility::RTPHeaderParser rtp_parser(packet, length);
return rtp_parser.RTCP();
}
bool RtpHeaderParserImpl::Parse(const uint8_t* packet, int length,
RTPHeader* header) const {
ModuleRTPUtility::RTPHeaderParser rtp_parser(packet, length);
memset(header, 0, sizeof(*header));
RtpHeaderExtensionMap map;
{
CriticalSectionScoped cs(critical_section_.get());
rtp_header_extension_map_.GetCopy(&map);
}
const bool valid_rtpheader = rtp_parser.Parse(*header, &map);
if (!valid_rtpheader) {
WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, -1,
"IncomingPacket invalid RTP header");
return false;
}
return true;
}
bool RtpHeaderParserImpl::RegisterRtpHeaderExtension(RTPExtensionType type,
uint8_t id) {
CriticalSectionScoped cs(critical_section_.get());
return rtp_header_extension_map_.Register(type, id) == 0;
}
bool RtpHeaderParserImpl::DeregisterRtpHeaderExtension(RTPExtensionType type) {
CriticalSectionScoped cs(critical_section_.get());
return rtp_header_extension_map_.Deregister(type) == 0;
}
} // namespace webrtc

View File

@ -54,7 +54,6 @@ RTPReceiver::RTPReceiver(const int32_t id,
packet_timeout_ms_(0), packet_timeout_ms_(0),
rtp_header_extension_map_(),
ssrc_(0), ssrc_(0),
num_csrcs_(0), num_csrcs_(0),
current_remote_csrc_(), current_remote_csrc_(),
@ -251,24 +250,6 @@ int32_t RTPReceiver::ReceivePayloadType(
payload_name, frequency, channels, rate, payload_type); payload_name, frequency, channels, rate, payload_type);
} }
int32_t RTPReceiver::RegisterRtpHeaderExtension(
const RTPExtensionType type,
const uint8_t id) {
CriticalSectionScoped cs(critical_section_rtp_receiver_);
return rtp_header_extension_map_.Register(type, id);
}
int32_t RTPReceiver::DeregisterRtpHeaderExtension(
const RTPExtensionType type) {
CriticalSectionScoped cs(critical_section_rtp_receiver_);
return rtp_header_extension_map_.Deregister(type);
}
void RTPReceiver::GetHeaderExtensionMapCopy(RtpHeaderExtensionMap* map) const {
CriticalSectionScoped cs(critical_section_rtp_receiver_);
rtp_header_extension_map_.GetCopy(map);
}
NACKMethod RTPReceiver::NACK() const { NACKMethod RTPReceiver::NACK() const {
CriticalSectionScoped lock(critical_section_rtp_receiver_); CriticalSectionScoped lock(critical_section_rtp_receiver_);
return nack_method_; return nack_method_;
@ -341,32 +322,32 @@ int32_t RTPReceiver::Energy(
} }
int32_t RTPReceiver::IncomingRTPPacket( int32_t RTPReceiver::IncomingRTPPacket(
WebRtcRTPHeader* rtp_header, RTPHeader* rtp_header,
const uint8_t* packet, const uint8_t* packet,
const uint16_t packet_length) { const uint16_t packet_length) {
TRACE_EVENT0("webrtc_rtp", "RTPRecv::Packet"); TRACE_EVENT0("webrtc_rtp", "RTPRecv::Packet");
// The rtp_header argument contains the parsed RTP header. // The rtp_header argument contains the parsed RTP header.
int length = packet_length - rtp_header->header.paddingLength; int length = packet_length - rtp_header->paddingLength;
// Sanity check. // Sanity check.
if ((length - rtp_header->header.headerLength) < 0) { if ((length - rtp_header->headerLength) < 0) {
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_, WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
"%s invalid argument", "%s invalid argument",
__FUNCTION__); __FUNCTION__);
return -1; return -1;
} }
if (rtx_) { if (rtx_) {
if (ssrc_rtx_ == rtp_header->header.ssrc) { if (ssrc_rtx_ == rtp_header->ssrc) {
// Sanity check, RTX packets has 2 extra header bytes. // Sanity check, RTX packets has 2 extra header bytes.
if (rtp_header->header.headerLength + kRtxHeaderSize > packet_length) { if (rtp_header->headerLength + kRtxHeaderSize > packet_length) {
return -1; return -1;
} }
// If a specific RTX payload type is negotiated, set back to the media // If a specific RTX payload type is negotiated, set back to the media
// payload type and treat it like a media packet from here. // payload type and treat it like a media packet from here.
if (payload_type_rtx_ != -1) { if (payload_type_rtx_ != -1) {
if (payload_type_rtx_ == rtp_header->header.payloadType && if (payload_type_rtx_ == rtp_header->payloadType &&
rtp_payload_registry_->last_received_media_payload_type() != -1) { rtp_payload_registry_->last_received_media_payload_type() != -1) {
rtp_header->header.payloadType = rtp_header->payloadType =
rtp_payload_registry_->last_received_media_payload_type(); rtp_payload_registry_->last_received_media_payload_type();
} else { } else {
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_, WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
@ -374,16 +355,16 @@ int32_t RTPReceiver::IncomingRTPPacket(
return -1; return -1;
} }
} }
rtp_header->header.ssrc = ssrc_; rtp_header->ssrc = ssrc_;
rtp_header->header.sequenceNumber = rtp_header->sequenceNumber =
(packet[rtp_header->header.headerLength] << 8) + (packet[rtp_header->headerLength] << 8) +
packet[1 + rtp_header->header.headerLength]; packet[1 + rtp_header->headerLength];
// Count the RTX header as part of the RTP header. // Count the RTX header as part of the RTP
rtp_header->header.headerLength += 2; rtp_header->headerLength += 2;
} }
} }
if (use_ssrc_filter_) { if (use_ssrc_filter_) {
if (rtp_header->header.ssrc != ssrc_filter_) { if (rtp_header->ssrc != ssrc_filter_) {
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_, WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
"%s drop packet due to SSRC filter", "%s drop packet due to SSRC filter",
__FUNCTION__); __FUNCTION__);
@ -392,7 +373,7 @@ int32_t RTPReceiver::IncomingRTPPacket(
} }
if (last_receive_time_ == 0) { if (last_receive_time_ == 0) {
// Trigger only once. // Trigger only once.
if (length - rtp_header->header.headerLength == 0) { if (length - rtp_header->headerLength == 0) {
// Keep-alive packet. // Keep-alive packet.
cb_rtp_feedback_->OnReceivedPacket(id_, kPacketKeepAlive); cb_rtp_feedback_->OnReceivedPacket(id_, kPacketKeepAlive);
} else { } else {
@ -401,7 +382,7 @@ int32_t RTPReceiver::IncomingRTPPacket(
} }
int8_t first_payload_byte = 0; int8_t first_payload_byte = 0;
if (length > 0) { if (length > 0) {
first_payload_byte = packet[rtp_header->header.headerLength]; first_payload_byte = packet[rtp_header->headerLength];
} }
// Trigger our callbacks. // Trigger our callbacks.
CheckSSRCChanged(rtp_header); CheckSSRCChanged(rtp_header);
@ -413,7 +394,7 @@ int32_t RTPReceiver::IncomingRTPPacket(
first_payload_byte, first_payload_byte,
is_red, is_red,
&specific_payload) == -1) { &specific_payload) == -1) {
if (length - rtp_header->header.headerLength == 0) { if (length - rtp_header->headerLength == 0) {
// OK, keep-alive packet. // OK, keep-alive packet.
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_, WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_,
"%s received keepalive", "%s received keepalive",
@ -425,18 +406,21 @@ int32_t RTPReceiver::IncomingRTPPacket(
__FUNCTION__); __FUNCTION__);
return -1; return -1;
} }
CheckCSRC(rtp_header); WebRtcRTPHeader webrtc_rtp_header;
memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header));
webrtc_rtp_header.header = *rtp_header;
CheckCSRC(&webrtc_rtp_header);
uint16_t payload_data_length = uint16_t payload_data_length =
ModuleRTPUtility::GetPayloadDataLength(rtp_header, packet_length); ModuleRTPUtility::GetPayloadDataLength(*rtp_header, packet_length);
bool is_first_packet_in_frame = bool is_first_packet_in_frame =
SequenceNumber() + 1 == rtp_header->header.sequenceNumber && SequenceNumber() + 1 == rtp_header->sequenceNumber &&
TimeStamp() != rtp_header->header.timestamp; TimeStamp() != rtp_header->timestamp;
bool is_first_packet = is_first_packet_in_frame || HaveNotReceivedPackets(); bool is_first_packet = is_first_packet_in_frame || HaveNotReceivedPackets();
int32_t ret_val = rtp_media_receiver_->ParseRtpPacket( int32_t ret_val = rtp_media_receiver_->ParseRtpPacket(
rtp_header, specific_payload, is_red, packet, packet_length, &webrtc_rtp_header, specific_payload, is_red, packet, packet_length,
clock_->TimeInMilliseconds(), is_first_packet); clock_->TimeInMilliseconds(), is_first_packet);
if (ret_val < 0) { if (ret_val < 0) {
@ -447,8 +431,8 @@ int32_t RTPReceiver::IncomingRTPPacket(
// This compares to received_seq_max_. We store the last received after we // This compares to received_seq_max_. We store the last received after we
// have done the callback. // have done the callback.
bool old_packet = RetransmitOfOldPacket(rtp_header->header.sequenceNumber, bool old_packet = RetransmitOfOldPacket(rtp_header->sequenceNumber,
rtp_header->header.timestamp); rtp_header->timestamp);
// This updates received_seq_max_ and other members. // This updates received_seq_max_ and other members.
UpdateStatistics(rtp_header, payload_data_length, old_packet); UpdateStatistics(rtp_header, payload_data_length, old_packet);
@ -459,11 +443,11 @@ int32_t RTPReceiver::IncomingRTPPacket(
last_received_payload_length_ = payload_data_length; last_received_payload_length_ = payload_data_length;
if (!old_packet) { if (!old_packet) {
if (last_received_timestamp_ != rtp_header->header.timestamp) { if (last_received_timestamp_ != rtp_header->timestamp) {
last_received_timestamp_ = rtp_header->header.timestamp; last_received_timestamp_ = rtp_header->timestamp;
last_received_frame_time_ms_ = clock_->TimeInMilliseconds(); last_received_frame_time_ms_ = clock_->TimeInMilliseconds();
} }
last_received_sequence_number_ = rtp_header->header.sequenceNumber; last_received_sequence_number_ = rtp_header->sequenceNumber;
last_received_transmission_time_offset_ = last_received_transmission_time_offset_ =
rtp_header->extension.transmissionTimeOffset; rtp_header->extension.transmissionTimeOffset;
} }
@ -472,7 +456,7 @@ int32_t RTPReceiver::IncomingRTPPacket(
// Implementation note: we expect to have the critical_section_rtp_receiver_ // Implementation note: we expect to have the critical_section_rtp_receiver_
// critsect when we call this. // critsect when we call this.
void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header, void RTPReceiver::UpdateStatistics(const RTPHeader* rtp_header,
const uint16_t bytes, const uint16_t bytes,
const bool old_packet) { const bool old_packet) {
uint32_t frequency_hz = rtp_media_receiver_->GetFrequencyHz(); uint32_t frequency_hz = rtp_media_receiver_->GetFrequencyHz();
@ -483,8 +467,8 @@ void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
if (received_seq_max_ == 0 && received_seq_wraps_ == 0) { if (received_seq_max_ == 0 && received_seq_wraps_ == 0) {
// This is the first received report. // This is the first received report.
received_seq_first_ = rtp_header->header.sequenceNumber; received_seq_first_ = rtp_header->sequenceNumber;
received_seq_max_ = rtp_header->header.sequenceNumber; received_seq_max_ = rtp_header->sequenceNumber;
received_inorder_packet_count_ = 1; received_inorder_packet_count_ = 1;
local_time_last_received_timestamp_ = local_time_last_received_timestamp_ =
GetCurrentRTP(clock_, frequency_hz); // Time in samples. GetCurrentRTP(clock_, frequency_hz); // Time in samples.
@ -492,26 +476,26 @@ void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
} }
// Count only the new packets received. // Count only the new packets received.
if (InOrderPacket(rtp_header->header.sequenceNumber)) { if (InOrderPacket(rtp_header->sequenceNumber)) {
const uint32_t RTPtime = const uint32_t RTPtime =
GetCurrentRTP(clock_, frequency_hz); // Time in samples. GetCurrentRTP(clock_, frequency_hz); // Time in samples.
received_inorder_packet_count_++; received_inorder_packet_count_++;
// Wrong if we use RetransmitOfOldPacket. // Wrong if we use RetransmitOfOldPacket.
int32_t seq_diff = int32_t seq_diff =
rtp_header->header.sequenceNumber - received_seq_max_; rtp_header->sequenceNumber - received_seq_max_;
if (seq_diff < 0) { if (seq_diff < 0) {
// Wrap around detected. // Wrap around detected.
received_seq_wraps_++; received_seq_wraps_++;
} }
// new max // new max
received_seq_max_ = rtp_header->header.sequenceNumber; received_seq_max_ = rtp_header->sequenceNumber;
if (rtp_header->header.timestamp != last_received_timestamp_ && if (rtp_header->timestamp != last_received_timestamp_ &&
received_inorder_packet_count_ > 1) { received_inorder_packet_count_ > 1) {
int32_t time_diff_samples = int32_t time_diff_samples =
(RTPtime - local_time_last_received_timestamp_) - (RTPtime - local_time_last_received_timestamp_) -
(rtp_header->header.timestamp - last_received_timestamp_); (rtp_header->timestamp - last_received_timestamp_);
time_diff_samples = abs(time_diff_samples); time_diff_samples = abs(time_diff_samples);
@ -528,7 +512,7 @@ void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
// Actual network jitter, excluding the source-introduced jitter. // Actual network jitter, excluding the source-introduced jitter.
int32_t time_diff_samples_ext = int32_t time_diff_samples_ext =
(RTPtime - local_time_last_received_timestamp_) - (RTPtime - local_time_last_received_timestamp_) -
((rtp_header->header.timestamp + ((rtp_header->timestamp +
rtp_header->extension.transmissionTimeOffset) - rtp_header->extension.transmissionTimeOffset) -
(last_received_timestamp_ + (last_received_timestamp_ +
last_received_transmission_time_offset_)); last_received_transmission_time_offset_));
@ -552,7 +536,7 @@ void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
} }
uint16_t packet_oh = uint16_t packet_oh =
rtp_header->header.headerLength + rtp_header->header.paddingLength; rtp_header->headerLength + rtp_header->paddingLength;
// Our measured overhead. Filter from RFC 5104 4.2.1.2: // Our measured overhead. Filter from RFC 5104 4.2.1.2:
// avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH, // avg_OH (new) = 15/16*avg_OH (old) + 1/16*pckt_OH,
@ -676,7 +660,7 @@ int32_t RTPReceiver::SetSSRCFilter(
} }
// Implementation note: must not hold critsect when called. // Implementation note: must not hold critsect when called.
void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtp_header) { void RTPReceiver::CheckSSRCChanged(const RTPHeader* rtp_header) {
bool new_ssrc = false; bool new_ssrc = false;
bool re_initialize_decoder = false; bool re_initialize_decoder = false;
char payload_name[RTP_PAYLOAD_NAME_SIZE]; char payload_name[RTP_PAYLOAD_NAME_SIZE];
@ -689,7 +673,7 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtp_header) {
int8_t last_received_payload_type = int8_t last_received_payload_type =
rtp_payload_registry_->last_received_payload_type(); rtp_payload_registry_->last_received_payload_type();
if (ssrc_ != rtp_header->header.ssrc || if (ssrc_ != rtp_header->ssrc ||
(last_received_payload_type == -1 && ssrc_ == 0)) { (last_received_payload_type == -1 && ssrc_ == 0)) {
// We need the payload_type_ to make the call if the remote SSRC is 0. // We need the payload_type_ to make the call if the remote SSRC is 0.
new_ssrc = true; new_ssrc = true;
@ -704,12 +688,12 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtp_header) {
// Do we have a SSRC? Then the stream is restarted. // Do we have a SSRC? Then the stream is restarted.
if (ssrc_) { if (ssrc_) {
// Do we have the same codec? Then re-initialize coder. // Do we have the same codec? Then re-initialize coder.
if (rtp_header->header.payloadType == last_received_payload_type) { if (rtp_header->payloadType == last_received_payload_type) {
re_initialize_decoder = true; re_initialize_decoder = true;
Payload* payload; Payload* payload;
if (rtp_payload_registry_->PayloadTypeToPayload( if (rtp_payload_registry_->PayloadTypeToPayload(
rtp_header->header.payloadType, payload) != 0) { rtp_header->payloadType, payload) != 0) {
return; return;
} }
assert(payload); assert(payload);
@ -724,23 +708,23 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtp_header) {
} }
} }
} }
ssrc_ = rtp_header->header.ssrc; ssrc_ = rtp_header->ssrc;
} }
} }
if (new_ssrc) { if (new_ssrc) {
// We need to get this to our RTCP sender and receiver. // We need to get this to our RTCP sender and receiver.
// We need to do this outside critical section. // We need to do this outside critical section.
rtp_rtcp_.SetRemoteSSRC(rtp_header->header.ssrc); rtp_rtcp_.SetRemoteSSRC(rtp_header->ssrc);
cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->header.ssrc); cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->ssrc);
} }
if (re_initialize_decoder) { if (re_initialize_decoder) {
if (-1 == cb_rtp_feedback_->OnInitializeDecoder( if (-1 == cb_rtp_feedback_->OnInitializeDecoder(
id_, rtp_header->header.payloadType, payload_name, frequency, id_, rtp_header->payloadType, payload_name, frequency,
channels, rate)) { channels, rate)) {
// New stream, same codec. // New stream, same codec.
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_, WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
"Failed to create decoder for payload type:%d", "Failed to create decoder for payload type:%d",
rtp_header->header.payloadType); rtp_header->payloadType);
} }
} }
} }
@ -753,14 +737,14 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtp_header) {
// media_specific interface (such as CheckPayloadChange, possibly get/set // media_specific interface (such as CheckPayloadChange, possibly get/set
// last known payload). // last known payload).
int32_t RTPReceiver::CheckPayloadChanged( int32_t RTPReceiver::CheckPayloadChanged(
const WebRtcRTPHeader* rtp_header, const RTPHeader* rtp_header,
const int8_t first_payload_byte, const int8_t first_payload_byte,
bool& is_red, bool& is_red,
ModuleRTPUtility::PayloadUnion* specific_payload) { ModuleRTPUtility::PayloadUnion* specific_payload) {
bool re_initialize_decoder = false; bool re_initialize_decoder = false;
char payload_name[RTP_PAYLOAD_NAME_SIZE]; char payload_name[RTP_PAYLOAD_NAME_SIZE];
int8_t payload_type = rtp_header->header.payloadType; int8_t payload_type = rtp_header->payloadType;
{ {
CriticalSectionScoped lock(critical_section_rtp_receiver_); CriticalSectionScoped lock(critical_section_rtp_receiver_);

View File

@ -75,7 +75,7 @@ class RTPReceiver : public Bitrate {
int8_t* payload_type) const; int8_t* payload_type) const;
int32_t IncomingRTPPacket( int32_t IncomingRTPPacket(
WebRtcRTPHeader* rtpheader, RTPHeader* rtpheader,
const uint8_t* incoming_rtp_packet, const uint8_t* incoming_rtp_packet,
const uint16_t incoming_rtp_packet_length); const uint16_t incoming_rtp_packet_length);
@ -154,7 +154,7 @@ class RTPReceiver : public Bitrate {
virtual bool RetransmitOfOldPacket(const uint16_t sequence_number, virtual bool RetransmitOfOldPacket(const uint16_t sequence_number,
const uint32_t rtp_time_stamp) const; const uint32_t rtp_time_stamp) const;
void UpdateStatistics(const WebRtcRTPHeader* rtp_header, void UpdateStatistics(const RTPHeader* rtp_header,
const uint16_t bytes, const uint16_t bytes,
const bool old_packet); const bool old_packet);
@ -164,9 +164,9 @@ class RTPReceiver : public Bitrate {
bool InOrderPacket(const uint16_t sequence_number) const; bool InOrderPacket(const uint16_t sequence_number) const;
void CheckSSRCChanged(const WebRtcRTPHeader* rtp_header); void CheckSSRCChanged(const RTPHeader* rtp_header);
void CheckCSRC(const WebRtcRTPHeader* rtp_header); void CheckCSRC(const WebRtcRTPHeader* rtp_header);
int32_t CheckPayloadChanged(const WebRtcRTPHeader* rtp_header, int32_t CheckPayloadChanged(const RTPHeader* rtp_header,
const int8_t first_payload_byte, const int8_t first_payload_byte,
bool& isRED, bool& isRED,
ModuleRTPUtility::PayloadUnion* payload); ModuleRTPUtility::PayloadUnion* payload);
@ -188,8 +188,6 @@ class RTPReceiver : public Bitrate {
uint32_t packet_timeout_ms_; uint32_t packet_timeout_ms_;
RtpHeaderExtensionMap rtp_header_extension_map_;
// SSRCs. // SSRCs.
uint32_t ssrc_; uint32_t ssrc_;
uint8_t num_csrcs_; uint8_t num_csrcs_;

View File

@ -194,10 +194,11 @@ int32_t RTPReceiverAudio::ParseRtpPacket(
TRACE_EVENT2("webrtc_rtp", "Audio::ParseRtp", TRACE_EVENT2("webrtc_rtp", "Audio::ParseRtp",
"seqnum", rtp_header->header.sequenceNumber, "seqnum", rtp_header->header.sequenceNumber,
"timestamp", rtp_header->header.timestamp); "timestamp", rtp_header->header.timestamp);
rtp_header->type.Audio.numEnergy = rtp_header->header.numCSRCs;
const uint8_t* payload_data = const uint8_t* payload_data =
ModuleRTPUtility::GetPayloadData(rtp_header, packet); ModuleRTPUtility::GetPayloadData(rtp_header->header, packet);
const uint16_t payload_data_length = const uint16_t payload_data_length =
ModuleRTPUtility::GetPayloadDataLength(rtp_header, packet_length); ModuleRTPUtility::GetPayloadDataLength(rtp_header->header, packet_length);
return ParseAudioCodecSpecific(rtp_header, return ParseAudioCodecSpecific(rtp_header,
payload_data, payload_data,

View File

@ -79,9 +79,9 @@ int32_t RTPReceiverVideo::ParseRtpPacket(
"seqnum", rtp_header->header.sequenceNumber, "seqnum", rtp_header->header.sequenceNumber,
"timestamp", rtp_header->header.timestamp); "timestamp", rtp_header->header.timestamp);
const uint8_t* payload_data = const uint8_t* payload_data =
ModuleRTPUtility::GetPayloadData(rtp_header, packet); ModuleRTPUtility::GetPayloadData(rtp_header->header, packet);
const uint16_t payload_data_length = const uint16_t payload_data_length =
ModuleRTPUtility::GetPayloadDataLength(rtp_header, packet_length); ModuleRTPUtility::GetPayloadDataLength(rtp_header->header, packet_length);
return ParseVideoCodecSpecific(rtp_header, return ParseVideoCodecSpecific(rtp_header,
payload_data, payload_data,
payload_data_length, payload_data_length,

View File

@ -28,10 +28,12 @@
}, },
'sources': [ 'sources': [
# Common # Common
'../interface/rtp_header_parser.h',
'../interface/rtp_rtcp.h', '../interface/rtp_rtcp.h',
'../interface/rtp_rtcp_defines.h', '../interface/rtp_rtcp_defines.h',
'bitrate.cc', 'bitrate.cc',
'bitrate.h', 'bitrate.h',
'rtp_header_parser.cc',
'rtp_rtcp_config.h', 'rtp_rtcp_config.h',
'rtp_rtcp_impl.cc', 'rtp_rtcp_impl.cc',
'rtp_rtcp_impl.h', 'rtp_rtcp_impl.h',

View File

@ -565,77 +565,56 @@ void ModuleRtpRtcpImpl::SetRtxReceivePayloadType(int payload_type) {
} }
// Called by the network module when we receive a packet. // Called by the network module when we receive a packet.
int32_t ModuleRtpRtcpImpl::IncomingPacket( int32_t ModuleRtpRtcpImpl::IncomingRtpPacket(
const uint8_t* incoming_packet, const uint8_t* incoming_packet,
const uint16_t incoming_packet_length) { const uint16_t incoming_packet_length,
const RTPHeader& parsed_rtp_header) {
WEBRTC_TRACE(kTraceStream, WEBRTC_TRACE(kTraceStream,
kTraceRtpRtcp, kTraceRtpRtcp,
id_, id_,
"IncomingPacket(packet_length:%u)", "IncomingRtpPacket(packet_length:%u)",
incoming_packet_length); incoming_packet_length);
RTPHeader rtp_header_copy = parsed_rtp_header;
return rtp_receiver_->IncomingRTPPacket(&rtp_header_copy,
incoming_packet,
incoming_packet_length);
}
int32_t ModuleRtpRtcpImpl::IncomingRtcpPacket(
const uint8_t* rtcp_packet,
const uint16_t length) {
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1,
"IncomingRtcpPacket(packet_length:%u)", length);
// Minimum RTP is 12 bytes. // Minimum RTP is 12 bytes.
// Minimum RTCP is 8 bytes (RTCP BYE). // Minimum RTCP is 8 bytes (RTCP BYE).
if (incoming_packet_length < 8 || incoming_packet == NULL) { if (length == 8) {
WEBRTC_TRACE(kTraceDebug, WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, -1,
kTraceRtpRtcp, "IncomingRtcpPacket invalid length");
id_, return false;
"IncomingPacket invalid buffer or length");
return -1;
} }
// Check RTP version. // Check RTP version.
const uint8_t version = incoming_packet[0] >> 6; const uint8_t version = rtcp_packet[0] >> 6;
if (version != 2) { if (version != 2) {
WEBRTC_TRACE(kTraceDebug, WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, -1,
kTraceRtpRtcp, "IncomingRtcpPacket invalid RTP version");
id_, return false;
"IncomingPacket invalid RTP version"); }
// Allow receive of non-compound RTCP packets.
RTCPUtility::RTCPParserV2 rtcp_parser(rtcp_packet, length, true);
const bool valid_rtcpheader = rtcp_parser.IsValid();
if (!valid_rtcpheader) {
WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, id_,
"IncomingRtcpPacket invalid RTCP packet");
return -1; return -1;
} }
RTCPHelp::RTCPPacketInformation rtcp_packet_information;
ModuleRTPUtility::RTPHeaderParser rtp_parser(incoming_packet, int32_t ret_val = rtcp_receiver_.IncomingRTCPPacket(
incoming_packet_length); rtcp_packet_information, &rtcp_parser);
if (ret_val == 0) {
if (rtp_parser.RTCP()) { rtcp_receiver_.TriggerCallbacksFromRTCPPacket(rtcp_packet_information);
// Allow receive of non-compound RTCP packets.
RTCPUtility::RTCPParserV2 rtcp_parser(incoming_packet,
incoming_packet_length,
true);
const bool valid_rtcpheader = rtcp_parser.IsValid();
if (!valid_rtcpheader) {
WEBRTC_TRACE(kTraceDebug,
kTraceRtpRtcp,
id_,
"IncomingPacket invalid RTCP packet");
return -1;
}
RTCPHelp::RTCPPacketInformation rtcp_packet_information;
int32_t ret_val = rtcp_receiver_.IncomingRTCPPacket(
rtcp_packet_information, &rtcp_parser);
if (ret_val == 0) {
rtcp_receiver_.TriggerCallbacksFromRTCPPacket(rtcp_packet_information);
}
return ret_val;
} else {
WebRtcRTPHeader rtp_header;
memset(&rtp_header, 0, sizeof(rtp_header));
RtpHeaderExtensionMap map;
rtp_receiver_->GetHeaderExtensionMapCopy(&map);
const bool valid_rtpheader = rtp_parser.Parse(rtp_header, &map);
if (!valid_rtpheader) {
WEBRTC_TRACE(kTraceDebug,
kTraceRtpRtcp,
id_,
"IncomingPacket invalid RTP header");
return -1;
}
return rtp_receiver_->IncomingRTPPacket(&rtp_header,
incoming_packet,
incoming_packet_length);
} }
return ret_val;
} }
int32_t ModuleRtpRtcpImpl::RegisterSendPayload( int32_t ModuleRtpRtcpImpl::RegisterSendPayload(
@ -1434,17 +1413,6 @@ int32_t ModuleRtpRtcpImpl::DeregisterSendRtpHeaderExtension(
return rtp_sender_.DeregisterRtpHeaderExtension(type); return rtp_sender_.DeregisterRtpHeaderExtension(type);
} }
int32_t ModuleRtpRtcpImpl::RegisterReceiveRtpHeaderExtension(
const RTPExtensionType type,
const uint8_t id) {
return rtp_receiver_->RegisterRtpHeaderExtension(type, id);
}
int32_t ModuleRtpRtcpImpl::DeregisterReceiveRtpHeaderExtension(
const RTPExtensionType type) {
return rtp_receiver_->DeregisterRtpHeaderExtension(type);
}
// (TMMBR) Temporary Max Media Bit Rate. // (TMMBR) Temporary Max Media Bit Rate.
bool ModuleRtpRtcpImpl::TMMBR() const { bool ModuleRtpRtcpImpl::TMMBR() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "TMMBR()"); WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "TMMBR()");
@ -1682,11 +1650,6 @@ int32_t ModuleRtpRtcpImpl::SetRTPAudioLevelIndicationStatus(
enable, enable,
id); id);
if (enable) {
rtp_receiver_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel, id);
} else {
rtp_receiver_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel);
}
return rtp_sender_.SetAudioLevelIndicationStatus(enable, id); return rtp_sender_.SetAudioLevelIndicationStatus(enable, id);
} }

View File

@ -70,14 +70,6 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
virtual int32_t DeRegisterReceivePayload( virtual int32_t DeRegisterReceivePayload(
const int8_t payload_type); const int8_t payload_type);
// Register RTP header extension.
virtual int32_t RegisterReceiveRtpHeaderExtension(
const RTPExtensionType type,
const uint8_t id);
virtual int32_t DeregisterReceiveRtpHeaderExtension(
const RTPExtensionType type);
// Get the currently configured SSRC filter. // Get the currently configured SSRC filter.
virtual int32_t SSRCFilter(uint32_t& allowed_ssrc) const; virtual int32_t SSRCFilter(uint32_t& allowed_ssrc) const;
@ -108,9 +100,14 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
virtual void SetRtxReceivePayloadType(int payload_type); virtual void SetRtxReceivePayloadType(int payload_type);
// Called by the network module when we receive a packet. // Called when we receive an RTP packet.
virtual int32_t IncomingPacket(const uint8_t* incoming_packet, virtual int32_t IncomingRtpPacket(const uint8_t* incoming_packet,
const uint16_t packet_length); const uint16_t packet_length,
const RTPHeader& parsed_rtp_header);
// Called when we receive an RTCP packet.
virtual int32_t IncomingRtcpPacket(const uint8_t* incoming_packet,
uint16_t incoming_packet_length);
// Sender part. // Sender part.

View File

@ -492,8 +492,8 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, uint32_t min_resend_time) {
} }
ModuleRTPUtility::RTPHeaderParser rtp_parser(data_buffer, length); ModuleRTPUtility::RTPHeaderParser rtp_parser(data_buffer, length);
WebRtcRTPHeader rtp_header; RTPHeader header;
rtp_parser.Parse(rtp_header); rtp_parser.Parse(header);
// Store the time when the packet was last sent or added to pacer. // Store the time when the packet was last sent or added to pacer.
packet_history_->UpdateResendTime(packet_id); packet_history_->UpdateResendTime(packet_id);
@ -508,12 +508,13 @@ int32_t RTPSender::ReSendPacket(uint16_t packet_id, uint32_t min_resend_time) {
} }
TRACE_EVENT_INSTANT2("webrtc_rtp", "RTPSender::ReSendPacket", TRACE_EVENT_INSTANT2("webrtc_rtp", "RTPSender::ReSendPacket",
"timestamp", rtp_header.header.timestamp, "timestamp", header.timestamp,
"seqnum", rtp_header.header.sequenceNumber); "seqnum", header.sequenceNumber);
if (paced_sender_) { if (paced_sender_) {
if (!paced_sender_->SendPacket(PacedSender::kHighPriority, if (!paced_sender_->SendPacket(PacedSender::kHighPriority,
rtp_header.header.ssrc, header.ssrc,
rtp_header.header.sequenceNumber, header.sequenceNumber,
capture_time_ms, capture_time_ms,
length)) { length)) {
// We can't send the packet right now. // We can't send the packet right now.
@ -678,10 +679,10 @@ void RTPSender::TimeToSendPacket(uint16_t sequence_number,
assert(length > 0); assert(length > 0);
ModuleRTPUtility::RTPHeaderParser rtp_parser(data_buffer, length); ModuleRTPUtility::RTPHeaderParser rtp_parser(data_buffer, length);
WebRtcRTPHeader rtp_header; RTPHeader rtp_header;
rtp_parser.Parse(rtp_header); rtp_parser.Parse(rtp_header);
TRACE_EVENT_INSTANT2("webrtc_rtp", "RTPSender::TimeToSendPacket", TRACE_EVENT_INSTANT2("webrtc_rtp", "RTPSender::TimeToSendPacket",
"timestamp", rtp_header.header.timestamp, "timestamp", rtp_header.timestamp,
"seqnum", sequence_number); "seqnum", sequence_number);
int64_t now_ms = clock_->TimeInMilliseconds(); int64_t now_ms = clock_->TimeInMilliseconds();
@ -693,8 +694,8 @@ void RTPSender::TimeToSendPacket(uint16_t sequence_number,
if (updated_transmission_time_offset || updated_abs_send_time) { if (updated_transmission_time_offset || updated_abs_send_time) {
// Update stored packet in case of receiving a re-transmission request. // Update stored packet in case of receiving a re-transmission request.
packet_history_->ReplaceRTPHeader(data_buffer, packet_history_->ReplaceRTPHeader(data_buffer,
rtp_header.header.sequenceNumber, rtp_header.sequenceNumber,
rtp_header.header.headerLength); rtp_header.headerLength);
} }
SendPacketToNetwork(data_buffer, length); SendPacketToNetwork(data_buffer, length);
} }
@ -705,7 +706,7 @@ int32_t RTPSender::SendToNetwork(
int64_t capture_time_ms, StorageType storage) { int64_t capture_time_ms, StorageType storage) {
ModuleRTPUtility::RTPHeaderParser rtp_parser( ModuleRTPUtility::RTPHeaderParser rtp_parser(
buffer, payload_length + rtp_header_length); buffer, payload_length + rtp_header_length);
WebRtcRTPHeader rtp_header; RTPHeader rtp_header;
rtp_parser.Parse(rtp_header); rtp_parser.Parse(rtp_header);
int64_t now_ms = clock_->TimeInMilliseconds(); int64_t now_ms = clock_->TimeInMilliseconds();
@ -753,8 +754,8 @@ int32_t RTPSender::SendToNetwork(
if (paced_sender_ && storage != kDontStore) { if (paced_sender_ && storage != kDontStore) {
if (!paced_sender_->SendPacket( if (!paced_sender_->SendPacket(
PacedSender::kNormalPriority, rtp_header.header.ssrc, PacedSender::kNormalPriority, rtp_header.ssrc,
rtp_header.header.sequenceNumber, capture_time_ms, rtp_header.sequenceNumber, capture_time_ms,
payload_length + rtp_header_length)) { payload_length + rtp_header_length)) {
// We can't send the packet right now. // We can't send the packet right now.
// We will be called when it is time. // We will be called when it is time.
@ -991,7 +992,7 @@ uint8_t RTPSender::BuildAbsoluteSendTimeExtension(
bool RTPSender::UpdateTransmissionTimeOffset( bool RTPSender::UpdateTransmissionTimeOffset(
uint8_t *rtp_packet, const uint16_t rtp_packet_length, uint8_t *rtp_packet, const uint16_t rtp_packet_length,
const WebRtcRTPHeader &rtp_header, const int64_t time_diff_ms) const { const RTPHeader &rtp_header, const int64_t time_diff_ms) const {
CriticalSectionScoped cs(send_critsect_); CriticalSectionScoped cs(send_critsect_);
// Get length until start of header extension block. // Get length until start of header extension block.
@ -1003,17 +1004,17 @@ bool RTPSender::UpdateTransmissionTimeOffset(
"Failed to update transmission time offset, not registered."); "Failed to update transmission time offset, not registered.");
return false; return false;
} }
int block_pos = 12 + rtp_header.header.numCSRCs + extension_block_pos; int block_pos = 12 + rtp_header.numCSRCs + extension_block_pos;
if (rtp_packet_length < block_pos + kTransmissionTimeOffsetLength || if (rtp_packet_length < block_pos + kTransmissionTimeOffsetLength ||
rtp_header.header.headerLength < rtp_header.headerLength <
block_pos + kTransmissionTimeOffsetLength) { block_pos + kTransmissionTimeOffsetLength) {
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_, WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_,
"Failed to update transmission time offset, invalid length."); "Failed to update transmission time offset, invalid length.");
return false; return false;
} }
// Verify that header contains extension. // Verify that header contains extension.
if (!((rtp_packet[12 + rtp_header.header.numCSRCs] == 0xBE) && if (!((rtp_packet[12 + rtp_header.numCSRCs] == 0xBE) &&
(rtp_packet[12 + rtp_header.header.numCSRCs + 1] == 0xDE))) { (rtp_packet[12 + rtp_header.numCSRCs + 1] == 0xDE))) {
WEBRTC_TRACE( WEBRTC_TRACE(
kTraceStream, kTraceRtpRtcp, id_, kTraceStream, kTraceRtpRtcp, id_,
"Failed to update transmission time offset, hdr extension not found."); "Failed to update transmission time offset, hdr extension not found.");
@ -1042,7 +1043,7 @@ bool RTPSender::UpdateTransmissionTimeOffset(
bool RTPSender::UpdateAbsoluteSendTime( bool RTPSender::UpdateAbsoluteSendTime(
uint8_t *rtp_packet, const uint16_t rtp_packet_length, uint8_t *rtp_packet, const uint16_t rtp_packet_length,
const WebRtcRTPHeader &rtp_header, const int64_t now_ms) const { const RTPHeader &rtp_header, const int64_t now_ms) const {
CriticalSectionScoped cs(send_critsect_); CriticalSectionScoped cs(send_critsect_);
// Get length until start of header extension block. // Get length until start of header extension block.
@ -1054,16 +1055,16 @@ bool RTPSender::UpdateAbsoluteSendTime(
"Failed to update absolute send time, not registered."); "Failed to update absolute send time, not registered.");
return false; return false;
} }
int block_pos = 12 + rtp_header.header.numCSRCs + extension_block_pos; int block_pos = 12 + rtp_header.numCSRCs + extension_block_pos;
if (rtp_packet_length < block_pos + kAbsoluteSendTimeLength || if (rtp_packet_length < block_pos + kAbsoluteSendTimeLength ||
rtp_header.header.headerLength < block_pos + kAbsoluteSendTimeLength) { rtp_header.headerLength < block_pos + kAbsoluteSendTimeLength) {
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_, WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_,
"Failed to update absolute send time, invalid length."); "Failed to update absolute send time, invalid length.");
return false; return false;
} }
// Verify that header contains extension. // Verify that header contains extension.
if (!((rtp_packet[12 + rtp_header.header.numCSRCs] == 0xBE) && if (!((rtp_packet[12 + rtp_header.numCSRCs] == 0xBE) &&
(rtp_packet[12 + rtp_header.header.numCSRCs + 1] == 0xDE))) { (rtp_packet[12 + rtp_header.numCSRCs + 1] == 0xDE))) {
WEBRTC_TRACE( WEBRTC_TRACE(
kTraceStream, kTraceRtpRtcp, id_, kTraceStream, kTraceRtpRtcp, id_,
"Failed to update absolute send time, hdr extension not found."); "Failed to update absolute send time, hdr extension not found.");
@ -1352,16 +1353,16 @@ void RTPSender::BuildRtxPacket(uint8_t* buffer, uint16_t* length,
ModuleRTPUtility::RTPHeaderParser rtp_parser( ModuleRTPUtility::RTPHeaderParser rtp_parser(
reinterpret_cast<const uint8_t *>(buffer), *length); reinterpret_cast<const uint8_t *>(buffer), *length);
WebRtcRTPHeader rtp_header; RTPHeader rtp_header;
rtp_parser.Parse(rtp_header); rtp_parser.Parse(rtp_header);
// Add original RTP header. // Add original RTP header.
memcpy(data_buffer_rtx, buffer, rtp_header.header.headerLength); memcpy(data_buffer_rtx, buffer, rtp_header.headerLength);
// Replace payload type, if a specific type is set for RTX. // Replace payload type, if a specific type is set for RTX.
if (payload_type_rtx_ != -1) { if (payload_type_rtx_ != -1) {
data_buffer_rtx[1] = static_cast<uint8_t>(payload_type_rtx_); data_buffer_rtx[1] = static_cast<uint8_t>(payload_type_rtx_);
if (rtp_header.header.markerBit) if (rtp_header.markerBit)
data_buffer_rtx[1] |= kRtpMarkerBitMask; data_buffer_rtx[1] |= kRtpMarkerBitMask;
} }
@ -1374,14 +1375,13 @@ void RTPSender::BuildRtxPacket(uint8_t* buffer, uint16_t* length,
ModuleRTPUtility::AssignUWord32ToBuffer(ptr, ssrc_rtx_); ModuleRTPUtility::AssignUWord32ToBuffer(ptr, ssrc_rtx_);
// Add OSN (original sequence number). // Add OSN (original sequence number).
ptr = data_buffer_rtx + rtp_header.header.headerLength; ptr = data_buffer_rtx + rtp_header.headerLength;
ModuleRTPUtility::AssignUWord16ToBuffer(ptr, ModuleRTPUtility::AssignUWord16ToBuffer(ptr, rtp_header.sequenceNumber);
rtp_header.header.sequenceNumber);
ptr += 2; ptr += 2;
// Add original payload data. // Add original payload data.
memcpy(ptr, buffer + rtp_header.header.headerLength, memcpy(ptr, buffer + rtp_header.headerLength,
*length - rtp_header.header.headerLength); *length - rtp_header.headerLength);
*length += 2; *length += 2;
} }

View File

@ -155,11 +155,11 @@ class RTPSender : public Bitrate, public RTPSenderInterface {
bool UpdateTransmissionTimeOffset(uint8_t *rtp_packet, bool UpdateTransmissionTimeOffset(uint8_t *rtp_packet,
const uint16_t rtp_packet_length, const uint16_t rtp_packet_length,
const WebRtcRTPHeader &rtp_header, const RTPHeader &rtp_header,
const int64_t time_diff_ms) const; const int64_t time_diff_ms) const;
bool UpdateAbsoluteSendTime(uint8_t *rtp_packet, bool UpdateAbsoluteSendTime(uint8_t *rtp_packet,
const uint16_t rtp_packet_length, const uint16_t rtp_packet_length,
const WebRtcRTPHeader &rtp_header, const RTPHeader &rtp_header,
const int64_t now_ms) const; const int64_t now_ms) const;
void TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms); void TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms);

View File

@ -88,14 +88,14 @@ class RtpSenderTest : public ::testing::Test {
const bool kMarkerBit; const bool kMarkerBit;
uint8_t packet_[kMaxPacketLength]; uint8_t packet_[kMaxPacketLength];
void VerifyRTPHeaderCommon(const WebRtcRTPHeader& rtp_header) { void VerifyRTPHeaderCommon(const RTPHeader& rtp_header) {
EXPECT_EQ(kMarkerBit, rtp_header.header.markerBit); EXPECT_EQ(kMarkerBit, rtp_header.markerBit);
EXPECT_EQ(payload_, rtp_header.header.payloadType); EXPECT_EQ(payload_, rtp_header.payloadType);
EXPECT_EQ(kSeqNum, rtp_header.header.sequenceNumber); EXPECT_EQ(kSeqNum, rtp_header.sequenceNumber);
EXPECT_EQ(kTimestamp, rtp_header.header.timestamp); EXPECT_EQ(kTimestamp, rtp_header.timestamp);
EXPECT_EQ(rtp_sender_->SSRC(), rtp_header.header.ssrc); EXPECT_EQ(rtp_sender_->SSRC(), rtp_header.ssrc);
EXPECT_EQ(0, rtp_header.header.numCSRCs); EXPECT_EQ(0, rtp_header.numCSRCs);
EXPECT_EQ(0, rtp_header.header.paddingLength); EXPECT_EQ(0, rtp_header.paddingLength);
} }
}; };
@ -170,7 +170,7 @@ TEST_F(RtpSenderTest, BuildRTPPacket) {
// Verify // Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length); webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map; RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset, map.Register(kRtpExtensionTransmissionTimeOffset,
@ -180,7 +180,7 @@ TEST_F(RtpSenderTest, BuildRTPPacket) {
ASSERT_TRUE(valid_rtp_header); ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP()); ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header); VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength); EXPECT_EQ(length, rtp_header.headerLength);
EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset); EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset);
EXPECT_EQ(0u, rtp_header.extension.absoluteSendTime); EXPECT_EQ(0u, rtp_header.extension.absoluteSendTime);
} }
@ -198,7 +198,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithTransmissionOffsetExtension) {
// Verify // Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length); webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map; RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset, map.Register(kRtpExtensionTransmissionTimeOffset,
@ -208,16 +208,16 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithTransmissionOffsetExtension) {
ASSERT_TRUE(valid_rtp_header); ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP()); ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header); VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength); EXPECT_EQ(length, rtp_header.headerLength);
EXPECT_EQ(kTimeOffset, rtp_header.extension.transmissionTimeOffset); EXPECT_EQ(kTimeOffset, rtp_header.extension.transmissionTimeOffset);
// Parse without map extension // Parse without map extension
webrtc::WebRtcRTPHeader rtp_header2; webrtc::RTPHeader rtp_header2;
const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL); const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
ASSERT_TRUE(valid_rtp_header2); ASSERT_TRUE(valid_rtp_header2);
VerifyRTPHeaderCommon(rtp_header2); VerifyRTPHeaderCommon(rtp_header2);
EXPECT_EQ(length, rtp_header2.header.headerLength); EXPECT_EQ(length, rtp_header2.headerLength);
EXPECT_EQ(0, rtp_header2.extension.transmissionTimeOffset); EXPECT_EQ(0, rtp_header2.extension.transmissionTimeOffset);
} }
@ -235,7 +235,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithNegativeTransmissionOffsetExtension) {
// Verify // Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length); webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map; RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset, map.Register(kRtpExtensionTransmissionTimeOffset,
@ -245,7 +245,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithNegativeTransmissionOffsetExtension) {
ASSERT_TRUE(valid_rtp_header); ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP()); ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header); VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength); EXPECT_EQ(length, rtp_header.headerLength);
EXPECT_EQ(kNegTimeOffset, rtp_header.extension.transmissionTimeOffset); EXPECT_EQ(kNegTimeOffset, rtp_header.extension.transmissionTimeOffset);
} }
@ -262,7 +262,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithAbsoluteSendTimeExtension) {
// Verify // Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length); webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map; RtpHeaderExtensionMap map;
map.Register(kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId); map.Register(kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId);
@ -271,16 +271,16 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithAbsoluteSendTimeExtension) {
ASSERT_TRUE(valid_rtp_header); ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP()); ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header); VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength); EXPECT_EQ(length, rtp_header.headerLength);
EXPECT_EQ(kAbsoluteSendTime, rtp_header.extension.absoluteSendTime); EXPECT_EQ(kAbsoluteSendTime, rtp_header.extension.absoluteSendTime);
// Parse without map extension // Parse without map extension
webrtc::WebRtcRTPHeader rtp_header2; webrtc::RTPHeader rtp_header2;
const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL); const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
ASSERT_TRUE(valid_rtp_header2); ASSERT_TRUE(valid_rtp_header2);
VerifyRTPHeaderCommon(rtp_header2); VerifyRTPHeaderCommon(rtp_header2);
EXPECT_EQ(length, rtp_header2.header.headerLength); EXPECT_EQ(length, rtp_header2.headerLength);
EXPECT_EQ(0u, rtp_header2.extension.absoluteSendTime); EXPECT_EQ(0u, rtp_header2.extension.absoluteSendTime);
} }
@ -300,7 +300,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithHeaderExtensions) {
// Verify // Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length); webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map; RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset, map.Register(kRtpExtensionTransmissionTimeOffset,
@ -311,17 +311,17 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithHeaderExtensions) {
ASSERT_TRUE(valid_rtp_header); ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP()); ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header); VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength); EXPECT_EQ(length, rtp_header.headerLength);
EXPECT_EQ(kTimeOffset, rtp_header.extension.transmissionTimeOffset); EXPECT_EQ(kTimeOffset, rtp_header.extension.transmissionTimeOffset);
EXPECT_EQ(kAbsoluteSendTime, rtp_header.extension.absoluteSendTime); EXPECT_EQ(kAbsoluteSendTime, rtp_header.extension.absoluteSendTime);
// Parse without map extension // Parse without map extension
webrtc::WebRtcRTPHeader rtp_header2; webrtc::RTPHeader rtp_header2;
const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL); const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
ASSERT_TRUE(valid_rtp_header2); ASSERT_TRUE(valid_rtp_header2);
VerifyRTPHeaderCommon(rtp_header2); VerifyRTPHeaderCommon(rtp_header2);
EXPECT_EQ(length, rtp_header2.header.headerLength); EXPECT_EQ(length, rtp_header2.headerLength);
EXPECT_EQ(0, rtp_header2.extension.transmissionTimeOffset); EXPECT_EQ(0, rtp_header2.extension.transmissionTimeOffset);
EXPECT_EQ(0u, rtp_header2.extension.absoluteSendTime); EXPECT_EQ(0u, rtp_header2.extension.absoluteSendTime);
} }
@ -364,7 +364,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) {
// Parse sent packet. // Parse sent packet.
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser( webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(
transport_.last_sent_packet_, rtp_length); transport_.last_sent_packet_, rtp_length);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map; RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset, map.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId); kTransmissionTimeOffsetExtensionId);
@ -425,7 +425,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) {
// Parse sent packet. // Parse sent packet.
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser( webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(
transport_.last_sent_packet_, rtp_length); transport_.last_sent_packet_, rtp_length);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map; RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset, map.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId); kTransmissionTimeOffsetExtensionId);
@ -454,15 +454,15 @@ TEST_F(RtpSenderTest, SendGenericVideo) {
ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_, ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_,
transport_.last_sent_packet_len_); transport_.last_sent_packet_len_);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header)); ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header, const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
transport_.last_sent_packet_); transport_.last_sent_packet_);
uint8_t generic_header = *payload_data++; uint8_t generic_header = *payload_data++;
ASSERT_EQ(sizeof(payload) + sizeof(generic_header), ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
ModuleRTPUtility::GetPayloadDataLength(&rtp_header, ModuleRTPUtility::GetPayloadDataLength(rtp_header,
transport_.last_sent_packet_len_)); transport_.last_sent_packet_len_));
EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit); EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
@ -483,7 +483,7 @@ TEST_F(RtpSenderTest, SendGenericVideo) {
transport_.last_sent_packet_len_); transport_.last_sent_packet_len_);
ASSERT_TRUE(rtp_parser.Parse(rtp_header)); ASSERT_TRUE(rtp_parser.Parse(rtp_header));
payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header, payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
transport_.last_sent_packet_); transport_.last_sent_packet_);
generic_header = *payload_data++; generic_header = *payload_data++;
@ -491,7 +491,7 @@ TEST_F(RtpSenderTest, SendGenericVideo) {
EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit); EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
ASSERT_EQ(sizeof(payload) + sizeof(generic_header), ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
ModuleRTPUtility::GetPayloadDataLength(&rtp_header, ModuleRTPUtility::GetPayloadDataLength(rtp_header,
transport_.last_sent_packet_len_)); transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload))); EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
@ -527,7 +527,7 @@ TEST_F(RtpSenderAudioTest, BuildRTPPacketWithAudioLevelExtension) {
// Verify // Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length); webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map; RtpHeaderExtensionMap map;
map.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId); map.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
@ -536,16 +536,16 @@ TEST_F(RtpSenderAudioTest, BuildRTPPacketWithAudioLevelExtension) {
ASSERT_TRUE(valid_rtp_header); ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP()); ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header); VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength); EXPECT_EQ(length, rtp_header.headerLength);
// TODO(solenberg): Should verify that we got audio level in header extension. // TODO(solenberg): Should verify that we got audio level in header extension.
// Parse without map extension // Parse without map extension
webrtc::WebRtcRTPHeader rtp_header2; webrtc::RTPHeader rtp_header2;
const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL); const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
ASSERT_TRUE(valid_rtp_header2); ASSERT_TRUE(valid_rtp_header2);
VerifyRTPHeaderCommon(rtp_header2); VerifyRTPHeaderCommon(rtp_header2);
EXPECT_EQ(length, rtp_header2.header.headerLength); EXPECT_EQ(length, rtp_header2.headerLength);
// TODO(solenberg): Should verify that we didn't get audio level. // TODO(solenberg): Should verify that we didn't get audio level.
} }
@ -562,13 +562,13 @@ TEST_F(RtpSenderAudioTest, SendAudio) {
ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_, ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_,
transport_.last_sent_packet_len_); transport_.last_sent_packet_len_);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header)); ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header, const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
transport_.last_sent_packet_); transport_.last_sent_packet_);
ASSERT_EQ(sizeof(payload), ModuleRTPUtility::GetPayloadDataLength(&rtp_header, ASSERT_EQ(sizeof(payload), ModuleRTPUtility::GetPayloadDataLength(rtp_header,
transport_.last_sent_packet_len_)); transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload))); EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
@ -593,13 +593,13 @@ TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_, ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_,
transport_.last_sent_packet_len_); transport_.last_sent_packet_len_);
webrtc::WebRtcRTPHeader rtp_header; webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header)); ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header, const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
transport_.last_sent_packet_); transport_.last_sent_packet_);
ASSERT_EQ(sizeof(payload), ModuleRTPUtility::GetPayloadDataLength(&rtp_header, ASSERT_EQ(sizeof(payload), ModuleRTPUtility::GetPayloadDataLength(rtp_header,
transport_.last_sent_packet_len_)); transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload))); EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));

View File

@ -86,15 +86,15 @@ uint32_t ConvertNTPTimeToMS(uint32_t NTPsec, uint32_t NTPfrac) {
* Misc utility routines * Misc utility routines
*/ */
const uint8_t* GetPayloadData(const WebRtcRTPHeader* rtp_header, const uint8_t* GetPayloadData(const RTPHeader& rtp_header,
const uint8_t* packet) { const uint8_t* packet) {
return packet + rtp_header->header.headerLength; return packet + rtp_header.headerLength;
} }
uint16_t GetPayloadDataLength(const WebRtcRTPHeader* rtp_header, uint16_t GetPayloadDataLength(const RTPHeader& rtp_header,
const uint16_t packet_length) { const uint16_t packet_length) {
uint16_t length = packet_length - rtp_header->header.paddingLength - uint16_t length = packet_length - rtp_header.paddingLength -
rtp_header->header.headerLength; rtp_header.headerLength;
return static_cast<uint16_t>(length); return static_cast<uint16_t>(length);
} }
@ -288,7 +288,7 @@ bool RTPHeaderParser::RTCP() const {
return RTCP; return RTCP;
} }
bool RTPHeaderParser::Parse(WebRtcRTPHeader& parsedPacket, bool RTPHeaderParser::Parse(RTPHeader& header,
RtpHeaderExtensionMap* ptrExtensionMap) const { RtpHeaderExtensionMap* ptrExtensionMap) const {
const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin; const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
@ -332,31 +332,30 @@ bool RTPHeaderParser::Parse(WebRtcRTPHeader& parsedPacket,
return false; return false;
} }
parsedPacket.header.markerBit = M; header.markerBit = M;
parsedPacket.header.payloadType = PT; header.payloadType = PT;
parsedPacket.header.sequenceNumber = sequenceNumber; header.sequenceNumber = sequenceNumber;
parsedPacket.header.timestamp = RTPTimestamp; header.timestamp = RTPTimestamp;
parsedPacket.header.ssrc = SSRC; header.ssrc = SSRC;
parsedPacket.header.numCSRCs = CC; header.numCSRCs = CC;
parsedPacket.header.paddingLength = P ? *(_ptrRTPDataEnd - 1) : 0; header.paddingLength = P ? *(_ptrRTPDataEnd - 1) : 0;
for (unsigned int i = 0; i < CC; ++i) { for (unsigned int i = 0; i < CC; ++i) {
uint32_t CSRC = *ptr++ << 24; uint32_t CSRC = *ptr++ << 24;
CSRC += *ptr++ << 16; CSRC += *ptr++ << 16;
CSRC += *ptr++ << 8; CSRC += *ptr++ << 8;
CSRC += *ptr++; CSRC += *ptr++;
parsedPacket.header.arrOfCSRCs[i] = CSRC; header.arrOfCSRCs[i] = CSRC;
} }
parsedPacket.type.Audio.numEnergy = parsedPacket.header.numCSRCs;
parsedPacket.header.headerLength = 12 + CSRCocts; header.headerLength = 12 + CSRCocts;
// If in effect, MAY be omitted for those packets for which the offset // If in effect, MAY be omitted for those packets for which the offset
// is zero. // is zero.
parsedPacket.extension.transmissionTimeOffset = 0; header.extension.transmissionTimeOffset = 0;
// May not be present in packet. // May not be present in packet.
parsedPacket.extension.absoluteSendTime = 0; header.extension.absoluteSendTime = 0;
if (X) { if (X) {
/* RTP header extension, RFC 3550. /* RTP header extension, RFC 3550.
@ -373,7 +372,7 @@ bool RTPHeaderParser::Parse(WebRtcRTPHeader& parsedPacket,
return false; return false;
} }
parsedPacket.header.headerLength += 4; header.headerLength += 4;
uint16_t definedByProfile = *ptr++ << 8; uint16_t definedByProfile = *ptr++ << 8;
definedByProfile += *ptr++; definedByProfile += *ptr++;
@ -387,18 +386,18 @@ bool RTPHeaderParser::Parse(WebRtcRTPHeader& parsedPacket,
} }
if (definedByProfile == kRtpOneByteHeaderExtensionId) { if (definedByProfile == kRtpOneByteHeaderExtensionId) {
const uint8_t* ptrRTPDataExtensionEnd = ptr + XLen; const uint8_t* ptrRTPDataExtensionEnd = ptr + XLen;
ParseOneByteExtensionHeader(parsedPacket, ParseOneByteExtensionHeader(header,
ptrExtensionMap, ptrExtensionMap,
ptrRTPDataExtensionEnd, ptrRTPDataExtensionEnd,
ptr); ptr);
} }
parsedPacket.header.headerLength += XLen; header.headerLength += XLen;
} }
return true; return true;
} }
void RTPHeaderParser::ParseOneByteExtensionHeader( void RTPHeaderParser::ParseOneByteExtensionHeader(
WebRtcRTPHeader& parsedPacket, RTPHeader& header,
const RtpHeaderExtensionMap* ptrExtensionMap, const RtpHeaderExtensionMap* ptrExtensionMap,
const uint8_t* ptrRTPDataExtensionEnd, const uint8_t* ptrRTPDataExtensionEnd,
const uint8_t* ptr) const { const uint8_t* ptr) const {
@ -446,10 +445,11 @@ void RTPHeaderParser::ParseOneByteExtensionHeader(
int32_t transmissionTimeOffset = *ptr++ << 16; int32_t transmissionTimeOffset = *ptr++ << 16;
transmissionTimeOffset += *ptr++ << 8; transmissionTimeOffset += *ptr++ << 8;
transmissionTimeOffset += *ptr++; transmissionTimeOffset += *ptr++;
parsedPacket.extension.transmissionTimeOffset = transmissionTimeOffset; header.extension.transmissionTimeOffset =
transmissionTimeOffset;
if (transmissionTimeOffset & 0x800000) { if (transmissionTimeOffset & 0x800000) {
// Negative offset, correct sign for Word24 to Word32. // Negative offset, correct sign for Word24 to Word32.
parsedPacket.extension.transmissionTimeOffset |= 0xFF000000; header.extension.transmissionTimeOffset |= 0xFF000000;
} }
break; break;
} }
@ -484,7 +484,7 @@ void RTPHeaderParser::ParseOneByteExtensionHeader(
uint32_t absoluteSendTime = *ptr++ << 16; uint32_t absoluteSendTime = *ptr++ << 16;
absoluteSendTime += *ptr++ << 8; absoluteSendTime += *ptr++ << 8;
absoluteSendTime += *ptr++; absoluteSendTime += *ptr++;
parsedPacket.extension.absoluteSendTime = absoluteSendTime; header.extension.absoluteSendTime = absoluteSendTime;
break; break;
} }
default: { default: {

View File

@ -73,11 +73,11 @@ namespace ModuleRTPUtility
uint32_t pow2(uint8_t exp); uint32_t pow2(uint8_t exp);
// Returns a pointer to the payload data given a packet. // Returns a pointer to the payload data given a packet.
const uint8_t* GetPayloadData(const WebRtcRTPHeader* rtp_header, const uint8_t* GetPayloadData(const RTPHeader& rtp_header,
const uint8_t* packet); const uint8_t* packet);
// Returns payload length given a packet. // Returns payload length given a packet.
uint16_t GetPayloadDataLength(const WebRtcRTPHeader* rtp_header, uint16_t GetPayloadDataLength(const RTPHeader& rtp_header,
const uint16_t packet_length); const uint16_t packet_length);
// Returns true if |newTimestamp| is older than |existingTimestamp|. // Returns true if |newTimestamp| is older than |existingTimestamp|.
@ -124,12 +124,12 @@ namespace ModuleRTPUtility
~RTPHeaderParser(); ~RTPHeaderParser();
bool RTCP() const; bool RTCP() const;
bool Parse(WebRtcRTPHeader& parsedPacket, bool Parse(RTPHeader& parsedPacket,
RtpHeaderExtensionMap* ptrExtensionMap = NULL) const; RtpHeaderExtensionMap* ptrExtensionMap = NULL) const;
private: private:
void ParseOneByteExtensionHeader( void ParseOneByteExtensionHeader(
WebRtcRTPHeader& parsedPacket, RTPHeader& parsedPacket,
const RtpHeaderExtensionMap* ptrExtensionMap, const RtpHeaderExtensionMap* ptrExtensionMap,
const uint8_t* ptrRTPDataExtensionEnd, const uint8_t* ptrRTPDataExtensionEnd,
const uint8_t* ptr) const; const uint8_t* ptr) const;

View File

@ -10,8 +10,10 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/common_types.h" #include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
namespace webrtc { namespace webrtc {
@ -37,16 +39,22 @@ class LoopBackTransport : public webrtc::Transport {
return len; return len;
} }
} }
if (_rtpRtcpModule->IncomingPacket((const uint8_t*)data, len) == 0) { RTPHeader header;
return len; scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
if (!parser->Parse(static_cast<const uint8_t*>(data), len, &header)) {
return -1;
} }
return -1; if (_rtpRtcpModule->IncomingRtpPacket(static_cast<const uint8_t*>(data),
len, header) < 0) {
return -1;
}
return len;
} }
virtual int SendRTCPPacket(int channel, const void *data, int len) { virtual int SendRTCPPacket(int channel, const void *data, int len) {
if (_rtpRtcpModule->IncomingPacket((const uint8_t*)data, len) == 0) { if (_rtpRtcpModule->IncomingRtcpPacket((const uint8_t*)data, len) < 0) {
return len; return -1;
} }
return -1; return len;
} }
private: private:
int _count; int _count;

View File

@ -153,7 +153,11 @@ TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) {
int packet_size = PaddingPacket(padding_packet, timestamp, seq_num, int packet_size = PaddingPacket(padding_packet, timestamp, seq_num,
kPadSize); kPadSize);
++seq_num; ++seq_num;
EXPECT_EQ(0, video_module_->IncomingPacket(padding_packet, packet_size)); RTPHeader header;
scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
EXPECT_TRUE(parser->Parse(padding_packet, packet_size, &header));
EXPECT_EQ(0, video_module_->IncomingRtpPacket(padding_packet,
packet_size, header));
EXPECT_EQ(0, receiver_->payload_size()); EXPECT_EQ(0, receiver_->payload_size());
EXPECT_EQ(packet_size - 12, receiver_->rtp_header().header.paddingLength); EXPECT_EQ(packet_size - 12, receiver_->rtp_header().header.paddingLength);
} }

View File

@ -8,11 +8,12 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "mt_test_common.h" #include "webrtc/modules/video_coding/main/test/mt_test_common.h"
#include <cmath> #include <cmath>
#include "rtp_dump.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/utility/interface/rtp_dump.h"
#include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/clock.h"
namespace webrtc { namespace webrtc {
@ -88,12 +89,15 @@ TransportCallback::TransportPackets()
_rtpPackets.pop_front(); _rtpPackets.pop_front();
// Send to receive side // Send to receive side
if (_rtp->IncomingPacket((const uint8_t*)packet->data, RTPHeader header;
packet->length) < 0) scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
if (!parser->Parse(packet->data, packet->length, &header)) {
delete packet;
return -1;
}
if (_rtp->IncomingRtpPacket(packet->data, packet->length, header) < 0)
{ {
delete packet; delete packet;
packet = NULL;
// Will return an error after the first packet that goes wrong
return -1; return -1;
} }
delete packet; delete packet;

View File

@ -193,7 +193,7 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface {
uint32_t dest_ip; uint32_t dest_ip;
uint16_t source_port; uint16_t source_port;
uint16_t dest_port; uint16_t dest_port;
WebRtcRTPHeader rtp_header; RTPHeader rtp_header;
int32_t pos_in_file; int32_t pos_in_file;
uint32_t payload_length; uint32_t payload_length;
}; };
@ -277,7 +277,7 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface {
return kResultSkip; return kResultSkip;
} }
uint32_t ssrc = marker.rtp_header.header.ssrc; uint32_t ssrc = marker.rtp_header.ssrc;
packets_by_ssrc_[ssrc].push_back(marker.packet_number); packets_by_ssrc_[ssrc].push_back(marker.packet_number);
packets_.push_back(marker); packets_.push_back(marker);
} }

View File

@ -56,9 +56,9 @@ class TestPcapFileReader : public ::testing::Test {
length = kBufferSize; length = kBufferSize;
ModuleRTPUtility::RTPHeaderParser rtp_header_parser(data, length); ModuleRTPUtility::RTPHeaderParser rtp_header_parser(data, length);
webrtc::WebRtcRTPHeader header; webrtc::RTPHeader header;
if (!rtp_header_parser.RTCP() && rtp_header_parser.Parse(header, NULL)) { if (!rtp_header_parser.RTCP() && rtp_header_parser.Parse(header, NULL)) {
pps[header.header.ssrc]++; pps[header.ssrc]++;
} }
} }
return pps; return pps;

View File

@ -13,8 +13,8 @@
#include <cstdio> #include <cstdio>
#include <map> #include <map>
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/modules/video_coding/main/source/internal_defines.h" #include "webrtc/modules/video_coding/main/source/internal_defines.h"
#include "webrtc/modules/video_coding/main/test/pcap_file_reader.h" #include "webrtc/modules/video_coding/main/test/pcap_file_reader.h"
#include "webrtc/modules/video_coding/main/test/rtp_file_reader.h" #include "webrtc/modules/video_coding/main/test/rtp_file_reader.h"
@ -229,7 +229,7 @@ class SsrcHandlers {
handler->rtp_module_->SetRTCPStatus(kRtcpNonCompound); handler->rtp_module_->SetRTCPStatus(kRtcpNonCompound);
handler->rtp_module_->SetREMBStatus(true); handler->rtp_module_->SetREMBStatus(true);
handler->rtp_module_->SetSSRCFilter(true, ssrc); handler->rtp_module_->SetSSRCFilter(true, ssrc);
handler->rtp_module_->RegisterReceiveRtpHeaderExtension( handler->rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kRtpExtensionTransmissionTimeOffset,
kDefaultTransmissionTimeOffsetExtensionId); kDefaultTransmissionTimeOffsetExtensionId);
@ -257,7 +257,13 @@ class SsrcHandlers {
void IncomingPacket(const uint8_t* data, uint32_t length) { void IncomingPacket(const uint8_t* data, uint32_t length) {
for (HandlerMapIt it = handlers_.begin(); it != handlers_.end(); ++it) { for (HandlerMapIt it = handlers_.begin(); it != handlers_.end(); ++it) {
it->second->rtp_module_->IncomingPacket(data, length); if (it->second->rtp_header_parser_->IsRtcp(data, length)) {
it->second->rtp_module_->IncomingRtcpPacket(data, length);
} else {
RTPHeader header;
it->second->rtp_header_parser_->Parse(data, length, &header);
it->second->rtp_module_->IncomingRtpPacket(data, length, header);
}
} }
} }
@ -266,7 +272,8 @@ class SsrcHandlers {
public: public:
Handler(uint32_t ssrc, const PayloadTypes& payload_types, Handler(uint32_t ssrc, const PayloadTypes& payload_types,
LostPackets* lost_packets) LostPackets* lost_packets)
: rtp_module_(), : rtp_header_parser_(RtpHeaderParser::Create()),
rtp_module_(),
payload_sink_(), payload_sink_(),
ssrc_(ssrc), ssrc_(ssrc),
payload_types_(payload_types), payload_types_(payload_types),
@ -288,6 +295,7 @@ class SsrcHandlers {
return payload_types_; return payload_types_;
} }
scoped_ptr<RtpHeaderParser> rtp_header_parser_;
scoped_ptr<RtpRtcp> rtp_module_; scoped_ptr<RtpRtcp> rtp_module_;
scoped_ptr<PayloadSinkInterface> payload_sink_; scoped_ptr<PayloadSinkInterface> payload_sink_;
@ -421,13 +429,13 @@ class RtpPlayerImpl : public RtpPlayerInterface {
assert(data); assert(data);
assert(length > 0); assert(length > 0);
ModuleRTPUtility::RTPHeaderParser rtp_header_parser(data, length); scoped_ptr<RtpHeaderParser> rtp_header_parser(RtpHeaderParser::Create());
if (!rtp_header_parser.RTCP()) { if (!rtp_header_parser->IsRtcp(data, length)) {
WebRtcRTPHeader header; RTPHeader header;
if (!rtp_header_parser.Parse(header, NULL)) { if (!rtp_header_parser->Parse(data, length, &header)) {
return -1; return -1;
} }
uint32_t ssrc = header.header.ssrc; uint32_t ssrc = header.ssrc;
if (ssrc_handlers_.RegisterSsrc(ssrc, &lost_packets_) < 0) { if (ssrc_handlers_.RegisterSsrc(ssrc, &lost_packets_) < 0) {
DEBUG_LOG1("Unable to register ssrc: %d", ssrc); DEBUG_LOG1("Unable to register ssrc: %d", ssrc);
return -1; return -1;
@ -436,7 +444,7 @@ class RtpPlayerImpl : public RtpPlayerInterface {
if (no_loss_startup_ > 0) { if (no_loss_startup_ > 0) {
no_loss_startup_--; no_loss_startup_--;
} else if ((rand() + 1.0)/(RAND_MAX + 1.0) < loss_rate_) { } else if ((rand() + 1.0)/(RAND_MAX + 1.0) < loss_rate_) {
uint16_t seq_num = header.header.sequenceNumber; uint16_t seq_num = header.sequenceNumber;
lost_packets_.AddPacket(new RawRtpPacket(data, length, ssrc, seq_num)); lost_packets_.AddPacket(new RawRtpPacket(data, length, ssrc, seq_num));
DEBUG_LOG1("Dropped packet: %d!", header.header.sequenceNumber); DEBUG_LOG1("Dropped packet: %d!", header.header.sequenceNumber);
return 0; return 0;

View File

@ -8,13 +8,14 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "test_callbacks.h" #include "webrtc/modules/video_coding/main/test/test_callbacks.h"
#include <cmath> #include <cmath>
#include "common_video/libyuv/include/webrtc_libyuv.h" #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "rtp_dump.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "test_macros.h" #include "webrtc/modules/utility/interface/rtp_dump.h"
#include "webrtc/modules/video_coding/main/test/test_macros.h"
#include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/clock.h"
namespace webrtc { namespace webrtc {
@ -292,12 +293,15 @@ RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len)
_rtpPackets.pop_front(); _rtpPackets.pop_front();
assert(_rtp); // We must have a configured RTP module for this test. assert(_rtp); // We must have a configured RTP module for this test.
// Send to receive side // Send to receive side
if (_rtp->IncomingPacket((const uint8_t*)packet->data, RTPHeader header;
packet->length) < 0) scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
if (!parser->Parse(packet->data, packet->length, &header)) {
delete packet;
return -1;
}
if (_rtp->IncomingRtpPacket(packet->data, packet->length, header) < 0)
{ {
delete packet; delete packet;
packet = NULL;
// Will return an error after the first packet that goes wrong
return -1; return -1;
} }
delete packet; delete packet;

View File

@ -50,7 +50,7 @@ int MTRxTxTest(CmdArgs& args);
double NormalDist(double mean, double stdDev); double NormalDist(double mean, double stdDev);
struct RtpPacket { struct RtpPacket {
int8_t data[1650]; // max packet size uint8_t data[1650]; // max packet size
int32_t length; int32_t length;
int64_t receiveTime; int64_t receiveTime;
}; };

View File

@ -150,7 +150,7 @@ bool VideoCall::DeliverRtcp(ModuleRTPUtility::RTPHeaderParser* rtp_parser,
bool VideoCall::DeliverRtp(ModuleRTPUtility::RTPHeaderParser* rtp_parser, bool VideoCall::DeliverRtp(ModuleRTPUtility::RTPHeaderParser* rtp_parser,
const void* packet, size_t length) { const void* packet, size_t length) {
WebRtcRTPHeader rtp_header; RTPHeader rtp_header;
// TODO(pbos): ExtensionMap if there are extensions // TODO(pbos): ExtensionMap if there are extensions
if (!rtp_parser->Parse(rtp_header)) { if (!rtp_parser->Parse(rtp_header)) {
@ -158,7 +158,7 @@ bool VideoCall::DeliverRtp(ModuleRTPUtility::RTPHeaderParser* rtp_parser,
return false; return false;
} }
uint32_t ssrc = rtp_header.header.ssrc; uint32_t ssrc = rtp_header.ssrc;
if (receive_ssrcs_.find(ssrc) == receive_ssrcs_.end()) { if (receive_ssrcs_.find(ssrc) == receive_ssrcs_.end()) {
// TODO(pbos): Log some warning, SSRC without receiver. // TODO(pbos): Log some warning, SSRC without receiver.
return false; return false;

View File

@ -873,13 +873,7 @@ int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) {
} }
int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) { int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) {
if (enable) { return vie_receiver_.SetReceiveTimestampOffsetStatus(enable, id);
return rtp_rtcp_->RegisterReceiveRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, id);
} else {
return rtp_rtcp_->DeregisterReceiveRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset);
}
} }
int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) { int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) {
@ -914,19 +908,8 @@ int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) {
} }
int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
if (enable) {
if (rtp_rtcp_->RegisterReceiveRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, id) != 0) {
return -1;
}
} else {
if (rtp_rtcp_->DeregisterReceiveRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime) != 0) {
return -1;
}
}
receive_absolute_send_time_enabled_ = enable; receive_absolute_send_time_enabled_ = enable;
return 0; return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id);
} }
bool ViEChannel::GetReceiveAbsoluteSendTimeStatus() const { bool ViEChannel::GetReceiveAbsoluteSendTimeStatus() const {

View File

@ -13,6 +13,7 @@
#include <vector> #include <vector>
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/utility/interface/rtp_dump.h" #include "webrtc/modules/utility/interface/rtp_dump.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h" #include "webrtc/modules/video_coding/main/interface/video_coding.h"
@ -27,6 +28,7 @@ ViEReceiver::ViEReceiver(const int32_t channel_id,
RemoteBitrateEstimator* remote_bitrate_estimator) RemoteBitrateEstimator* remote_bitrate_estimator)
: receive_cs_(CriticalSectionWrapper::CreateCriticalSection()), : receive_cs_(CriticalSectionWrapper::CreateCriticalSection()),
channel_id_(channel_id), channel_id_(channel_id),
rtp_header_parser_(RtpHeaderParser::Create()),
rtp_rtcp_(NULL), rtp_rtcp_(NULL),
vcm_(module_vcm), vcm_(module_vcm),
remote_bitrate_estimator_(remote_bitrate_estimator), remote_bitrate_estimator_(remote_bitrate_estimator),
@ -87,6 +89,26 @@ void ViEReceiver::RegisterSimulcastRtpRtcpModules(
} }
} }
int ViEReceiver::SetReceiveTimestampOffsetStatus(bool enable, int id) {
if (enable) {
return rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, id);
} else {
return rtp_header_parser_->DeregisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset);
}
}
int ViEReceiver::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) {
if (enable) {
return rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, id);
} else {
return rtp_header_parser_->DeregisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime);
}
}
int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet, int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet,
int rtp_packet_length) { int rtp_packet_length) {
if (!receiving_) { if (!receiving_) {
@ -168,8 +190,16 @@ int ViEReceiver::InsertRTPPacket(const int8_t* rtp_packet,
static_cast<uint16_t>(received_packet_length)); static_cast<uint16_t>(received_packet_length));
} }
} }
RTPHeader header;
if (!rtp_header_parser_->Parse(received_packet, received_packet_length,
&header)) {
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, channel_id_,
"IncomingPacket invalid RTP header");
return -1;
}
assert(rtp_rtcp_); // Should be set by owner at construction time. assert(rtp_rtcp_); // Should be set by owner at construction time.
return rtp_rtcp_->IncomingPacket(received_packet, received_packet_length); return rtp_rtcp_->IncomingRtpPacket(received_packet, received_packet_length,
header);
} }
int ViEReceiver::InsertRTCPPacket(const int8_t* rtcp_packet, int ViEReceiver::InsertRTCPPacket(const int8_t* rtcp_packet,
@ -213,11 +243,11 @@ int ViEReceiver::InsertRTCPPacket(const int8_t* rtcp_packet,
std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin(); std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin();
while (it != rtp_rtcp_simulcast_.end()) { while (it != rtp_rtcp_simulcast_.end()) {
RtpRtcp* rtp_rtcp = *it++; RtpRtcp* rtp_rtcp = *it++;
rtp_rtcp->IncomingPacket(received_packet, received_packet_length); rtp_rtcp->IncomingRtcpPacket(received_packet, received_packet_length);
} }
} }
assert(rtp_rtcp_); // Should be set by owner at construction time. assert(rtp_rtcp_); // Should be set by owner at construction time.
return rtp_rtcp_->IncomingPacket(received_packet, received_packet_length); return rtp_rtcp_->IncomingRtcpPacket(received_packet, received_packet_length);
} }
void ViEReceiver::StartReceive() { void ViEReceiver::StartReceive() {

View File

@ -25,6 +25,7 @@ class CriticalSectionWrapper;
class Encryption; class Encryption;
class RemoteBitrateEstimator; class RemoteBitrateEstimator;
class RtpDump; class RtpDump;
class RtpHeaderParser;
class RtpRtcp; class RtpRtcp;
class VideoCodingModule; class VideoCodingModule;
@ -41,6 +42,9 @@ class ViEReceiver : public RtpData {
void RegisterSimulcastRtpRtcpModules(const std::list<RtpRtcp*>& rtp_modules); void RegisterSimulcastRtpRtcpModules(const std::list<RtpRtcp*>& rtp_modules);
int SetReceiveTimestampOffsetStatus(bool enable, int id);
int SetReceiveAbsoluteSendTimeStatus(bool enable, int id);
void StartReceive(); void StartReceive();
void StopReceive(); void StopReceive();
@ -71,6 +75,7 @@ class ViEReceiver : public RtpData {
scoped_ptr<CriticalSectionWrapper> receive_cs_; scoped_ptr<CriticalSectionWrapper> receive_cs_;
const int32_t channel_id_; const int32_t channel_id_;
scoped_ptr<RtpHeaderParser> rtp_header_parser_;
RtpRtcp* rtp_rtcp_; RtpRtcp* rtp_rtcp_;
std::list<RtpRtcp*> rtp_rtcp_simulcast_; std::list<RtpRtcp*> rtp_rtcp_simulcast_;
VideoCodingModule* vcm_; VideoCodingModule* vcm_;

View File

@ -868,6 +868,7 @@ Channel::Channel(int32_t channelId,
_callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()), _callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
_instanceId(instanceId), _instanceId(instanceId),
_channelId(channelId), _channelId(channelId),
rtp_header_parser_(RtpHeaderParser::Create()),
_audioCodingModule(*AudioCodingModule::Create( _audioCodingModule(*AudioCodingModule::Create(
VoEModuleId(instanceId, channelId))), VoEModuleId(instanceId, channelId))),
_rtpDumpIn(*RtpDump::CreateRtpDump()), _rtpDumpIn(*RtpDump::CreateRtpDump()),
@ -2128,12 +2129,20 @@ int32_t Channel::ReceivedRTPPacket(const int8_t* data, int32_t length) {
VoEId(_instanceId,_channelId), VoEId(_instanceId,_channelId),
"Channel::SendPacket() RTP dump to input file failed"); "Channel::SendPacket() RTP dump to input file failed");
} }
RTPHeader header;
if (!rtp_header_parser_->Parse(reinterpret_cast<const uint8_t*>(data),
static_cast<uint16_t>(length), &header)) {
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo,
VoEId(_instanceId,_channelId),
"IncomingPacket invalid RTP header");
return -1;
}
// Deliver RTP packet to RTP/RTCP module for parsing // Deliver RTP packet to RTP/RTCP module for parsing
// The packet will be pushed back to the channel thru the // The packet will be pushed back to the channel thru the
// OnReceivedPayloadData callback so we don't push it to the ACM here // OnReceivedPayloadData callback so we don't push it to the ACM here
if (_rtpRtcpModule->IncomingPacket((const uint8_t*)data, if (_rtpRtcpModule->IncomingRtpPacket(reinterpret_cast<const uint8_t*>(data),
(uint16_t)length) == -1) { static_cast<uint16_t>(length),
header) == -1) {
_engineStatisticsPtr->SetLastError( _engineStatisticsPtr->SetLastError(
VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
"Channel::IncomingRTPPacket() RTP packet is invalid"); "Channel::IncomingRTPPacket() RTP packet is invalid");
@ -2156,8 +2165,8 @@ int32_t Channel::ReceivedRTCPPacket(const int8_t* data, int32_t length) {
} }
// Deliver RTCP packet to RTP/RTCP module for parsing // Deliver RTCP packet to RTP/RTCP module for parsing
if (_rtpRtcpModule->IncomingPacket((const uint8_t*)data, if (_rtpRtcpModule->IncomingRtcpPacket((const uint8_t*)data,
(uint16_t)length) == -1) { (uint16_t)length) == -1) {
_engineStatisticsPtr->SetLastError( _engineStatisticsPtr->SetLastError(
VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning, VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
"Channel::IncomingRTPPacket() RTCP packet is invalid"); "Channel::IncomingRTPPacket() RTCP packet is invalid");
@ -3699,6 +3708,12 @@ Channel::SetRTPAudioLevelIndicationStatus(bool enable, unsigned char ID)
} }
_includeAudioLevelIndication = enable; _includeAudioLevelIndication = enable;
if (enable) {
rtp_header_parser_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
ID);
} else {
rtp_header_parser_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel);
}
return _rtpRtcpModule->SetRTPAudioLevelIndicationStatus(enable, ID); return _rtpRtcpModule->SetRTPAudioLevelIndicationStatus(enable, ID);
} }
int int

View File

@ -15,6 +15,7 @@
#include "webrtc/common_types.h" #include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h" #include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
#include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer_defines.h" #include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer_defines.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
#include "webrtc/modules/utility/interface/file_player.h" #include "webrtc/modules/utility/interface/file_player.h"
#include "webrtc/modules/utility/interface/file_recorder.h" #include "webrtc/modules/utility/interface/file_recorder.h"
@ -442,6 +443,7 @@ private:
int32_t _channelId; int32_t _channelId;
private: private:
scoped_ptr<RtpHeaderParser> rtp_header_parser_;
scoped_ptr<RtpRtcp> _rtpRtcpModule; scoped_ptr<RtpRtcp> _rtpRtcpModule;
AudioCodingModule& _audioCodingModule; AudioCodingModule& _audioCodingModule;
RtpDump& _rtpDumpIn; RtpDump& _rtpDumpIn;