diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc index f6f496c628..4027315d99 100644 --- a/webrtc/voice_engine/channel.cc +++ b/webrtc/voice_engine/channel.cc @@ -799,6 +799,8 @@ Channel::OnReceivedPayloadData(const WebRtc_UWord8* payloadData, rtpHeader->header.payloadType, rtpHeader->type.Audio.channel); + _lastRemoteTimeStamp = rtpHeader->header.timestamp; + if (!_playing) { // Avoid inserting into NetEQ when we are not playing. Count the @@ -1152,6 +1154,7 @@ Channel::Channel(const WebRtc_Word32 channelId, _insertExtraRTPPacket(false), _extraMarkerBit(false), _lastLocalTimeStamp(0), + _lastRemoteTimeStamp(0), _lastPayloadType(0), _includeAudioLevelIndication(false), _rtpPacketTimedOut(false), diff --git a/webrtc/voice_engine/channel.h b/webrtc/voice_engine/channel.h index 2aacf3b555..7469a77b98 100644 --- a/webrtc/voice_engine/channel.h +++ b/webrtc/voice_engine/channel.h @@ -359,6 +359,7 @@ public: int InsertExtraRTPPacket(unsigned char payloadType, bool markerBit, const char* payloadData, unsigned short payloadSize); + uint32_t LastRemoteTimeStamp() { return _lastRemoteTimeStamp; } public: // From AudioPacketizationCallback in the ACM @@ -635,6 +636,7 @@ private: bool _insertExtraRTPPacket; bool _extraMarkerBit; WebRtc_UWord32 _lastLocalTimeStamp; + uint32_t _lastRemoteTimeStamp; WebRtc_Word8 _lastPayloadType; bool _includeAudioLevelIndication; // VoENetwork diff --git a/webrtc/voice_engine/include/voe_rtp_rtcp.h b/webrtc/voice_engine/include/voe_rtp_rtcp.h index fd0ca0b4d2..4f22c59a12 100644 --- a/webrtc/voice_engine/include/voe_rtp_rtcp.h +++ b/webrtc/voice_engine/include/voe_rtp_rtcp.h @@ -245,6 +245,10 @@ public: int channel, unsigned char payloadType, bool markerBit, const char* payloadData, unsigned short payloadSize) = 0; + // Gets the timestamp of the last RTP packet received by |channel|. + virtual int GetLastRemoteTimeStamp(int channel, + uint32_t* lastRemoteTimeStamp) = 0; + protected: VoERTP_RTCP() {} virtual ~VoERTP_RTCP() {} diff --git a/webrtc/voice_engine/test/auto_test/standard/rtp_rtcp_before_streaming_test.cc b/webrtc/voice_engine/test/auto_test/standard/rtp_rtcp_before_streaming_test.cc index 93170f61cd..5532bbff2b 100644 --- a/webrtc/voice_engine/test/auto_test/standard/rtp_rtcp_before_streaming_test.cc +++ b/webrtc/voice_engine/test/auto_test/standard/rtp_rtcp_before_streaming_test.cc @@ -48,3 +48,9 @@ TEST_F(RtpRtcpBeforeStreamingTest, GetLocalSsrcObeysSetLocalSsrc) { EXPECT_EQ(0, voe_rtp_rtcp_->GetLocalSSRC(channel_, result)); EXPECT_EQ(1234u, result); } + +TEST_F(RtpRtcpBeforeStreamingTest, GetLastRemoteTimeStamp) { + uint32_t timestamp; + EXPECT_EQ(0, voe_rtp_rtcp_->GetLastRemoteTimeStamp(channel_, ×tamp)); + EXPECT_EQ(0u, timestamp); +} diff --git a/webrtc/voice_engine/voe_rtp_rtcp_impl.cc b/webrtc/voice_engine/voe_rtp_rtcp_impl.cc index d21f722def..0414ecdac4 100644 --- a/webrtc/voice_engine/voe_rtp_rtcp_impl.cc +++ b/webrtc/voice_engine/voe_rtp_rtcp_impl.cc @@ -662,6 +662,27 @@ int VoERTP_RTCPImpl::InsertExtraRTPPacket(int channel, payloadSize); } +int VoERTP_RTCPImpl::GetLastRemoteTimeStamp(int channel, + uint32_t* timestamp) { + WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1), + "GetLastRemoteTimeStamp(channel=%d, timestamp=?)", channel); + if (!_shared->statistics().Initialized()) + { + _shared->SetLastError(VE_NOT_INITED, kTraceError); + return -1; + } + voe::ScopedChannel sc(_shared->channel_manager(), channel); + voe::Channel* channelPtr = sc.ChannelPtr(); + if (channelPtr == NULL) + { + _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, + "GetLastRemoteTimeStamp() failed to locate channel"); + return -1; + } + *timestamp = channelPtr->LastRemoteTimeStamp(); + return 0; +} + #endif // #ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API } // namespace webrtc diff --git a/webrtc/voice_engine/voe_rtp_rtcp_impl.h b/webrtc/voice_engine/voe_rtp_rtcp_impl.h index 721499cf5e..3d64205b9a 100644 --- a/webrtc/voice_engine/voe_rtp_rtcp_impl.h +++ b/webrtc/voice_engine/voe_rtp_rtcp_impl.h @@ -111,7 +111,8 @@ public: bool markerBit, const char* payloadData, unsigned short payloadSize); - + virtual int GetLastRemoteTimeStamp(int channel, + uint32_t* lastRemoteTimeStamp); protected: VoERTP_RTCPImpl(voe::SharedData* shared); virtual ~VoERTP_RTCPImpl();