diff --git a/src/modules/rtp_rtcp/source/rtp_header_extension.cc b/src/modules/rtp_rtcp/source/rtp_header_extension.cc index 37a87d7dec..58b01bf410 100644 --- a/src/modules/rtp_rtcp/source/rtp_header_extension.cc +++ b/src/modules/rtp_rtcp/source/rtp_header_extension.cc @@ -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::iterator it = extensionMap_.find(id); diff --git a/src/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc b/src/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc index 003e92cc55..e4160c7c51 100644 --- a/src/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc +++ b/src/modules/rtp_rtcp/source/rtp_header_extension_unittest.cc @@ -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)); diff --git a/src/modules/rtp_rtcp/source/rtp_sender.cc b/src/modules/rtp_rtcp/source/rtp_sender.cc index 8652ff8128..757d25c314 100644 --- a/src/modules/rtp_rtcp/source/rtp_sender.cc +++ b/src/modules/rtp_rtcp/source/rtp_sender.cc @@ -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); diff --git a/src/modules/rtp_rtcp/source/rtp_utility.cc b/src/modules/rtp_rtcp/source/rtp_utility.cc index 67d53afd5b..298d47996e 100644 --- a/src/modules/rtp_rtcp/source/rtp_utility.cc +++ b/src/modules/rtp_rtcp/source/rtp_utility.cc @@ -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; } diff --git a/src/video_engine/include/vie_rtp_rtcp.h b/src/video_engine/include/vie_rtp_rtcp.h index f3a87667f0..15eef355cf 100644 --- a/src/video_engine/include/vie_rtp_rtcp.h +++ b/src/video_engine/include/vie_rtp_rtcp.h @@ -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( diff --git a/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc b/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc index d3a1331576..e3420429f4 100644 --- a/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc +++ b/src/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc @@ -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 //*************************************************************** diff --git a/src/video_engine/vie_channel.cc b/src/video_engine/vie_channel.cc index eae7e7f9ff..0d6d2d9d7e 100644 --- a/src/video_engine/vie_channel.cc +++ b/src/video_engine/vie_channel.cc @@ -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); diff --git a/src/video_engine/vie_channel.h b/src/video_engine/vie_channel.h index eadfc3b181..a9b90cc55b 100644 --- a/src/video_engine/vie_channel.h +++ b/src/video_engine/vie_channel.h @@ -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 bandwidth_observer_; bool rtp_packet_timeout_; + int send_timestamp_extension_id_; bool using_packet_spread_; Transport* external_transport_; diff --git a/src/video_engine/vie_rtp_rtcp_impl.cc b/src/video_engine/vie_rtp_rtcp_impl.cc index 2e009ffe41..b4b4746948 100644 --- a/src/video_engine/vie_rtp_rtcp_impl.cc +++ b/src/video_engine/vie_rtp_rtcp_impl.cc @@ -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, diff --git a/src/video_engine/vie_rtp_rtcp_impl.h b/src/video_engine/vie_rtp_rtcp_impl.h index 1d96e084cb..7c1614b9d6 100644 --- a/src/video_engine/vie_rtp_rtcp_impl.h +++ b/src/video_engine/vie_rtp_rtcp_impl.h @@ -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,