Skip to content

Commit 77b93e5

Browse files
authored
fix: cargo tests failing on windows (#1704)
1 parent 2260165 commit 77b93e5

File tree

5 files changed

+85
-76
lines changed

5 files changed

+85
-76
lines changed

src/rust/lib_ccxr/src/time/timing.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub struct GlobalTimingInfo {
9595
pub fts_at_gop_start: Timestamp,
9696
pub gop_rollover: bool,
9797
pub timing_settings: TimingSettings,
98+
pub mpeg_clock_freq: i64,
9899
}
99100

100101
impl TimingContext {
@@ -132,12 +133,14 @@ impl TimingContext {
132133
///
133134
/// It also checks for PTS resets.
134135
pub fn set_current_pts(&mut self, pts: MpegClockTick) {
136+
let timing_info = GLOBAL_TIMING_INFO.read().unwrap();
137+
135138
let prev_pts = self.current_pts;
136139
self.current_pts = pts;
137140
if self.pts_set == PtsSet::No {
138141
self.pts_set = PtsSet::Received
139142
}
140-
debug!(msg_type = DebugMessageFlag::VIDEO_STREAM; "PTS: {} ({:8})", self.current_pts.as_timestamp().to_hms_millis_time(':').unwrap(), self.current_pts.as_i64());
143+
debug!(msg_type = DebugMessageFlag::VIDEO_STREAM; "PTS: {} ({:8})", self.current_pts.as_timestamp(timing_info.mpeg_clock_freq).to_hms_millis_time(':').unwrap(), self.current_pts.as_i64());
141144
debug!(msg_type = DebugMessageFlag::VIDEO_STREAM; " FTS: {} \n", self.fts_now.to_hms_millis_time(':').unwrap());
142145

143146
// Check if PTS reset
@@ -162,7 +165,9 @@ impl TimingContext {
162165
// Disables sync check. Used for several input formats.
163166
0
164167
} else {
165-
(self.current_pts - self.sync_pts).as_timestamp().seconds()
168+
(self.current_pts - self.sync_pts)
169+
.as_timestamp(timing_info.mpeg_clock_freq)
170+
.seconds()
166171
};
167172

168173
// Previously in C equivalent code, its -0.2
@@ -221,7 +226,7 @@ impl TimingContext {
221226
self.sync_pts = self.current_pts
222227
- self
223228
.current_tref
224-
.as_mpeg_clock_tick(timing_info.current_fps);
229+
.as_mpeg_clock_tick(timing_info.current_fps, timing_info.mpeg_clock_freq);
225230

226231
if self.current_tref.as_u64() == 0
227232
|| (timing_info.total_frames_count - timing_info.frames_since_ref_time).as_u64()
@@ -245,7 +250,7 @@ impl TimingContext {
245250
debug!(
246251
msg_type = DebugMessageFlag::TIME;
247252
"\nFirst sync time PTS: {} {:+}ms (time before this PTS)\n",
248-
self.min_pts.as_timestamp().to_hms_millis_time(':').unwrap(),
253+
self.min_pts.as_timestamp(timing_info.mpeg_clock_freq).to_hms_millis_time(':').unwrap(),
249254
self.fts_offset.millis()
250255
);
251256
debug!(
@@ -262,7 +267,7 @@ impl TimingContext {
262267
// sync_pts (set at the beginning of the last GOP) plus the
263268
// time of the frames since then.
264269
self.fts_offset = self.fts_offset
265-
+ (self.sync_pts - self.min_pts).as_timestamp()
270+
+ (self.sync_pts - self.min_pts).as_timestamp(timing_info.mpeg_clock_freq)
266271
+ timing_info
267272
.frames_since_ref_time
268273
.as_timestamp(timing_info.current_fps);
@@ -277,14 +282,14 @@ impl TimingContext {
277282
self.sync_pts = self.current_pts
278283
- self
279284
.current_tref
280-
.as_mpeg_clock_tick(timing_info.current_fps);
285+
.as_mpeg_clock_tick(timing_info.current_fps, timing_info.mpeg_clock_freq);
281286
// Set min_pts = sync_pts as this is used for fts_now
282287
self.min_pts = self.sync_pts;
283288

284289
debug!(
285290
msg_type = DebugMessageFlag::TIME;
286291
"\nNew min PTS time: {} {:+}ms (time before this PTS)\n",
287-
self.min_pts.as_timestamp().to_hms_millis_time(':').unwrap(),
292+
self.min_pts.as_timestamp(timing_info.mpeg_clock_freq).to_hms_millis_time(':').unwrap(),
288293
self.fts_offset.millis()
289294
);
290295
}
@@ -305,7 +310,9 @@ impl TimingContext {
305310
// CFS: Remove or think decent condition
306311
if self.pts_set != PtsSet::No {
307312
// If pts_set is TRUE we have min_pts
308-
self.fts_now = (self.current_pts - self.min_pts).as_timestamp() + self.fts_offset;
313+
self.fts_now = (self.current_pts - self.min_pts)
314+
.as_timestamp(timing_info.mpeg_clock_freq)
315+
+ self.fts_offset;
309316
if !self.sync_pts2fts_set {
310317
self.sync_pts2fts_pts = self.current_pts;
311318
self.sync_pts2fts_fts = self.fts_now;
@@ -373,7 +380,7 @@ impl TimingContext {
373380
info!(
374381
"Sync time stamps: PTS: {} ",
375382
self.sync_pts
376-
.as_timestamp()
383+
.as_timestamp(timing_info.mpeg_clock_freq)
377384
.to_hms_millis_time(':')
378385
.unwrap()
379386
);
@@ -385,7 +392,8 @@ impl TimingContext {
385392
// Length first GOP to last GOP
386393
let goplenms = gop_time - first_gop_time;
387394
// Length at last sync point
388-
let ptslenms = (self.sync_pts - tempmin_pts).as_timestamp() + self.fts_offset;
395+
let ptslenms = (self.sync_pts - tempmin_pts).as_timestamp(timing_info.mpeg_clock_freq)
396+
+ self.fts_offset;
389397

390398
info!(
391399
"Last FTS: {}",
@@ -548,6 +556,7 @@ impl GlobalTimingInfo {
548556
no_sync: false,
549557
is_elementary_stream: false,
550558
},
559+
mpeg_clock_freq: 0,
551560
}
552561
}
553562
}

src/rust/lib_ccxr/src/time/units.rs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::convert::TryInto;
2-
use std::ffi::c_int;
32
use std::fmt::Write;
43
use std::num::TryFromIntError;
54
use std::time::{SystemTime, UNIX_EPOCH};
@@ -12,10 +11,6 @@ use time::{
1211
Duration,
1312
};
1413

15-
extern "C" {
16-
static mut MPEG_CLOCK_FREQ: c_int;
17-
}
18-
1914
/// Represents a timestamp in milliseconds.
2015
///
2116
/// The number can be negetive.
@@ -482,11 +477,6 @@ impl Timestamp {
482477
pub struct MpegClockTick(i64);
483478

484479
impl MpegClockTick {
485-
/// Returns the ratio to convert a clock tick to time duration.
486-
pub fn mpeg_clock_freq() -> i64 {
487-
unsafe { MPEG_CLOCK_FREQ.into() }
488-
}
489-
490480
/// Create a value representing `ticks` clock ticks.
491481
pub fn new(ticks: i64) -> MpegClockTick {
492482
MpegClockTick(ticks)
@@ -499,9 +489,9 @@ impl MpegClockTick {
499489

500490
/// Converts the clock ticks to its equivalent time duration.
501491
///
502-
/// The conversion ratio used is [`MpegClockTick::MPEG_CLOCK_FREQ`].
503-
pub fn as_timestamp(&self) -> Timestamp {
504-
Timestamp::from_millis(self.0 / (MpegClockTick::mpeg_clock_freq() / 1000))
492+
/// The conversion ratio used is governed by `mpeg_clock_freq`
493+
pub fn as_timestamp(&self, mpeg_clock_freq: i64) -> Timestamp {
494+
Timestamp::from_millis(self.0 / (mpeg_clock_freq / 1000))
505495
}
506496
}
507497

@@ -531,9 +521,9 @@ impl FrameCount {
531521

532522
/// Converts the frames to its equivalent number of clock ticks.
533523
///
534-
/// The conversion ratio used is [`MpegClockTick::MPEG_CLOCK_FREQ`] and `fps`.
535-
pub fn as_mpeg_clock_tick(&self, fps: f64) -> MpegClockTick {
536-
MpegClockTick::new(((self.0 * MpegClockTick::mpeg_clock_freq() as u64) as f64 / fps) as i64)
524+
/// The conversion ratio used is governed by `fps` and `mpeg_clock_freq`
525+
pub fn as_mpeg_clock_tick(&self, fps: f64, mpeg_clock_freq: i64) -> MpegClockTick {
526+
MpegClockTick::new(((self.0 * mpeg_clock_freq as u64) as f64 / fps) as i64)
537527
}
538528
}
539529

src/rust/src/lib.rs

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use std::os::windows::io::{FromRawHandle, RawHandle};
2727

2828
use args::Args;
2929
use bindings::*;
30+
use cfg_if::cfg_if;
3031
use clap::{error::ErrorKind, Parser};
3132
use common::{copy_from_rust, CType, CType2};
3233
use decoder::Dtvcc;
@@ -42,39 +43,62 @@ use std::{
4243
os::raw::{c_char, c_double, c_int, c_long, c_uint},
4344
};
4445

45-
#[cfg(test)]
46-
static mut cb_708: c_int = 0;
47-
#[cfg(test)]
48-
static mut cb_field1: c_int = 0;
49-
#[cfg(test)]
50-
static mut cb_field2: c_int = 0;
51-
52-
#[cfg(not(test))]
53-
extern "C" {
54-
static mut cb_708: c_int;
55-
static mut cb_field1: c_int;
56-
static mut cb_field2: c_int;
57-
}
58-
59-
#[allow(dead_code)]
60-
extern "C" {
61-
static mut usercolor_rgb: [c_int; 8];
62-
static mut FILEBUFFERSIZE: c_int;
63-
static mut MPEG_CLOCK_FREQ: c_int;
64-
static mut tlt_config: ccx_s_teletext_config;
65-
static mut ccx_options: ccx_s_options;
66-
static mut pts_big_change: c_uint;
67-
static mut current_fps: c_double;
68-
static mut frames_since_ref_time: c_int;
69-
static mut total_frames_count: c_uint;
70-
static mut gop_time: gop_time_code;
71-
static mut first_gop_time: gop_time_code;
72-
static mut fts_at_gop_start: c_long;
73-
static mut gop_rollover: c_int;
74-
static mut ccx_common_timing_settings: ccx_common_timing_settings_t;
75-
static mut capitalization_list: word_list;
76-
static mut profane: word_list;
77-
}
46+
// Mock data for rust unit tests
47+
cfg_if! {
48+
if #[cfg(test)] {
49+
static mut cb_708: c_int = 0;
50+
static mut cb_field1: c_int = 0;
51+
static mut cb_field2: c_int = 0;
52+
static mut current_fps: c_double = 30.0;
53+
static mut usercolor_rgb: [c_int; 8] = [0; 8];
54+
static mut FILEBUFFERSIZE: c_int = 0;
55+
static mut MPEG_CLOCK_FREQ: c_int = 90000;
56+
57+
static mut frames_since_ref_time: c_int = 0;
58+
static mut total_frames_count: c_uint = 0;
59+
static mut fts_at_gop_start: c_long = 0;
60+
static mut gop_rollover: c_int = 0;
61+
static mut pts_big_change: c_uint = 0;
62+
63+
static mut tlt_config: ccx_s_teletext_config = unsafe { std::mem::zeroed() };
64+
static mut ccx_options: ccx_s_options = unsafe { std::mem::zeroed() };
65+
static mut gop_time: gop_time_code = unsafe { std::mem::zeroed() };
66+
static mut first_gop_time: gop_time_code = unsafe { std::mem::zeroed() };
67+
static mut ccx_common_timing_settings: ccx_common_timing_settings_t = unsafe { std::mem::zeroed() };
68+
static mut capitalization_list: word_list = unsafe { std::mem::zeroed() };
69+
static mut profane: word_list = unsafe { std::mem::zeroed() };
70+
71+
unsafe extern "C" fn version(_location: *const c_char) {}
72+
unsafe extern "C" fn set_binary_mode() {}
73+
}
74+
}
75+
76+
// External C symbols (only when not testing)
77+
#[cfg(not(test))]
78+
extern "C" {
79+
static mut cb_708: c_int;
80+
static mut cb_field1: c_int;
81+
static mut cb_field2: c_int;
82+
static mut current_fps: c_double;
83+
static mut usercolor_rgb: [c_int; 8];
84+
static mut FILEBUFFERSIZE: c_int;
85+
static mut MPEG_CLOCK_FREQ: c_int;
86+
static mut tlt_config: ccx_s_teletext_config;
87+
static mut ccx_options: ccx_s_options;
88+
static mut frames_since_ref_time: c_int;
89+
static mut total_frames_count: c_uint;
90+
static mut gop_time: gop_time_code;
91+
static mut first_gop_time: gop_time_code;
92+
static mut fts_at_gop_start: c_long;
93+
static mut gop_rollover: c_int;
94+
static mut ccx_common_timing_settings: ccx_common_timing_settings_t;
95+
static mut capitalization_list: word_list;
96+
static mut profane: word_list;
97+
static mut pts_big_change: c_uint;
98+
99+
fn version(location: *const c_char);
100+
fn set_binary_mode();
101+
}
78102

79103
/// Initialize env logger with custom format, using stdout as target
80104
#[no_mangle]
@@ -216,12 +240,6 @@ extern "C" fn ccxr_close_handle(handle: RawHandle) {
216240
}
217241
}
218242

219-
extern "C" {
220-
fn version(location: *const c_char);
221-
#[allow(dead_code)]
222-
fn set_binary_mode();
223-
}
224-
225243
/// # Safety
226244
/// Safe if argv is a valid pointer
227245
///

src/rust/src/libccxr_exports/time.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::ffi::{c_char, c_int, c_long, CStr};
66
use crate::{
77
bindings::*, cb_708, cb_field1, cb_field2, ccx_common_timing_settings as timing_settings,
88
current_fps, first_gop_time, frames_since_ref_time, fts_at_gop_start, gop_rollover, gop_time,
9-
pts_big_change, total_frames_count,
9+
pts_big_change, total_frames_count, MPEG_CLOCK_FREQ,
1010
};
1111

1212
use lib_ccxr::common::FrameType;
@@ -279,6 +279,7 @@ unsafe fn apply_timing_info() {
279279
timing_info.timing_settings.disable_sync_check = timing_settings.disable_sync_check != 0;
280280
timing_info.timing_settings.no_sync = timing_settings.no_sync != 0;
281281
timing_info.timing_settings.is_elementary_stream = timing_settings.is_elementary_stream != 0;
282+
timing_info.mpeg_clock_freq = MPEG_CLOCK_FREQ.into();
282283
}
283284

284285
/// Write from [`GLOBAL_TIMING_INFO`] to the equivalent static variables in C.

src/rust/src/parser.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,7 @@ use time::OffsetDateTime;
2424
use crate::args::CCXCodec;
2525
use crate::args::{self, InFormat};
2626

27-
cfg_if! {
28-
if #[cfg(test)] {
29-
use crate::parser::tests::{set_binary_mode, MPEG_CLOCK_FREQ, usercolor_rgb, FILEBUFFERSIZE};
30-
} else {
31-
use crate::{set_binary_mode, MPEG_CLOCK_FREQ, usercolor_rgb, FILEBUFFERSIZE};
32-
}
33-
}
27+
use crate::{set_binary_mode, usercolor_rgb, FILEBUFFERSIZE, MPEG_CLOCK_FREQ};
3428

3529
cfg_if! {
3630
if #[cfg(windows)] {
@@ -1684,9 +1678,6 @@ pub mod tests {
16841678

16851679
#[no_mangle]
16861680
pub unsafe extern "C" fn set_binary_mode() {}
1687-
pub static mut MPEG_CLOCK_FREQ: u64 = 0;
1688-
pub static mut FILEBUFFERSIZE: i32 = 0;
1689-
pub static mut usercolor_rgb: [i32; 8] = [0; 8];
16901681

16911682
fn parse_args(args: &[&str]) -> (Options, TeletextConfig) {
16921683
let mut common_args = vec!["./ccextractor", "input_file"];

0 commit comments

Comments
 (0)