[rtp_rtcp] time helper functions

RTP timestams helper functions moved from rtp_utility
  added functions to deal with CompactNtp timestamps

R=åsapersson
BUG=webrtc:5260

Review URL: https://codereview.webrtc.org/1535113002

Cr-Commit-Position: refs/heads/master@{#11106}
This commit is contained in:
danilchap 2015-12-21 11:06:50 -08:00 committed by Commit bot
parent 5908c71128
commit 1227e8b345
9 changed files with 126 additions and 66 deletions

View File

@ -328,6 +328,7 @@
'rtp_rtcp/source/rtp_rtcp_impl_unittest.cc',
'rtp_rtcp/source/rtp_header_extension_unittest.cc',
'rtp_rtcp/source/rtp_sender_unittest.cc',
'rtp_rtcp/source/time_util_unittest.cc',
'rtp_rtcp/source/vp8_partition_aggregator_unittest.cc',
'rtp_rtcp/test/testAPI/test_api.cc',
'rtp_rtcp/test/testAPI/test_api.h',

View File

@ -14,7 +14,7 @@
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
#include "webrtc/modules/rtp_rtcp/source/time_util.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
namespace webrtc {
@ -37,8 +37,6 @@ StreamStatisticianImpl::StreamStatisticianImpl(
cumulative_loss_(0),
jitter_q4_transmission_time_offset_(0),
last_receive_time_ms_(0),
last_receive_time_secs_(0),
last_receive_time_frac_(0),
last_received_timestamp_(0),
last_received_transmission_time_offset_(0),
received_seq_first_(0),
@ -79,9 +77,7 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
// are received, 4 will be ignored.
if (in_order) {
// Current time in samples.
uint32_t receive_time_secs;
uint32_t receive_time_frac;
clock_->CurrentNtp(receive_time_secs, receive_time_frac);
NtpTime receive_time(*clock_);
// Wrong if we use RetransmitOfOldPacket.
if (receive_counters_.transmitted.packets > 1 &&
@ -97,11 +93,10 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
if (header.timestamp != last_received_timestamp_ &&
(receive_counters_.transmitted.packets -
receive_counters_.retransmitted.packets) > 1) {
UpdateJitter(header, receive_time_secs, receive_time_frac);
UpdateJitter(header, receive_time);
}
last_received_timestamp_ = header.timestamp;
last_receive_time_secs_ = receive_time_secs;
last_receive_time_frac_ = receive_time_frac;
last_receive_time_ntp_ = receive_time;
last_receive_time_ms_ = clock_->TimeInMilliseconds();
}
@ -113,14 +108,11 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
}
void StreamStatisticianImpl::UpdateJitter(const RTPHeader& header,
uint32_t receive_time_secs,
uint32_t receive_time_frac) {
uint32_t receive_time_rtp = RtpUtility::ConvertNTPTimeToRTP(
receive_time_secs, receive_time_frac, header.payload_type_frequency);
NtpTime receive_time) {
uint32_t receive_time_rtp =
NtpToRtp(receive_time, header.payload_type_frequency);
uint32_t last_receive_time_rtp =
RtpUtility::ConvertNTPTimeToRTP(last_receive_time_secs_,
last_receive_time_frac_,
header.payload_type_frequency);
NtpToRtp(last_receive_time_ntp_, header.payload_type_frequency);
int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) -
(header.timestamp - last_received_timestamp_);
@ -319,8 +311,8 @@ void StreamStatisticianImpl::ProcessBitrate() {
void StreamStatisticianImpl::LastReceiveTimeNtp(uint32_t* secs,
uint32_t* frac) const {
CriticalSectionScoped cs(stream_lock_.get());
*secs = last_receive_time_secs_;
*frac = last_receive_time_frac_;
*secs = last_receive_time_ntp_.seconds();
*frac = last_receive_time_ntp_.fractions();
}
bool StreamStatisticianImpl::IsRetransmitOfOldPacket(

View File

@ -19,6 +19,7 @@
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/source/bitrate.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/ntp_time.h"
namespace webrtc {
@ -52,9 +53,7 @@ class StreamStatisticianImpl : public StreamStatistician {
private:
bool InOrderPacketInternal(uint16_t sequence_number) const;
RtcpStatistics CalculateRtcpStatistics();
void UpdateJitter(const RTPHeader& header,
uint32_t receive_time_secs,
uint32_t receive_time_frac);
void UpdateJitter(const RTPHeader& header, NtpTime receive_time);
void UpdateCounters(const RTPHeader& rtp_header,
size_t packet_length,
bool retransmitted);
@ -73,8 +72,7 @@ class StreamStatisticianImpl : public StreamStatistician {
uint32_t jitter_q4_transmission_time_offset_;
int64_t last_receive_time_ms_;
uint32_t last_receive_time_secs_;
uint32_t last_receive_time_frac_;
NtpTime last_receive_time_ntp_;
uint32_t last_received_timestamp_;
int32_t last_received_transmission_time_offset_;
uint16_t received_seq_first_;

View File

@ -22,7 +22,6 @@
namespace webrtc {
using RtpUtility::GetCurrentRTP;
using RtpUtility::Payload;
using RtpUtility::StringCompare;

View File

@ -21,6 +21,7 @@
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h"
#include "webrtc/modules/rtp_rtcp/source/time_util.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/tick_util.h"
@ -1643,7 +1644,7 @@ uint16_t RTPSender::UpdateTransportSequenceNumber(
void RTPSender::SetSendingStatus(bool enabled) {
if (enabled) {
uint32_t frequency_hz = SendPayloadFrequency();
uint32_t RTPtime = RtpUtility::GetCurrentRTP(clock_, frequency_hz);
uint32_t RTPtime = CurrentRtp(*clock_, frequency_hz);
// Will be ignored if it's already configured via API.
SetStartTimestamp(RTPtime, false);

View File

@ -76,38 +76,6 @@ enum {
kRtpMinParseLength = 12
};
/*
* Time routines.
*/
uint32_t GetCurrentRTP(Clock* clock, uint32_t freq) {
const bool use_global_clock = (clock == NULL);
Clock* local_clock = clock;
if (use_global_clock) {
local_clock = Clock::GetRealTimeClock();
}
uint32_t secs = 0, frac = 0;
local_clock->CurrentNtp(secs, frac);
if (use_global_clock) {
delete local_clock;
}
return ConvertNTPTimeToRTP(secs, frac, freq);
}
uint32_t ConvertNTPTimeToRTP(uint32_t NTPsec, uint32_t NTPfrac, uint32_t freq) {
float ftemp = (float)NTPfrac / (float)NTP_FRAC;
uint32_t tmp = (uint32_t)(ftemp * freq);
return NTPsec * freq + tmp;
}
uint32_t ConvertNTPTimeToMS(uint32_t NTPsec, uint32_t NTPfrac) {
int freq = 1000;
float ftemp = (float)NTPfrac / (float)NTP_FRAC;
uint32_t tmp = (uint32_t)(ftemp * freq);
uint32_t MStime = NTPsec * freq + tmp;
return MStime;
}
/*
* Misc utility routines
*/

View File

@ -46,15 +46,6 @@ namespace RtpUtility {
typedef std::map<int8_t, Payload*> PayloadTypeMap;
// Return the current RTP timestamp from the NTP timestamp
// returned by the specified clock.
uint32_t GetCurrentRTP(Clock* clock, uint32_t freq);
// Return the current RTP absolute timestamp.
uint32_t ConvertNTPTimeToRTP(uint32_t NTPsec,
uint32_t NTPfrac,
uint32_t freq);
uint32_t pow2(uint8_t exp);
// Returns true if |newTimestamp| is older than |existingTimestamp|.

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2015 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
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_TIME_UTIL_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_TIME_UTIL_H_
#include "webrtc/base/basictypes.h"
#include "webrtc/system_wrappers/include/ntp_time.h"
namespace webrtc {
// Converts NTP timestamp to RTP timestamp.
inline uint32_t NtpToRtp(NtpTime ntp, uint32_t freq) {
uint32_t tmp = (static_cast<uint64_t>(ntp.fractions()) * freq) >> 32;
return ntp.seconds() * freq + tmp;
}
// Return the current RTP timestamp from the NTP timestamp
// returned by the specified clock.
inline uint32_t CurrentRtp(const Clock& clock, uint32_t freq) {
return NtpToRtp(NtpTime(clock), freq);
}
// Helper function for compact ntp representation:
// RFC 3550, Section 4. Time Format.
// Wallclock time is represented using the timestamp format of
// the Network Time Protocol (NTP).
// ...
// In some fields where a more compact representation is
// appropriate, only the middle 32 bits are used; that is, the low 16
// bits of the integer part and the high 16 bits of the fractional part.
inline uint32_t CompactNtp(NtpTime ntp) {
return (ntp.seconds() << 16) | (ntp.fractions() >> 16);
}
// Converts interval between compact ntp timestamps to milliseconds.
// This interval can be upto ~18.2 hours (2^16 seconds).
inline uint32_t CompactNtpIntervalToMs(uint32_t compact_ntp_interval) {
return static_cast<uint64_t>(compact_ntp_interval) * 1000 / (1 << 16);
}
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_TIME_UTIL_H_

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2015 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
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/modules/rtp_rtcp/source/time_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace webrtc {
TEST(TimeUtilTest, CompactNtp) {
const uint32_t kNtpSec = 0x12345678;
const uint32_t kNtpFrac = 0x23456789;
const NtpTime kNtp(kNtpSec, kNtpFrac);
const uint32_t kNtpMid = 0x56782345;
EXPECT_EQ(kNtpMid, CompactNtp(kNtp));
}
TEST(TimeUtilTest, CompactNtpToMs) {
const NtpTime ntp1(0x12345, 0x23456);
const NtpTime ntp2(0x12654, 0x64335);
uint32_t ms_diff = ntp2.ToMs() - ntp1.ToMs();
uint32_t ntp_diff = CompactNtp(ntp2) - CompactNtp(ntp1);
uint32_t ntp_to_ms_diff = CompactNtpIntervalToMs(ntp_diff);
EXPECT_NEAR(ms_diff, ntp_to_ms_diff, 1);
}
TEST(TimeUtilTest, CompactNtpToMsWithWrap) {
const NtpTime ntp1(0x1ffff, 0x23456);
const NtpTime ntp2(0x20000, 0x64335);
uint32_t ms_diff = ntp2.ToMs() - ntp1.ToMs();
// While ntp2 > ntp1, there compact ntp presentation happen to be opposite.
// That shouldn't be a problem as long as unsigned arithmetic is used.
ASSERT_GT(ntp2.ToMs(), ntp1.ToMs());
ASSERT_LT(CompactNtp(ntp2), CompactNtp(ntp1));
uint32_t ntp_diff = CompactNtp(ntp2) - CompactNtp(ntp1);
uint32_t ntp_to_ms_diff = CompactNtpIntervalToMs(ntp_diff);
EXPECT_NEAR(ms_diff, ntp_to_ms_diff, 1);
}
TEST(TimeUtilTest, CompactNtpToMsLarge) {
const NtpTime ntp1(0x10000, 0x23456);
const NtpTime ntp2(0x1ffff, 0x64335);
uint32_t ms_diff = ntp2.ToMs() - ntp1.ToMs();
// Ntp difference close to maximum of ~18 hours should convert correctly too.
ASSERT_GT(ms_diff, 18u * 3600 * 1000);
uint32_t ntp_diff = CompactNtp(ntp2) - CompactNtp(ntp1);
uint32_t ntp_to_ms_diff = CompactNtpIntervalToMs(ntp_diff);
EXPECT_NEAR(ms_diff, ntp_to_ms_diff, 1);
}
} // namespace webrtc