mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-07-08 18:06:30 +00:00
[FEAT] Add time units module in lib_ccxr (#1623)
* chore: Add cargo dependencies * feat: Make time module in `lib_ccxr` * feat: Add conversion guide in `time/mod.rs` module & Create `units` module * feat: Add time units code * feat: Make time module in `lib_ccxr/util` & Add helper function * feat: Add utils time related functions * feat: Add extern functions in `libccxr_exports` * feat: Add extern functions in C and use in proper place * docs: Mention in Changelogs
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
0.95 (to be released)
|
||||
-----------------
|
||||
- New: Add time units module in lib_ccxr (#1623)
|
||||
- New: Add bits and levenshtein module in lib_ccxr (#1627)
|
||||
- New: [FEAT] Add constants module in lib_ccxr (#1624)
|
||||
- New: Add constants module in lib_ccxr (#1624)
|
||||
- New: Add log module in lib_ccxr (#1622)
|
||||
- New: Create `lib_ccxr` and `libccxr_exports` (#1621)
|
||||
- Fix: Unexpected behavior of get_write_interval (#1609)
|
||||
|
||||
@@ -26,6 +26,9 @@ int fdprintf(int fd, const char *fmt, ...)
|
||||
void millis_to_time(LLONG milli, unsigned *hours, unsigned *minutes,
|
||||
unsigned *seconds, unsigned *ms)
|
||||
{
|
||||
#ifndef DISABLE_RUST
|
||||
return ccxr_millis_to_time(milli, hours, minutes, seconds, ms);
|
||||
#endif /* ifndef DISABLE_RUST */
|
||||
// LLONG milli = (LLONG) ((ccblock*1000)/29.97);
|
||||
*ms = (unsigned)(milli % 1000); // milliseconds
|
||||
milli = (milli - *ms) / 1000; // Remainder, in seconds
|
||||
|
||||
@@ -43,6 +43,11 @@
|
||||
int cc608_parity(unsigned int byte);
|
||||
int fdprintf(int fd, const char *fmt, ...);
|
||||
void millis_to_time(LLONG milli, unsigned *hours, unsigned *minutes,unsigned *seconds, unsigned *ms);
|
||||
|
||||
#ifndef DISABLE_RUST
|
||||
extern void ccxr_millis_to_time(LLONG milli, unsigned *hours, unsigned *minutes,unsigned *seconds, unsigned *ms);
|
||||
#endif // !DISABLE_RUST
|
||||
|
||||
void freep(void *arg);
|
||||
void dbg_print(LLONG mask, const char *fmt, ...);
|
||||
unsigned char *debug_608_to_ASC(unsigned char *ccdata, int channel);
|
||||
|
||||
@@ -89,6 +89,9 @@ int verify_crc32(uint8_t *buf, int len)
|
||||
|
||||
int stringztoms(const char *s, struct ccx_boundary_time *bt)
|
||||
{
|
||||
#ifndef DISABLE_RUST
|
||||
return ccxr_stringztoms(s, bt);
|
||||
#endif
|
||||
unsigned ss = 0, mm = 0, hh = 0;
|
||||
int value = -1;
|
||||
int colons = 0;
|
||||
@@ -133,6 +136,10 @@ int stringztoms(const char *s, struct ccx_boundary_time *bt)
|
||||
}
|
||||
void timestamp_to_srttime(uint64_t timestamp, char *buffer)
|
||||
{
|
||||
#ifndef DISABLE_RUST
|
||||
return ccxr_timestamp_to_srttime(timestamp, buffer);
|
||||
#endif
|
||||
|
||||
uint64_t p = timestamp;
|
||||
uint8_t h = (uint8_t)(p / 3600000);
|
||||
uint8_t m = (uint8_t)(p / 60000 - 60 * h);
|
||||
@@ -142,6 +149,10 @@ void timestamp_to_srttime(uint64_t timestamp, char *buffer)
|
||||
}
|
||||
void timestamp_to_vtttime(uint64_t timestamp, char *buffer)
|
||||
{
|
||||
#ifndef DISABLE_RUST
|
||||
return ccxr_timestamp_to_vtttime(timestamp, buffer);
|
||||
#endif
|
||||
|
||||
uint64_t p = timestamp;
|
||||
uint8_t h = (uint8_t)(p / 3600000);
|
||||
uint8_t m = (uint8_t)(p / 60000 - 60 * h);
|
||||
@@ -202,6 +213,10 @@ int levenshtein_dist_char(const char *s1, const char *s2, unsigned s1len, unsign
|
||||
|
||||
void millis_to_date(uint64_t timestamp, char *buffer, enum ccx_output_date_format date_format, char millis_separator)
|
||||
{
|
||||
#ifndef DISABLE_RUST
|
||||
return ccxr_millis_to_date(timestamp, buffer, date_format, millis_separator);
|
||||
#endif
|
||||
|
||||
time_t secs;
|
||||
unsigned int millis;
|
||||
char c_temp[80];
|
||||
|
||||
@@ -30,6 +30,10 @@ volatile extern sig_atomic_t change_filename_requested;
|
||||
extern int ccxr_verify_crc32(uint8_t *buf, int len);
|
||||
extern int ccxr_levenshtein_dist(const uint64_t *s1, const uint64_t *s2, unsigned s1len, unsigned s2len);
|
||||
extern int ccxr_levenshtein_dist_char(const char *s1, const char *s2, unsigned s1len, unsigned s2len);
|
||||
extern void ccxr_timestamp_to_srttime(uint64_t timestamp, char *buffer);
|
||||
extern void ccxr_timestamp_to_vtttime(uint64_t timestamp, char *buffer);
|
||||
extern void ccxr_millis_to_date(uint64_t timestamp, char *buffer, enum ccx_output_date_format date_format, char millis_separator);
|
||||
extern int ccxr_stringztoms(const char *s, struct ccx_boundary_time *bt);
|
||||
#endif
|
||||
|
||||
int levenshtein_dist_char (const char *s1, const char *s2, unsigned s1len, unsigned s2len);
|
||||
|
||||
316
src/rust/Cargo.lock
generated
316
src/rust/Cargo.lock
generated
@@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.5"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -33,9 +33,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
@@ -78,7 +78,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.71",
|
||||
"which",
|
||||
]
|
||||
|
||||
@@ -96,18 +96,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.6"
|
||||
version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
|
||||
|
||||
[[package]]
|
||||
name = "ccx_rust"
|
||||
@@ -141,15 +132,43 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.6.1"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn_buf"
|
||||
version = "0.1.0"
|
||||
@@ -158,9 +177,9 @@ checksum = "74c57ab96715773d9cb9789b38eb7cbf04b3c6f5624a9d98f51761603376767c"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
@@ -177,25 +196,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.3"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
|
||||
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-crate"
|
||||
version = "0.6.3"
|
||||
@@ -222,9 +230,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.5"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
|
||||
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
@@ -255,10 +263,16 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
@@ -268,9 +282,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "leptonica-sys"
|
||||
version = "0.4.6"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eff3f1dc2f0112411228f8db99ca8a6a1157537a7887b28b1c91fdc4051fb326"
|
||||
checksum = "1c924779fadc73838b9390ddda5fc1939f844fb43bd44ef6794c32bd6e52238a"
|
||||
dependencies = [
|
||||
"bindgen 0.64.0",
|
||||
"pkg-config",
|
||||
@@ -282,41 +296,44 @@ name = "lib_ccxr"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"derive_more",
|
||||
"thiserror",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.4"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.7"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.3"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
@@ -335,19 +352,25 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.16"
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "palette"
|
||||
@@ -375,9 +398,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.14"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
@@ -415,7 +438,7 @@ dependencies = [
|
||||
"phf_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -429,34 +452,40 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.27"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.16"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5"
|
||||
checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -478,9 +507,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.5"
|
||||
version = "1.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -490,9 +519,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.3.8"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
|
||||
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
@@ -501,9 +530,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.5"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
|
||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||
|
||||
[[package]]
|
||||
name = "rsmpeg"
|
||||
@@ -524,10 +553,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.13"
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
@@ -551,30 +589,36 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.188"
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.188"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
@@ -595,9 +639,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.52"
|
||||
version = "2.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -606,9 +650,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
@@ -627,22 +671,53 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.48"
|
||||
version = "1.0.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
|
||||
checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.48"
|
||||
version = "1.0.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
|
||||
checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.52",
|
||||
"syn 2.0.71",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -656,9 +731,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.11"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
@@ -696,11 +771,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -711,22 +786,23 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
@@ -735,42 +811,48 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
170
src/rust/lib_ccxr/Cargo.lock
generated
170
src/rust/lib_ccxr/Cargo.lock
generated
@@ -8,9 +8,179 @@ version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "lib_ccxr"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"derive_more",
|
||||
"thiserror",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.204"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
@@ -7,9 +7,18 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "2.6.0"
|
||||
thiserror = "1.0.61"
|
||||
time = { version = "0.3.36", features = ["macros", "formatting"] }
|
||||
derive_more = "0.99.18"
|
||||
|
||||
[features]
|
||||
default = ["enable_sharing", "wtv_debug", "enable_ffmpeg", "debug", "with_libcurl"]
|
||||
default = [
|
||||
"enable_sharing",
|
||||
"wtv_debug",
|
||||
"enable_ffmpeg",
|
||||
"debug",
|
||||
"with_libcurl",
|
||||
]
|
||||
enable_sharing = []
|
||||
wtv_debug = []
|
||||
enable_ffmpeg = []
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod common;
|
||||
pub mod time;
|
||||
pub mod util;
|
||||
|
||||
23
src/rust/lib_ccxr/src/time/mod.rs
Normal file
23
src/rust/lib_ccxr/src/time/mod.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
//! Provide types for storing time in different formats
|
||||
//!
|
||||
//! Time can be represented in one of following formats:
|
||||
//! - [`Timestamp`] as number of milliseconds
|
||||
//! - [`MpegClockTick`] as number of clock ticks (as defined in the MPEG standard)
|
||||
//! - [`FrameCount`] as number of frames
|
||||
//! - [`GopTimeCode`] as a GOP time code (as defined in the MPEG standard)
|
||||
//!
|
||||
//! # Conversion Guide
|
||||
//!
|
||||
//! | From | To |
|
||||
//! |-------------------------------------------|-------------------------------------------------------|
|
||||
//! | `ccx_boundary_time` | [`Option<Timestamp>`](Timestamp) |
|
||||
//! | any fts | [`Timestamp`] |
|
||||
//! | `ccx_output_date_format` | [`TimestampFormat`] |
|
||||
//! | any pts | [`MpegClockTick`] |
|
||||
//! | any frame count | [`FrameCount`] |
|
||||
//! | `gop_time_code` | [`GopTimeCode`] |
|
||||
//! | `print_mstime_static` | [`Timestamp::to_hms_millis_time`] |
|
||||
//! | `gop_accepted` | [`GopTimeCode::did_rollover`] + some additional logic |
|
||||
//! | `calculate_ms_gop_time` | [`GopTimeCode::new`], [`GopTimeCode::timestamp`] |
|
||||
|
||||
pub mod units;
|
||||
645
src/rust/lib_ccxr/src/time/units.rs
Normal file
645
src/rust/lib_ccxr/src/time/units.rs
Normal file
@@ -0,0 +1,645 @@
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::Write;
|
||||
use std::num::TryFromIntError;
|
||||
use std::os::raw::c_int;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use derive_more::{Add, Neg, Sub};
|
||||
use thiserror::Error;
|
||||
use time::{
|
||||
error::Format,
|
||||
macros::{datetime, format_description},
|
||||
Duration,
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
static mut MPEG_CLOCK_FREQ: c_int;
|
||||
}
|
||||
|
||||
/// Represents a timestamp in milliseconds.
|
||||
///
|
||||
/// The number can be negetive.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Add, Sub, Neg)]
|
||||
pub struct Timestamp {
|
||||
millis: i64,
|
||||
}
|
||||
|
||||
/// Represents an error during operations on [`Timestamp`].
|
||||
#[derive(Error, Debug)]
|
||||
pub enum TimestampError {
|
||||
#[error("input parameter given is out of range")]
|
||||
InputOutOfRangeError,
|
||||
#[error("timestamp is out of range")]
|
||||
OutOfRangeError(#[from] TryFromIntError),
|
||||
#[error("error ocurred during formatting")]
|
||||
FormattingError(#[from] std::fmt::Error),
|
||||
#[error("error ocurred during formatting a date")]
|
||||
DateFormattingError(#[from] Format),
|
||||
#[error("error ocurred during parsing")]
|
||||
ParsingError,
|
||||
}
|
||||
|
||||
/// Represents the different string formats for [`Timestamp`].
|
||||
pub enum TimestampFormat {
|
||||
/// Format: blank string.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use crate::time::units::{Timestamp, TimestampFormat};
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// let output = timestamp.to_formatted_time(TimestampFormat::None).unwrap();
|
||||
/// assert_eq!(output, "");
|
||||
/// ```
|
||||
None,
|
||||
|
||||
/// Format: `{hour:02}:{minute:02}:{second:02}`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use crate::time::units::{Timestamp, TimestampFormat};
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// let output = timestamp.to_formatted_time(TimestampFormat::HHMMSS).unwrap();
|
||||
/// assert_eq!(output, "01:48:44");
|
||||
/// ```
|
||||
HHMMSS,
|
||||
|
||||
/// Format: `{second:02}{millis_separator}{millis:03}`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use crate::time::units::{Timestamp, TimestampFormat};
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// let output = timestamp.to_formatted_time(
|
||||
/// TimestampFormat::Seconds {
|
||||
/// millis_separator: ',',
|
||||
/// },
|
||||
/// ).unwrap();
|
||||
/// assert_eq!(output, "6524,365");
|
||||
/// ```
|
||||
Seconds { millis_separator: char },
|
||||
|
||||
/// Format:
|
||||
/// `{year:04}{month:02}{day:02}{hour:02}{minute:02}{second:02}{millis_separator}{millis:03}`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use crate::time::units::{Timestamp, TimestampFormat};
|
||||
/// // 11 March 2023 14:53:36.749 in UNIX timestamp.
|
||||
/// let timestamp = Timestamp::from_millis(1678546416749);
|
||||
/// let output = timestamp.to_formatted_time(
|
||||
/// TimestampFormat::Date {
|
||||
/// millis_separator: ',',
|
||||
/// },
|
||||
/// ).unwrap();
|
||||
/// assert_eq!(output, "20230311145336,749");
|
||||
/// ```
|
||||
Date { millis_separator: char },
|
||||
|
||||
/// Format: `{hour:02}:{minute:02}:{second:02},{millis:03}`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::{Timestamp, TimestampFormat};
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// let output = timestamp.to_formatted_time(TimestampFormat::HHMMSSFFF).unwrap();
|
||||
/// assert_eq!(output, "01:48:44,365");
|
||||
/// ```
|
||||
HHMMSSFFF,
|
||||
}
|
||||
|
||||
impl Timestamp {
|
||||
/// Create a new [`Timestamp`] based on the number of milliseconds since the Unix Epoch.
|
||||
pub fn now() -> Timestamp {
|
||||
let duration = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("System Time cannot be behind the Unix Epoch");
|
||||
|
||||
Timestamp {
|
||||
millis: duration.as_millis() as i64,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new [`Timestamp`] from number of milliseconds.
|
||||
pub const fn from_millis(millis: i64) -> Timestamp {
|
||||
Timestamp { millis }
|
||||
}
|
||||
|
||||
/// Create a new [`Timestamp`] from hours, minutes, seconds and milliseconds.
|
||||
///
|
||||
/// It will fail if any parameter doesn't follow their respective ranges:
|
||||
///
|
||||
/// | Parameter | Range |
|
||||
/// |-----------|---------|
|
||||
/// | minutes | 0 - 59 |
|
||||
/// | seconds | 0 - 59 |
|
||||
/// | millis | 0 - 999 |
|
||||
pub fn from_hms_millis(
|
||||
hours: u8,
|
||||
minutes: u8,
|
||||
seconds: u8,
|
||||
millis: u16,
|
||||
) -> Result<Timestamp, TimestampError> {
|
||||
if minutes < 60 && seconds < 60 && millis < 1000 {
|
||||
Ok(Timestamp::from_millis(
|
||||
(hours as i64) * 3_600_000
|
||||
+ (minutes as i64) * 60_000
|
||||
+ (seconds as i64) * 1000
|
||||
+ millis as i64,
|
||||
))
|
||||
} else {
|
||||
Err(TimestampError::InputOutOfRangeError)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of milliseconds.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// assert_eq!(timestamp.millis(), 6524365);
|
||||
/// ```
|
||||
pub fn millis(&self) -> i64 {
|
||||
self.millis
|
||||
}
|
||||
|
||||
/// Returns the number of whole seconds.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// assert_eq!(timestamp.seconds(), 6524);
|
||||
/// ```
|
||||
pub fn seconds(&self) -> i64 {
|
||||
self.millis / 1000
|
||||
}
|
||||
|
||||
/// Returns the number of whole seconds and leftover milliseconds as unsigned integers.
|
||||
///
|
||||
/// It will return an [`TimestampError::OutOfRangeError`] if the timestamp is negetive.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// assert_eq!(timestamp.as_sec_millis().unwrap(), (6524, 365));
|
||||
/// ```
|
||||
pub fn as_sec_millis(&self) -> Result<(u64, u16), TimestampError> {
|
||||
let millis: u64 = self.millis.try_into()?;
|
||||
let s = millis / 1000;
|
||||
let u = millis % 1000;
|
||||
Ok((s, u as u16))
|
||||
}
|
||||
|
||||
/// Returns the time in the form of hours, minutes, seconds and milliseconds as unsigned
|
||||
/// integers.
|
||||
///
|
||||
/// It will return an [`TimestampError::OutOfRangeError`] if the timestamp is negetive.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// assert_eq!(timestamp.as_hms_millis().unwrap(), (1, 48, 44, 365));
|
||||
/// ```
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::{Timestamp, TimestampError};
|
||||
/// let timestamp = Timestamp::from_millis(1678546416749);
|
||||
/// assert!(matches!(
|
||||
/// timestamp.as_hms_millis().unwrap_err(),
|
||||
/// TimestampError::OutOfRangeError(_)
|
||||
/// ));
|
||||
/// ```
|
||||
pub fn as_hms_millis(&self) -> Result<(u8, u8, u8, u16), TimestampError> {
|
||||
let millis: u64 = self.millis.try_into()?;
|
||||
let h = millis / 3600000;
|
||||
let m = millis / 60000 - 60 * h;
|
||||
let s = millis / 1000 - 3600 * h - 60 * m;
|
||||
let u = millis - 3600000 * h - 60000 * m - 1000 * s;
|
||||
if h > 24 {
|
||||
println!("{}", h)
|
||||
}
|
||||
Ok((h.try_into()?, m as u8, s as u8, u as u16))
|
||||
}
|
||||
|
||||
/// Fills `output` with the [`Timestamp`] using SRT's timestamp format.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// let mut output = String::new();
|
||||
/// timestamp.write_srt_time(&mut output);
|
||||
/// assert_eq!(output, "01:48:44,365");
|
||||
/// ```
|
||||
pub fn write_srt_time(&self, output: &mut String) -> Result<(), TimestampError> {
|
||||
let (h, m, s, u) = self.as_hms_millis()?;
|
||||
write!(output, "{:02}:{:02}:{:02},{:03}", h, m, s, u)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fills `output` with the [`Timestamp`] using VTT's timestamp format.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// let mut output = String::new();
|
||||
/// timestamp.write_vtt_time(&mut output);
|
||||
/// assert_eq!(output, "01:48:44.365");
|
||||
/// ```
|
||||
pub fn write_vtt_time(&self, output: &mut String) -> Result<(), TimestampError> {
|
||||
let (h, m, s, u) = self.as_hms_millis()?;
|
||||
write!(output, "{:02}:{:02}:{:02}.{:03}", h, m, s, u)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fills `output` with the [`Timestamp`] using
|
||||
/// "{sign}{hour:02}:{minute:02}:{second:02}{sep}{millis:03}" format, where `sign` can be `-`
|
||||
/// if time is negetive or blank if it is positive.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// let mut output = String::new();
|
||||
/// timestamp.write_hms_millis_time(&mut output, ':');
|
||||
/// assert_eq!(output, "01:48:44:365");
|
||||
/// ```
|
||||
pub fn write_hms_millis_time(
|
||||
&self,
|
||||
output: &mut String,
|
||||
sep: char,
|
||||
) -> Result<(), TimestampError> {
|
||||
let sign = if self.millis < 0 { "-" } else { "" };
|
||||
let timestamp = if self.millis < 0 { -*self } else { *self };
|
||||
let (h, m, s, u) = timestamp.as_hms_millis()?;
|
||||
write!(output, "{}{:02}:{:02}:{:02}{}{:03}", sign, h, m, s, sep, u)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fills `output` with the [`Timestamp`] using ctime's format.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// let mut output = String::new();
|
||||
/// timestamp.write_ctime(&mut output);
|
||||
/// assert_eq!(output, "Thu Jan 01 01:48:44 1970");
|
||||
/// ```
|
||||
pub fn write_ctime(&self, output: &mut String) -> Result<(), TimestampError> {
|
||||
let (sec, millis) = self.as_sec_millis()?;
|
||||
let d = datetime!(1970-01-01 0:00)
|
||||
+ Duration::new(sec.try_into()?, (millis as i32) * 1_000_000);
|
||||
let format = format_description!(
|
||||
"[weekday repr:short] [month repr:short] [day] [hour]:[minute]:[second] [year]"
|
||||
);
|
||||
write!(output, "{}", d.format(&format)?)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fills `output` with the [`Timestamp`] using format specified by [`TimestampFormat`].
|
||||
///
|
||||
/// See [`TimestampFormat`] for examples.
|
||||
pub fn write_formatted_time(
|
||||
&self,
|
||||
output: &mut String,
|
||||
format: TimestampFormat,
|
||||
) -> Result<(), TimestampError> {
|
||||
match format {
|
||||
TimestampFormat::None => Ok(()),
|
||||
TimestampFormat::HHMMSS => {
|
||||
let (h, m, s, _) = self.as_hms_millis()?;
|
||||
write!(output, "{:02}:{:02}:{:02}", h, m, s)?;
|
||||
Ok(())
|
||||
}
|
||||
TimestampFormat::Seconds { millis_separator } => {
|
||||
let (sec, millis) = self.as_sec_millis()?;
|
||||
write!(output, "{}{}{:03}", sec, millis_separator, millis)?;
|
||||
Ok(())
|
||||
}
|
||||
TimestampFormat::Date { millis_separator } => {
|
||||
let (sec, millis) = self.as_sec_millis()?;
|
||||
let d = datetime!(1970-01-01 0:00)
|
||||
+ Duration::new(sec.try_into()?, (millis as i32) * 1_000_000);
|
||||
let format1 = format_description!("[year][month][day][hour][minute][second]");
|
||||
let format2 = format_description!("[subsecond digits:3]");
|
||||
|
||||
write!(
|
||||
output,
|
||||
"{}{}{}",
|
||||
d.format(&format1)?,
|
||||
millis_separator,
|
||||
d.format(&format2)?
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
TimestampFormat::HHMMSSFFF => self.write_srt_time(output),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a formatted [`Timestamp`] using SRT's timestamp format.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// assert_eq!(timestamp.to_srt_time().unwrap(), "01:48:44,365");
|
||||
/// ```
|
||||
pub fn to_srt_time(&self) -> Result<String, TimestampError> {
|
||||
let mut s = String::new();
|
||||
self.write_srt_time(&mut s)?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
/// Returns a formatted [`Timestamp`] using VTT's timestamp format.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// assert_eq!(timestamp.to_vtt_time().unwrap(), "01:48:44.365");
|
||||
/// ```
|
||||
pub fn to_vtt_time(&self) -> Result<String, TimestampError> {
|
||||
let mut s = String::new();
|
||||
self.write_vtt_time(&mut s)?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
/// Returns a formatted [`Timestamp`] using
|
||||
/// "{sign}{hour:02}:{minute:02}:{second:02}{sep}{millis:03}" format, where `sign` can be `-`
|
||||
/// if time is negetive or blank if it is positive.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// assert_eq!(timestamp.to_hms_millis_time(':').unwrap(), "01:48:44:365");
|
||||
/// ```
|
||||
pub fn to_hms_millis_time(&self, sep: char) -> Result<String, TimestampError> {
|
||||
let mut s = String::new();
|
||||
self.write_hms_millis_time(&mut s, sep)?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
/// Returns a formatted [`Timestamp`] using ctime's format.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::from_millis(6524365);
|
||||
/// assert_eq!(timestamp.to_ctime().unwrap(), "Thu Jan 01 01:48:44 1970");
|
||||
/// ```
|
||||
pub fn to_ctime(&self) -> Result<String, TimestampError> {
|
||||
let mut s = String::new();
|
||||
self.write_ctime(&mut s)?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
/// Returns a formatted [`Timestamp`] using format specified by [`TimestampFormat`].
|
||||
///
|
||||
/// See [`TimestampFormat`] for examples.
|
||||
pub fn to_formatted_time(&self, format: TimestampFormat) -> Result<String, TimestampError> {
|
||||
let mut s = String::new();
|
||||
self.write_formatted_time(&mut s, format)?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
/// Creates a [`Timestamp`] by parsing `input` using format `SS` or `MM:SS` or `HH:MM:SS`.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use lib_ccxr::util::time::Timestamp;
|
||||
/// let timestamp = Timestamp::parse_optional_hhmmss_from_str("01:12:45").unwrap();
|
||||
/// assert_eq!(timestamp, Timestamp::from_millis(4_365_000));
|
||||
/// ```
|
||||
pub fn parse_optional_hhmmss_from_str(input: &str) -> Result<Timestamp, TimestampError> {
|
||||
let mut numbers = input
|
||||
.split(':')
|
||||
.map(|x| x.parse::<u8>().map_err(|_| TimestampError::ParsingError))
|
||||
.rev();
|
||||
|
||||
let mut millis: u64 = 0;
|
||||
|
||||
let seconds: u64 = numbers.next().ok_or(TimestampError::ParsingError)??.into();
|
||||
if seconds > 59 {
|
||||
return Err(TimestampError::InputOutOfRangeError);
|
||||
}
|
||||
millis += seconds * 1000;
|
||||
|
||||
if let Some(x) = numbers.next() {
|
||||
let minutes: u64 = x?.into();
|
||||
if minutes > 59 {
|
||||
return Err(TimestampError::InputOutOfRangeError);
|
||||
}
|
||||
millis += 60_000 * minutes;
|
||||
}
|
||||
|
||||
if let Some(x) = numbers.next() {
|
||||
let hours: u64 = x?.into();
|
||||
millis += 3_600_000 * hours;
|
||||
}
|
||||
|
||||
if numbers.next().is_some() {
|
||||
return Err(TimestampError::ParsingError);
|
||||
}
|
||||
|
||||
Ok(Timestamp::from_millis(millis.try_into()?))
|
||||
}
|
||||
}
|
||||
|
||||
/// Represent the number of clock ticks as defined in Mpeg standard.
|
||||
///
|
||||
/// This number can never be negetive.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Add, Sub)]
|
||||
pub struct MpegClockTick(i64);
|
||||
|
||||
impl MpegClockTick {
|
||||
/// Returns the ratio to convert a clock tick to time duration.
|
||||
pub fn mpeg_clock_freq() -> i64 {
|
||||
unsafe { MPEG_CLOCK_FREQ.into() }
|
||||
}
|
||||
|
||||
/// Create a value representing `ticks` clock ticks.
|
||||
pub fn new(ticks: i64) -> MpegClockTick {
|
||||
MpegClockTick(ticks)
|
||||
}
|
||||
|
||||
/// Returns the number of clock ticks.
|
||||
pub fn as_i64(&self) -> i64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Converts the clock ticks to its equivalent time duration.
|
||||
///
|
||||
/// The conversion ratio used is [`MpegClockTick::MPEG_CLOCK_FREQ`].
|
||||
pub fn as_timestamp(&self) -> Timestamp {
|
||||
Timestamp::from_millis(self.0 / (MpegClockTick::mpeg_clock_freq() / 1000))
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the number of frames.
|
||||
///
|
||||
/// This number can never be negetive.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Add, Sub)]
|
||||
pub struct FrameCount(u64);
|
||||
|
||||
impl FrameCount {
|
||||
/// Create a value representing `frames` number of frames.
|
||||
pub const fn new(frames: u64) -> FrameCount {
|
||||
FrameCount(frames)
|
||||
}
|
||||
|
||||
/// Returns the number of frames.
|
||||
pub fn as_u64(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Converts the frames to its equivalent time duration.
|
||||
///
|
||||
/// The conversion ratio used is `fps`.
|
||||
pub fn as_timestamp(&self, fps: f64) -> Timestamp {
|
||||
Timestamp::from_millis((self.0 as f64 * 1000.0 / fps) as i64)
|
||||
}
|
||||
|
||||
/// Converts the frames to its equivalent number of clock ticks.
|
||||
///
|
||||
/// The conversion ratio used is [`MpegClockTick::MPEG_CLOCK_FREQ`] and `fps`.
|
||||
pub fn as_mpeg_clock_tick(&self, fps: f64) -> MpegClockTick {
|
||||
MpegClockTick::new(((self.0 * MpegClockTick::mpeg_clock_freq() as u64) as f64 / fps) as i64)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a GOP Time code as defined in the Mpeg standard.
|
||||
///
|
||||
/// This structure stores its time in the form of hours, minutes, seconds and pictures. This
|
||||
/// structure also stores its time in the form of a [`Timestamp`] when it is created. This
|
||||
/// [`Timestamp`] can be modified by [`timestamp_mut`](GopTimeCode::timestamp_mut) and an
|
||||
/// additional 24 hours may be added on rollover, so it is not necessary that the above two
|
||||
/// formats refer to the same time. Therefore it is recommended to only rely on the
|
||||
/// [`Timestamp`] instead of the other format.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct GopTimeCode {
|
||||
drop_frame: bool,
|
||||
time_code_hours: u8,
|
||||
time_code_minutes: u8,
|
||||
time_code_seconds: u8,
|
||||
time_code_pictures: u8,
|
||||
timestamp: Timestamp,
|
||||
}
|
||||
|
||||
impl GopTimeCode {
|
||||
/// Create a new [`GopTimeCode`] from the specified parameters.
|
||||
///
|
||||
/// The number of frames or pictures is converted to time duration using `fps`.
|
||||
///
|
||||
/// If `rollover` is true, then an extra of 24 hours will added.
|
||||
///
|
||||
/// It will return [`None`] if any parameter doesn't follow their respective ranges:
|
||||
///
|
||||
/// | Parameter | Range |
|
||||
/// |-----------|--------|
|
||||
/// | hours | 0 - 23 |
|
||||
/// | minutes | 0 - 59 |
|
||||
/// | seconds | 0 - 59 |
|
||||
/// | pictures | 0 - 59 |
|
||||
pub fn new(
|
||||
drop_frame: bool,
|
||||
hours: u8,
|
||||
minutes: u8,
|
||||
seconds: u8,
|
||||
pictures: u8,
|
||||
fps: f64,
|
||||
rollover: bool,
|
||||
) -> Option<GopTimeCode> {
|
||||
if hours < 24 && minutes < 60 && seconds < 60 && pictures < 60 {
|
||||
let millis = (1000.0 * (pictures as f64) / fps) as u16;
|
||||
let extra_hours = if rollover { 24 } else { 0 };
|
||||
let timestamp =
|
||||
Timestamp::from_hms_millis(hours + extra_hours, minutes, seconds, millis)
|
||||
.expect("The fps given is probably too low");
|
||||
|
||||
Some(GopTimeCode {
|
||||
drop_frame,
|
||||
time_code_hours: hours,
|
||||
time_code_minutes: minutes,
|
||||
time_code_seconds: seconds,
|
||||
time_code_pictures: pictures,
|
||||
timestamp,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the GOP time code in its equivalent time duration.
|
||||
pub fn timestamp(&self) -> Timestamp {
|
||||
self.timestamp
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to internal [`Timestamp`].
|
||||
pub fn timestamp_mut(&mut self) -> &mut Timestamp {
|
||||
&mut self.timestamp
|
||||
}
|
||||
|
||||
/// Check if a rollover has ocurred by comparing the previous [`GopTimeCode`] that is `prev`
|
||||
/// with the current [`GopTimeCode`].
|
||||
pub fn did_rollover(&self, prev: &GopTimeCode) -> bool {
|
||||
prev.time_code_hours == 23
|
||||
&& prev.time_code_minutes == 59
|
||||
&& self.time_code_hours == 0
|
||||
&& self.time_code_minutes == 0
|
||||
}
|
||||
|
||||
/// Constructs a [`GopTimeCode`] from its individual fields.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The fields other than [`Timestamp`] may not be accurate if it is changed using
|
||||
/// [`timestamp_mut`](GopTimeCode::timestamp_mut).
|
||||
pub unsafe fn from_raw_parts(
|
||||
drop_frame: bool,
|
||||
hours: u8,
|
||||
minutes: u8,
|
||||
seconds: u8,
|
||||
pictures: u8,
|
||||
timestamp: Timestamp,
|
||||
) -> GopTimeCode {
|
||||
GopTimeCode {
|
||||
drop_frame,
|
||||
time_code_hours: hours,
|
||||
time_code_minutes: minutes,
|
||||
time_code_seconds: seconds,
|
||||
time_code_pictures: pictures,
|
||||
timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the individuals field of a [`GopTimeCode`].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The fields other than [`Timestamp`] may not be accurate if it is changed using
|
||||
/// [`timestamp_mut`](GopTimeCode::timestamp_mut).
|
||||
pub unsafe fn as_raw_parts(&self) -> (bool, u8, u8, u8, u8, Timestamp) {
|
||||
let GopTimeCode {
|
||||
drop_frame,
|
||||
time_code_hours,
|
||||
time_code_minutes,
|
||||
time_code_seconds,
|
||||
time_code_pictures,
|
||||
timestamp,
|
||||
} = *self;
|
||||
|
||||
(
|
||||
drop_frame,
|
||||
time_code_hours,
|
||||
time_code_minutes,
|
||||
time_code_seconds,
|
||||
time_code_pictures,
|
||||
timestamp,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -3,3 +3,17 @@
|
||||
pub mod bits;
|
||||
pub mod levenshtein;
|
||||
pub mod log;
|
||||
pub mod time;
|
||||
|
||||
use std::os::raw::c_char;
|
||||
|
||||
/// Helper function that converts a Rust-String (`string`) to C-String (`buffer`).
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `buffer` must have enough allocated space for `string` to fit.
|
||||
pub fn write_string_into_pointer(buffer: *mut c_char, string: &str) {
|
||||
let buffer = unsafe { std::slice::from_raw_parts_mut(buffer as *mut u8, string.len() + 1) };
|
||||
buffer[..string.len()].copy_from_slice(string.as_bytes());
|
||||
buffer[string.len()] = b'\0';
|
||||
}
|
||||
|
||||
35
src/rust/lib_ccxr/src/util/time.rs
Normal file
35
src/rust/lib_ccxr/src/util/time.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
//! Provides Rust equivalent code for functions in `utility.c` involves time operations. Uses Rust-native types as input and output.
|
||||
|
||||
use crate::time::units::{Timestamp, TimestampError, TimestampFormat};
|
||||
|
||||
/// Rust equivalent for `timestamp_to_srttime` function in C.
|
||||
/// Uses Rust-native types as input and output.
|
||||
pub fn timestamp_to_srttime(
|
||||
timestamp: Timestamp,
|
||||
buffer: &mut String,
|
||||
) -> Result<(), TimestampError> {
|
||||
timestamp.write_srt_time(buffer)
|
||||
}
|
||||
|
||||
/// Rust equivalent for `timestamp_to_vtttime` function in C.
|
||||
/// Uses Rust-native types as input and output.
|
||||
pub fn timestamp_to_vtttime(
|
||||
timestamp: Timestamp,
|
||||
buffer: &mut String,
|
||||
) -> Result<(), TimestampError> {
|
||||
timestamp.write_vtt_time(buffer)
|
||||
}
|
||||
|
||||
/// Rust equivalent for `millis_to_date` function in C. Uses Rust-native types as input and output.
|
||||
pub fn millis_to_date(
|
||||
timestamp: Timestamp,
|
||||
buffer: &mut String,
|
||||
date_format: TimestampFormat,
|
||||
) -> Result<(), TimestampError> {
|
||||
timestamp.write_formatted_time(buffer, date_format)
|
||||
}
|
||||
|
||||
/// Rust equivalent for `stringztoms` function in C. Uses Rust-native types as input and output.
|
||||
pub fn stringztoms(s: &str) -> Option<Timestamp> {
|
||||
Timestamp::parse_optional_hhmmss_from_str(s).ok()
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
//! Provides C-FFI functions that are direct equivalent of functions available in C.
|
||||
|
||||
pub mod time;
|
||||
|
||||
use crate::ccx_s_options;
|
||||
use lib_ccxr::util::log::*;
|
||||
use lib_ccxr::util::{bits::*, levenshtein::*};
|
||||
|
||||
125
src/rust/src/libccxr_exports/time.rs
Normal file
125
src/rust/src/libccxr_exports/time.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use crate::bindings::*;
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
use lib_ccxr::time::units::*;
|
||||
use lib_ccxr::util::{time::*, write_string_into_pointer};
|
||||
|
||||
/// Rust equivalent for `timestamp_to_srttime` function in C. Uses C-native types as input and
|
||||
/// output.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `buffer` must have enough allocated space for the formatted `timestamp` to fit.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ccxr_timestamp_to_srttime(timestamp: u64, buffer: *mut c_char) {
|
||||
let mut s = String::new();
|
||||
let timestamp = Timestamp::from_millis(timestamp as i64);
|
||||
|
||||
let _ = timestamp_to_srttime(timestamp, &mut s);
|
||||
|
||||
write_string_into_pointer(buffer, &s);
|
||||
}
|
||||
|
||||
/// Rust equivalent for `timestamp_to_vtttime` function in C. Uses C-native types as input and
|
||||
/// output.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `buffer` must have enough allocated space for the formatted `timestamp` to fit.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ccxr_timestamp_to_vtttime(timestamp: u64, buffer: *mut c_char) {
|
||||
let mut s = String::new();
|
||||
let timestamp = Timestamp::from_millis(timestamp as i64);
|
||||
|
||||
let _ = timestamp_to_vtttime(timestamp, &mut s);
|
||||
|
||||
write_string_into_pointer(buffer, &s);
|
||||
}
|
||||
|
||||
/// Rust equivalent for `millis_to_date` function in C. Uses C-native types as input and output.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `buffer` must have enough allocated space for the formatted `timestamp` to fit.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ccxr_millis_to_date(
|
||||
timestamp: u64,
|
||||
buffer: *mut c_char,
|
||||
date_format: ccx_output_date_format,
|
||||
millis_separator: c_char,
|
||||
) {
|
||||
let mut s = String::new();
|
||||
let timestamp = Timestamp::from_millis(timestamp as i64);
|
||||
let date_format = match date_format {
|
||||
ccx_output_date_format_ODF_NONE => TimestampFormat::None,
|
||||
ccx_output_date_format_ODF_HHMMSS => TimestampFormat::HHMMSS,
|
||||
ccx_output_date_format_ODF_HHMMSSMS => TimestampFormat::HHMMSSFFF,
|
||||
ccx_output_date_format_ODF_SECONDS => TimestampFormat::Seconds {
|
||||
millis_separator: millis_separator as u8 as char,
|
||||
},
|
||||
ccx_output_date_format_ODF_DATE => TimestampFormat::Date {
|
||||
millis_separator: millis_separator as u8 as char,
|
||||
},
|
||||
_ => TimestampFormat::None,
|
||||
};
|
||||
|
||||
let _ = millis_to_date(timestamp, &mut s, date_format);
|
||||
|
||||
write_string_into_pointer(buffer, &s);
|
||||
}
|
||||
|
||||
/// Rust equivalent for `stringztoms` function in C. Uses C-native types as input and output.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `s` must contain valid utf-8 data and have a null terminator at the end of the string.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ccxr_stringztoms(s: *const c_char, bt: *mut ccx_boundary_time) -> c_int {
|
||||
let s = CStr::from_ptr(s)
|
||||
.to_str()
|
||||
.expect("Failed to convert buffer `s` into a &str");
|
||||
|
||||
let option_timestamp = stringztoms(s);
|
||||
|
||||
if let Some(timestamp) = option_timestamp {
|
||||
if let Ok((h, m, s, _)) = timestamp.as_hms_millis() {
|
||||
(*bt).set = 1;
|
||||
(*bt).hh = h.into();
|
||||
(*bt).mm = m.into();
|
||||
(*bt).ss = s.into();
|
||||
(*bt).time_in_ms = (timestamp.millis() / 1000) * 1000;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
-1
|
||||
}
|
||||
|
||||
/// Rust equivalent for `millis_to_time` function in C. Uses C-native types as input and output.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Must ensure all passed pointers are valid and non-null.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ccxr_millis_to_time(
|
||||
milli: i64,
|
||||
hours: *mut u32,
|
||||
minutes: *mut u32,
|
||||
seconds: *mut u32,
|
||||
ms: *mut u32,
|
||||
) {
|
||||
let ms_value = (milli % 1000) as u32; // milliseconds
|
||||
let mut remaining = (milli - ms_value as i64) / 1000; // Remainder, in seconds
|
||||
let seconds_value = (remaining % 60) as u32;
|
||||
remaining = (remaining - seconds_value as i64) / 60; // Remainder, in minutes
|
||||
let minutes_value = (remaining % 60) as u32;
|
||||
remaining = (remaining - minutes_value as i64) / 60; // Remainder, in hours
|
||||
let hours_value = remaining as u32;
|
||||
|
||||
*hours = hours_value;
|
||||
*minutes = minutes_value;
|
||||
*seconds = seconds_value;
|
||||
*ms = ms_value;
|
||||
}
|
||||
Reference in New Issue
Block a user