diff --git a/webrtc/video_engine/include/vie_rtp_rtcp.h b/webrtc/video_engine/include/vie_rtp_rtcp.h index d36b341ba..e2f079544 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 d94681a52..03d5b5eb9 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 53124a656..2129742af 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 540385f77..489abfb1b 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 a3ce9a3b3..845dfb6f8 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 134c9541d..a34af02e6 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 fb8bd542e..9af4b0c2b 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,