Merge pull request #3283 from Carbenium/time-2

Time: Remove defunct timeval methods and DeltaTimeval
This commit is contained in:
Peter Keresztes Schmidt 2021-06-07 23:59:26 +02:00 committed by GitHub
commit 48b1e8a055
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 55 additions and 258 deletions

View File

@ -60,7 +60,6 @@ set(ZM_BIN_SRC_FILES
zm_signal.cpp zm_signal.cpp
zm_stream.cpp zm_stream.cpp
zm_swscale.cpp zm_swscale.cpp
zm_time.cpp
zm_user.cpp zm_user.cpp
zm_utils.cpp zm_utils.cpp
zm_videostore.cpp zm_videostore.cpp

View File

@ -238,7 +238,7 @@ Event::~Event() {
gettimeofday(&end_time, nullptr); gettimeofday(&end_time, nullptr);
} }
std::chrono::duration<double> delta_time = FPSeconds delta_time =
zm::chrono::duration_cast<Microseconds>(end_time) - zm::chrono::duration_cast<Microseconds>(start_time); zm::chrono::duration_cast<Microseconds>(end_time) - zm::chrono::duration_cast<Microseconds>(start_time);
Debug(2, "start_time: %" PRIi64 ".% " PRIi64 " end_time: %" PRIi64 ".%" PRIi64, Debug(2, "start_time: %" PRIi64 ".% " PRIi64 " end_time: %" PRIi64 ".%" PRIi64,
static_cast<int64>(start_time.tv_sec), static_cast<int64>(start_time.tv_sec),
@ -454,14 +454,12 @@ void Event::WriteDbFrames() {
while (frame_data.size()) { while (frame_data.size()) {
Frame *frame = frame_data.front(); Frame *frame = frame_data.front();
frame_data.pop(); frame_data.pop();
frame_insert_sql += stringtf("\n( %" PRIu64 ", %d, '%s', from_unixtime( %ld ), %s%ld.%02ld, %d ),", frame_insert_sql += stringtf("\n( %" PRIu64 ", %d, '%s', from_unixtime( %ld ), %.2f, %d ),",
id, frame->frame_id, id, frame->frame_id,
frame_type_names[frame->type], frame_type_names[frame->type],
frame->timestamp.tv_sec, frame->timestamp.tv_sec,
frame->delta.positive ? "" : "-", std::chrono::duration_cast<FPSeconds>(frame->delta).count(),
frame->delta.sec, frame->score);
frame->delta.fsec,
frame->score);
if (config.record_event_stats and frame->zone_stats.size()) { if (config.record_event_stats and frame->zone_stats.size()) {
for (ZoneStats &stats : frame->zone_stats) { for (ZoneStats &stats : frame->zone_stats) {
stats_insert_sql += stringtf("\n(%" PRIu64 ",%d,%u,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%u),", stats_insert_sql += stringtf("\n(%" PRIu64 ",%d,%u,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%u),",
@ -580,7 +578,7 @@ void Event::AddFrame(
or ( monitor_state == Monitor::PREALARM ); or ( monitor_state == Monitor::PREALARM );
if (db_frame) { if (db_frame) {
std::chrono::duration<double> delta_time = FPSeconds delta_time =
zm::chrono::duration_cast<Microseconds>(timestamp) - zm::chrono::duration_cast<Microseconds>(start_time); zm::chrono::duration_cast<Microseconds>(timestamp) - zm::chrono::duration_cast<Microseconds>(start_time);
Debug(1, "Frame delta is %" PRIi64 ".%" PRIi64 " - %" PRIi64 ".%" PRIi64 " = %.2f, score %u zone_stats.size %zu", Debug(1, "Frame delta is %" PRIi64 ".%" PRIi64 " - %" PRIi64 ".%" PRIi64 " = %.2f, score %u zone_stats.size %zu",
static_cast<int64>(start_time.tv_sec), static_cast<int64>(start_time.tv_usec), static_cast<int64>(start_time.tv_sec), static_cast<int64>(start_time.tv_usec),
@ -591,13 +589,7 @@ void Event::AddFrame(
Milliseconds delta_time_ms = std::chrono::duration_cast<Milliseconds>(delta_time); Milliseconds delta_time_ms = std::chrono::duration_cast<Milliseconds>(delta_time);
// The idea is to write out 1/sec // The idea is to write out 1/sec
frame_data.push(new Frame(id, frame_data.push(new Frame(id, frames, frame_type, timestamp, delta_time_ms, score, zone_stats));
frames,
frame_type,
timestamp,
zm::chrono::duration_cast<DeltaTimeval, DT_PREC_3>(delta_time_ms),
score,
zone_stats));
double fps = monitor->get_capture_fps(); double fps = monitor->get_capture_fps();
if (write_to_db if (write_to_db
or or

View File

@ -4,7 +4,7 @@ Frame::Frame(event_id_t p_event_id,
int p_frame_id, int p_frame_id,
FrameType p_type, FrameType p_type,
struct timeval p_timestamp, struct timeval p_timestamp,
const DeltaTimeval &p_delta, Milliseconds p_delta,
int p_score, int p_score,
std::vector<ZoneStats> p_stats) std::vector<ZoneStats> p_stats)
: event_id(p_event_id), : event_id(p_event_id),

View File

@ -42,7 +42,7 @@ class Frame {
int p_frame_id, int p_frame_id,
FrameType p_type, FrameType p_type,
struct timeval p_timestamp, struct timeval p_timestamp,
const DeltaTimeval &p_delta, Milliseconds p_delta,
int p_score, int p_score,
std::vector<ZoneStats> p_stats std::vector<ZoneStats> p_stats
); );
@ -51,7 +51,7 @@ class Frame {
int frame_id; int frame_id;
FrameType type; FrameType type;
struct timeval timestamp; struct timeval timestamp;
struct DeltaTimeval delta; Milliseconds delta;
int score; int score;
std::vector<ZoneStats> zone_stats; std::vector<ZoneStats> zone_stats;
}; };

View File

@ -484,8 +484,8 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
/* "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS," */ /* "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS," */
analysis_fps_limit = dbrow[col] ? strtod(dbrow[col], nullptr) : 0.0; col++; analysis_fps_limit = dbrow[col] ? strtod(dbrow[col], nullptr) : 0.0; col++;
analysis_update_delay = strtoul(dbrow[col++], nullptr, 0); analysis_update_delay = strtoul(dbrow[col++], nullptr, 0);
capture_delay = (dbrow[col] && atof(dbrow[col])>0.0)?int(DT_PREC_6/atof(dbrow[col])):0; col++; capture_delay = (dbrow[col] && atof(dbrow[col]) > 0.0) ? int(Microseconds::period::den / atof(dbrow[col])) : 0; col++;
alarm_capture_delay = (dbrow[col] && atof(dbrow[col])>0.0)?int(DT_PREC_6/atof(dbrow[col])):0; col++; alarm_capture_delay = (dbrow[col] && atof(dbrow[col]) > 0.0) ? int(Microseconds::period::den / atof(dbrow[col])) : 0; col++;
/* "Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings */ /* "Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings */
device = dbrow[col] ? dbrow[col] : ""; col++; device = dbrow[col] ? dbrow[col] : ""; col++;
@ -2963,8 +2963,8 @@ bool Monitor::DumpSettings(char *output, bool verbose) {
sprintf(output+strlen(output), "Alarm Frame Count : %d\n", alarm_frame_count ); sprintf(output+strlen(output), "Alarm Frame Count : %d\n", alarm_frame_count );
sprintf(output+strlen(output), "Section Length : %d\n", section_length); sprintf(output+strlen(output), "Section Length : %d\n", section_length);
sprintf(output+strlen(output), "Min Section Length : %d\n", min_section_length); sprintf(output+strlen(output), "Min Section Length : %d\n", min_section_length);
sprintf(output+strlen(output), "Maximum FPS : %.2f\n", capture_delay?(double)DT_PREC_3/capture_delay:0.0); sprintf(output+strlen(output), "Maximum FPS : %.2f\n", capture_delay ? (double) Microseconds::period::den / capture_delay : 0.0);
sprintf(output+strlen(output), "Alarm Maximum FPS : %.2f\n", alarm_capture_delay?(double)DT_PREC_3/alarm_capture_delay:0.0); sprintf(output+strlen(output), "Alarm Maximum FPS : %.2f\n", alarm_capture_delay ? (double) Microseconds::period::den / alarm_capture_delay : 0.0);
sprintf(output+strlen(output), "Reference Blend %%ge : %d\n", ref_blend_perc); sprintf(output+strlen(output), "Reference Blend %%ge : %d\n", ref_blend_perc);
sprintf(output+strlen(output), "Alarm Reference Blend %%ge : %d\n", alarm_ref_blend_perc); sprintf(output+strlen(output), "Alarm Reference Blend %%ge : %d\n", alarm_ref_blend_perc);
sprintf(output+strlen(output), "Track Motion : %d\n", track_motion); sprintf(output+strlen(output), "Track Motion : %d\n", track_motion);

View File

@ -347,8 +347,7 @@ bool MonitorStream::sendFrame(const char *filepath, const timeval &timestamp) {
} }
// Calculate how long it takes to actually send the frame // Calculate how long it takes to actually send the frame
struct timeval frameStartTime; TimePoint send_start_time = std::chrono::steady_clock::now();
gettimeofday(&frameStartTime, nullptr);
if ( if (
(0 > fprintf(stdout, "Content-Length: %d\r\nX-Timestamp: %d.%06d\r\n\r\n", (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 &timestamp) {
fputs("\r\n", stdout); fputs("\r\n", stdout);
fflush(stdout); fflush(stdout);
struct timeval frameEndTime; TimePoint send_end_time = std::chrono::steady_clock::now();
gettimeofday(&frameEndTime, nullptr); Milliseconds frame_send_time = std::chrono::duration_cast<Milliseconds>(send_end_time - send_start_time);
int frameSendTime = tvDiffMsec(frameStartTime, frameEndTime); if (frame_send_time > Milliseconds(lround(Milliseconds::period::den / maxfps))) {
if ( frameSendTime > 1000/maxfps ) {
maxfps /= 2; 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<int64>(frame_send_time.count()),
maxfps);
} }
last_frame_sent = TV_2_FLOAT(now); last_frame_sent = TV_2_FLOAT(now);
@ -408,8 +408,7 @@ bool MonitorStream::sendFrame(Image *image, const timeval &timestamp) {
unsigned char *img_buffer = temp_img_buffer; unsigned char *img_buffer = temp_img_buffer;
// Calculate how long it takes to actually send the frame // Calculate how long it takes to actually send the frame
struct timeval frameStartTime; TimePoint send_start_time = std::chrono::steady_clock::now();
gettimeofday(&frameStartTime, nullptr);
switch ( type ) { switch ( type ) {
case STREAM_JPEG : case STREAM_JPEG :
@ -451,14 +450,14 @@ bool MonitorStream::sendFrame(Image *image, const timeval &timestamp) {
fputs("\r\n", stdout); fputs("\r\n", stdout);
fflush(stdout); fflush(stdout);
struct timeval frameEndTime; TimePoint send_end_time = std::chrono::steady_clock::now();
gettimeofday(&frameEndTime, nullptr); Milliseconds frame_send_time = std::chrono::duration_cast<Milliseconds>(send_end_time - send_start_time);
int frameSendTime = tvDiffMsec(frameStartTime, frameEndTime); if (frame_send_time > Milliseconds(lround(Milliseconds::period::den / maxfps))) {
if ( frameSendTime > 1000/maxfps ) {
maxfps /= 1.5; maxfps /= 1.5;
Warning("Frame send time %d msec too slow, throttling maxfps to %.2f", Warning("Frame send time %" PRIi64 " msec too slow, throttling maxfps to %.2f",
frameSendTime, maxfps); static_cast<int64>(frame_send_time.count()),
maxfps);
} }
} // Not mpeg } // Not mpeg
last_frame_sent = TV_2_FLOAT(now); last_frame_sent = TV_2_FLOAT(now);

View File

@ -67,11 +67,11 @@ RtpSource::RtpSource(
mRtpFactor = mRtpClock; mRtpFactor = mRtpClock;
mBaseTimeReal = tvNow(); mBaseTimeReal = tvNow();
mBaseTimeNtp = tvZero(); mBaseTimeNtp = {};
mBaseTimeRtp = rtpTime; mBaseTimeRtp = rtpTime;
mLastSrTimeReal = tvZero(); mLastSrTimeReal = {};
mLastSrTimeNtp = tvZero(); mLastSrTimeNtp = {};
mLastSrTimeRtp = 0; mLastSrTimeRtp = 0;
if ( mCodecId != AV_CODEC_ID_H264 && mCodecId != AV_CODEC_ID_MPEG4 ) 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 ) { void RtpSource::updateJitter( const RtpDataHeader *header ) {
if ( mRtpFactor > 0 ) { if ( mRtpFactor > 0 ) {
uint32_t localTimeRtp = mBaseTimeRtp + uint32_t(tvDiffSec(mBaseTimeReal) * mRtpFactor); timeval now = {};
gettimeofday(&now, nullptr);
FPSeconds time_diff =
zm::chrono::duration_cast<Microseconds>(now) - zm::chrono::duration_cast<Microseconds>(mBaseTimeReal);
uint32_t localTimeRtp = mBaseTimeRtp + static_cast<uint32>(time_diff.count() * mRtpFactor);
uint32_t packetTransit = localTimeRtp - ntohl(header->timestampN); uint32_t packetTransit = localTimeRtp - ntohl(header->timestampN);
Debug(5, Debug(5,
"Delta rtp = %.6f\n Local RTP time = %x Packet RTP time = %x Packet transit RTP time = %x", "Delta rtp = %.6f\n Local RTP time = %x Packet RTP time = %x Packet transit RTP time = %x",
tvDiffSec(mBaseTimeReal), time_diff.count(),
localTimeRtp, localTimeRtp,
ntohl(header->timestampN), ntohl(header->timestampN),
packetTransit); packetTransit);
@ -190,7 +196,8 @@ void RtpSource::updateRtcpData(
uint32_t ntpTimeSecs, uint32_t ntpTimeSecs,
uint32_t ntpTimeFrac, uint32_t ntpTimeFrac,
uint32_t rtpTime) { uint32_t rtpTime) {
struct timeval ntpTime = tvMake(ntpTimeSecs, suseconds_t((USEC_PER_SEC*(ntpTimeFrac>>16))/(1<<16))); timeval ntpTime = zm::chrono::duration_cast<timeval>(
Seconds(ntpTimeSecs) + Microseconds((Microseconds::period::den * (ntpTimeFrac >> 16)) / (1 << 16)));
Debug(5, "ntpTime: %ld.%06ld, rtpTime: %x", ntpTime.tv_sec, ntpTime.tv_usec, rtpTime); 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, mLastSrTimeNtp.tv_sec, mLastSrTimeNtp.tv_usec, rtpTime,
ntpTime.tv_sec, ntpTime.tv_usec, rtpTime); ntpTime.tv_sec, ntpTime.tv_usec, rtpTime);
double diffNtpTime = tvDiffSec( mBaseTimeNtp, ntpTime ); FPSeconds diffNtpTime =
zm::chrono::duration_cast<Microseconds>(ntpTime) - zm::chrono::duration_cast<Microseconds>(mBaseTimeNtp);
uint32_t diffRtpTime = rtpTime - mBaseTimeRtp; uint32_t diffRtpTime = rtpTime - mBaseTimeRtp;
mRtpFactor = (uint32_t)(diffRtpTime / diffNtpTime); mRtpFactor = static_cast<uint32>(diffRtpTime / diffNtpTime.count());
Debug( 5, "NTP-diff: %.6f RTP-diff: %d RTPfactor: %d", Debug( 5, "NTP-diff: %.6f RTP-diff: %d RTPfactor: %d",
diffNtpTime, diffRtpTime, mRtpFactor); diffNtpTime.count(), diffRtpTime, mRtpFactor);
} }
mLastSrTimeNtpSecs = ntpTimeSecs; mLastSrTimeNtpSecs = ntpTimeSecs;
mLastSrTimeNtpFrac = ntpTimeFrac; mLastSrTimeNtpFrac = ntpTimeFrac;

View File

@ -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

View File

@ -20,168 +20,13 @@
#ifndef ZM_TIME_H #ifndef ZM_TIME_H
#define ZM_TIME_H #define ZM_TIME_H
#include "zm_logger.h"
#include <chrono> #include <chrono>
#include <sys/time.h> #include <sys/time.h>
// Structure used for storing the results of the subtraction inline struct timeval tvNow() {
// of one struct timeval from another timeval t = {};
gettimeofday(&t, nullptr);
struct DeltaTimeval return t;
{
bool positive;
unsigned long delta;
unsigned long sec;
unsigned long fsec;
unsigned long prec;
};
#define DT_GRAN_1000000 1000000
#define DT_PREC_6 DT_GRAN_1000000
#define DT_GRAN_100000 100000
#define DT_PREC_5 DT_GRAN_100000
#define DT_GRAN_10000 10000
#define DT_PREC_4 DT_GRAN_10000
#define DT_GRAN_1000 1000
#define DT_PREC_3 DT_GRAN_1000
#define DT_GRAN_100 100
#define DT_PREC_2 DT_GRAN_100
#define DT_GRAN_10 10
#define DT_PREC_1 DT_GRAN_10
#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 );
} }
typedef std::chrono::microseconds Microseconds; typedef std::chrono::microseconds Microseconds;
@ -190,6 +35,9 @@ typedef std::chrono::seconds Seconds;
typedef std::chrono::minutes Minutes; typedef std::chrono::minutes Minutes;
typedef std::chrono::hours Hours; typedef std::chrono::hours Hours;
// floating point seconds
typedef std::chrono::duration<double> FPSeconds;
typedef std::chrono::steady_clock::time_point TimePoint; typedef std::chrono::steady_clock::time_point TimePoint;
typedef std::chrono::system_clock::time_point SystemTimePoint; typedef std::chrono::system_clock::time_point SystemTimePoint;
@ -224,27 +72,6 @@ struct posix_duration_cast<timeval, std::chrono::duration<Rep, Period>> {
); );
} }
}; };
// chrono -> DeltaTimeval caster
template<typename Rep, typename Period>
struct posix_duration_cast<std::chrono::duration<Rep, Period>, DeltaTimeval> {
template<uint32 Prec>
static DeltaTimeval cast(std::chrono::duration<Rep, Period> const &d) {
typedef std::chrono::duration<int64, std::ratio<1, Prec>> fsec_t;
DeltaTimeval res = {};
Seconds secs = std::chrono::duration_cast<Seconds>(d);
fsec_t fsec = std::chrono::duration_cast<fsec_t, int64, std::ratio<1, Prec>>(d - secs);
res.positive = fsec >= Seconds::zero();
res.delta = abs((secs + fsec).count());
res.sec = secs.count();
res.fsec = fsec.count();
res.prec = Prec;
return res;
}
};
} }
// chrono -> timeval // chrono -> timeval
@ -259,13 +86,6 @@ template<typename Duration>
Duration duration_cast(timeval const &tv) { Duration duration_cast(timeval const &tv) {
return impl::posix_duration_cast<timeval, Duration>::cast(tv); return impl::posix_duration_cast<timeval, Duration>::cast(tv);
} }
// chrono -> DeltaTimeval
template<typename T, uint32 Prec, typename Rep, typename Period>
auto duration_cast(std::chrono::duration<Rep, Period> const &d)
-> typename std::enable_if<std::is_same<T, DeltaTimeval>::value, DeltaTimeval>::type {
return impl::posix_duration_cast<std::chrono::duration<Rep, Period>, DeltaTimeval>::template cast<Prec>(d);
}
} }
} }