CCExtractor / CCExtractor/ccextractor

BUG: SCC timecodes use hardcoded 29.97 FPS instead of actual stream frame rate

Open
#2,145 10 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
903
Forks
589
Avg merge
3d 2h
Merged PRs (30d)
10

Description

## Summary

`print_scc_time()` in `src/lib_ccx/ccx_common_timing.c` computes SCC timecode frame numbers using a hardcoded literal `29.97`, completely ignoring the `current_fps` global that exists in the same file and is dynamically updated from stream NAL data at runtime.

Any SCC output from a 24fps, 25fps, 30fps, or 50/60fps source will have **incorrect frame numbers in every timecode**, making the output non-standard and potentially rejected by downstream validators.

---

## Affected File

`src/lib_ccx/ccx_common_timing.c` — Line 125

---

## Reproduction
```bash
grep -n "29\.97" src/lib_ccx/ccx_common_timing.c
```
```
22: double current_fps = (double)30000.0 / 1001; /* 29.97 */ // TODO: Get from framerates_values[] instead
125: frame = ((double)(time.time_in_ms - 1000 * (time.ss + 60 * (time.mm + 60 * time.hh))) * 29.97 / 1000);
```

---

## Root Cause

`current_fps` is already updated dynamically in two places:

- `avc_functions.c:891` — from stream NAL timing data
- `avc_functions.c:991` and `es_functions.c:442` — from `framerates_values[current_frame_rate]`

`print_scc_time()` is simply the one function that was never updated to use it.

---

## Impact

- All non-NTSC sources (24fps film, 25fps PAL, 30fps progressive) produce SCC timecodes with wrong frame numbers
- 25fps PAL broadcasts — common across Europe — see a ~20% frame count error
- Downstream broadcast validators may reject the output or apply incorrect sync

---

## Suggested Fix

Single-token change on line 125:
```c
// BEFORE:
frame = ((double)(time.time_in_ms - 1000 * (time.ss + 60 * (time.mm + 60 * time.hh))) * 29.97 / 1000);

// AFTER:
frame = ((double)(time.time_in_ms - 1000 * (time.ss + 60 * (time.mm + 60 * time.hh))) * current_fps / 1000);
```

`current_fps` is a file-level global in the same translation unit — no header changes needed. Happy to submit a PR for this.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.