Added API to set RTP timestamp offset extension.

BUG=745

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2604 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2012-08-13 17:13:27 +00:00
parent 1fb39ba422
commit 90071dd647
10 changed files with 146 additions and 30 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2012 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
@ -48,7 +48,7 @@ int32_t RtpHeaderExtensionMap::Register(const RTPExtensionType type,
int32_t RtpHeaderExtensionMap::Deregister(const RTPExtensionType type) {
uint8_t id;
if (GetId(type, &id) != 0) {
return -1;
return 0;
}
std::map<uint8_t, HeaderExtension*>::iterator it =
extensionMap_.find(id);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2012 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
@ -44,11 +44,6 @@ TEST_F(RtpHeaderExtensionTest, RegisterIllegalArg) {
EXPECT_EQ(-1, map_.Register(kRtpExtensionTransmissionTimeOffset, 15));
}
TEST_F(RtpHeaderExtensionTest, DeregisterIllegalArg) {
// Not registered.
EXPECT_EQ(-1, map_.Deregister(kRtpExtensionTransmissionTimeOffset));
}
TEST_F(RtpHeaderExtensionTest, NonUniqueId) {
EXPECT_EQ(0, map_.Register(kRtpExtensionTransmissionTimeOffset, kId));
EXPECT_EQ(-1, map_.Register(kRtpExtensionTransmissionTimeOffset, kId));

View File

@ -917,7 +917,7 @@ RTPSender::SendToNetwork(WebRtc_UWord8* buffer,
if (capture_time_ms >= 0) {
ModuleRTPUtility::RTPHeaderParser rtpParser(buffer, length);
WebRtcRTPHeader rtp_header;
rtpParser.Parse(rtp_header, &_rtpHeaderExtensionMap);
rtpParser.Parse(rtp_header);
int64_t time_now = _clock.GetTimeInMS();
UpdateTransmissionTimeOffset(buffer, length, rtp_header,
time_now - capture_time_ms);

View File

@ -608,7 +608,6 @@ void RTPHeaderParser::ParseOneByteExtensionHeader(
const WebRtc_UWord8* ptrRTPDataExtensionEnd,
const WebRtc_UWord8* ptr) const {
if (!ptrExtensionMap) {
WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "No extension map.");
return;
}

View File

@ -209,6 +209,16 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP {
bool sender,
bool receiver) = 0;
// Enables RTP timestamp extension offset described in RFC 5450. This call
// must be done before ViECodec::SetSendCodec is called.
virtual int SetSendTimestampOffsetStatus(int video_channel,
bool enable,
int id) = 0;
virtual int SetReceiveTimestampOffsetStatus(int video_channel,
bool enable,
int id) = 0;
// This function returns our locally created statistics of the received RTP
// stream.
virtual int GetReceivedRTCPStatistics(

View File

@ -610,6 +610,44 @@ void ViEAutoTest::ViERtpRtcpAPITest()
EXPECT_EQ(0, ViE.rtp_rtcp->SetNACKStatus(tbChannel.videoChannel, true));
}
// Timsetamp offset extension.
// Valid range is 1 to 14 inclusive.
EXPECT_EQ(-1, ViE.rtp_rtcp->SetSendTimestampOffsetStatus(
tbChannel.videoChannel, true, 0));
EXPECT_EQ(-1, ViE.rtp_rtcp->SetSendTimestampOffsetStatus(
tbChannel.videoChannel, true, 15));
EXPECT_EQ(0, ViE.rtp_rtcp->SetSendTimestampOffsetStatus(
tbChannel.videoChannel, true, 3));
EXPECT_EQ(-1, ViE.rtp_rtcp->SetSendTimestampOffsetStatus(
tbChannel.videoChannel, true, 3));
EXPECT_EQ(0, ViE.rtp_rtcp->SetSendTimestampOffsetStatus(
tbChannel.videoChannel, false, 3));
EXPECT_EQ(0, ViE.rtp_rtcp->SetSendTimestampOffsetStatus(
tbChannel.videoChannel, true, 3));
EXPECT_EQ(0, ViE.rtp_rtcp->SetSendTimestampOffsetStatus(
tbChannel.videoChannel, false, 3));
EXPECT_EQ(0, ViE.rtp_rtcp->SetSendTimestampOffsetStatus(
tbChannel.videoChannel, false, 3));
EXPECT_EQ(-1, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus(
tbChannel.videoChannel, true, 0));
EXPECT_EQ(-1, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus(
tbChannel.videoChannel, true, 15));
EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus(
tbChannel.videoChannel, true, 3));
EXPECT_EQ(-1, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus(
tbChannel.videoChannel, true, 3));
EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus(
tbChannel.videoChannel, false, 3));
EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus(
tbChannel.videoChannel, true, 3));
EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus(
tbChannel.videoChannel, false, 3));
EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus(
tbChannel.videoChannel, false, 3));
//***************************************************************
// Testing finished. Tear down Video Engine
//***************************************************************

View File

@ -31,6 +31,7 @@
namespace webrtc {
const int kMaxDecodeWaitTimeMs = 50;
const int kInvalidRtpExtensionId = 0;
ViEChannel::ViEChannel(WebRtc_Word32 channel_id,
WebRtc_Word32 engine_id,
@ -66,6 +67,7 @@ ViEChannel::ViEChannel(WebRtc_Word32 channel_id,
intra_frame_observer_(intra_frame_observer),
bandwidth_observer_(bandwidth_observer),
rtp_packet_timeout_(false),
send_timestamp_extension_id_(kInvalidRtpExtensionId),
using_packet_spread_(false),
external_transport_(NULL),
decoder_reset_(true),
@ -121,20 +123,6 @@ WebRtc_Word32 ViEChannel::Init() {
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: RTP::SetRTCPStatus failure", __FUNCTION__);
}
if (rtp_rtcp_->RegisterSendRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, 1) != 0) {
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: RTP::RegisterSendRtpHeaderExtension failure",
__FUNCTION__);
return -1;
}
if (rtp_rtcp_->RegisterReceiveRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, 1) != 0) {
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: RTP::RegisterReceiveRtpHeaderExtension failure",
__FUNCTION__);
return -1;
}
// VCM initialization
if (vcm_.InitializeReceiver() != 0) {
@ -299,12 +287,20 @@ WebRtc_Word32 ViEChannel::SetSendCodec(const VideoCodec& video_codec,
if (restart_rtp) {
rtp_rtcp->SetSendingStatus(true);
}
if (rtp_rtcp->RegisterReceiveRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, 1) != 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: could not register transmission time offset extension",
__FUNCTION__);
return -1;
if (send_timestamp_extension_id_ != kInvalidRtpExtensionId) {
// Deregister in case the extension was previously enabled.
rtp_rtcp->DeregisterSendRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset);
if (rtp_rtcp->RegisterSendRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset,
send_timestamp_extension_id_) != 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: could not register transmission time extension",
__FUNCTION__);
}
} else {
rtp_rtcp->DeregisterSendRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset);
}
}
// |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old
@ -682,6 +678,28 @@ bool ViEChannel::EnableRemb(bool enable) {
return true;
}
int ViEChannel::SetSendTimestampOffsetStatus(bool enable, int id) {
if (enable) {
send_timestamp_extension_id_ = id;
return rtp_rtcp_->RegisterSendRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, id);
} else {
send_timestamp_extension_id_ = kInvalidRtpExtensionId;
return rtp_rtcp_->DeregisterSendRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset);
}
}
int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) {
if (enable) {
return rtp_rtcp_->RegisterReceiveRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, id);
} else {
return rtp_rtcp_->DeregisterReceiveRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset);
}
}
WebRtc_Word32 ViEChannel::EnableTMMBR(const bool enable) {
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
"%s: %d", __FUNCTION__, enable);

View File

@ -106,6 +106,8 @@ class ViEChannel
const unsigned char payload_typeFEC);
WebRtc_Word32 SetKeyFrameRequestMethod(const KeyFrameRequestMethod method);
bool EnableRemb(bool enable);
int SetSendTimestampOffsetStatus(bool enable, int id);
int SetReceiveTimestampOffsetStatus(bool enable, int id);
WebRtc_Word32 EnableTMMBR(const bool enable);
WebRtc_Word32 EnableKeyFrameRequestCallback(const bool enable);
@ -373,6 +375,7 @@ class ViEChannel
RtcpIntraFrameObserver* intra_frame_observer_;
scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_;
bool rtp_packet_timeout_;
int send_timestamp_extension_id_;
bool using_packet_spread_;
Transport* external_transport_;

View File

@ -613,6 +613,53 @@ int ViERTP_RTCPImpl::SetRembStatus(int video_channel, bool sender,
return 0;
}
int ViERTP_RTCPImpl::SetSendTimestampOffsetStatus(int video_channel,
bool enable,
int id) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"ViERTP_RTCPImpl::SetSendTimestampOffsetStatus(%d, %d, %d)",
video_channel, enable, id);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetSendTimestampOffsetStatus(enable, id) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::SetReceiveTimestampOffsetStatus(int video_channel,
bool enable,
int id) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"ViERTP_RTCPImpl::SetReceiveTimestampOffsetStatus(%d, %d, %d)",
video_channel, enable, id);
ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
ViEChannel* vie_channel = cs.Channel(video_channel);
if (!vie_channel) {
WEBRTC_TRACE(kTraceError, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetReceiveTimestampOffsetStatus(enable, id) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
return 0;
}
int ViERTP_RTCPImpl::GetReceivedRTCPStatistics(const int video_channel,
uint16_t& fraction_lost,
unsigned int& cumulative_lost,

View File

@ -68,6 +68,12 @@ class ViERTP_RTCPImpl
const ViEKeyFrameRequestMethod method);
virtual int SetTMMBRStatus(const int video_channel, const bool enable);
virtual int SetRembStatus(int video_channel, bool sender, bool receiver);
virtual int SetSendTimestampOffsetStatus(int video_channel,
bool enable,
int id);
virtual int SetReceiveTimestampOffsetStatus(int video_channel,
bool enable,
int id);
virtual int GetReceivedRTCPStatistics(const int video_channel,
uint16_t& fraction_lost,
unsigned int& cumulative_lost,