[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:
parent
5908c71128
commit
1227e8b345
@ -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',
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -22,7 +22,6 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
using RtpUtility::GetCurrentRTP;
|
||||
using RtpUtility::Payload;
|
||||
using RtpUtility::StringCompare;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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|.
|
||||
|
||||
48
webrtc/modules/rtp_rtcp/source/time_util.h
Normal file
48
webrtc/modules/rtp_rtcp/source/time_util.h
Normal 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_
|
||||
62
webrtc/modules/rtp_rtcp/source/time_util_unittest.cc
Normal file
62
webrtc/modules/rtp_rtcp/source/time_util_unittest.cc
Normal 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
|
||||
Loading…
x
Reference in New Issue
Block a user