From cb9cff0c7190ac66660056245f7095d7a8c3e247 Mon Sep 17 00:00:00 2001 From: "solenberg@webrtc.org" Date: Mon, 20 May 2013 12:00:23 +0000 Subject: [PATCH] Add functions to ViE API to enable/disable the absolute send time header extension. BUG= R=mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1487004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4065 4adac7df-926f-26a2-2b94-8c16560cd09d --- webrtc/video_engine/include/vie_rtp_rtcp.h | 10 ++++ .../auto_test/source/vie_autotest_rtp_rtcp.cc | 38 ++++++++++++- webrtc/video_engine/vie_channel.cc | 57 +++++++++++++++++++ webrtc/video_engine/vie_channel.h | 3 + webrtc/video_engine/vie_encoder.cc | 7 --- webrtc/video_engine/vie_rtp_rtcp_impl.cc | 47 +++++++++++++++ webrtc/video_engine/vie_rtp_rtcp_impl.h | 6 ++ 7 files changed, 160 insertions(+), 8 deletions(-) diff --git a/webrtc/video_engine/include/vie_rtp_rtcp.h b/webrtc/video_engine/include/vie_rtp_rtcp.h index d36b341baa..e2f0795442 100644 --- a/webrtc/video_engine/include/vie_rtp_rtcp.h +++ b/webrtc/video_engine/include/vie_rtp_rtcp.h @@ -242,6 +242,16 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP { bool enable, int id) = 0; + // Enables RTP absolute send time header extension. This call must be done + // before ViECodec::SetSendCodec is called. + virtual int SetSendAbsoluteSendTimeStatus(int video_channel, + bool enable, + int id) = 0; + + virtual int SetReceiveAbsoluteSendTimeStatus(int video_channel, + bool enable, + int id) = 0; + // Enables transmission smoothening, i.e. packets belonging to the same frame // will be sent over a longer period of time instead of sending them // back-to-back. diff --git a/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc b/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc index d94681a529..03d5b5eb93 100644 --- a/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc +++ b/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc @@ -718,7 +718,7 @@ void ViEAutoTest::ViERtpRtcpAPITest() EXPECT_EQ(0, ViE.rtp_rtcp->SetNACKStatus(tbChannel.videoChannel, true)); } - // Timsetamp offset extension. + // Timestamp offset extension. // Valid range is 1 to 14 inclusive. EXPECT_EQ(-1, ViE.rtp_rtcp->SetSendTimestampOffsetStatus( tbChannel.videoChannel, true, 0)); @@ -754,6 +754,42 @@ void ViEAutoTest::ViERtpRtcpAPITest() EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveTimestampOffsetStatus( tbChannel.videoChannel, false, 3)); + // Absolute send time extension. + // Valid range is 1 to 14 inclusive. + EXPECT_EQ(-1, ViE.rtp_rtcp->SetSendAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 0)); + EXPECT_EQ(-1, ViE.rtp_rtcp->SetSendAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 15)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetSendAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetSendAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetSendAbsoluteSendTimeStatus( + tbChannel.videoChannel, false, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetSendAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetSendAbsoluteSendTimeStatus( + tbChannel.videoChannel, false, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetSendAbsoluteSendTimeStatus( + tbChannel.videoChannel, false, 3)); + + EXPECT_EQ(-1, ViE.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 0)); + EXPECT_EQ(-1, ViE.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 15)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus( + tbChannel.videoChannel, false, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus( + tbChannel.videoChannel, true, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus( + tbChannel.videoChannel, false, 3)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus( + tbChannel.videoChannel, false, 3)); + // Transmission smoothening. const int invalid_channel_id = 17; EXPECT_EQ(-1, ViE.rtp_rtcp->SetTransmissionSmoothingStatus( diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 53124a656a..2129742af6 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -90,6 +90,7 @@ ViEChannel::ViEChannel(int32_t channel_id, bandwidth_observer_(bandwidth_observer), rtp_packet_timeout_(false), send_timestamp_extension_id_(kInvalidRtpExtensionId), + absolute_send_time_extension_id_(kInvalidRtpExtensionId), using_packet_spread_(false), external_transport_(NULL), decoder_reset_(true), @@ -370,6 +371,21 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec, rtp_rtcp->DeregisterSendRtpHeaderExtension( kRtpExtensionTransmissionTimeOffset); } + if (absolute_send_time_extension_id_ != kInvalidRtpExtensionId) { + // Deregister in case the extension was previously enabled. + rtp_rtcp->DeregisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime); + if (rtp_rtcp->RegisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime, + absolute_send_time_extension_id_) != 0) { + WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_), + "%s: could not register absolute send time extension", + __FUNCTION__); + } + } else { + rtp_rtcp->DeregisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime); + } } // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old // modules can be deleted after this step. @@ -865,6 +881,47 @@ int ViEChannel::SetReceiveTimestampOffsetStatus(bool enable, int id) { } } +int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) { + CriticalSectionScoped cs(rtp_rtcp_cs_.get()); + int error = 0; + if (enable) { + // Enable the extension, but disable possible old id to avoid errors. + absolute_send_time_extension_id_ = id; + rtp_rtcp_->DeregisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime); + error = rtp_rtcp_->RegisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime, id); + for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); + it != simulcast_rtp_rtcp_.end(); it++) { + (*it)->DeregisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime); + error |= (*it)->RegisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime, id); + } + } else { + // Disable the extension. + absolute_send_time_extension_id_ = kInvalidRtpExtensionId; + rtp_rtcp_->DeregisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime); + for (std::list::iterator it = simulcast_rtp_rtcp_.begin(); + it != simulcast_rtp_rtcp_.end(); it++) { + (*it)->DeregisterSendRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime); + } + } + return error; +} + +int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { + if (enable) { + return rtp_rtcp_->RegisterReceiveRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime, id); + } else { + return rtp_rtcp_->DeregisterReceiveRtpHeaderExtension( + kRtpExtensionAbsoluteSendTime); + } +} + void ViEChannel::SetTransmissionSmoothingStatus(bool enable) { assert(paced_sender_ && "No paced sender registered."); paced_sender_->SetStatus(enable); diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index 540385f770..489abfb1ba 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -123,6 +123,8 @@ class ViEChannel bool EnableRemb(bool enable); int SetSendTimestampOffsetStatus(bool enable, int id); int SetReceiveTimestampOffsetStatus(bool enable, int id); + int SetSendAbsoluteSendTimeStatus(bool enable, int id); + int SetReceiveAbsoluteSendTimeStatus(bool enable, int id); void SetTransmissionSmoothingStatus(bool enable); int32_t EnableTMMBR(const bool enable); int32_t EnableKeyFrameRequestCallback(const bool enable); @@ -382,6 +384,7 @@ class ViEChannel scoped_ptr bandwidth_observer_; bool rtp_packet_timeout_; int send_timestamp_extension_id_; + int absolute_send_time_extension_id_; bool using_packet_spread_; Transport* external_transport_; diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index a3ce9a3b34..845dfb6f80 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -194,13 +194,6 @@ bool ViEEncoder::Init() { "%s RegisterSendPayload failure", __FUNCTION__); return false; } - if (default_rtp_rtcp_->RegisterSendRtpHeaderExtension( - kRtpExtensionTransmissionTimeOffset, 1) != 0) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, - ViEId(engine_id_, channel_id_), - "%s RegisterSendRtpHeaderExtension failure", __FUNCTION__); - return false; - } #else VideoCodec video_codec; if (vcm_.Codec(webrtc::kVideoCodecI420, &video_codec) == VCM_OK) { diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.cc b/webrtc/video_engine/vie_rtp_rtcp_impl.cc index 134c9541d4..a34af02e69 100644 --- a/webrtc/video_engine/vie_rtp_rtcp_impl.cc +++ b/webrtc/video_engine/vie_rtp_rtcp_impl.cc @@ -765,6 +765,53 @@ int ViERTP_RTCPImpl::SetReceiveTimestampOffsetStatus(int video_channel, return 0; } +int ViERTP_RTCPImpl::SetSendAbsoluteSendTimeStatus(int video_channel, + bool enable, + int id) { + WEBRTC_TRACE(kTraceApiCall, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "ViERTP_RTCPImpl::SetSendAbsoluteSendTimeStatus(%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->SetSendAbsoluteSendTimeStatus(enable, id) != 0) { + shared_data_->SetLastError(kViERtpRtcpUnknownError); + return -1; + } + return 0; +} + +int ViERTP_RTCPImpl::SetReceiveAbsoluteSendTimeStatus(int video_channel, + bool enable, + int id) { + WEBRTC_TRACE(kTraceApiCall, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "ViERTP_RTCPImpl::SetReceiveAbsoluteSendTimeStatus(%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->SetReceiveAbsoluteSendTimeStatus(enable, id) != 0) { + shared_data_->SetLastError(kViERtpRtcpUnknownError); + return -1; + } + return 0; +} + int ViERTP_RTCPImpl::SetTransmissionSmoothingStatus(int video_channel, bool enable) { WEBRTC_TRACE(kTraceApiCall, kTraceVideo, diff --git a/webrtc/video_engine/vie_rtp_rtcp_impl.h b/webrtc/video_engine/vie_rtp_rtcp_impl.h index fb8bd542eb..9af4b0c2b2 100644 --- a/webrtc/video_engine/vie_rtp_rtcp_impl.h +++ b/webrtc/video_engine/vie_rtp_rtcp_impl.h @@ -82,6 +82,12 @@ class ViERTP_RTCPImpl virtual int SetReceiveTimestampOffsetStatus(int video_channel, bool enable, int id); + virtual int SetSendAbsoluteSendTimeStatus(int video_channel, + bool enable, + int id); + virtual int SetReceiveAbsoluteSendTimeStatus(int video_channel, + bool enable, + int id); virtual int SetTransmissionSmoothingStatus(int video_channel, bool enable); virtual int GetReceivedRTCPStatistics(const int video_channel, uint16_t& fraction_lost,