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:
		| @@ -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 |  *  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 |  *  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) { | int32_t RtpHeaderExtensionMap::Deregister(const RTPExtensionType type) { | ||||||
|   uint8_t id; |   uint8_t id; | ||||||
|   if (GetId(type, &id) != 0) { |   if (GetId(type, &id) != 0) { | ||||||
|     return -1; |     return 0; | ||||||
|   } |   } | ||||||
|   std::map<uint8_t, HeaderExtension*>::iterator it = |   std::map<uint8_t, HeaderExtension*>::iterator it = | ||||||
|       extensionMap_.find(id); |       extensionMap_.find(id); | ||||||
|   | |||||||
| @@ -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 |  *  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 |  *  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)); |   EXPECT_EQ(-1, map_.Register(kRtpExtensionTransmissionTimeOffset, 15)); | ||||||
| } | } | ||||||
|  |  | ||||||
| TEST_F(RtpHeaderExtensionTest, DeregisterIllegalArg) { |  | ||||||
|   // Not registered. |  | ||||||
|   EXPECT_EQ(-1, map_.Deregister(kRtpExtensionTransmissionTimeOffset)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| TEST_F(RtpHeaderExtensionTest, NonUniqueId) { | TEST_F(RtpHeaderExtensionTest, NonUniqueId) { | ||||||
|   EXPECT_EQ(0, map_.Register(kRtpExtensionTransmissionTimeOffset, kId)); |   EXPECT_EQ(0, map_.Register(kRtpExtensionTransmissionTimeOffset, kId)); | ||||||
|   EXPECT_EQ(-1, map_.Register(kRtpExtensionTransmissionTimeOffset, kId)); |   EXPECT_EQ(-1, map_.Register(kRtpExtensionTransmissionTimeOffset, kId)); | ||||||
|   | |||||||
| @@ -917,7 +917,7 @@ RTPSender::SendToNetwork(WebRtc_UWord8* buffer, | |||||||
|   if (capture_time_ms >= 0) { |   if (capture_time_ms >= 0) { | ||||||
|     ModuleRTPUtility::RTPHeaderParser rtpParser(buffer, length); |     ModuleRTPUtility::RTPHeaderParser rtpParser(buffer, length); | ||||||
|     WebRtcRTPHeader rtp_header; |     WebRtcRTPHeader rtp_header; | ||||||
|     rtpParser.Parse(rtp_header, &_rtpHeaderExtensionMap); |     rtpParser.Parse(rtp_header); | ||||||
|     int64_t time_now = _clock.GetTimeInMS(); |     int64_t time_now = _clock.GetTimeInMS(); | ||||||
|     UpdateTransmissionTimeOffset(buffer, length, rtp_header, |     UpdateTransmissionTimeOffset(buffer, length, rtp_header, | ||||||
|                                  time_now - capture_time_ms); |                                  time_now - capture_time_ms); | ||||||
|   | |||||||
| @@ -608,7 +608,6 @@ void RTPHeaderParser::ParseOneByteExtensionHeader( | |||||||
|     const WebRtc_UWord8* ptrRTPDataExtensionEnd, |     const WebRtc_UWord8* ptrRTPDataExtensionEnd, | ||||||
|     const WebRtc_UWord8* ptr) const { |     const WebRtc_UWord8* ptr) const { | ||||||
|   if (!ptrExtensionMap) { |   if (!ptrExtensionMap) { | ||||||
|     WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, -1, "No extension map."); |  | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -209,6 +209,16 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP { | |||||||
|                             bool sender, |                             bool sender, | ||||||
|                             bool receiver) = 0; |                             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 |   // This function returns our locally created statistics of the received RTP | ||||||
|   // stream. |   // stream. | ||||||
|   virtual int GetReceivedRTCPStatistics( |   virtual int GetReceivedRTCPStatistics( | ||||||
|   | |||||||
| @@ -610,6 +610,44 @@ void ViEAutoTest::ViERtpRtcpAPITest() | |||||||
|       EXPECT_EQ(0, ViE.rtp_rtcp->SetNACKStatus(tbChannel.videoChannel, true)); |       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 |     //  Testing finished. Tear down Video Engine | ||||||
|     //*************************************************************** |     //*************************************************************** | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ | |||||||
| namespace webrtc { | namespace webrtc { | ||||||
|  |  | ||||||
| const int kMaxDecodeWaitTimeMs = 50; | const int kMaxDecodeWaitTimeMs = 50; | ||||||
|  | const int kInvalidRtpExtensionId = 0; | ||||||
|  |  | ||||||
| ViEChannel::ViEChannel(WebRtc_Word32 channel_id, | ViEChannel::ViEChannel(WebRtc_Word32 channel_id, | ||||||
|                        WebRtc_Word32 engine_id, |                        WebRtc_Word32 engine_id, | ||||||
| @@ -66,6 +67,7 @@ ViEChannel::ViEChannel(WebRtc_Word32 channel_id, | |||||||
|       intra_frame_observer_(intra_frame_observer), |       intra_frame_observer_(intra_frame_observer), | ||||||
|       bandwidth_observer_(bandwidth_observer), |       bandwidth_observer_(bandwidth_observer), | ||||||
|       rtp_packet_timeout_(false), |       rtp_packet_timeout_(false), | ||||||
|  |       send_timestamp_extension_id_(kInvalidRtpExtensionId), | ||||||
|       using_packet_spread_(false), |       using_packet_spread_(false), | ||||||
|       external_transport_(NULL), |       external_transport_(NULL), | ||||||
|       decoder_reset_(true), |       decoder_reset_(true), | ||||||
| @@ -121,20 +123,6 @@ WebRtc_Word32 ViEChannel::Init() { | |||||||
|     WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_), |     WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_), | ||||||
|                  "%s: RTP::SetRTCPStatus failure", __FUNCTION__); |                  "%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 |   // VCM initialization | ||||||
|   if (vcm_.InitializeReceiver() != 0) { |   if (vcm_.InitializeReceiver() != 0) { | ||||||
| @@ -299,12 +287,20 @@ WebRtc_Word32 ViEChannel::SetSendCodec(const VideoCodec& video_codec, | |||||||
|       if (restart_rtp) { |       if (restart_rtp) { | ||||||
|         rtp_rtcp->SetSendingStatus(true); |         rtp_rtcp->SetSendingStatus(true); | ||||||
|       } |       } | ||||||
|       if (rtp_rtcp->RegisterReceiveRtpHeaderExtension( |       if (send_timestamp_extension_id_ != kInvalidRtpExtensionId) { | ||||||
|           kRtpExtensionTransmissionTimeOffset, 1) != 0) { |         // 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_), |           WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_), | ||||||
|             "%s: could not register transmission time offset extension", |                        "%s: could not register transmission time extension", | ||||||
|                        __FUNCTION__); |                        __FUNCTION__); | ||||||
|         return -1; |         } | ||||||
|  |       } else { | ||||||
|  |         rtp_rtcp->DeregisterSendRtpHeaderExtension( | ||||||
|  |             kRtpExtensionTransmissionTimeOffset); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old |     // |RegisterSimulcastRtpRtcpModules| resets all old weak pointers and old | ||||||
| @@ -682,6 +678,28 @@ bool ViEChannel::EnableRemb(bool enable) { | |||||||
|   return true; |   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_Word32 ViEChannel::EnableTMMBR(const bool enable) { | ||||||
|   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), |   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), | ||||||
|                "%s: %d", __FUNCTION__, enable); |                "%s: %d", __FUNCTION__, enable); | ||||||
|   | |||||||
| @@ -106,6 +106,8 @@ class ViEChannel | |||||||
|                                        const unsigned char payload_typeFEC); |                                        const unsigned char payload_typeFEC); | ||||||
|   WebRtc_Word32 SetKeyFrameRequestMethod(const KeyFrameRequestMethod method); |   WebRtc_Word32 SetKeyFrameRequestMethod(const KeyFrameRequestMethod method); | ||||||
|   bool EnableRemb(bool enable); |   bool EnableRemb(bool enable); | ||||||
|  |   int SetSendTimestampOffsetStatus(bool enable, int id); | ||||||
|  |   int SetReceiveTimestampOffsetStatus(bool enable, int id); | ||||||
|   WebRtc_Word32 EnableTMMBR(const bool enable); |   WebRtc_Word32 EnableTMMBR(const bool enable); | ||||||
|   WebRtc_Word32 EnableKeyFrameRequestCallback(const bool enable); |   WebRtc_Word32 EnableKeyFrameRequestCallback(const bool enable); | ||||||
|  |  | ||||||
| @@ -373,6 +375,7 @@ class ViEChannel | |||||||
|   RtcpIntraFrameObserver* intra_frame_observer_; |   RtcpIntraFrameObserver* intra_frame_observer_; | ||||||
|   scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_; |   scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_; | ||||||
|   bool rtp_packet_timeout_; |   bool rtp_packet_timeout_; | ||||||
|  |   int send_timestamp_extension_id_; | ||||||
|   bool using_packet_spread_; |   bool using_packet_spread_; | ||||||
|  |  | ||||||
|   Transport* external_transport_; |   Transport* external_transport_; | ||||||
|   | |||||||
| @@ -613,6 +613,53 @@ int ViERTP_RTCPImpl::SetRembStatus(int video_channel, bool sender, | |||||||
|   return 0; |   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, | int ViERTP_RTCPImpl::GetReceivedRTCPStatistics(const int video_channel, | ||||||
|                                                uint16_t& fraction_lost, |                                                uint16_t& fraction_lost, | ||||||
|                                                unsigned int& cumulative_lost, |                                                unsigned int& cumulative_lost, | ||||||
|   | |||||||
| @@ -68,6 +68,12 @@ class ViERTP_RTCPImpl | |||||||
|                                        const ViEKeyFrameRequestMethod method); |                                        const ViEKeyFrameRequestMethod method); | ||||||
|   virtual int SetTMMBRStatus(const int video_channel, const bool enable); |   virtual int SetTMMBRStatus(const int video_channel, const bool enable); | ||||||
|   virtual int SetRembStatus(int video_channel, bool sender, bool receiver); |   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, |   virtual int GetReceivedRTCPStatistics(const int video_channel, | ||||||
|                                         uint16_t& fraction_lost, |                                         uint16_t& fraction_lost, | ||||||
|                                         unsigned int& cumulative_lost, |                                         unsigned int& cumulative_lost, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 mflodman@webrtc.org
					mflodman@webrtc.org