clean-up: relocate NTSC drop-frame conversion functions
...extract these functions and the associated test
from the low-level C time handling library and
document them with a dedicated C++ header and test.
''This is unfinished work'' —
the extracted functions provide only the low level computations;
actually, a specialised time quantisation or time code would be required.
------------
Note though,
after extracting these functions, the rest of the plain-C test
can be removed, since equivalent functionality is covered in
much more detail by the tests of the C++ time handling framework.
Notably this allows to get rid of the direct component accessor functions.
------------
__Remark__: the base implementation of many time conversion functions
and especially NTSC drop-frame was provided by Stefan Kangas
See:
6a44134833
This commit is contained in:
parent
55b39ae592
commit
255fc82a1b
8 changed files with 305 additions and 661 deletions
|
|
@ -140,85 +140,6 @@ lumiera_time_of_gridpoint (int64_t nr, raw_time_64 origin, raw_time_64 grid);
|
|||
raw_time_64
|
||||
lumiera_build_time (long millis, uint secs, uint mins, uint hours);
|
||||
|
||||
/**
|
||||
* Builds a time value by summing up the given components.
|
||||
* @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
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_build_time_fps (uint fps, uint frames, uint secs, uint mins, uint hours);
|
||||
|
||||
/**
|
||||
* Builds a time value by summing up the given components.
|
||||
* The components are interpreted as a NTSC drop-frame timecode.
|
||||
* @warning take care not to specify time codes that are illegal NTSC drop-frame times.
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_build_time_ntsc_drop (uint frames, uint secs, uint mins, uint hours);
|
||||
|
||||
|
||||
/** Extract the hour part of given time. */
|
||||
int
|
||||
lumiera_time_hours (raw_time_64 time);
|
||||
|
||||
|
||||
/** Extract the minute part of given time. */
|
||||
int
|
||||
lumiera_time_minutes (raw_time_64 time);
|
||||
|
||||
|
||||
/** Extract the seconds part of given time. */
|
||||
int
|
||||
lumiera_time_seconds (raw_time_64 time);
|
||||
|
||||
|
||||
/** Extract the milliseconds part of given time. */
|
||||
int
|
||||
lumiera_time_millis (raw_time_64 time);
|
||||
|
||||
/**
|
||||
* Extract the remaining frame part of given time.
|
||||
* @param fps frame rate (frames per second)
|
||||
*/
|
||||
int
|
||||
lumiera_time_frames (raw_time_64 time, uint fps);
|
||||
|
||||
/**
|
||||
* Extract the frame part of given time, using NTSC drop-frame timecode.
|
||||
*/
|
||||
int
|
||||
lumiera_time_ntsc_drop_frames (raw_time_64 time);
|
||||
|
||||
/**
|
||||
* Extract the second part of given time, using NTSC drop-frame timecode.
|
||||
*/
|
||||
int
|
||||
lumiera_time_ntsc_drop_seconds (raw_time_64 time);
|
||||
|
||||
/**
|
||||
* Extract the minute part of given time, using NTSC drop-frame timecode.
|
||||
*/
|
||||
int
|
||||
lumiera_time_ntsc_drop_minutes (raw_time_64 time);
|
||||
|
||||
/**
|
||||
* Extract the hour part of given time, using NTSC drop-frame timecode.
|
||||
*/
|
||||
int
|
||||
lumiera_time_ntsc_drop_hours (raw_time_64 time);
|
||||
|
||||
|
||||
/**
|
||||
* @internal Diagnostics helper: render time value in H:MM:SS.mmm format.
|
||||
* @return `safeclib` temporary buffer containing formatted time string
|
||||
* @note any time output for real should go through quantisation followed
|
||||
* by rendering into a suitable timecode format.
|
||||
*/
|
||||
char*
|
||||
lumiera_tmpbuf_print_time (raw_time_64 time);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
DROPFRAME.hpp - Utilities for handling time
|
||||
DROPFRAME.hpp - drop-frame timecode conversions
|
||||
|
||||
Copyright (C)
|
||||
2010, Stefan Kangas <skangas@skangas.se>
|
||||
|
|
@ -11,35 +11,39 @@
|
|||
*/
|
||||
|
||||
/** @file dropframe.hpp
|
||||
** Common functions for handling of time values.
|
||||
** Working with time values in sexagesimal format, quantising time and converting
|
||||
** to/from common timecode formats can be tricky to get right. Thus the goal is
|
||||
** to concentrate the actual bits of math for these operations into a small number
|
||||
** of library functions, which are easy to test thoroughly in isolation.
|
||||
** Calculations to support mapping into NTSC drop frame timecode.
|
||||
** This is a scheme for mapping frame numbers to a time display in SMPTE format,
|
||||
** i.e. with hours, minutes, seconds and a frame count. It was introduced in USA
|
||||
** at the time when colour television with the NTSC standard was introduced.
|
||||
** Since the existing black and white television broadcast system based on analogue
|
||||
** signal processing had initially be fixed to the same frequency as the power grid,
|
||||
** which runs with 60 Hz in USA, the addition of the additional carriers for the
|
||||
** colour information was confronted with problems of signal cross-talk, due to
|
||||
** some overtones of the used carriers falling into the same frequency band.
|
||||
** As a pragmatic workaround, the frame rate was reduced to 29.97 fps.
|
||||
**
|
||||
** Built on top of that, the actual time handling in the GUI and within the Lumiera
|
||||
** session is mostly confined to use the opaque lib::time::Time wrapper objects.
|
||||
** When time values actually need to be _quantised_ (aligned to a frame grid),
|
||||
** this is expressed at the API through using the lib::time::QuTime type, which
|
||||
** then in turn can be materialised into a number of _timecode formats_.
|
||||
** These definitions ensure that whenever an actual quantisation (rounding)
|
||||
** operation is performed, the link to the appropriate time grid is available,
|
||||
** so that multiple output or rendering operations can use differing time origins
|
||||
** and frame rates simultaneously on the same model.
|
||||
** This fix of one problem however caused secondary problems for the production
|
||||
** of content for television broadcast, since at this frame rate, one hour of
|
||||
** content would not sum up cleanly to a simple number of frames. Since the
|
||||
** purpose of time code is to label each frame with a time stamp, as a solution,
|
||||
** the mapping of time stamps to frame numbers is manipulated:
|
||||
** - every minute, there is one second which is mapped to 28 frames only
|
||||
** - with the exception of every 10 minutes, where no such gap is applied
|
||||
** This scheme adds up to allocating 108 frames less per hour, as would be used
|
||||
** with a full frame rate of 30 fps. It should be noted though that applying such
|
||||
** a »drop event« every minute does not mean to _omit actual content frames_ —
|
||||
** rather it is the dime display in the time stamp which suddenly skips ahead by
|
||||
** +2 frames every minute (but not every 10th minute).
|
||||
**
|
||||
** The Lumiera Vault Layer functions mostly operate on raw frame counts, which in
|
||||
** this model are defined to be a special kind of timecode, and thus dependent on
|
||||
** a preceding time quantisation.
|
||||
** @todo 2025 this header provides some calculation functions to implement such
|
||||
** a mapping scheme (thereby documenting the know-how). But the project
|
||||
** never got to the point of integrating this functionality into an
|
||||
** actual timecode implementation. Doing so will be future work.
|
||||
** ///////////////////////////////////////////////////TICKET #751
|
||||
**
|
||||
** @deprecated 2025 this should not be a "simple" C library set aside from the Lumiera
|
||||
** time handling framework, rather it should be clarified that these are
|
||||
** implementation helpers and must not be used by any application code.
|
||||
** It should be checked which of these functions actually need to be
|
||||
** exposed through an interface header, since these are typically
|
||||
** used to implement parts of the time handling framework.
|
||||
**
|
||||
** @see lib::time::Time
|
||||
** @see time-dropframe-test.cpp
|
||||
** @see timequant.hpp
|
||||
** @see lib::time::Time
|
||||
** @see TimeValue_test
|
||||
**
|
||||
*/
|
||||
|
|
@ -48,180 +52,28 @@
|
|||
#ifndef LUMIERA_TIME_DROPFRAME_H
|
||||
#define LUMIERA_TIME_DROPFRAME_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus /*=================== C++ facilities ===================== */
|
||||
#include "lib/time/timevalue.hpp"
|
||||
|
||||
using lib::time::raw_time_64;
|
||||
|
||||
|
||||
/**
|
||||
* Converts a fraction of seconds to Lumiera's internal opaque time scale.
|
||||
* @param fractionalSeconds given as rational number
|
||||
* @note inconsistent with Lumiera's general quantisation behaviour,
|
||||
* here negative fractional micro-ticks are truncated towards zero.
|
||||
* This was deemed irrelevant in practice.
|
||||
namespace lib {
|
||||
namespace time {
|
||||
|
||||
|
||||
/**
|
||||
* Compute the consecutive frame number from a given time,
|
||||
* which is interpreted at the NTSC drop frame timecode grid.
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_rational_to_time (lib::time::FSecs const& fractionalSeconds);
|
||||
int64_t calculate_ntsc_drop_frame_number (raw_time_64 time);
|
||||
|
||||
|
||||
/**
|
||||
* Converts a frame count into Lumiera's internal time scale.
|
||||
* based on a framerate given as rational number (e.g. NTSC)
|
||||
* @note handles only positive frame counts and assumes the
|
||||
* origin to be at zero.
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_framecount_to_time (uint64_t frameCount, lib::time::FrameRate const& fps);
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the duration of one frame in Lumiera time units.
|
||||
* @param framerate underlying framerate as rational number
|
||||
* @throw error::Logic on zero framerate
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_frame_duration (lib::time::FrameRate const& fps);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C" { /* ===================== C interface ======================== */
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Quantise the given time into a fixed grid, relative to the origin.
|
||||
* The time grid used for quantisation is comprised of equally spaced intervals,
|
||||
* rooted at the given origin. The interval starting with the origin is numbered
|
||||
* as zero. Each interval includes its lower bound, but excludes its upper bound.
|
||||
* @param grid spacing of the grid intervals, measured in TimeValue::Scale (µ-ticks)
|
||||
* @return number of the grid interval containing the given time.
|
||||
* @warning the resulting value is limited to (Time::Min, Time::MAX)
|
||||
*/
|
||||
int64_t
|
||||
lumiera_quantise_frames (raw_time_64 time, raw_time_64 origin, raw_time_64 grid);
|
||||
|
||||
int64_t
|
||||
lumiera_quantise_frames_fps (raw_time_64 time, raw_time_64 origin, uint framerate);
|
||||
|
||||
/**
|
||||
* Similar to #lumiera_quantise_frames, but returns a grid aligned _relative time_.
|
||||
* @return time of start of the grid interval containing the given time,
|
||||
* but measured relative to the origin
|
||||
* @warning because the resulting value needs to be limited to fit into a 64bit long,
|
||||
* the addressable time range can be considerably reduced. For example, if
|
||||
* origin = Time::MIN, then all original time values above zero will be
|
||||
* clipped, because the result, relative to origin, needs to be <= Time::MAX
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_quantise_time (raw_time_64 time, raw_time_64 origin, raw_time_64 grid);
|
||||
|
||||
/**
|
||||
* Calculate time of a grid point (frame start)
|
||||
* @param nr index number of the grid point (0 is at origin)
|
||||
* @param grid spacing of the grid intervals, measured in TimeValue::Scale (µ-ticks)
|
||||
* @return time point (frame start) on the Lumiera internal time scale
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_time_of_gridpoint (int64_t nr, raw_time_64 origin, raw_time_64 grid);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param hours number of hours
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_build_time (long millis, uint secs, uint mins, uint hours);
|
||||
|
||||
/**
|
||||
* Builds a time value by summing up the given components.
|
||||
* @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
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_build_time_fps (uint fps, uint frames, uint secs, uint mins, uint hours);
|
||||
|
||||
/**
|
||||
* Builds a time value by summing up the given components.
|
||||
* The components are interpreted as a NTSC drop-frame timecode.
|
||||
/**
|
||||
* Build effective time from a NTSC drop frame timecode.
|
||||
* @warning take care not to specify time codes that are illegal NTSC drop-frame times.
|
||||
*/
|
||||
raw_time_64
|
||||
lumiera_build_time_ntsc_drop (uint frames, uint secs, uint mins, uint hours);
|
||||
|
||||
|
||||
/** Extract the hour part of given time. */
|
||||
int
|
||||
lumiera_time_hours (raw_time_64 time);
|
||||
|
||||
|
||||
/** Extract the minute part of given time. */
|
||||
int
|
||||
lumiera_time_minutes (raw_time_64 time);
|
||||
|
||||
|
||||
/** Extract the seconds part of given time. */
|
||||
int
|
||||
lumiera_time_seconds (raw_time_64 time);
|
||||
|
||||
|
||||
/** Extract the milliseconds part of given time. */
|
||||
int
|
||||
lumiera_time_millis (raw_time_64 time);
|
||||
|
||||
/**
|
||||
* Extract the remaining frame part of given time.
|
||||
* @param fps frame rate (frames per second)
|
||||
*/
|
||||
int
|
||||
lumiera_time_frames (raw_time_64 time, uint fps);
|
||||
|
||||
/**
|
||||
* Extract the frame part of given time, using NTSC drop-frame timecode.
|
||||
*/
|
||||
int
|
||||
lumiera_time_ntsc_drop_frames (raw_time_64 time);
|
||||
|
||||
/**
|
||||
* Extract the second part of given time, using NTSC drop-frame timecode.
|
||||
*/
|
||||
int
|
||||
lumiera_time_ntsc_drop_seconds (raw_time_64 time);
|
||||
|
||||
/**
|
||||
* Extract the minute part of given time, using NTSC drop-frame timecode.
|
||||
*/
|
||||
int
|
||||
lumiera_time_ntsc_drop_minutes (raw_time_64 time);
|
||||
|
||||
/**
|
||||
* Extract the hour part of given time, using NTSC drop-frame timecode.
|
||||
*/
|
||||
int
|
||||
lumiera_time_ntsc_drop_hours (raw_time_64 time);
|
||||
|
||||
|
||||
/**
|
||||
* @internal Diagnostics helper: render time value in H:MM:SS.mmm format.
|
||||
* @return `safeclib` temporary buffer containing formatted time string
|
||||
* @note any time output for real should go through quantisation followed
|
||||
* by rendering into a suitable timecode format.
|
||||
*/
|
||||
char*
|
||||
lumiera_tmpbuf_print_time (raw_time_64 time);
|
||||
raw_time_64 build_time_from_ntsc_drop_frame (uint frames, uint secs, uint mins, uint hours);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}//extern "C"
|
||||
#endif
|
||||
}} // lib::time
|
||||
#endif /*LUMIERA_TIME_DROPFRAME_H*/
|
||||
|
|
|
|||
|
|
@ -42,10 +42,6 @@
|
|||
#include "lib/format-string.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "lib/tmpbuf.h"
|
||||
}
|
||||
|
||||
#include <math.h>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
|
@ -382,32 +378,6 @@ namespace util {
|
|||
/* ===== implementation of the C API functions ===== */
|
||||
|
||||
|
||||
char*
|
||||
lumiera_tmpbuf_print_time (raw_time_64 time)
|
||||
{
|
||||
int milliseconds, seconds, minutes, hours;
|
||||
bool negative = (time < 0);
|
||||
|
||||
if (negative)
|
||||
time = -time;
|
||||
|
||||
time /= TIME_SCALE_MS;
|
||||
milliseconds = time % 1000;
|
||||
time /= 1000;
|
||||
seconds = time % 60;
|
||||
time /= 60;
|
||||
minutes = time % 60;
|
||||
time /= 60;
|
||||
hours = time;
|
||||
|
||||
char *buffer = lumiera_tmpbuf_snprintf(64, lib::time::DIAGNOSTIC_FORMAT,
|
||||
negative ? "-" : "", hours, minutes, seconds, milliseconds);
|
||||
|
||||
ENSURE(buffer != NULL);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
/// @todo this utility function could be factored out into a `FSecs` or `RSec` class ///////////////////////TICKET #1262
|
||||
raw_time_64
|
||||
lumiera_rational_to_time (FSecs const& fractionalSeconds)
|
||||
|
|
@ -564,24 +534,30 @@ lumiera_time_frames (raw_time_64 time, uint fps)
|
|||
|
||||
|
||||
|
||||
|
||||
/* ===== NTSC drop-frame conversions ===== */
|
||||
namespace lib {
|
||||
namespace time { ////////////////////////////////////////////////////////////////////////////////////////////TICKET #1259 : move all calculation functions into a C++ namespace
|
||||
|
||||
|
||||
namespace { // implementation helper
|
||||
/* ===== NTSC drop-frame conversions ===== */
|
||||
|
||||
namespace { // conversion parameters
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/** 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!!
|
||||
/**
|
||||
* @remark This function reverses building the drop-frame timecode,
|
||||
* and thus maps a time into consecutive frame numbers
|
||||
* at NTSC framerate (i.e. without gaps)
|
||||
* @param timecode represented as time value in µ-ticks
|
||||
* @return the absolute frame number as addressed by NTSC drop-frame
|
||||
* @todo 2011 I doubt this works correct for negative times!!
|
||||
*/
|
||||
inline int64_t
|
||||
calculate_drop_frame_number (raw_time_64 time)
|
||||
int64_t
|
||||
calculate_ntsc_drop_frame_number (raw_time_64 time)
|
||||
{
|
||||
int64_t frameNr = calculate_quantisation (time, 0, 30000, 1001);
|
||||
|
||||
|
|
@ -596,35 +572,18 @@ namespace { // implementation helper
|
|||
int64_t dropIncidents = (10-1) * tenMinFrames.quot + remainingMinutes;
|
||||
return frameNr + 2*dropIncidents;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_ntsc_drop_frames (raw_time_64 time)
|
||||
{
|
||||
return calculate_drop_frame_number(time) % 30;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_ntsc_drop_seconds (raw_time_64 time)
|
||||
{
|
||||
return calculate_drop_frame_number(time) / 30 % 60;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_ntsc_drop_minutes (raw_time_64 time)
|
||||
{
|
||||
return calculate_drop_frame_number(time) / 30 / 60 % 60;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_ntsc_drop_hours (raw_time_64 time)
|
||||
{
|
||||
return calculate_drop_frame_number(time) / 30 / 60 / 60 % 24;
|
||||
}
|
||||
|
||||
raw_time_64
|
||||
lumiera_build_time_ntsc_drop (uint frames, uint secs, uint mins, uint hours)
|
||||
{
|
||||
/**
|
||||
* @remark This is the mapping function to translate NTSC drop frame
|
||||
* timecode specification into an actual time, with the necessary
|
||||
* skip events every 1.-9. minute, thereby allocating 108 frames
|
||||
* less per hour, than would be required for full 30 fps.
|
||||
* @return raw time value on a µ-tick scale
|
||||
*/
|
||||
raw_time_64
|
||||
build_time_from_ntsc_drop_frame (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
|
||||
|
|
@ -636,4 +595,7 @@ lumiera_build_time_ntsc_drop (uint frames, uint secs, uint mins, uint hours)
|
|||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}} // lib::time
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
TESTING "Time conversion" ./test-time
|
||||
|
||||
TEST "ntsc drop-frame calculations" ntsc_drop_frame << END
|
||||
return: 0
|
||||
END
|
||||
|
|
@ -130,7 +130,7 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
PLANNED "Drop-Frame calculation" TimeDropframe_test <<END
|
||||
TEST "NTSC drop-frame calculation" TimeDropframe_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -20,109 +20,110 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "lib/test/test.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ctype.h>
|
||||
#include <nobug.h>
|
||||
|
||||
typedef int64_t raw_time_64; //////////////////////////////////////////////////////////////////////////////TICKET #1259 turn time.h in to a C++ implementation header
|
||||
|
||||
#include "lib/time.h" /////////////////////////////////////////////////////////////////////////////////////TICKET #1259 this should not be a general purpose library, but rather an implementation base
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/time/dropframe.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
|
||||
|
||||
static int
|
||||
calculate_framecount (raw_time_64 t, uint fps)
|
||||
{
|
||||
return lumiera_quantise_frames_fps (t,0,fps);
|
||||
}
|
||||
namespace lib {
|
||||
namespace time{
|
||||
namespace test{
|
||||
|
||||
using time::Time;
|
||||
using time::TimeVar;
|
||||
using time::FSecs;
|
||||
using time::raw_time_64;
|
||||
|
||||
namespace {// Test setup
|
||||
const int FRAMES = 15;
|
||||
const int MILLIS = 700;
|
||||
const int SECONDS = 20;
|
||||
const int MINUTES = 55;
|
||||
const int HOURS = 3;
|
||||
|
||||
|
||||
TESTS_BEGIN
|
||||
/* ====== conversion helpers to verify results ====== */
|
||||
|
||||
const int FRAMES = 15;
|
||||
const int MILLIS = 700;
|
||||
const int SECONDS = 20;
|
||||
const int MINUTES = 55;
|
||||
const int HOURS = 3;
|
||||
const int FPS = 24;
|
||||
const auto TIME_SCALE_sec{lib::time::TimeValue::SCALE };
|
||||
const auto TIME_SCALE_ms {lib::time::TimeValue::SCALE / 1'000};
|
||||
|
||||
/*
|
||||
* 1. Basic functionality
|
||||
int
|
||||
dropframe_frames (raw_time_64 timecode)
|
||||
{
|
||||
return calculate_ntsc_drop_frame_number(timecode) % 30;
|
||||
}
|
||||
|
||||
int
|
||||
dropframe_seconds (raw_time_64 timecode)
|
||||
{
|
||||
return calculate_ntsc_drop_frame_number(timecode) / 30 % 60;
|
||||
}
|
||||
|
||||
int
|
||||
dropframe_minutes (raw_time_64 timecode)
|
||||
{
|
||||
return calculate_ntsc_drop_frame_number(timecode) / 30 / 60 % 60;
|
||||
}
|
||||
|
||||
int
|
||||
dropframe_hours (raw_time_64 timecode)
|
||||
{
|
||||
return calculate_ntsc_drop_frame_number(timecode) / 30 / 60 / 60 % 24;
|
||||
}
|
||||
|
||||
int
|
||||
time_hours (raw_time_64 time)
|
||||
{
|
||||
return time / TIME_SCALE_sec / 60 / 60;
|
||||
}
|
||||
|
||||
int
|
||||
time_minutes (raw_time_64 time)
|
||||
{
|
||||
return (time / TIME_SCALE_sec / 60) % 60;
|
||||
}
|
||||
|
||||
int
|
||||
time_seconds (raw_time_64 time)
|
||||
{
|
||||
return (time / TIME_SCALE_sec) % 60;
|
||||
}
|
||||
|
||||
int
|
||||
time_millis (raw_time_64 time)
|
||||
{
|
||||
return (time / TIME_SCALE_ms) % 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************//**
|
||||
* @test document the computation of NTSC drop frame timecode mapping.
|
||||
*/
|
||||
class TimeDropframe_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
verify_DropFrame_conv();
|
||||
verify_completeMapping();
|
||||
}
|
||||
|
||||
TEST (basic)
|
||||
{
|
||||
// Zero
|
||||
raw_time_64 t = lumiera_build_time (0,0,0,0);
|
||||
|
||||
CHECK ((raw_time_64) 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) == 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));
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. Frame rate dependent calculations.
|
||||
/** @test perform a drop-frame timecode conversion
|
||||
* and verify the complete round-trip is correct.
|
||||
*/
|
||||
|
||||
TEST (fps)
|
||||
{
|
||||
raw_time_64 t = lumiera_build_time_fps (FPS, FRAMES, SECONDS, MINUTES, HOURS);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 3. NTSC drop-frame calculations.
|
||||
*/
|
||||
|
||||
TEST (ntsc_drop_frame)
|
||||
{
|
||||
void
|
||||
verify_DropFrame_conv()
|
||||
{
|
||||
// Make sure frame 0 begins at 0
|
||||
raw_time_64 t = lumiera_build_time_ntsc_drop (0, 0, 0, 0);
|
||||
raw_time_64 t = build_time_from_ntsc_drop_frame (0, 0, 0, 0);
|
||||
CHECK (t == 0);
|
||||
|
||||
CHECK ((raw_time_64) 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);
|
||||
t = build_time_from_ntsc_drop_frame (FRAMES, SECONDS, MINUTES, HOURS);
|
||||
|
||||
// Calculate manually what result to expect....
|
||||
int frames = FRAMES + 30*SECONDS + 30*60*MINUTES + 30*60*60*HOURS; // sum up using nominal 30fps
|
||||
|
|
@ -131,33 +132,37 @@ TEST (ntsc_drop_frame)
|
|||
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 (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);
|
||||
CHECK (time_seconds (t) == SECONDS); // while all other components should come out equal as set
|
||||
CHECK (time_minutes (t) == MINUTES);
|
||||
CHECK (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
|
||||
//CHECK (lumiera_quantise_frames (t, 0, dropFrameDuration) == frames); // the total nominal frames
|
||||
CHECK (dropframe_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.
|
||||
int min;
|
||||
int sec;
|
||||
int frame;
|
||||
int hrs;
|
||||
for (hrs = 0; hrs <= 24; hrs += 6)
|
||||
for (min = 0; min <= 59; min += 1)
|
||||
for (sec = 0; sec <= 59; sec += 10)
|
||||
for (frame = 0; frame <= 29; frame++)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test Cover the whole value range of a day in drop-frame:
|
||||
* - manually construct a drop-frame timecode
|
||||
* - make sure our library function returns the same times.
|
||||
*/
|
||||
void
|
||||
verify_completeMapping()
|
||||
{
|
||||
for (int hrs = 0; hrs <= 24; hrs += 6)
|
||||
for (int min = 0; min <= 59; min += 1)
|
||||
for (int sec = 0; sec <= 59; sec += 10)
|
||||
for (int frame = 0; frame <= 29; frame++)
|
||||
{
|
||||
// Skip dropped frames
|
||||
if (min % 10 && sec == 0 && frame < 2)
|
||||
continue;
|
||||
|
||||
t = lumiera_build_time_ntsc_drop(frame, sec, min, hrs);
|
||||
raw_time_64 t = build_time_from_ntsc_drop_frame(frame, sec, min, hrs);
|
||||
/*
|
||||
ECHO ("%02d:%02d:%02d;%02d"
|
||||
, lumiera_time_ntsc_drop_hours (t)
|
||||
|
|
@ -166,20 +171,26 @@ TEST (ntsc_drop_frame)
|
|||
, 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);
|
||||
CHECK (dropframe_frames (t) == frame);
|
||||
CHECK (dropframe_seconds (t) == sec);
|
||||
CHECK (dropframe_minutes (t) == min);
|
||||
CHECK (dropframe_hours (t) == hrs % 24);
|
||||
}
|
||||
|
||||
// Make sure we do not get non-existent frames
|
||||
int i;
|
||||
for (i = 0; i < 59; i++)
|
||||
for (int i = 0; i < 59; i++)
|
||||
{
|
||||
int frame = (i % 10 == 0) ? 0 : 2;
|
||||
t = lumiera_build_time_ntsc_drop (frame, 0, i, 0);
|
||||
CHECK (lumiera_time_ntsc_drop_frames (t) == frame);
|
||||
raw_time_64 t = build_time_from_ntsc_drop_frame (frame, 0, i, 0);
|
||||
CHECK (dropframe_frames (t) == frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TESTS_END
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (TimeDropframe_test, "unit common");
|
||||
|
||||
|
||||
|
||||
}}} // namespace lib::time::test
|
||||
|
|
|
|||
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
TEST-TIME - test the time conversion lib
|
||||
|
||||
Copyright (C)
|
||||
2010, Stefan Kangas <skangas@skangas.se>
|
||||
|
||||
**Lumiera** 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. See the file COPYING for further details.
|
||||
|
||||
* *****************************************************************/
|
||||
|
||||
/** @file test-time.c
|
||||
** C unit test to cover the basic low-level time handling operations
|
||||
** @see time.h
|
||||
** @see timevalue.hpp
|
||||
** @see TimeValue_test high-level time entities
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/test/test.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <ctype.h>
|
||||
#include <nobug.h>
|
||||
|
||||
typedef int64_t raw_time_64; //////////////////////////////////////////////////////////////////////////////TICKET #1259 turn time.h in to a C++ implementation header
|
||||
|
||||
#include "lib/time.h" /////////////////////////////////////////////////////////////////////////////////////TICKET #1259 this should not be a general purpose library, but rather an implementation base
|
||||
|
||||
|
||||
static int
|
||||
calculate_framecount (raw_time_64 t, uint fps)
|
||||
{
|
||||
return lumiera_quantise_frames_fps (t,0,fps);
|
||||
}
|
||||
|
||||
|
||||
TESTS_BEGIN
|
||||
|
||||
const int FRAMES = 15;
|
||||
const int SECONDS = 20;
|
||||
const int MINUTES = 55;
|
||||
const int HOURS = 3;
|
||||
const int FPS = 24;
|
||||
|
||||
|
||||
/*
|
||||
* 3. NTSC drop-frame calculations.
|
||||
*/
|
||||
|
||||
TEST (ntsc_drop_frame)
|
||||
{
|
||||
// Make sure frame 0 begins at 0
|
||||
raw_time_64 t = lumiera_build_time_ntsc_drop (0, 0, 0, 0);
|
||||
|
||||
CHECK ((raw_time_64) 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);
|
||||
|
||||
// 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.
|
||||
int min;
|
||||
int sec;
|
||||
int frame;
|
||||
int hrs;
|
||||
for (hrs = 0; hrs <= 24; hrs += 6)
|
||||
for (min = 0; min <= 59; min += 1)
|
||||
for (sec = 0; sec <= 59; sec += 10)
|
||||
for (frame = 0; frame <= 29; frame++)
|
||||
{
|
||||
// Skip dropped frames
|
||||
if (min % 10 && sec == 0 && frame < 2)
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
// Make sure we do not get non-existent frames
|
||||
int i;
|
||||
for (i = 0; i < 59; i++)
|
||||
{
|
||||
int frame = (i % 10 == 0) ? 0 : 2;
|
||||
t = lumiera_build_time_ntsc_drop (frame, 0, i, 0);
|
||||
CHECK (lumiera_time_ntsc_drop_frames (t) == frame);
|
||||
}
|
||||
}
|
||||
|
||||
TESTS_END
|
||||
|
|
@ -162886,8 +162886,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
...nachdem gavl_time_t durch einen Typedef ersetzt ist, und ich das Thema durch #1261 bereits abgesteckt habe, könnte der Bestand einer eigenständigen Basis-Library durch wenige Umordnungen aufgehoben werden. Denn darum geht es mir: ich will in Lumiera eine Ordnung schaffen, in der gedankenloses einfach-mal-Machen keinen Raum findet.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<node CREATED="1747520507617" ID="ID_391130031" MODIFIED="1748350248986" TEXT="sollte die konkreten Verwendungen durchsehen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
|
|
@ -162896,8 +162895,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
...möglicherweise lassen sich diese Funktionen nämlich in Gruppen einteilen und dann direkt in einen anonymen namespace in die jeweilige Translation-Unit schieben....
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1747520518579" ID="ID_1232667630" MODIFIED="1747520531129" TEXT="müßte dann auch den C-Test (test-time) auflösen">
|
||||
<node CREATED="1747520690709" ID="ID_920147641" MODIFIED="1747520695437" TEXT="der ist eigentlich nicht lang"/>
|
||||
|
|
@ -163166,7 +163164,8 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1748363166124" ID="ID_20271646" MODIFIED="1748363183352" TEXT="also: stattdessen rigoros mit Stubs arbeiten">
|
||||
<node CREATED="1748363166124" ID="ID_20271646" MODIFIED="1748388589043" TEXT="also: stattdessen rigoros mit Stubs arbeiten">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1748363186304" ID="ID_1752179075" MODIFIED="1748363276225" TEXT="d.h. das Timecode-Widget ganz ersichtlich brechen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
|
|
@ -163175,8 +163174,7 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
gebrochen ist es ja ohnehin und sowiso, und weiter damit arbeiten möchte ich nicht — ganz ehrlich, das war ein »Griff ins Klo«, das ist kein Code, den man erhalten sollte.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1748370343922" ID="ID_767625066" MODIFIED="1748370424799" TEXT="weitere Verwendungen der Dezimator-Funktionen direkt inlinen">
|
||||
|
|
@ -163192,11 +163190,46 @@ Since then others have made contributions, see the log for the history.</font></
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1748370446771" ID="ID_514685019" MODIFIED="1748370458042" TEXT="Drop-Frame-Berechnung dokumentieren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#435e98" CREATED="1748370471401" ID="ID_241597558" MODIFIED="1748370583898" TEXT="teset-time.c ⟼ time/time-dropframe-test.cpp">
|
||||
<node COLOR="#338800" CREATED="1748370446771" ID="ID_514685019" MODIFIED="1748388515380" TEXT="Drop-Frame-Berechnung dokumentieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1748370471401" ID="ID_241597558" MODIFIED="1748383700953" TEXT="test-time.c ⟼ time/time-dropframe-test.cpp">
|
||||
<icon BUILTIN="list"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1748383707870" ID="ID_1871702886" MODIFIED="1748388462890" TEXT="Funktionen umordnen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1748383746542" ID="ID_1117132995" MODIFIED="1748383761481" TEXT="umziehen in Namespace lib::time"/>
|
||||
<node CREATED="1748383717910" ID="ID_6099644" MODIFIED="1748383730804" TEXT="umziehen in Header lib/time/dropframe.hpp"/>
|
||||
<node CREATED="1748383731428" ID="ID_1472070007" MODIFIED="1748383743307" TEXT="Implementierung verbleibt in lib/time/time.cpp"/>
|
||||
<node CREATED="1748383780122" ID="ID_170667006" MODIFIED="1748383790175" TEXT="nur die eigentliche Berechnungslogik erhalten">
|
||||
<node CREATED="1748383816257" ID="ID_1470396784" MODIFIED="1748384512960" TEXT="int64_t calculate_ntsc_drop_frame_number (raw_time_64 timecode)"/>
|
||||
<node CREATED="1748383835599" ID="ID_328152526" MODIFIED="1748385988435" TEXT="raw_time_64 build_time_from_ntsc_drop_frame (frames, secs, mins, hours)"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1748388465815" ID="ID_1825328642" MODIFIED="1748388490811" STYLE="fork" TEXT="all die Konverter / Deizimator-Funktionen direkt lokal im Test definieren">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#174956" COLOR="#8dfd49" CREATED="1748388518698" ID="ID_1682762507" MODIFIED="1748388574315" STYLE="bubble" TEXT="umgezogener Test läuft GRÜN">
|
||||
<edge COLOR="#61fe5b" STYLE="bezier" WIDTH="thin"/>
|
||||
<font NAME="SansSerif" SIZE="15"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#8b2f98" CREATED="1748388204363" ID="ID_926423450" MODIFIED="1748388454445" TEXT=" �� totmachen ��">
|
||||
<node COLOR="#435e98" CREATED="1748388215333" ID="ID_1531959638" MODIFIED="1748388508038" TEXT="test-time.c">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="back"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1748388277997" ID="ID_1633487385" MODIFIED="1748388508037" TEXT="lumiera_build_time_fps (uint fps, uint frames, uint secs, uint mins, uint hours)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388277999" ID="ID_260910175" MODIFIED="1748388508037" TEXT="lumiera_build_time_ntsc_drop (uint frames, uint secs, uint mins, uint hours)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278001" ID="ID_1058883405" MODIFIED="1748388508037" TEXT="lumiera_time_hours (raw_time_64 time)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278002" ID="ID_235432384" MODIFIED="1748388508037" TEXT="lumiera_time_minutes (raw_time_64 time)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278003" ID="ID_493874247" MODIFIED="1748388508036" TEXT="lumiera_time_seconds (raw_time_64 time)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278005" ID="ID_1348006733" MODIFIED="1748388508036" TEXT="lumiera_time_millis (raw_time_64 time)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278006" ID="ID_1001439160" MODIFIED="1748388508036" TEXT="lumiera_time_frames (raw_time_64 time, uint fps)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278008" ID="ID_18545784" MODIFIED="1748388508036" TEXT="lumiera_time_ntsc_drop_frames (raw_time_64 time)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278010" ID="ID_1558655339" MODIFIED="1748388508035" TEXT="lumiera_time_ntsc_drop_seconds (raw_time_64 time)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278011" ID="ID_1940069424" MODIFIED="1748388508035" TEXT="lumiera_time_ntsc_drop_minutes (raw_time_64 time)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278013" ID="ID_1868369312" MODIFIED="1748388508035" TEXT="lumiera_time_ntsc_drop_hours (raw_time_64 time)"/>
|
||||
<node COLOR="#435e98" CREATED="1748388278014" ID="ID_275417741" MODIFIED="1748388508019" TEXT="lumiera_tmpbuf_print_time (raw_time_64 time)"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue