diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 7db44cfee..1484d5234 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -27,16 +27,10 @@ extern "C" { #include -#if HAVE_LIBAVUTIL_HWCONTEXT_H - #include -#endif - -#include } -#include +TimePoint start_read_time; -time_t start_read_time; #if HAVE_LIBAVUTIL_HWCONTEXT_H #if LIBAVCODEC_VERSION_CHECK(57, 89, 0, 89, 0) static enum AVPixelFormat hw_pix_fmt; @@ -169,7 +163,7 @@ FfmpegCamera::~FfmpegCamera() { } int FfmpegCamera::PrimeCapture() { - start_read_time = time(nullptr); + start_read_time = std::chrono::steady_clock::now(); if ( mCanCapture ) { Debug(1, "Priming capture from %s, Closing", mPath.c_str()); Close(); @@ -188,7 +182,7 @@ int FfmpegCamera::PreCapture() { int FfmpegCamera::Capture(std::shared_ptr &zm_packet) { if (!mCanCapture) return -1; - start_read_time = time(nullptr); + start_read_time = std::chrono::steady_clock::now(); int ret; AVFormatContext *formatContextPtr; @@ -558,11 +552,12 @@ int FfmpegCamera::FfmpegInterruptCallback(void *ctx) { Debug(1, "Received terminate in cb"); return zm_terminate; } - time_t now = time(nullptr); - if (now - start_read_time > 10) { - Debug(1, "timeout in ffmpeg camera now %" PRIi64 " - %" PRIi64 " > 10", - static_cast(now), - static_cast(start_read_time)); + + TimePoint now = std::chrono::steady_clock::now(); + if (now - start_read_time > Seconds(10)) { + Debug(1, "timeout in ffmpeg camera now %" PRIi64 " - %" PRIi64 " > 10 s", + static_cast(std::chrono::duration_cast(now.time_since_epoch()).count()), + static_cast(std::chrono::duration_cast(start_read_time.time_since_epoch()).count())); return 1; } return 0; diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 3f05669f9..4dc7a3128 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -137,8 +137,9 @@ Monitor::MonitorLink::~MonitorLink() { } bool Monitor::MonitorLink::connect() { - if ( !last_connect_time || (time(nullptr) - last_connect_time) > 60 ) { - last_connect_time = time(nullptr); + SystemTimePoint now = std::chrono::system_clock::now(); + if (!last_connect_time || (now - std::chrono::system_clock::from_time_t(last_connect_time)) > Seconds(60)) { + last_connect_time = std::chrono::system_clock::to_time_t(now); mem_size = sizeof(SharedData) + sizeof(TriggerData); @@ -2266,7 +2267,7 @@ bool Monitor::Analyse() { UpdateAnalysisFPS(); } packetqueue.unlock(packet_lock); - shared_data->last_read_time = time(nullptr); + shared_data->last_read_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); return true; } // end Monitor::Analyse diff --git a/src/zm_rtp_ctrl.cpp b/src/zm_rtp_ctrl.cpp index 265d594d4..25d34f0ff 100644 --- a/src/zm_rtp_ctrl.cpp +++ b/src/zm_rtp_ctrl.cpp @@ -274,11 +274,11 @@ void RtpCtrlThread::Run() { unsigned char buffer[ZM_NETWORK_BUFSIZ]; - time_t last_receive = time(nullptr); - bool timeout = false; // used as a flag that we had a timeout, and then sent an RR to see if we wake back up. Real timeout will happen when this is true. + TimePoint last_receive = std::chrono::steady_clock::now(); + bool timeout = false; // used as a flag that we had a timeout, and then sent an RR to see if we wake back up. Real timeout will happen when this is true. while (!mTerminate && select.wait() >= 0) { - time_t now = time(nullptr); + TimePoint now = std::chrono::steady_clock::now(); zm::Select::CommsList readable = select.getReadable(); if ( readable.size() == 0 ) { if ( ! timeout ) { @@ -287,20 +287,20 @@ void RtpCtrlThread::Run() { unsigned char *bufferPtr = buffer; bufferPtr += generateRr( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); bufferPtr += generateSdes( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); - Debug(3, "Preventing timeout by sending %zd bytes on sd %d. Time since last receive: %" PRIi64, - bufferPtr - buffer, rtpCtrlServer.getWriteDesc(), static_cast(now - last_receive)); + Debug(3, "Preventing timeout by sending %zd bytes on sd %d. Time since last receive: %.2f s", + bufferPtr - buffer, rtpCtrlServer.getWriteDesc(), FPSeconds(now - last_receive).count()); if ( (nBytes = rtpCtrlServer.send(buffer, bufferPtr-buffer)) < 0 ) Error("Unable to send: %s", strerror(errno)); timeout = true; continue; } else { - Debug(1, "RTCP timed out. Time since last receive: %" PRIi64, static_cast(now - last_receive)); + Debug(1, "RTCP timed out. Time since last receive: %.2f s", FPSeconds(now - last_receive).count()); continue; //break; } } else { timeout = false; - last_receive = time(nullptr); + last_receive = std::chrono::steady_clock::now(); } for (zm::Select::CommsList::iterator iter = readable.begin(); iter != readable.end(); ++iter ) { if ( zm::UdpInetSocket *socket = dynamic_cast(*iter) ) { diff --git a/src/zm_rtsp.cpp b/src/zm_rtsp.cpp index 5c4af87eb..f73a74760 100644 --- a/src/zm_rtsp.cpp +++ b/src/zm_rtsp.cpp @@ -439,15 +439,18 @@ void RtspThread::Run() { lines = Split(response, "\r\n"); std::string session; - int timeout = 0; + Seconds timeout = Seconds(0); char transport[256] = ""; for ( size_t i = 0; i < lines.size(); i++ ) { if ( ( lines[i].size() > 8 ) && ( lines[i].substr(0, 8) == "Session:" ) ) { StringVector sessionLine = Split(lines[i].substr(9), ";"); session = TrimSpaces(sessionLine[0]); - if ( sessionLine.size() == 2 ) - sscanf(TrimSpaces(sessionLine[1]).c_str(), "timeout=%d", &timeout); + if ( sessionLine.size() == 2 ){ + int32 timeout_val = 0; + sscanf(TrimSpaces(sessionLine[1]).c_str(), "timeout=%d", &timeout_val); + timeout = Seconds(timeout_val); + } } sscanf(lines[i].c_str(), "Transport: %s", transport); } @@ -455,7 +458,7 @@ void RtspThread::Run() { if ( session.empty() ) Fatal("Unable to get session identifier from response '%s'", response.c_str()); - Debug(2, "Got RTSP session %s, timeout %d secs", session.c_str(), timeout); + Debug(2, "Got RTSP session %s, timeout %" PRIi64 " secs", session.c_str(), Seconds(timeout).count()); if ( !transport[0] ) Fatal("Unable to get transport details from response '%s'", response.c_str()); @@ -518,12 +521,17 @@ void RtspThread::Run() { if ( ( lines[i].size() > 9 ) && ( lines[i].substr(0, 9) == "RTP-Info:" ) ) rtpInfo = TrimSpaces(lines[i].substr(9)); // Check for a timeout again. Some rtsp devices don't send a timeout until after the PLAY command is sent - if ( ( lines[i].size() > 8 ) && ( lines[i].substr(0, 8) == "Session:" ) && ( timeout == 0 ) ) { + if ((lines[i].size() > 8) && (lines[i].substr(0, 8) == "Session:") && (timeout == Seconds(0))) { StringVector sessionLine = Split(lines[i].substr(9), ";"); - if ( sessionLine.size() == 2 ) - sscanf(TrimSpaces(sessionLine[1]).c_str(), "timeout=%d", &timeout); - if ( timeout > 0 ) - Debug(2, "Got timeout %d secs from PLAY command response", timeout); + if ( sessionLine.size() == 2 ){ + int32 timeout_val = 0; + sscanf(TrimSpaces(sessionLine[1]).c_str(), "timeout=%d", &timeout_val); + timeout = Seconds(timeout_val); + } + + if ( timeout > Seconds(0) ) { + Debug(2, "Got timeout %" PRIi64 " secs from PLAY command response", Seconds(timeout).count()); + } } } @@ -558,8 +566,8 @@ void RtspThread::Run() { Debug( 2, "RTSP Seq is %d", seq ); Debug( 2, "RTSP Rtptime is %ld", rtpTime ); - time_t lastKeepalive = time(nullptr); - time_t now; + TimePoint lastKeepalive = std::chrono::steady_clock::now(); + TimePoint now; message = "GET_PARAMETER "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; switch( mMethod ) { @@ -571,16 +579,17 @@ void RtspThread::Run() { RtpCtrlThread rtpCtrlThread( *this, *source ); while (!mTerminate) { - now = time(nullptr); + now = std::chrono::steady_clock::now(); // Send a keepalive message if the server supports this feature and we are close to the timeout expiration - Debug(5, "sendkeepalive %d, timeout %d, now: %" PRIi64 " last: %" PRIi64 " since: %" PRIi64, + Debug(5, "sendkeepalive %d, timeout %" PRIi64 " s, now: %" PRIi64 " s last: %" PRIi64 " s since: %" PRIi64 "s ", sendKeepalive, - timeout, - static_cast(now), - static_cast(lastKeepalive), - static_cast(now - lastKeepalive)); - if ( sendKeepalive && (timeout > 0) && ((now-lastKeepalive) > (timeout-5)) ) { - if ( !sendCommand( message ) ) + static_cast(Seconds(timeout).count()), + static_cast(std::chrono::duration_cast(now.time_since_epoch()).count()), + static_cast(std::chrono::duration_cast(lastKeepalive.time_since_epoch()).count()), + static_cast(std::chrono::duration_cast((now - lastKeepalive)).count())); + + if (sendKeepalive && (timeout > Seconds(0)) && ((now - lastKeepalive) > (timeout - Seconds(5)))) { + if (!sendCommand(message)) return; lastKeepalive = now; } @@ -695,21 +704,23 @@ void RtspThread::Run() { } // Send a keepalive message if the server supports this feature and we are close to the timeout expiration // FIXME: Is this really necessary when using tcp ? - now = time(nullptr); + now = std::chrono::steady_clock::now(); // Send a keepalive message if the server supports this feature and we are close to the timeout expiration - Debug(5, "sendkeepalive %d, timeout %d, now: %" PRIi64 " last: %" PRIi64 " since: %" PRIi64, + Debug(5, "sendkeepalive %d, timeout %" PRIi64 " s, now: %" PRIi64 " s last: %" PRIi64 " s since: %" PRIi64 " s", sendKeepalive, - timeout, - static_cast(now), - static_cast(lastKeepalive), - static_cast(now - lastKeepalive)); - if ( sendKeepalive && (timeout > 0) && ((now-lastKeepalive) > (timeout-5)) ) - { - if ( !sendCommand( message ) ) + static_cast(Seconds(timeout).count()), + static_cast(std::chrono::duration_cast(now.time_since_epoch()).count()), + static_cast(std::chrono::duration_cast(lastKeepalive.time_since_epoch()).count()), + static_cast(std::chrono::duration_cast((now - lastKeepalive)).count())); + + if (sendKeepalive && (timeout > Seconds(0)) && ((now - lastKeepalive) > (timeout - Seconds(5)))) { + if (!sendCommand(message)) { return; + } + lastKeepalive = now; } - buffer.tidy( 1 ); + buffer.tidy(true); } #if 0 message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; @@ -738,10 +749,12 @@ void RtspThread::Run() { while (!mTerminate) { // Send a keepalive message if the server supports this feature and we are close to the timeout expiration - if ( sendKeepalive && (timeout > 0) && ((time(nullptr)-lastKeepalive) > (timeout-5)) ) { - if ( !sendCommand( message ) ) + if (sendKeepalive && (timeout > Seconds(0)) + && ((std::chrono::steady_clock::now() - lastKeepalive) > (timeout - Seconds(5)))) { + if (!sendCommand(message)) { return; - lastKeepalive = time(nullptr); + } + lastKeepalive = std::chrono::steady_clock::now(); } std::this_thread::sleep_for(Microseconds(100)); } diff --git a/src/zm_user.cpp b/src/zm_user.cpp index 0b761c44f..85e858545 100644 --- a/src/zm_user.cpp +++ b/src/zm_user.cpp @@ -21,6 +21,7 @@ #include "zm_crypt.h" #include "zm_logger.h" +#include "zm_time.h" #include "zm_utils.h" #include @@ -205,24 +206,27 @@ User *zmLoadAuthUser(const char *auth, bool use_remote_addr) { return nullptr; } - // getting the time is expensive, so only do it once. - time_t now = time(nullptr); - unsigned int hours = config.auth_hash_ttl; - if (!hours) { + SystemTimePoint now = std::chrono::system_clock::now(); + Hours hours = Hours(config.auth_hash_ttl); + + if (hours == Hours(0)) { Warning("No value set for ZM_AUTH_HASH_TTL. Defaulting to 2."); - hours = 2; + hours = Hours(2); } else { - Debug(1, "AUTH_HASH_TTL is %d, time is %" PRIi64, hours, static_cast(now)); + Debug(1, "AUTH_HASH_TTL is %" PRIi64 " h, time is %" PRIi64 " s", + static_cast(Hours(hours).count()), + static_cast(std::chrono::duration_cast(now.time_since_epoch()).count())); } while (MYSQL_ROW dbrow = mysql_fetch_row(result)) { const char *username = dbrow[1]; const char *password = dbrow[2]; - time_t our_now = now; + SystemTimePoint our_now = now; tm now_tm = {}; - for (unsigned int i = 0; i < hours; i++, our_now -= 3600) { - localtime_r(&our_now, &now_tm); + for (Hours i = Hours(0); i < hours; i++, our_now -= Hours(1)) { + time_t our_now_t = std::chrono::system_clock::to_time_t(our_now); + localtime_r(&our_now_t, &now_tm); std::string auth_key = stringtf("%s%s%s%s%d%d%d%d", config.auth_hash_secret, diff --git a/src/zms.cpp b/src/zms.cpp index 70b0b1b80..a5621e02e 100644 --- a/src/zms.cpp +++ b/src/zms.cpp @@ -241,7 +241,7 @@ int main(int argc, const char *argv[], char **envp) { } fprintf(stdout, "Server: ZoneMinder Video Server/%s\r\n", ZM_VERSION); - time_t now = time(nullptr); + time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); char date_string[64]; tm now_tm = {}; strftime(date_string, sizeof(date_string)-1,