Fix drop-frame: remove float framerate
This commit is contained in:
parent
b6f81d1e1e
commit
49d5a9592a
3 changed files with 177 additions and 138 deletions
135
src/lib/time.cpp
135
src/lib/time.cpp
|
|
@ -28,7 +28,7 @@ extern "C" {
|
|||
#include "lib/tmpbuf.h"
|
||||
}
|
||||
|
||||
#include <limits.h>
|
||||
#include <limits>
|
||||
#include <math.h>
|
||||
|
||||
using util::floordiv;
|
||||
|
|
@ -102,25 +102,55 @@ lumiera_frame_duration (FrameRate const& fps)
|
|||
}
|
||||
|
||||
|
||||
namespace { // implementation helper
|
||||
namespace { // implementation: basic frame quantisation....
|
||||
|
||||
inline long long
|
||||
inline int64_t
|
||||
calculate_quantisation (gavl_time_t time, gavl_time_t origin, gavl_time_t grid)
|
||||
{
|
||||
time -= origin;
|
||||
return floordiv (time,grid);
|
||||
}
|
||||
|
||||
inline int64_t
|
||||
calculate_quantisation (gavl_time_t time, gavl_time_t origin, uint framerate, uint framerate_divisor=1)
|
||||
{
|
||||
REQUIRE (framerate);
|
||||
REQUIRE (framerate_divisor);
|
||||
|
||||
const int64_t limit_num = std::numeric_limits<gavl_time_t>::max() / framerate;
|
||||
const int64_t limit_den = std::numeric_limits<gavl_time_t>::max() / framerate_divisor;
|
||||
const int64_t microScale(GAVL_TIME_SCALE);
|
||||
|
||||
// protect against numeric overflow
|
||||
if (abs(time) < limit_num && microScale < limit_den)
|
||||
{
|
||||
// safe to calculate "time * framerate"
|
||||
time -= origin;
|
||||
return floordiv (time*framerate, microScale*framerate_divisor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// direct calculation will overflow.
|
||||
// use the less precise method instead...
|
||||
gavl_time_t frameDuration = microScale / framerate; // truncated to µs
|
||||
return calculate_quantisation (time,origin, frameDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int64_t
|
||||
lumiera_quantise_frames (gavl_time_t time, gavl_time_t origin, gavl_time_t grid)
|
||||
{
|
||||
ENSURE (sizeof(int64_t) <= sizeof(long long));
|
||||
|
||||
return calculate_quantisation (time, origin, grid);
|
||||
}
|
||||
|
||||
int64_t
|
||||
lumiera_quantise_frames_fps (gavl_time_t time, gavl_time_t origin, uint framerate)
|
||||
{
|
||||
return calculate_quantisation (time,origin,framerate);
|
||||
}
|
||||
|
||||
gavl_time_t
|
||||
lumiera_quantise_time (gavl_time_t time, gavl_time_t origin, gavl_time_t grid)
|
||||
{
|
||||
|
|
@ -149,9 +179,9 @@ lumiera_build_time(long millis, uint secs, uint mins, uint hours)
|
|||
}
|
||||
|
||||
gavl_time_t
|
||||
lumiera_build_time_fps (float fps, uint frames, uint secs, uint mins, uint hours)
|
||||
lumiera_build_time_fps (uint fps, uint frames, uint secs, uint mins, uint hours)
|
||||
{
|
||||
gavl_time_t time = frames * (1000.0 / fps)
|
||||
gavl_time_t time = 1000LL * frames/fps
|
||||
+ 1000 * secs
|
||||
+ 1000 * 60 * mins
|
||||
+ 1000 * 60 * 60 * hours;
|
||||
|
|
@ -159,19 +189,6 @@ lumiera_build_time_fps (float fps, uint frames, uint secs, uint mins, uint hours
|
|||
return time;
|
||||
}
|
||||
|
||||
gavl_time_t
|
||||
lumiera_build_time_ntsc_drop (uint frames, uint secs, uint mins, uint hours)
|
||||
{
|
||||
uint64_t total_mins = 60 * hours + mins;
|
||||
uint64_t total_frames = 108000 * hours
|
||||
+ 1800 * mins
|
||||
+ 30 * secs
|
||||
+ frames
|
||||
- 2 * (total_mins - total_mins / 10);
|
||||
|
||||
return lumiera_framecount_to_time (total_frames, FrameRate::NTSC);
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_hours (gavl_time_t time)
|
||||
{
|
||||
|
|
@ -197,56 +214,84 @@ lumiera_time_millis (gavl_time_t time)
|
|||
}
|
||||
|
||||
int
|
||||
lumiera_time_frames (gavl_time_t time, float fps)
|
||||
lumiera_time_frames (gavl_time_t time, uint fps)
|
||||
{
|
||||
return (fps * (lumiera_time_millis(time))) / 1000;
|
||||
REQUIRE (fps < uint(std::numeric_limits<int>::max()));
|
||||
return floordiv (lumiera_time_millis(time) * int(fps), GAVL_TIME_SCALE_MS);
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_frame_count (gavl_time_t time, float fps)
|
||||
{
|
||||
REQUIRE (fps > 0);
|
||||
|
||||
return roundf((time / GAVL_TIME_SCALE_MS / 1000.0f) * fps);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used in the NTSC drop-frame functions to avoid code
|
||||
* repetition.
|
||||
* @return the frame number for given time
|
||||
*/
|
||||
static int
|
||||
ntsc_drop_get_frame_number (gavl_time_t time)
|
||||
{
|
||||
int frame = lumiera_time_frame_count (time, NTSC_DROP_FRAME_FPS);
|
||||
|
||||
|
||||
/* ===== NTSC drop-frame conversions ===== */
|
||||
|
||||
|
||||
namespace { // implementation helper
|
||||
|
||||
int d = frame / 17982; // 17982 = 600 * 29.97
|
||||
int m = frame % 17982; // 17982 = 600 * 29.97
|
||||
const uint FRAMES_PER_10min = 10*60 * 30000/1001;
|
||||
const uint FRAMES_PER_1min = 1*60 * 30000/1001;
|
||||
const uint DISCREPANCY = (1*60 * 30) - FRAMES_PER_1min;
|
||||
|
||||
|
||||
return frame + 18*d + 2*((m - 2) / 1798); // 1798 = 60 * 29.97
|
||||
/** reverse the drop-frame calculation
|
||||
* @param time absolute time value in micro ticks
|
||||
* @return the absolute frame number using NTSC drop-frame encoding
|
||||
* @todo I doubt this works correct for negative times!!
|
||||
*/
|
||||
inline int64_t
|
||||
calculate_drop_frame_number (gavl_time_t time)
|
||||
{
|
||||
int64_t frameNr = calculate_quantisation (time, 0, 30000, 1001);
|
||||
|
||||
// partition into 10 minute segments
|
||||
lldiv_t tenMinFrames = lldiv (frameNr, FRAMES_PER_10min);
|
||||
|
||||
// ensure the drop-frame incidents happen at full minutes;
|
||||
// at start of each 10-minute segment *no* drop incident happens,
|
||||
// thus we need to correct discrepancy between nominal/real framerate once:
|
||||
int64_t remainingMinutes = (tenMinFrames.rem - DISCREPANCY) / FRAMES_PER_1min;
|
||||
|
||||
int64_t dropIncidents = (10-1) * tenMinFrames.quot + remainingMinutes;
|
||||
return frameNr + 2*dropIncidents;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_ntsc_drop_frames (gavl_time_t time)
|
||||
{
|
||||
return ntsc_drop_get_frame_number(time) % 30;
|
||||
return calculate_drop_frame_number(time) % 30;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_ntsc_drop_seconds (gavl_time_t time)
|
||||
{
|
||||
return ntsc_drop_get_frame_number(time) / 30 % 60;
|
||||
return calculate_drop_frame_number(time) / 30 % 60;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_ntsc_drop_minutes (gavl_time_t time)
|
||||
{
|
||||
return ntsc_drop_get_frame_number(time) / 30 / 60 % 60;
|
||||
return calculate_drop_frame_number(time) / 30 / 60 % 60;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_ntsc_drop_hours (gavl_time_t time)
|
||||
{
|
||||
return ntsc_drop_get_frame_number(time) / 30 / 60 / 60 % 24;
|
||||
return calculate_drop_frame_number(time) / 30 / 60 / 60 % 24;
|
||||
}
|
||||
|
||||
gavl_time_t
|
||||
lumiera_build_time_ntsc_drop (uint frames, uint secs, uint mins, uint hours)
|
||||
{
|
||||
uint64_t total_mins = 60 * hours + mins;
|
||||
uint64_t total_frames = 30*60*60 * hours
|
||||
+ 30*60 * mins
|
||||
+ 30 * secs
|
||||
+ frames
|
||||
- 2 * (total_mins - total_mins / 10);
|
||||
gavl_time_t result = lumiera_framecount_to_time (total_frames, FrameRate::NTSC);
|
||||
|
||||
if (0 != result) // compensate for truncating down on conversion
|
||||
result += 1; // without this adjustment the frame number
|
||||
return result; // would turn out off by -1 on back conversion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,8 +94,6 @@ lumiera_frame_duration (lib::time::FrameRate const& fps);
|
|||
extern "C" { /* ===================== C interface ======================== */
|
||||
#endif
|
||||
|
||||
#define NTSC_DROP_FRAME_FPS 29.97
|
||||
/* TODO: replace this by lib::time::FrameRate::NTSC */
|
||||
|
||||
/**
|
||||
* Formats a time value in H:MM:SS.mmm format into a temporary buffer.
|
||||
|
|
@ -116,6 +114,9 @@ lumiera_tmpbuf_print_time (gavl_time_t time);
|
|||
int64_t
|
||||
lumiera_quantise_frames (gavl_time_t time, gavl_time_t origin, gavl_time_t grid);
|
||||
|
||||
int64_t
|
||||
lumiera_quantise_frames_fps (gavl_time_t time, gavl_time_t origin, uint framerate);
|
||||
|
||||
/**
|
||||
* Similar to #lumiera_quantise_frames, but returns a grid aligned \em time value
|
||||
* @return time of start of the grid interval containing the given time,
|
||||
|
|
@ -138,7 +139,7 @@ gavl_time_t
|
|||
lumiera_time_of_gridpoint (int64_t nr, gavl_time_t origin, gavl_time_t grid);
|
||||
|
||||
/**
|
||||
* Builds a time value by summing up the given components.
|
||||
* Build a time value by summing up the given components.
|
||||
* @param millis number of milliseconds
|
||||
* @param secs number of seconds
|
||||
* @param mins number of minutes
|
||||
|
|
@ -149,15 +150,14 @@ lumiera_build_time (long millis, uint secs, uint mins, uint hours);
|
|||
|
||||
/**
|
||||
* Builds a time value by summing up the given components.
|
||||
* @todo replace float framerates by lib::time::FrameRate
|
||||
* @deprecated this function doesn't fit in the general time handling concept.
|
||||
* SMPTE is a timecode format, and should be distinguished from a
|
||||
* raw time value. For any timecode format, we always require an explicit
|
||||
* 'time grid' (coordinate system), which also defines a zero point.
|
||||
* Usually, this time grid is managed and provided by the session
|
||||
* @param fps framerate (frames per second)
|
||||
* @param frames number of additional frames
|
||||
* @param secs number of seconds
|
||||
* @param mins number of minutes
|
||||
* @param hours number of hours
|
||||
*/
|
||||
gavl_time_t
|
||||
lumiera_build_time_fps (float fps, uint frames, uint secs, uint mins, uint hours);
|
||||
lumiera_build_time_fps (uint fps, uint frames, uint secs, uint mins, uint hours);
|
||||
|
||||
/**
|
||||
* Builds a time value by summing up the given components.
|
||||
|
|
@ -188,22 +188,11 @@ int
|
|||
lumiera_time_millis (gavl_time_t time);
|
||||
|
||||
/**
|
||||
* Extract the frame part of given time, using the given fps.
|
||||
* @param fps frame rate
|
||||
* @todo use the rational lib::time::FrameRate instead of a float
|
||||
* Extract the remaining frame part of given time.
|
||||
* @param fps frame rate (frames per second)
|
||||
*/
|
||||
int
|
||||
lumiera_time_frames (gavl_time_t time, float fps);
|
||||
|
||||
/**
|
||||
* Extract the frame count for the given time, using the given fps.
|
||||
* @todo use the rational lib::time::FrameRate instead of a float
|
||||
* @deprecated should be moved down into the implementation;
|
||||
* this function doesn't fit into the general time handling,
|
||||
* because it doesn't link to a time grid (coordinate system)
|
||||
*/
|
||||
int
|
||||
lumiera_time_frame_count (gavl_time_t time, float fps);
|
||||
lumiera_time_frames (gavl_time_t time, uint fps);
|
||||
|
||||
/**
|
||||
* Extract the frame part of given time, using NTSC drop-frame timecode.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,13 @@ typedef unsigned int uint;
|
|||
|
||||
#include <nobug.h>
|
||||
|
||||
static int
|
||||
calculate_framecount (gavl_time_t t, uint fps)
|
||||
{
|
||||
return lumiera_quantise_frames_fps (t,0,fps);
|
||||
}
|
||||
|
||||
|
||||
TESTS_BEGIN
|
||||
|
||||
const int FRAMES = 15;
|
||||
|
|
@ -33,7 +40,7 @@ const int MILLIS = 700;
|
|||
const int SECONDS = 20;
|
||||
const int MINUTES = 55;
|
||||
const int HOURS = 3;
|
||||
const float FPS = 24.0;
|
||||
const int FPS = 24;
|
||||
|
||||
/*
|
||||
* 1. Basic functionality
|
||||
|
|
@ -44,29 +51,29 @@ TEST (basic)
|
|||
// Zero
|
||||
gavl_time_t t = lumiera_build_time (0,0,0,0);
|
||||
|
||||
CHECK ((gavl_time_t) t == 0);
|
||||
CHECK (lumiera_time_millis (t) == 0);
|
||||
CHECK (lumiera_time_seconds (t) == 0);
|
||||
CHECK (lumiera_time_minutes (t) == 0);
|
||||
CHECK (lumiera_time_hours (t) == 0);
|
||||
CHECK (lumiera_time_frames (t, FPS) == 0);
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == 0);
|
||||
CHECK (lumiera_time_frame_count (t, FPS) == 0);
|
||||
CHECK (lumiera_time_frame_count (t, FPS+5) == 0);
|
||||
CHECK ((gavl_time_t) t == 0);
|
||||
CHECK (lumiera_time_millis (t) == 0);
|
||||
CHECK (lumiera_time_seconds (t) == 0);
|
||||
CHECK (lumiera_time_minutes (t) == 0);
|
||||
CHECK (lumiera_time_hours (t) == 0);
|
||||
CHECK (lumiera_time_frames (t, FPS) == 0);
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == 0);
|
||||
CHECK (calculate_framecount (t,FPS) == 0);
|
||||
CHECK (calculate_framecount (t, FPS+5) == 0);
|
||||
|
||||
ECHO ("%s", lumiera_tmpbuf_print_time (t));
|
||||
|
||||
// Non-zero
|
||||
t = lumiera_build_time (MILLIS, SECONDS, MINUTES, HOURS);
|
||||
|
||||
CHECK (lumiera_time_millis (t) == MILLIS);
|
||||
CHECK (lumiera_time_seconds (t) == SECONDS);
|
||||
CHECK (lumiera_time_minutes (t) == MINUTES);
|
||||
CHECK (lumiera_time_hours (t) == HOURS);
|
||||
CHECK (lumiera_time_frames (t, FPS) == (int)((FPS * MILLIS) / 1000));
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == (int)(((FPS+5) * MILLIS) / 1000));
|
||||
CHECK (lumiera_time_frame_count (t, FPS) == 338897);
|
||||
CHECK (lumiera_time_frame_count (t, FPS+5) == 409500);
|
||||
CHECK (lumiera_time_millis (t) == MILLIS);
|
||||
CHECK (lumiera_time_seconds (t) == SECONDS);
|
||||
CHECK (lumiera_time_minutes (t) == MINUTES);
|
||||
CHECK (lumiera_time_hours (t) == HOURS);
|
||||
CHECK (lumiera_time_frames (t, FPS) == FPS * MILLIS / 1000);
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == (FPS+5) * MILLIS / 1000);
|
||||
CHECK (calculate_framecount (t, FPS) == 338896);
|
||||
CHECK (calculate_framecount (t, FPS+5) == 409500);
|
||||
|
||||
ECHO ("%s", lumiera_tmpbuf_print_time (t));
|
||||
}
|
||||
|
|
@ -79,14 +86,14 @@ TEST (fps)
|
|||
{
|
||||
gavl_time_t t = lumiera_build_time_fps (FPS, FRAMES, SECONDS, MINUTES, HOURS);
|
||||
|
||||
CHECK (lumiera_time_millis (t) == (int)(FRAMES * (1000.0 / FPS)));
|
||||
CHECK (lumiera_time_seconds (t) == SECONDS);
|
||||
CHECK (lumiera_time_minutes (t) == MINUTES);
|
||||
CHECK (lumiera_time_hours (t) == HOURS);
|
||||
CHECK (lumiera_time_frames (t, FPS) == FRAMES);
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == (int)(((FPS+5) * 625) / 1000));
|
||||
CHECK (lumiera_time_frame_count (t, FPS) == 338895);
|
||||
CHECK (lumiera_time_frame_count (t, FPS+5) == 409498);
|
||||
CHECK (lumiera_time_millis (t) == FRAMES * 1000 / FPS);
|
||||
CHECK (lumiera_time_seconds (t) == SECONDS);
|
||||
CHECK (lumiera_time_minutes (t) == MINUTES);
|
||||
CHECK (lumiera_time_hours (t) == HOURS);
|
||||
CHECK (lumiera_time_frames (t, FPS) == FRAMES);
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == FRAMES * (FPS+5)/FPS);
|
||||
CHECK (calculate_framecount (t, FPS) == 338895);
|
||||
CHECK (calculate_framecount (t, FPS+5) == 409498);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -98,40 +105,37 @@ TEST (ntsc_drop_frame)
|
|||
// Make sure frame 0 begins at 0
|
||||
gavl_time_t t = lumiera_build_time_ntsc_drop (0, 0, 0, 0);
|
||||
|
||||
CHECK ((gavl_time_t) t == 0);
|
||||
CHECK (lumiera_time_millis (t) == 0);
|
||||
CHECK (lumiera_time_seconds (t) == 0);
|
||||
CHECK (lumiera_time_minutes (t) == 0);
|
||||
CHECK (lumiera_time_hours (t) == 0);
|
||||
CHECK (lumiera_time_frames (t, FPS) == 0);
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == 0);
|
||||
CHECK (lumiera_time_frame_count (t, FPS) == 0);
|
||||
CHECK (lumiera_time_frame_count (t, FPS+5) == 0);
|
||||
|
||||
// Use some arbitrary value to test with
|
||||
const int FRAMES = 15;
|
||||
const int SECONDS = 20;
|
||||
const int MINUTES = 55;
|
||||
const int HOURS = 3;
|
||||
const float FPS = 24.0;
|
||||
|
||||
CHECK ((gavl_time_t) t == 0);
|
||||
CHECK (lumiera_time_millis (t) == 0);
|
||||
CHECK (lumiera_time_seconds (t) == 0);
|
||||
CHECK (lumiera_time_minutes (t) == 0);
|
||||
CHECK (lumiera_time_hours (t) == 0);
|
||||
CHECK (lumiera_time_frames (t, FPS) == 0);
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == 0);
|
||||
CHECK (calculate_framecount (t, FPS) == 0);
|
||||
CHECK (calculate_framecount (t, FPS+5) == 0);
|
||||
|
||||
|
||||
|
||||
t = lumiera_build_time_ntsc_drop (FRAMES, SECONDS, MINUTES, HOURS);
|
||||
|
||||
CHECK (lumiera_time_millis (t) == 486);
|
||||
CHECK (lumiera_time_seconds (t) == SECONDS);
|
||||
CHECK (lumiera_time_minutes (t) == MINUTES);
|
||||
CHECK (lumiera_time_hours (t) == HOURS);
|
||||
|
||||
// Check standard frame calculations to verify build_time_ntsc_drop
|
||||
CHECK (lumiera_time_frames (t, FPS) == 11);
|
||||
CHECK (lumiera_time_frames (t, FPS+5) == 14);
|
||||
CHECK (lumiera_time_frame_count (t, FPS) == 338892);
|
||||
CHECK (lumiera_time_frame_count (t, FPS+5) == 409494);
|
||||
|
||||
// Frames for NTSC drop
|
||||
CHECK (lumiera_time_ntsc_drop_frames (t) == 15);
|
||||
CHECK (lumiera_time_frame_count (t, NTSC_DROP_FRAME_FPS) == 423191);
|
||||
|
||||
|
||||
// Calculate manually what result to expect....
|
||||
int frames = FRAMES + 30*SECONDS + 30*60*MINUTES + 30*60*60*HOURS; // sum up using nominal 30fps
|
||||
int minutes_to_drop_frames = (MINUTES - MINUTES/10) + (HOURS * 54); // but every minute, with the exception of every 10 minutes...
|
||||
frames -= 2*minutes_to_drop_frames; // ...drop 2 frames
|
||||
int64_t expectedMillis = 1000LL * frames * 1001/30000; // now convert frames to time, using the real framerate
|
||||
|
||||
expectedMillis %= 1000; // look at the remainder..
|
||||
CHECK (lumiera_time_millis (t) == expectedMillis);
|
||||
|
||||
CHECK (lumiera_time_seconds (t) == SECONDS); // while all other components should come out equal as set
|
||||
CHECK (lumiera_time_minutes (t) == MINUTES);
|
||||
CHECK (lumiera_time_hours (t) == HOURS);
|
||||
|
||||
// Reverse calculate frames for NTSC drop
|
||||
//CHECK (lumiera_quantise_frames (t, 0, dropFrameDuration) == frames); // the total nominal frames
|
||||
CHECK (lumiera_time_ntsc_drop_frames (t) == FRAMES); // maximum one frame off due to rounding
|
||||
|
||||
// Cover the whole value range;
|
||||
// Manually construct a drop-frame timecode
|
||||
// Make sure our library function returns the same times.
|
||||
|
|
@ -140,8 +144,8 @@ TEST (ntsc_drop_frame)
|
|||
int frame;
|
||||
int hrs;
|
||||
for (hrs = 0; hrs <= 24; hrs += 6)
|
||||
for (min = 0; min <= 59; min += 8)
|
||||
for (sec = 0; sec <= 59; sec += 8)
|
||||
for (min = 0; min <= 59; min += 1)
|
||||
for (sec = 0; sec <= 59; sec += 10)
|
||||
for (frame = 0; frame <= 29; frame++)
|
||||
{
|
||||
// Skip dropped frames
|
||||
|
|
@ -149,14 +153,15 @@ TEST (ntsc_drop_frame)
|
|||
continue;
|
||||
|
||||
t = lumiera_build_time_ntsc_drop(frame, sec, min, hrs);
|
||||
|
||||
/* ECHO ("%02d:%02d:%02d.%02d", */
|
||||
/* lumiera_time_ntsc_drop_hours (t), */
|
||||
/* lumiera_time_ntsc_drop_minutes (t), */
|
||||
/* lumiera_time_ntsc_drop_seconds (t), */
|
||||
/* lumiera_time_ntsc_drop_frames (t)); */
|
||||
|
||||
CHECK (lumiera_time_ntsc_drop_frames (t) == frame);
|
||||
/*
|
||||
ECHO ("%02d:%02d:%02d;%02d"
|
||||
, lumiera_time_ntsc_drop_hours (t)
|
||||
, lumiera_time_ntsc_drop_minutes (t)
|
||||
, lumiera_time_ntsc_drop_seconds (t)
|
||||
, lumiera_time_ntsc_drop_frames (t)
|
||||
);
|
||||
*/
|
||||
CHECK (lumiera_time_ntsc_drop_frames (t) == frame);
|
||||
CHECK (lumiera_time_ntsc_drop_seconds (t) == sec);
|
||||
CHECK (lumiera_time_ntsc_drop_minutes (t) == min);
|
||||
CHECK (lumiera_time_ntsc_drop_hours (t) == hrs % 24);
|
||||
|
|
|
|||
Loading…
Reference in a new issue