From 6c683972499ed435c9a782ba3f706016691d5ec1 Mon Sep 17 00:00:00 2001 From: Peter Keresztes Schmidt Date: Sun, 6 Jun 2021 16:38:02 +0200 Subject: [PATCH] Time: Convert some timeval operations to std::chrono Also remove now defunct timeval helper methods. --- src/CMakeLists.txt | 1 - src/zm_event.cpp | 4 +- src/zm_monitorstream.cpp | 29 ++++---- src/zm_rtp_source.cpp | 27 +++++--- src/zm_time.cpp | 22 ------- src/zm_time.h | 139 ++------------------------------------- 6 files changed, 41 insertions(+), 181 deletions(-) delete mode 100644 src/zm_time.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 82f6cefe0..4e8224db2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,7 +60,6 @@ set(ZM_BIN_SRC_FILES zm_signal.cpp zm_stream.cpp zm_swscale.cpp - zm_time.cpp zm_user.cpp zm_utils.cpp zm_videostore.cpp diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 32cb95f76..b9b5f3925 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -238,7 +238,7 @@ Event::~Event() { gettimeofday(&end_time, nullptr); } - std::chrono::duration delta_time = + FPSeconds delta_time = zm::chrono::duration_cast(end_time) - zm::chrono::duration_cast(start_time); Debug(2, "start_time: %" PRIi64 ".% " PRIi64 " end_time: %" PRIi64 ".%" PRIi64, static_cast(start_time.tv_sec), @@ -580,7 +580,7 @@ void Event::AddFrame( or ( monitor_state == Monitor::PREALARM ); if (db_frame) { - std::chrono::duration delta_time = + FPSeconds delta_time = zm::chrono::duration_cast(timestamp) - zm::chrono::duration_cast(start_time); Debug(1, "Frame delta is %" PRIi64 ".%" PRIi64 " - %" PRIi64 ".%" PRIi64 " = %.2f, score %u zone_stats.size %zu", static_cast(start_time.tv_sec), static_cast(start_time.tv_usec), diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index a9fead28b..99cc01720 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -347,8 +347,7 @@ bool MonitorStream::sendFrame(const char *filepath, const timeval ×tamp) { } // Calculate how long it takes to actually send the frame - struct timeval frameStartTime; - gettimeofday(&frameStartTime, nullptr); + TimePoint send_start_time = std::chrono::steady_clock::now(); if ( (0 > fprintf(stdout, "Content-Length: %d\r\nX-Timestamp: %d.%06d\r\n\r\n", @@ -363,13 +362,14 @@ bool MonitorStream::sendFrame(const char *filepath, const timeval ×tamp) { fputs("\r\n", stdout); fflush(stdout); - struct timeval frameEndTime; - gettimeofday(&frameEndTime, nullptr); + TimePoint send_end_time = std::chrono::steady_clock::now(); + Milliseconds frame_send_time = std::chrono::duration_cast(send_end_time - send_start_time); - int frameSendTime = tvDiffMsec(frameStartTime, frameEndTime); - if ( frameSendTime > 1000/maxfps ) { + if (frame_send_time > Milliseconds(lround(Milliseconds::period::den / maxfps))) { maxfps /= 2; - Info("Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps); + Info("Frame send time %" PRIi64 " msec too slow, throttling maxfps to %.2f", + static_cast(frame_send_time.count()), + maxfps); } last_frame_sent = TV_2_FLOAT(now); @@ -408,8 +408,7 @@ bool MonitorStream::sendFrame(Image *image, const timeval ×tamp) { unsigned char *img_buffer = temp_img_buffer; // Calculate how long it takes to actually send the frame - struct timeval frameStartTime; - gettimeofday(&frameStartTime, nullptr); + TimePoint send_start_time = std::chrono::steady_clock::now(); switch ( type ) { case STREAM_JPEG : @@ -451,14 +450,14 @@ bool MonitorStream::sendFrame(Image *image, const timeval ×tamp) { fputs("\r\n", stdout); fflush(stdout); - struct timeval frameEndTime; - gettimeofday(&frameEndTime, nullptr); + TimePoint send_end_time = std::chrono::steady_clock::now(); + Milliseconds frame_send_time = std::chrono::duration_cast(send_end_time - send_start_time); - int frameSendTime = tvDiffMsec(frameStartTime, frameEndTime); - if ( frameSendTime > 1000/maxfps ) { + if (frame_send_time > Milliseconds(lround(Milliseconds::period::den / maxfps))) { maxfps /= 1.5; - Warning("Frame send time %d msec too slow, throttling maxfps to %.2f", - frameSendTime, maxfps); + Warning("Frame send time %" PRIi64 " msec too slow, throttling maxfps to %.2f", + static_cast(frame_send_time.count()), + maxfps); } } // Not mpeg last_frame_sent = TV_2_FLOAT(now); diff --git a/src/zm_rtp_source.cpp b/src/zm_rtp_source.cpp index 2fd5bc41b..0d9330f8e 100644 --- a/src/zm_rtp_source.cpp +++ b/src/zm_rtp_source.cpp @@ -67,11 +67,11 @@ RtpSource::RtpSource( mRtpFactor = mRtpClock; mBaseTimeReal = tvNow(); - mBaseTimeNtp = tvZero(); + mBaseTimeNtp = {}; mBaseTimeRtp = rtpTime; - mLastSrTimeReal = tvZero(); - mLastSrTimeNtp = tvZero(); + mLastSrTimeReal = {}; + mLastSrTimeNtp = {}; mLastSrTimeRtp = 0; if ( mCodecId != AV_CODEC_ID_H264 && mCodecId != AV_CODEC_ID_MPEG4 ) @@ -160,12 +160,18 @@ bool RtpSource::updateSeq(uint16_t seq) { void RtpSource::updateJitter( const RtpDataHeader *header ) { if ( mRtpFactor > 0 ) { - uint32_t localTimeRtp = mBaseTimeRtp + uint32_t(tvDiffSec(mBaseTimeReal) * mRtpFactor); + timeval now = {}; + gettimeofday(&now, nullptr); + + FPSeconds time_diff = + zm::chrono::duration_cast(now) - zm::chrono::duration_cast(mBaseTimeReal); + + uint32_t localTimeRtp = mBaseTimeRtp + static_cast(time_diff.count() * mRtpFactor); uint32_t packetTransit = localTimeRtp - ntohl(header->timestampN); Debug(5, "Delta rtp = %.6f\n Local RTP time = %x Packet RTP time = %x Packet transit RTP time = %x", - tvDiffSec(mBaseTimeReal), + time_diff.count(), localTimeRtp, ntohl(header->timestampN), packetTransit); @@ -190,7 +196,8 @@ void RtpSource::updateRtcpData( uint32_t ntpTimeSecs, uint32_t ntpTimeFrac, uint32_t rtpTime) { - struct timeval ntpTime = tvMake(ntpTimeSecs, suseconds_t((USEC_PER_SEC*(ntpTimeFrac>>16))/(1<<16))); + timeval ntpTime = zm::chrono::duration_cast( + Seconds(ntpTimeSecs) + Microseconds((Microseconds::period::den * (ntpTimeFrac >> 16)) / (1 << 16))); Debug(5, "ntpTime: %ld.%06ld, rtpTime: %x", ntpTime.tv_sec, ntpTime.tv_usec, rtpTime); @@ -204,12 +211,14 @@ void RtpSource::updateRtcpData( mLastSrTimeNtp.tv_sec, mLastSrTimeNtp.tv_usec, rtpTime, ntpTime.tv_sec, ntpTime.tv_usec, rtpTime); - double diffNtpTime = tvDiffSec( mBaseTimeNtp, ntpTime ); + FPSeconds diffNtpTime = + zm::chrono::duration_cast(ntpTime) - zm::chrono::duration_cast(mBaseTimeNtp); + uint32_t diffRtpTime = rtpTime - mBaseTimeRtp; - mRtpFactor = (uint32_t)(diffRtpTime / diffNtpTime); + mRtpFactor = static_cast(diffRtpTime / diffNtpTime.count()); Debug( 5, "NTP-diff: %.6f RTP-diff: %d RTPfactor: %d", - diffNtpTime, diffRtpTime, mRtpFactor); + diffNtpTime.count(), diffRtpTime, mRtpFactor); } mLastSrTimeNtpSecs = ntpTimeSecs; mLastSrTimeNtpFrac = ntpTimeFrac; diff --git a/src/zm_time.cpp b/src/zm_time.cpp deleted file mode 100644 index 417ee2b2b..000000000 --- a/src/zm_time.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// ZoneMinder Time Functions & Definitions Implementation, $Date$, $Revision$ -// Copyright (C) 2001-2008 Philip Coombes -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// - -#include "zm_time.h" - -// Blank diff --git a/src/zm_time.h b/src/zm_time.h index c5e7fe75e..d263dfb41 100644 --- a/src/zm_time.h +++ b/src/zm_time.h @@ -20,7 +20,6 @@ #ifndef ZM_TIME_H #define ZM_TIME_H -#include "zm_logger.h" #include #include @@ -51,137 +50,10 @@ struct DeltaTimeval #define DT_MAXGRAN DT_GRAN_1000000 -#define USEC_PER_SEC 1000000 -#define MSEC_PER_SEC 1000 - -/* -extern struct timeval tv; -*/ - -inline int tvDiffUsec( struct timeval first, struct timeval last ) -{ - return( (last.tv_sec - first.tv_sec) * USEC_PER_SEC) + ((USEC_PER_SEC + last.tv_usec - first.tv_usec) - USEC_PER_SEC ); -} - -inline int tvDiffUsec( struct timeval first ) -{ - struct timeval now; - gettimeofday( &now, nullptr ); - return( tvDiffUsec( first, now ) ); -} - -inline int tvDiffMsec( struct timeval first, struct timeval last ) -{ - return( (last.tv_sec - first.tv_sec) * MSEC_PER_SEC) + (((MSEC_PER_SEC + last.tv_usec - first.tv_usec) / MSEC_PER_SEC) - MSEC_PER_SEC ); -} - -inline int tvDiffMsec( struct timeval first ) -{ - struct timeval now; - gettimeofday( &now, nullptr ); - return( tvDiffMsec( first, now ) ); -} - -inline double tvDiffSec( struct timeval first, struct timeval last ) -{ - return( double(last.tv_sec - first.tv_sec) + double(((USEC_PER_SEC + last.tv_usec - first.tv_usec) - USEC_PER_SEC) / (1.0*USEC_PER_SEC) ) ); -} - -inline double tvDiffSec( struct timeval first ) -{ - struct timeval now; - gettimeofday( &now, nullptr ); - return( tvDiffSec( first, now ) ); -} - -inline struct timeval tvZero() -{ - struct timeval t = { 0, 0 }; - return( t ); -} - -inline int tvIsZero( const struct timeval t ) -{ - return( t.tv_sec == 0 && t.tv_usec == 0 ); -} - -inline int tvCmp( struct timeval t1, struct timeval t2 ) -{ - if ( t1.tv_sec < t2.tv_sec ) - return( -1 ); - if ( t1.tv_sec > t2.tv_sec ) - return( 1 ); - if ( t1.tv_usec < t2.tv_usec ) - return( -1 ); - if ( t1.tv_usec > t2.tv_usec ) - return( 1 ); - return( 0 ); -} - -inline int tvEq( struct timeval t1, struct timeval t2 ) -{ - return( t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec ); -} - -inline struct timeval tvNow( void ) -{ - struct timeval t; - gettimeofday( &t, nullptr ); - return( t ); -} - -inline struct timeval tvCheck( struct timeval &t ) -{ - if ( t.tv_usec >= USEC_PER_SEC ) - { - Warning( "Timestamp too large %ld.%ld\n", t.tv_sec, (long int) t.tv_usec ); - t.tv_sec += t.tv_usec / USEC_PER_SEC; - t.tv_usec %= USEC_PER_SEC; - } - else if ( t.tv_usec < 0 ) - { - Warning( "Got negative timestamp %ld.%ld\n", t.tv_sec, (long int)t.tv_usec ); - t.tv_usec = 0; - } - return( t ); -} - -// Add t2 to t1 -inline struct timeval tvAdd( struct timeval t1, struct timeval t2 ) -{ - tvCheck(t1); - tvCheck(t2); - t1.tv_sec += t2.tv_sec; - t1.tv_usec += t2.tv_usec; - if ( t1.tv_usec >= USEC_PER_SEC ) - { - t1.tv_sec++; - t1.tv_usec -= USEC_PER_SEC; - } - return( t1 ); -} - -// Subtract t2 from t1 -inline struct timeval tvSub( struct timeval t1, struct timeval t2 ) -{ - tvCheck(t1); - tvCheck(t2); - t1.tv_sec -= t2.tv_sec; - t1.tv_usec -= t2.tv_usec; - if ( t1.tv_usec < 0 ) - { - t1.tv_sec--; - t1.tv_usec += USEC_PER_SEC; - } - return( t1 ) ; -} - -inline struct timeval tvMake( time_t sec, suseconds_t usec ) -{ - struct timeval t; - t.tv_sec = sec; - t.tv_usec = usec; - return( t ); +inline struct timeval tvNow() { + timeval t = {}; + gettimeofday(&t, nullptr); + return t; } typedef std::chrono::microseconds Microseconds; @@ -190,6 +62,9 @@ typedef std::chrono::seconds Seconds; typedef std::chrono::minutes Minutes; typedef std::chrono::hours Hours; +// floating point seconds +typedef std::chrono::duration FPSeconds; + typedef std::chrono::steady_clock::time_point TimePoint; typedef std::chrono::system_clock::time_point SystemTimePoint;