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,6 +27,12 @@
namespace webrtc {
struct RTPHeaderExtension
{
int32_t transmissionTimeOffset;
uint32_t absoluteSendTime;
};
struct RTPHeader
{
bool markerBit;
@ -38,12 +44,7 @@ struct RTPHeader
uint32_t arrOfCSRCs[kRtpCsrcSize];
uint8_t paddingLength;
uint16_t headerLength;
};
struct RTPHeaderExtension
{
int32_t transmissionTimeOffset;
uint32_t absoluteSendTime;
RTPHeaderExtension extension;
};
struct RTPAudioHeader
@ -122,7 +123,6 @@ struct WebRtcRTPHeader
RTPHeader header;
FrameType frameType;
RTPTypeHeader type;
RTPHeaderExtension extension;
};
class RTPFragmentationHeader

View File

@ -142,7 +142,7 @@ void RemoteBitrateEstimatorMultiStream::IncomingPacket(
const WebRtcRTPHeader& header) {
uint32_t ssrc = header.header.ssrc;
uint32_t rtp_timestamp = header.header.timestamp +
header.extension.transmissionTimeOffset;
header.header.extension.transmissionTimeOffset;
CriticalSectionScoped cs(crit_sect_.get());
incoming_bitrate_.Update(payload_size, arrival_time_ms);
// 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) {
uint32_t ssrc = header.header.ssrc;
uint32_t rtp_timestamp = header.header.timestamp +
header.extension.transmissionTimeOffset;
header.header.extension.transmissionTimeOffset;
CriticalSectionScoped cs(crit_sect_.get());
SsrcOveruseDetectorMap::iterator it = overuse_detectors_.find(ssrc);
if (it == overuse_detectors_.end()) {

View File

@ -227,7 +227,7 @@ void RemoteBitrateEstimatorTest::IncomingPacket(uint32_t ssrc,
memset(&header, 0, sizeof(header));
header.header.ssrc = ssrc;
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);
}

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(
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
*/
@ -250,11 +238,16 @@ class RtpRtcp : public Module {
*
* incomingPacket - incoming packet buffer
* packetLength - length of incoming buffer
* parsed_rtp_header - the parsed RTP header
*
* return -1 on failure else 0
*/
virtual int32_t IncomingPacket(const uint8_t* incomingPacket,
const uint16_t packetLength) = 0;
virtual int32_t IncomingRtpPacket(const uint8_t* incomingPacket,
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));
MOCK_METHOD1(DeRegisterReceivePayload,
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,
uint32_t());
MOCK_CONST_METHOD0(LocalTimeOfRemoteTimeStamp,
@ -81,8 +77,11 @@ class MockRtpRtcp : public RtpRtcp {
int32_t(bool* enable, uint32_t* ssrc, int* payload_type));
MOCK_METHOD1(SetRtxReceivePayloadType,
void(int));
MOCK_METHOD2(IncomingPacket,
int32_t(const uint8_t* incomingPacket, const uint16_t packetLength));
MOCK_METHOD3(IncomingRtpPacket,
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,
int32_t(const uint32_t audioReceivedNTPsecs,
const uint32_t audioReceivedNTPfrac,

View File

@ -15,8 +15,10 @@
#include "testing/gtest/include/gtest/gtest.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_defines.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
using namespace webrtc;
@ -87,14 +89,20 @@ class RtxLoopBackTransport : public webrtc::Transport {
count_ < consecutive_drop_end_) {
return len;
}
if (module_->IncomingPacket((const uint8_t*)data, len) == 0) {
return len;
}
RTPHeader header;
scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
if (!parser->Parse(static_cast<const uint8_t*>(data), len, &header)) {
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) {
if (module_->IncomingPacket((const uint8_t*)data, len) == 0) {
if (module_->IncomingRtcpPacket((const uint8_t*)data, len) == 0) {
return len;
}
return -1;

View File

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

View File

@ -16,13 +16,14 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "common_types.h"
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "modules/rtp_rtcp/source/rtcp_receiver.h"
#include "modules/rtp_rtcp/source/rtcp_sender.h"
#include "modules/rtp_rtcp/source/rtp_utility.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
namespace webrtc {
@ -353,7 +354,11 @@ TEST_F(RtcpSenderTest, TestCompound) {
EXPECT_EQ(0, rtp_rtcp_impl_->RegisterReceivePayload(codec_inst));
// 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_->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),
rtp_header_extension_map_(),
ssrc_(0),
num_csrcs_(0),
current_remote_csrc_(),
@ -251,24 +250,6 @@ int32_t RTPReceiver::ReceivePayloadType(
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 {
CriticalSectionScoped lock(critical_section_rtp_receiver_);
return nack_method_;
@ -341,32 +322,32 @@ int32_t RTPReceiver::Energy(
}
int32_t RTPReceiver::IncomingRTPPacket(
WebRtcRTPHeader* rtp_header,
RTPHeader* rtp_header,
const uint8_t* packet,
const uint16_t packet_length) {
TRACE_EVENT0("webrtc_rtp", "RTPRecv::Packet");
// 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.
if ((length - rtp_header->header.headerLength) < 0) {
if ((length - rtp_header->headerLength) < 0) {
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
"%s invalid argument",
__FUNCTION__);
return -1;
}
if (rtx_) {
if (ssrc_rtx_ == rtp_header->header.ssrc) {
if (ssrc_rtx_ == rtp_header->ssrc) {
// 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;
}
// If a specific RTX payload type is negotiated, set back to the media
// payload type and treat it like a media packet from here.
if (payload_type_rtx_ != -1) {
if (payload_type_rtx_ == rtp_header->header.payloadType &&
if (payload_type_rtx_ == rtp_header->payloadType &&
rtp_payload_registry_->last_received_media_payload_type() != -1) {
rtp_header->header.payloadType =
rtp_header->payloadType =
rtp_payload_registry_->last_received_media_payload_type();
} else {
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
@ -374,16 +355,16 @@ int32_t RTPReceiver::IncomingRTPPacket(
return -1;
}
}
rtp_header->header.ssrc = ssrc_;
rtp_header->header.sequenceNumber =
(packet[rtp_header->header.headerLength] << 8) +
packet[1 + rtp_header->header.headerLength];
// Count the RTX header as part of the RTP header.
rtp_header->header.headerLength += 2;
rtp_header->ssrc = ssrc_;
rtp_header->sequenceNumber =
(packet[rtp_header->headerLength] << 8) +
packet[1 + rtp_header->headerLength];
// Count the RTX header as part of the RTP
rtp_header->headerLength += 2;
}
}
if (use_ssrc_filter_) {
if (rtp_header->header.ssrc != ssrc_filter_) {
if (rtp_header->ssrc != ssrc_filter_) {
WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, id_,
"%s drop packet due to SSRC filter",
__FUNCTION__);
@ -392,7 +373,7 @@ int32_t RTPReceiver::IncomingRTPPacket(
}
if (last_receive_time_ == 0) {
// Trigger only once.
if (length - rtp_header->header.headerLength == 0) {
if (length - rtp_header->headerLength == 0) {
// Keep-alive packet.
cb_rtp_feedback_->OnReceivedPacket(id_, kPacketKeepAlive);
} else {
@ -401,7 +382,7 @@ int32_t RTPReceiver::IncomingRTPPacket(
}
int8_t first_payload_byte = 0;
if (length > 0) {
first_payload_byte = packet[rtp_header->header.headerLength];
first_payload_byte = packet[rtp_header->headerLength];
}
// Trigger our callbacks.
CheckSSRCChanged(rtp_header);
@ -413,7 +394,7 @@ int32_t RTPReceiver::IncomingRTPPacket(
first_payload_byte,
is_red,
&specific_payload) == -1) {
if (length - rtp_header->header.headerLength == 0) {
if (length - rtp_header->headerLength == 0) {
// OK, keep-alive packet.
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, id_,
"%s received keepalive",
@ -425,18 +406,21 @@ int32_t RTPReceiver::IncomingRTPPacket(
__FUNCTION__);
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 =
ModuleRTPUtility::GetPayloadDataLength(rtp_header, packet_length);
ModuleRTPUtility::GetPayloadDataLength(*rtp_header, packet_length);
bool is_first_packet_in_frame =
SequenceNumber() + 1 == rtp_header->header.sequenceNumber &&
TimeStamp() != rtp_header->header.timestamp;
SequenceNumber() + 1 == rtp_header->sequenceNumber &&
TimeStamp() != rtp_header->timestamp;
bool is_first_packet = is_first_packet_in_frame || HaveNotReceivedPackets();
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);
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
// have done the callback.
bool old_packet = RetransmitOfOldPacket(rtp_header->header.sequenceNumber,
rtp_header->header.timestamp);
bool old_packet = RetransmitOfOldPacket(rtp_header->sequenceNumber,
rtp_header->timestamp);
// This updates received_seq_max_ and other members.
UpdateStatistics(rtp_header, payload_data_length, old_packet);
@ -459,11 +443,11 @@ int32_t RTPReceiver::IncomingRTPPacket(
last_received_payload_length_ = payload_data_length;
if (!old_packet) {
if (last_received_timestamp_ != rtp_header->header.timestamp) {
last_received_timestamp_ = rtp_header->header.timestamp;
if (last_received_timestamp_ != rtp_header->timestamp) {
last_received_timestamp_ = rtp_header->timestamp;
last_received_frame_time_ms_ = clock_->TimeInMilliseconds();
}
last_received_sequence_number_ = rtp_header->header.sequenceNumber;
last_received_sequence_number_ = rtp_header->sequenceNumber;
last_received_transmission_time_offset_ =
rtp_header->extension.transmissionTimeOffset;
}
@ -472,7 +456,7 @@ int32_t RTPReceiver::IncomingRTPPacket(
// Implementation note: we expect to have the critical_section_rtp_receiver_
// critsect when we call this.
void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
void RTPReceiver::UpdateStatistics(const RTPHeader* rtp_header,
const uint16_t bytes,
const bool old_packet) {
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) {
// This is the first received report.
received_seq_first_ = rtp_header->header.sequenceNumber;
received_seq_max_ = rtp_header->header.sequenceNumber;
received_seq_first_ = rtp_header->sequenceNumber;
received_seq_max_ = rtp_header->sequenceNumber;
received_inorder_packet_count_ = 1;
local_time_last_received_timestamp_ =
GetCurrentRTP(clock_, frequency_hz); // Time in samples.
@ -492,26 +476,26 @@ void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
}
// Count only the new packets received.
if (InOrderPacket(rtp_header->header.sequenceNumber)) {
if (InOrderPacket(rtp_header->sequenceNumber)) {
const uint32_t RTPtime =
GetCurrentRTP(clock_, frequency_hz); // Time in samples.
received_inorder_packet_count_++;
// Wrong if we use RetransmitOfOldPacket.
int32_t seq_diff =
rtp_header->header.sequenceNumber - received_seq_max_;
rtp_header->sequenceNumber - received_seq_max_;
if (seq_diff < 0) {
// Wrap around detected.
received_seq_wraps_++;
}
// 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) {
int32_t time_diff_samples =
(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);
@ -528,7 +512,7 @@ void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
// Actual network jitter, excluding the source-introduced jitter.
int32_t time_diff_samples_ext =
(RTPtime - local_time_last_received_timestamp_) -
((rtp_header->header.timestamp +
((rtp_header->timestamp +
rtp_header->extension.transmissionTimeOffset) -
(last_received_timestamp_ +
last_received_transmission_time_offset_));
@ -552,7 +536,7 @@ void RTPReceiver::UpdateStatistics(const WebRtcRTPHeader* rtp_header,
}
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:
// 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.
void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtp_header) {
void RTPReceiver::CheckSSRCChanged(const RTPHeader* rtp_header) {
bool new_ssrc = false;
bool re_initialize_decoder = false;
char payload_name[RTP_PAYLOAD_NAME_SIZE];
@ -689,7 +673,7 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtp_header) {
int8_t 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)) {
// We need the payload_type_ to make the call if the remote SSRC is 0.
new_ssrc = true;
@ -704,12 +688,12 @@ void RTPReceiver::CheckSSRCChanged(const WebRtcRTPHeader* rtp_header) {
// Do we have a SSRC? Then the stream is restarted.
if (ssrc_) {
// 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;
Payload* payload;
if (rtp_payload_registry_->PayloadTypeToPayload(
rtp_header->header.payloadType, payload) != 0) {
rtp_header->payloadType, payload) != 0) {
return;
}
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) {
// We need to get this to our RTCP sender and receiver.
// We need to do this outside critical section.
rtp_rtcp_.SetRemoteSSRC(rtp_header->header.ssrc);
cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->header.ssrc);
rtp_rtcp_.SetRemoteSSRC(rtp_header->ssrc);
cb_rtp_feedback_->OnIncomingSSRCChanged(id_, rtp_header->ssrc);
}
if (re_initialize_decoder) {
if (-1 == cb_rtp_feedback_->OnInitializeDecoder(
id_, rtp_header->header.payloadType, payload_name, frequency,
id_, rtp_header->payloadType, payload_name, frequency,
channels, rate)) {
// New stream, same codec.
WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, id_,
"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
// last known payload).
int32_t RTPReceiver::CheckPayloadChanged(
const WebRtcRTPHeader* rtp_header,
const RTPHeader* rtp_header,
const int8_t first_payload_byte,
bool& is_red,
ModuleRTPUtility::PayloadUnion* specific_payload) {
bool re_initialize_decoder = false;
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_);

View File

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

View File

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

View File

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

View File

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

View File

@ -565,48 +565,47 @@ void ModuleRtpRtcpImpl::SetRtxReceivePayloadType(int payload_type) {
}
// Called by the network module when we receive a packet.
int32_t ModuleRtpRtcpImpl::IncomingPacket(
int32_t ModuleRtpRtcpImpl::IncomingRtpPacket(
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,
kTraceRtpRtcp,
id_,
"IncomingPacket(packet_length:%u)",
"IncomingRtpPacket(packet_length:%u)",
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 RTCP is 8 bytes (RTCP BYE).
if (incoming_packet_length < 8 || incoming_packet == NULL) {
WEBRTC_TRACE(kTraceDebug,
kTraceRtpRtcp,
id_,
"IncomingPacket invalid buffer or length");
return -1;
if (length == 8) {
WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, -1,
"IncomingRtcpPacket invalid length");
return false;
}
// Check RTP version.
const uint8_t version = incoming_packet[0] >> 6;
const uint8_t version = rtcp_packet[0] >> 6;
if (version != 2) {
WEBRTC_TRACE(kTraceDebug,
kTraceRtpRtcp,
id_,
"IncomingPacket invalid RTP version");
return -1;
WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, -1,
"IncomingRtcpPacket invalid RTP version");
return false;
}
ModuleRTPUtility::RTPHeaderParser rtp_parser(incoming_packet,
incoming_packet_length);
if (rtp_parser.RTCP()) {
// Allow receive of non-compound RTCP packets.
RTCPUtility::RTCPParserV2 rtcp_parser(incoming_packet,
incoming_packet_length,
true);
RTCPUtility::RTCPParserV2 rtcp_parser(rtcp_packet, length, true);
const bool valid_rtcpheader = rtcp_parser.IsValid();
if (!valid_rtcpheader) {
WEBRTC_TRACE(kTraceDebug,
kTraceRtpRtcp,
id_,
"IncomingPacket invalid RTCP packet");
WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, id_,
"IncomingRtcpPacket invalid RTCP packet");
return -1;
}
RTCPHelp::RTCPPacketInformation rtcp_packet_information;
@ -616,26 +615,6 @@ int32_t ModuleRtpRtcpImpl::IncomingPacket(
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);
}
}
int32_t ModuleRtpRtcpImpl::RegisterSendPayload(
@ -1434,17 +1413,6 @@ int32_t ModuleRtpRtcpImpl::DeregisterSendRtpHeaderExtension(
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.
bool ModuleRtpRtcpImpl::TMMBR() const {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "TMMBR()");
@ -1682,11 +1650,6 @@ int32_t ModuleRtpRtcpImpl::SetRTPAudioLevelIndicationStatus(
enable,
id);
if (enable) {
rtp_receiver_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel, id);
} else {
rtp_receiver_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel);
}
return rtp_sender_.SetAudioLevelIndicationStatus(enable, id);
}

View File

@ -70,14 +70,6 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
virtual int32_t DeRegisterReceivePayload(
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.
virtual int32_t SSRCFilter(uint32_t& allowed_ssrc) const;
@ -108,9 +100,14 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
virtual void SetRtxReceivePayloadType(int payload_type);
// Called by the network module when we receive a packet.
virtual int32_t IncomingPacket(const uint8_t* incoming_packet,
const uint16_t packet_length);
// Called when we receive an RTP packet.
virtual int32_t IncomingRtpPacket(const uint8_t* incoming_packet,
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.

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

View File

@ -155,11 +155,11 @@ class RTPSender : public Bitrate, public RTPSenderInterface {
bool UpdateTransmissionTimeOffset(uint8_t *rtp_packet,
const uint16_t rtp_packet_length,
const WebRtcRTPHeader &rtp_header,
const RTPHeader &rtp_header,
const int64_t time_diff_ms) const;
bool UpdateAbsoluteSendTime(uint8_t *rtp_packet,
const uint16_t rtp_packet_length,
const WebRtcRTPHeader &rtp_header,
const RTPHeader &rtp_header,
const int64_t now_ms) const;
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;
uint8_t packet_[kMaxPacketLength];
void VerifyRTPHeaderCommon(const WebRtcRTPHeader& rtp_header) {
EXPECT_EQ(kMarkerBit, rtp_header.header.markerBit);
EXPECT_EQ(payload_, rtp_header.header.payloadType);
EXPECT_EQ(kSeqNum, rtp_header.header.sequenceNumber);
EXPECT_EQ(kTimestamp, rtp_header.header.timestamp);
EXPECT_EQ(rtp_sender_->SSRC(), rtp_header.header.ssrc);
EXPECT_EQ(0, rtp_header.header.numCSRCs);
EXPECT_EQ(0, rtp_header.header.paddingLength);
void VerifyRTPHeaderCommon(const RTPHeader& rtp_header) {
EXPECT_EQ(kMarkerBit, rtp_header.markerBit);
EXPECT_EQ(payload_, rtp_header.payloadType);
EXPECT_EQ(kSeqNum, rtp_header.sequenceNumber);
EXPECT_EQ(kTimestamp, rtp_header.timestamp);
EXPECT_EQ(rtp_sender_->SSRC(), rtp_header.ssrc);
EXPECT_EQ(0, rtp_header.numCSRCs);
EXPECT_EQ(0, rtp_header.paddingLength);
}
};
@ -170,7 +170,7 @@ TEST_F(RtpSenderTest, BuildRTPPacket) {
// Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset,
@ -180,7 +180,7 @@ TEST_F(RtpSenderTest, BuildRTPPacket) {
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
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(0u, rtp_header.extension.absoluteSendTime);
}
@ -198,7 +198,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithTransmissionOffsetExtension) {
// Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset,
@ -208,16 +208,16 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithTransmissionOffsetExtension) {
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength);
EXPECT_EQ(length, rtp_header.headerLength);
EXPECT_EQ(kTimeOffset, rtp_header.extension.transmissionTimeOffset);
// Parse without map extension
webrtc::WebRtcRTPHeader rtp_header2;
webrtc::RTPHeader rtp_header2;
const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
ASSERT_TRUE(valid_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);
}
@ -235,7 +235,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithNegativeTransmissionOffsetExtension) {
// Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset,
@ -245,7 +245,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithNegativeTransmissionOffsetExtension) {
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength);
EXPECT_EQ(length, rtp_header.headerLength);
EXPECT_EQ(kNegTimeOffset, rtp_header.extension.transmissionTimeOffset);
}
@ -262,7 +262,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithAbsoluteSendTimeExtension) {
// Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId);
@ -271,16 +271,16 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithAbsoluteSendTimeExtension) {
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
VerifyRTPHeaderCommon(rtp_header);
EXPECT_EQ(length, rtp_header.header.headerLength);
EXPECT_EQ(length, rtp_header.headerLength);
EXPECT_EQ(kAbsoluteSendTime, rtp_header.extension.absoluteSendTime);
// Parse without map extension
webrtc::WebRtcRTPHeader rtp_header2;
webrtc::RTPHeader rtp_header2;
const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
ASSERT_TRUE(valid_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);
}
@ -300,7 +300,7 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithHeaderExtensions) {
// Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset,
@ -311,17 +311,17 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithHeaderExtensions) {
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
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(kAbsoluteSendTime, rtp_header.extension.absoluteSendTime);
// Parse without map extension
webrtc::WebRtcRTPHeader rtp_header2;
webrtc::RTPHeader rtp_header2;
const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
ASSERT_TRUE(valid_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(0u, rtp_header2.extension.absoluteSendTime);
}
@ -364,7 +364,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) {
// Parse sent packet.
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(
transport_.last_sent_packet_, rtp_length);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId);
@ -425,7 +425,7 @@ TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) {
// Parse sent packet.
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(
transport_.last_sent_packet_, rtp_length);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId);
@ -454,15 +454,15 @@ TEST_F(RtpSenderTest, SendGenericVideo) {
ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_,
transport_.last_sent_packet_len_);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header,
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
transport_.last_sent_packet_);
uint8_t generic_header = *payload_data++;
ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
ModuleRTPUtility::GetPayloadDataLength(&rtp_header,
ModuleRTPUtility::GetPayloadDataLength(rtp_header,
transport_.last_sent_packet_len_));
EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
@ -483,7 +483,7 @@ TEST_F(RtpSenderTest, SendGenericVideo) {
transport_.last_sent_packet_len_);
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header,
payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
transport_.last_sent_packet_);
generic_header = *payload_data++;
@ -491,7 +491,7 @@ TEST_F(RtpSenderTest, SendGenericVideo) {
EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
ModuleRTPUtility::GetPayloadDataLength(&rtp_header,
ModuleRTPUtility::GetPayloadDataLength(rtp_header,
transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
@ -527,7 +527,7 @@ TEST_F(RtpSenderAudioTest, BuildRTPPacketWithAudioLevelExtension) {
// Verify
webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
RtpHeaderExtensionMap map;
map.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
@ -536,16 +536,16 @@ TEST_F(RtpSenderAudioTest, BuildRTPPacketWithAudioLevelExtension) {
ASSERT_TRUE(valid_rtp_header);
ASSERT_FALSE(rtp_parser.RTCP());
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.
// Parse without map extension
webrtc::WebRtcRTPHeader rtp_header2;
webrtc::RTPHeader rtp_header2;
const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
ASSERT_TRUE(valid_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.
}
@ -562,13 +562,13 @@ TEST_F(RtpSenderAudioTest, SendAudio) {
ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_,
transport_.last_sent_packet_len_);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header,
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
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_));
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_,
transport_.last_sent_packet_len_);
webrtc::WebRtcRTPHeader rtp_header;
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header,
const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(rtp_header,
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_));
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
*/
const uint8_t* GetPayloadData(const WebRtcRTPHeader* rtp_header,
const uint8_t* GetPayloadData(const RTPHeader& rtp_header,
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) {
uint16_t length = packet_length - rtp_header->header.paddingLength -
rtp_header->header.headerLength;
uint16_t length = packet_length - rtp_header.paddingLength -
rtp_header.headerLength;
return static_cast<uint16_t>(length);
}
@ -288,7 +288,7 @@ bool RTPHeaderParser::RTCP() const {
return RTCP;
}
bool RTPHeaderParser::Parse(WebRtcRTPHeader& parsedPacket,
bool RTPHeaderParser::Parse(RTPHeader& header,
RtpHeaderExtensionMap* ptrExtensionMap) const {
const ptrdiff_t length = _ptrRTPDataEnd - _ptrRTPDataBegin;
@ -332,31 +332,30 @@ bool RTPHeaderParser::Parse(WebRtcRTPHeader& parsedPacket,
return false;
}
parsedPacket.header.markerBit = M;
parsedPacket.header.payloadType = PT;
parsedPacket.header.sequenceNumber = sequenceNumber;
parsedPacket.header.timestamp = RTPTimestamp;
parsedPacket.header.ssrc = SSRC;
parsedPacket.header.numCSRCs = CC;
parsedPacket.header.paddingLength = P ? *(_ptrRTPDataEnd - 1) : 0;
header.markerBit = M;
header.payloadType = PT;
header.sequenceNumber = sequenceNumber;
header.timestamp = RTPTimestamp;
header.ssrc = SSRC;
header.numCSRCs = CC;
header.paddingLength = P ? *(_ptrRTPDataEnd - 1) : 0;
for (unsigned int i = 0; i < CC; ++i) {
uint32_t CSRC = *ptr++ << 24;
CSRC += *ptr++ << 16;
CSRC += *ptr++ << 8;
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
// is zero.
parsedPacket.extension.transmissionTimeOffset = 0;
header.extension.transmissionTimeOffset = 0;
// May not be present in packet.
parsedPacket.extension.absoluteSendTime = 0;
header.extension.absoluteSendTime = 0;
if (X) {
/* RTP header extension, RFC 3550.
@ -373,7 +372,7 @@ bool RTPHeaderParser::Parse(WebRtcRTPHeader& parsedPacket,
return false;
}
parsedPacket.header.headerLength += 4;
header.headerLength += 4;
uint16_t definedByProfile = *ptr++ << 8;
definedByProfile += *ptr++;
@ -387,18 +386,18 @@ bool RTPHeaderParser::Parse(WebRtcRTPHeader& parsedPacket,
}
if (definedByProfile == kRtpOneByteHeaderExtensionId) {
const uint8_t* ptrRTPDataExtensionEnd = ptr + XLen;
ParseOneByteExtensionHeader(parsedPacket,
ParseOneByteExtensionHeader(header,
ptrExtensionMap,
ptrRTPDataExtensionEnd,
ptr);
}
parsedPacket.header.headerLength += XLen;
header.headerLength += XLen;
}
return true;
}
void RTPHeaderParser::ParseOneByteExtensionHeader(
WebRtcRTPHeader& parsedPacket,
RTPHeader& header,
const RtpHeaderExtensionMap* ptrExtensionMap,
const uint8_t* ptrRTPDataExtensionEnd,
const uint8_t* ptr) const {
@ -446,10 +445,11 @@ void RTPHeaderParser::ParseOneByteExtensionHeader(
int32_t transmissionTimeOffset = *ptr++ << 16;
transmissionTimeOffset += *ptr++ << 8;
transmissionTimeOffset += *ptr++;
parsedPacket.extension.transmissionTimeOffset = transmissionTimeOffset;
header.extension.transmissionTimeOffset =
transmissionTimeOffset;
if (transmissionTimeOffset & 0x800000) {
// Negative offset, correct sign for Word24 to Word32.
parsedPacket.extension.transmissionTimeOffset |= 0xFF000000;
header.extension.transmissionTimeOffset |= 0xFF000000;
}
break;
}
@ -484,7 +484,7 @@ void RTPHeaderParser::ParseOneByteExtensionHeader(
uint32_t absoluteSendTime = *ptr++ << 16;
absoluteSendTime += *ptr++ << 8;
absoluteSendTime += *ptr++;
parsedPacket.extension.absoluteSendTime = absoluteSendTime;
header.extension.absoluteSendTime = absoluteSendTime;
break;
}
default: {

View File

@ -73,11 +73,11 @@ namespace ModuleRTPUtility
uint32_t pow2(uint8_t exp);
// 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);
// 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);
// Returns true if |newTimestamp| is older than |existingTimestamp|.
@ -124,12 +124,12 @@ namespace ModuleRTPUtility
~RTPHeaderParser();
bool RTCP() const;
bool Parse(WebRtcRTPHeader& parsedPacket,
bool Parse(RTPHeader& parsedPacket,
RtpHeaderExtensionMap* ptrExtensionMap = NULL) const;
private:
void ParseOneByteExtensionHeader(
WebRtcRTPHeader& parsedPacket,
RTPHeader& parsedPacket,
const RtpHeaderExtensionMap* ptrExtensionMap,
const uint8_t* ptrRTPDataExtensionEnd,
const uint8_t* ptr) const;

View File

@ -10,8 +10,10 @@
#include "testing/gtest/include/gtest/gtest.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_defines.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
namespace webrtc {
@ -37,17 +39,23 @@ class LoopBackTransport : public webrtc::Transport {
return len;
}
}
if (_rtpRtcpModule->IncomingPacket((const uint8_t*)data, len) == 0) {
return len;
}
RTPHeader header;
scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
if (!parser->Parse(static_cast<const uint8_t*>(data), len, &header)) {
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) {
if (_rtpRtcpModule->IncomingPacket((const uint8_t*)data, len) == 0) {
return len;
}
if (_rtpRtcpModule->IncomingRtcpPacket((const uint8_t*)data, len) < 0) {
return -1;
}
return len;
}
private:
int _count;
int _packetLoss;

View File

@ -153,7 +153,11 @@ TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) {
int packet_size = PaddingPacket(padding_packet, timestamp, seq_num,
kPadSize);
++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(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.
*/
#include "mt_test_common.h"
#include "webrtc/modules/video_coding/main/test/mt_test_common.h"
#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"
namespace webrtc {
@ -88,12 +89,15 @@ TransportCallback::TransportPackets()
_rtpPackets.pop_front();
// Send to receive side
if (_rtp->IncomingPacket((const uint8_t*)packet->data,
packet->length) < 0)
RTPHeader header;
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;
packet = NULL;
// Will return an error after the first packet that goes wrong
return -1;
}
delete packet;

View File

@ -193,7 +193,7 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface {
uint32_t dest_ip;
uint16_t source_port;
uint16_t dest_port;
WebRtcRTPHeader rtp_header;
RTPHeader rtp_header;
int32_t pos_in_file;
uint32_t payload_length;
};
@ -277,7 +277,7 @@ class PcapFileReaderImpl : public RtpPacketSourceInterface {
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_.push_back(marker);
}

View File

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

View File

@ -13,8 +13,8 @@
#include <cstdio>
#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/source/rtp_utility.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/rtp_file_reader.h"
@ -229,7 +229,7 @@ class SsrcHandlers {
handler->rtp_module_->SetRTCPStatus(kRtcpNonCompound);
handler->rtp_module_->SetREMBStatus(true);
handler->rtp_module_->SetSSRCFilter(true, ssrc);
handler->rtp_module_->RegisterReceiveRtpHeaderExtension(
handler->rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset,
kDefaultTransmissionTimeOffsetExtensionId);
@ -257,7 +257,13 @@ class SsrcHandlers {
void IncomingPacket(const uint8_t* data, uint32_t length) {
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:
Handler(uint32_t ssrc, const PayloadTypes& payload_types,
LostPackets* lost_packets)
: rtp_module_(),
: rtp_header_parser_(RtpHeaderParser::Create()),
rtp_module_(),
payload_sink_(),
ssrc_(ssrc),
payload_types_(payload_types),
@ -288,6 +295,7 @@ class SsrcHandlers {
return payload_types_;
}
scoped_ptr<RtpHeaderParser> rtp_header_parser_;
scoped_ptr<RtpRtcp> rtp_module_;
scoped_ptr<PayloadSinkInterface> payload_sink_;
@ -421,13 +429,13 @@ class RtpPlayerImpl : public RtpPlayerInterface {
assert(data);
assert(length > 0);
ModuleRTPUtility::RTPHeaderParser rtp_header_parser(data, length);
if (!rtp_header_parser.RTCP()) {
WebRtcRTPHeader header;
if (!rtp_header_parser.Parse(header, NULL)) {
scoped_ptr<RtpHeaderParser> rtp_header_parser(RtpHeaderParser::Create());
if (!rtp_header_parser->IsRtcp(data, length)) {
RTPHeader header;
if (!rtp_header_parser->Parse(data, length, &header)) {
return -1;
}
uint32_t ssrc = header.header.ssrc;
uint32_t ssrc = header.ssrc;
if (ssrc_handlers_.RegisterSsrc(ssrc, &lost_packets_) < 0) {
DEBUG_LOG1("Unable to register ssrc: %d", ssrc);
return -1;
@ -436,7 +444,7 @@ class RtpPlayerImpl : public RtpPlayerInterface {
if (no_loss_startup_ > 0) {
no_loss_startup_--;
} 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));
DEBUG_LOG1("Dropped packet: %d!", header.header.sequenceNumber);
return 0;

View File

@ -8,13 +8,14 @@
* 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 "common_video/libyuv/include/webrtc_libyuv.h"
#include "rtp_dump.h"
#include "test_macros.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.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"
namespace webrtc {
@ -292,12 +293,15 @@ RTPSendCompleteCallback::SendPacket(int channel, const void *data, int len)
_rtpPackets.pop_front();
assert(_rtp); // We must have a configured RTP module for this test.
// Send to receive side
if (_rtp->IncomingPacket((const uint8_t*)packet->data,
packet->length) < 0)
RTPHeader header;
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;
packet = NULL;
// Will return an error after the first packet that goes wrong
return -1;
}
delete packet;

View File

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

View File

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

View File

@ -873,13 +873,7 @@ int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) {
}
int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) {
if (enable) {
return rtp_rtcp_->RegisterReceiveRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, id);
} else {
return rtp_rtcp_->DeregisterReceiveRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset);
}
return vie_receiver_.SetReceiveTimestampOffsetStatus(enable, 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) {
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;
return 0;
return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id);
}
bool ViEChannel::GetReceiveAbsoluteSendTimeStatus() const {

View File

@ -13,6 +13,7 @@
#include <vector>
#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/utility/interface/rtp_dump.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)
: receive_cs_(CriticalSectionWrapper::CreateCriticalSection()),
channel_id_(channel_id),
rtp_header_parser_(RtpHeaderParser::Create()),
rtp_rtcp_(NULL),
vcm_(module_vcm),
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 rtp_packet_length) {
if (!receiving_) {
@ -168,8 +190,16 @@ int ViEReceiver::InsertRTPPacket(const int8_t* rtp_packet,
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.
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,
@ -213,11 +243,11 @@ int ViEReceiver::InsertRTCPPacket(const int8_t* rtcp_packet,
std::list<RtpRtcp*>::iterator it = rtp_rtcp_simulcast_.begin();
while (it != rtp_rtcp_simulcast_.end()) {
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.
return rtp_rtcp_->IncomingPacket(received_packet, received_packet_length);
return rtp_rtcp_->IncomingRtcpPacket(received_packet, received_packet_length);
}
void ViEReceiver::StartReceive() {

View File

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

View File

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

View File

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