From 0111c713ef856763377bea2f1fa7c5a73f86cbbf Mon Sep 17 00:00:00 2001 From: Lexag Date: Tue, 3 Mar 2026 14:33:02 +0100 Subject: [PATCH 1/3] add timecode properties --- mem/src/lib.rs | 2 ++ mem/src/timecode.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/mem/src/lib.rs b/mem/src/lib.rs index 5459548..12a45e4 100644 --- a/mem/src/lib.rs +++ b/mem/src/lib.rs @@ -23,4 +23,6 @@ pub mod time; /// Low level data types for SMPTE Timecode pub mod smpte { pub use super::timecode::TimecodeInstant; + pub use super::timecode::TimecodeProperties; + pub use super::timecode::TimecodeUserBitFormat; } diff --git a/mem/src/timecode.rs b/mem/src/timecode.rs index 253db92..486ecc2 100644 --- a/mem/src/timecode.rs +++ b/mem/src/timecode.rs @@ -1,5 +1,45 @@ use core::fmt::{Display, Formatter, Result}; +/// SMPTE timecode properties +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)] +pub struct TimecodeProperties { + /// Frame numbers 0 and 1 are skipped during the first second of every minute, except multiples + /// of 10 minutes. This converts 30 frames/second time code to the 29.97 frames/second NTSC + /// standard. (from Wikipedia, "Linear timecode") + pub drop_frame: bool, + /// Set to 1 if the time code is synchronized to a color video signal. The frame number modulo + /// 2 (for NTSC and SECAM) or modulo 4 (for PAL) should be preserved across cuts in order to + /// avoid phase jumps in the chrominance subcarrier. (from Wikipedia, "Linear timecode") + pub color_framing: bool, + /// Binary group flag; user bit format + pub user_bit_format: TimecodeUserBitFormat, + /// Indicates that the time code is synchronized to an external clock. False indicates the time + /// origin is arbitrary. In practice, this means "ignore the timestamp in an LTC event, and run + /// LTC from device time instead". + pub use_wall_time: bool, + /// 32 user bits + pub user_bits: [u8; 4], + /// Frame number offset + pub frame_offset: u8, +} + +/// SMPTE BFG, binary group flag. +/// Indicates the format of user bits +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)] +pub enum TimecodeUserBitFormat { + /// No (or unspecified) format + #[default] + Unspecified = 0, + /// Date and timezone, according to SMPTE 309M + DateTimezone = 1, + /// Four 8-bit characters, transmitted little-endian + EightBitLittleEndian = 2, + /// Reserved and unused + Reserved11 = 3, +} + /// A SMPTE LTC timestamp, including frame rate. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, Clone, Copy, Eq)] From ca33b65838cb6432b9b0e18c9f0e883428afdcee Mon Sep 17 00:00:00 2001 From: Lexag Date: Tue, 3 Mar 2026 14:37:12 +0100 Subject: [PATCH 2/3] add properties to timecode event --- event/src/event.rs | 7 ++++++- mem/src/timecode.rs | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/event/src/event.rs b/event/src/event.rs index 7fef8a7..48b051c 100644 --- a/event/src/event.rs +++ b/event/src/event.rs @@ -1,5 +1,8 @@ use core::fmt; -use mem::{smpte::TimecodeInstant, str::StaticString}; +use mem::{ + smpte::{TimecodeInstant, TimecodeProperties}, + str::StaticString, +}; /// Conditional VLT requirement to perform a [EventDescription::JumpEvent]. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -204,6 +207,8 @@ pub enum EventDescription { TimecodeEvent { /// Timecode Instant this LTC starts at time: TimecodeInstant, + /// Timecode properties + properties: TimecodeProperties, }, /// Marks the point where SMPTE LTC should stop running diff --git a/mem/src/timecode.rs b/mem/src/timecode.rs index 486ecc2..c1aed7c 100644 --- a/mem/src/timecode.rs +++ b/mem/src/timecode.rs @@ -2,7 +2,7 @@ use core::fmt::{Display, Formatter, Result}; /// SMPTE timecode properties #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)] +#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)] pub struct TimecodeProperties { /// Frame numbers 0 and 1 are skipped during the first second of every minute, except multiples /// of 10 minutes. This converts 30 frames/second time code to the 29.97 frames/second NTSC @@ -27,7 +27,7 @@ pub struct TimecodeProperties { /// SMPTE BFG, binary group flag. /// Indicates the format of user bits #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)] +#[derive(Default, Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)] pub enum TimecodeUserBitFormat { /// No (or unspecified) format #[default] From 5000c86d23c0737322ff6bb4964e4dd860403d3a Mon Sep 17 00:00:00 2001 From: Lexag Date: Tue, 3 Mar 2026 15:14:37 +0100 Subject: [PATCH 3/3] fix clippy errors --- event/src/eventcursor.rs | 1 + mem/src/timecode.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/event/src/eventcursor.rs b/event/src/eventcursor.rs index 4c3be6c..a41f8be 100644 --- a/event/src/eventcursor.rs +++ b/event/src/eventcursor.rs @@ -106,6 +106,7 @@ mod tests { f: 0, frame_progress: 0, }, + properties: mem::smpte::TimecodeProperties::default(), }), }, ); diff --git a/mem/src/timecode.rs b/mem/src/timecode.rs index c1aed7c..d98048c 100644 --- a/mem/src/timecode.rs +++ b/mem/src/timecode.rs @@ -4,11 +4,11 @@ use core::fmt::{Display, Formatter, Result}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord)] pub struct TimecodeProperties { - /// Frame numbers 0 and 1 are skipped during the first second of every minute, except multiples + /// If set to true, frame numbers 0 and 1 are skipped during the first second of every minute, except multiples /// of 10 minutes. This converts 30 frames/second time code to the 29.97 frames/second NTSC /// standard. (from Wikipedia, "Linear timecode") pub drop_frame: bool, - /// Set to 1 if the time code is synchronized to a color video signal. The frame number modulo + /// Set to true if the time code is synchronized to a color video signal. The frame number modulo /// 2 (for NTSC and SECAM) or modulo 4 (for PAL) should be preserved across cuts in order to /// avoid phase jumps in the chrominance subcarrier. (from Wikipedia, "Linear timecode") pub color_framing: bool,