FA-78416 / Broadcast timecode arithmetic / Open access
Frame count to drop-frame 29.97 label: ten-minute block size · case 01
Labels drift by several frames per hour relative to the frame count.
ROOT CAUSE
The ten-minute block uses the nominal 18000 frames instead of the 17982 real frames.
VERIFIED REPAIR
Divide the count into 17982-frame blocks.
Unsuccessful approach: A 17980-frame block over-corrects and still drifts.
Case contract
Convert a non-negative frame count (negative counts return None; counts wrap to the 2589408-frame drop-frame day) to an HH:MM:SS;FF 29.97 drop-frame label: 18 labels are skipped per 10-minute block of 17982 frames, and labels ;00/;01 are skipped at each minute not divisible by ten.
Why this case matters
Timecode arithmetic errors misplace edits, commercial breaks and captions against the broadcast clock.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(frames):
if frames<0:
return None
frames%=2589408
d,mrem=divmod(frames,18000)
add=18*d
if mrem>=2:
add+=2*((mrem-2)//1798)
n=frames+add
ff=n%30
ss=n//30%60
mm=n//1800%60
hh=n//108000
return '%02d:%02d:%02d;%02d'%(hh,mm,ss,ff)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: ten-minute block size', [17982], '00:10:00;00'), ('regression variant: ten-minute block size', [1183387], '10:58:05;23'), ('partial repair probe: ten-minute block size', [985344], '09:07:57;20'), ('partial repair variant: ten-minute block size', [793007], '07:20:59;29'), ('boundary control', [1800], '00:01:00;02'), ('boundary control', [0], '00:00:00;00'), ('normal control', [1799], '00:00:59;29'), ('normal control', [-1], None), ('normal control', [107891], '00:59:59;29')], [('regression: ten-minute block size', [2589407], '23:59:59;29'), ('regression variant: ten-minute block size', [2576030], '23:52:33;18'), ('partial repair probe: ten-minute block size', [1190345], '11:01:57;25'), ('partial repair variant: ten-minute block size', [1688437], '15:38:57;17'), ('boundary control', [1799], '00:00:59;29'), ('boundary control', [-1], None), ('normal control', [-2], None), ('normal control', [683315], '06:19:59;29'), ('normal control', [666705], '06:10:45;21')], [('regression: ten-minute block size', [5138128], '23:37:22;12'), ('regression variant: ten-minute block size', [2535623], '23:30:05;11'), ('partial repair probe: ten-minute block size', [1073449], '09:56:57;13'), ('partial repair variant: ten-minute block size', [1264068], '11:42:57;22'), ('boundary control', [107892], '01:00:00;00'), ('boundary control', [1800], '00:01:00;02'), ('normal control', [3599], '00:02:00;03'), ('normal control', [431569], '04:00:00;01'), ('normal control', [737264], '06:50:00;02')], [('regression: ten-minute block size', [703099], '06:31:00;03'), ('regression variant: ten-minute block size', [757044], '07:01:00;02'), ('partial repair probe: ten-minute block size', [4738204], '19:54:58;06'), ('partial repair variant: ten-minute block size', [489111], '04:31:59;29'), ('boundary control', [0], '00:00:00;00'), ('boundary control', [1799], '00:00:59;29'), ('normal control', [3598], '00:02:00;02'), ('normal control', [1092788], '10:07:42;22'), ('normal control', [-464827], None)], [('regression: ten-minute block size', [916013], '08:29:24;11'), ('regression variant: ten-minute block size', [1508377], '13:58:49;17'), ('partial repair probe: ten-minute block size', [451349], '04:10:59;29'), ('partial repair variant: ten-minute block size', [235565], '02:10:59;29'), ('boundary control', [-1], None), ('boundary control', [107892], '01:00:00;00'), ('normal control', [143856], '01:20:00;00'), ('normal control', [449552], '04:10:00;02'), ('normal control', [557441], '05:09:59;29')]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: ten-minute block size | 00:10:00;02 | 00:10:00;00 | Failed |
| regression variant: ten-minute block size | 10:58:05;21 | 10:58:05;23 | Failed |
| partial repair probe: ten-minute block size | 09:07:57;20 | 09:07:57;20 | Passed |
| partial repair variant: ten-minute block size | 07:20:59;29 | 07:20:59;29 | Passed |
| boundary control | 00:01:00;02 | 00:01:00;02 | Passed |
| boundary control | 00:00:00;00 | 00:00:00;00 | Passed |
| normal control | 00:00:59;29 | 00:00:59;29 | Passed |
| normal control | None | None | Passed |
| normal control | 00:59:59;29 | 00:59:59;29 | Passed |
SHA-256 / e3197423a98dc41c2d67cc15f466e91e82eb32eb28ab9cb9a1d1c5e9ab3b6205
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(frames):
if frames<0:
return None
frames%=2589408
d,mrem=divmod(frames,17980)
add=18*d
if mrem>=2:
add+=2*((mrem-2)//1798)
n=frames+add
ff=n%30
ss=n//30%60
mm=n//1800%60
hh=n//108000
return '%02d:%02d:%02d;%02d'%(hh,mm,ss,ff)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: ten-minute block size', [17982], '00:10:00;00'), ('regression variant: ten-minute block size', [1183387], '10:58:05;23'), ('partial repair probe: ten-minute block size', [985344], '09:07:57;20'), ('partial repair variant: ten-minute block size', [793007], '07:20:59;29'), ('boundary control', [1800], '00:01:00;02'), ('boundary control', [0], '00:00:00;00'), ('normal control', [1799], '00:00:59;29'), ('normal control', [-1], None), ('normal control', [107891], '00:59:59;29')], [('regression: ten-minute block size', [2589407], '23:59:59;29'), ('regression variant: ten-minute block size', [2576030], '23:52:33;18'), ('partial repair probe: ten-minute block size', [1190345], '11:01:57;25'), ('partial repair variant: ten-minute block size', [1688437], '15:38:57;17'), ('boundary control', [1799], '00:00:59;29'), ('boundary control', [-1], None), ('normal control', [-2], None), ('normal control', [683315], '06:19:59;29'), ('normal control', [666705], '06:10:45;21')], [('regression: ten-minute block size', [5138128], '23:37:22;12'), ('regression variant: ten-minute block size', [2535623], '23:30:05;11'), ('partial repair probe: ten-minute block size', [1073449], '09:56:57;13'), ('partial repair variant: ten-minute block size', [1264068], '11:42:57;22'), ('boundary control', [107892], '01:00:00;00'), ('boundary control', [1800], '00:01:00;02'), ('normal control', [3599], '00:02:00;03'), ('normal control', [431569], '04:00:00;01'), ('normal control', [737264], '06:50:00;02')], [('regression: ten-minute block size', [703099], '06:31:00;03'), ('regression variant: ten-minute block size', [757044], '07:01:00;02'), ('partial repair probe: ten-minute block size', [4738204], '19:54:58;06'), ('partial repair variant: ten-minute block size', [489111], '04:31:59;29'), ('boundary control', [0], '00:00:00;00'), ('boundary control', [1799], '00:00:59;29'), ('normal control', [3598], '00:02:00;02'), ('normal control', [1092788], '10:07:42;22'), ('normal control', [-464827], None)], [('regression: ten-minute block size', [916013], '08:29:24;11'), ('regression variant: ten-minute block size', [1508377], '13:58:49;17'), ('partial repair probe: ten-minute block size', [451349], '04:10:59;29'), ('partial repair variant: ten-minute block size', [235565], '02:10:59;29'), ('boundary control', [-1], None), ('boundary control', [107892], '01:00:00;00'), ('normal control', [143856], '01:20:00;00'), ('normal control', [449552], '04:10:00;02'), ('normal control', [557441], '05:09:59;29')]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: ten-minute block size | 00:10:00;00 | 00:10:00;00 | Passed |
| regression variant: ten-minute block size | 10:58:05;23 | 10:58:05;23 | Passed |
| partial repair probe: ten-minute block size | 09:07:57;22 | 09:07:57;20 | Failed |
| partial repair variant: ten-minute block size | 07:21:00;01 | 07:20:59;29 | Failed |
| boundary control | 00:01:00;02 | 00:01:00;02 | Passed |
| boundary control | 00:00:00;00 | 00:00:00;00 | Passed |
| normal control | 00:00:59;29 | 00:00:59;29 | Passed |
| normal control | None | None | Passed |
| normal control | 00:59:59;29 | 00:59:59;29 | Passed |
SHA-256 / 1e6438eb94d694078426ebb741856b0a98528f3884a6e45eecba0356ea0b1c98
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(frames):
if frames<0:
return None
frames%=2589408
d,mrem=divmod(frames,17982)
add=18*d
if mrem>=2:
add+=2*((mrem-2)//1798)
n=frames+add
ff=n%30
ss=n//30%60
mm=n//1800%60
hh=n//108000
return '%02d:%02d:%02d;%02d'%(hh,mm,ss,ff)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: ten-minute block size', [17982], '00:10:00;00'), ('regression variant: ten-minute block size', [1183387], '10:58:05;23'), ('partial repair probe: ten-minute block size', [985344], '09:07:57;20'), ('partial repair variant: ten-minute block size', [793007], '07:20:59;29'), ('boundary control', [1800], '00:01:00;02'), ('boundary control', [0], '00:00:00;00'), ('normal control', [1799], '00:00:59;29'), ('normal control', [-1], None), ('normal control', [107891], '00:59:59;29')], [('regression: ten-minute block size', [2589407], '23:59:59;29'), ('regression variant: ten-minute block size', [2576030], '23:52:33;18'), ('partial repair probe: ten-minute block size', [1190345], '11:01:57;25'), ('partial repair variant: ten-minute block size', [1688437], '15:38:57;17'), ('boundary control', [1799], '00:00:59;29'), ('boundary control', [-1], None), ('normal control', [-2], None), ('normal control', [683315], '06:19:59;29'), ('normal control', [666705], '06:10:45;21')], [('regression: ten-minute block size', [5138128], '23:37:22;12'), ('regression variant: ten-minute block size', [2535623], '23:30:05;11'), ('partial repair probe: ten-minute block size', [1073449], '09:56:57;13'), ('partial repair variant: ten-minute block size', [1264068], '11:42:57;22'), ('boundary control', [107892], '01:00:00;00'), ('boundary control', [1800], '00:01:00;02'), ('normal control', [3599], '00:02:00;03'), ('normal control', [431569], '04:00:00;01'), ('normal control', [737264], '06:50:00;02')], [('regression: ten-minute block size', [703099], '06:31:00;03'), ('regression variant: ten-minute block size', [757044], '07:01:00;02'), ('partial repair probe: ten-minute block size', [4738204], '19:54:58;06'), ('partial repair variant: ten-minute block size', [489111], '04:31:59;29'), ('boundary control', [0], '00:00:00;00'), ('boundary control', [1799], '00:00:59;29'), ('normal control', [3598], '00:02:00;02'), ('normal control', [1092788], '10:07:42;22'), ('normal control', [-464827], None)], [('regression: ten-minute block size', [916013], '08:29:24;11'), ('regression variant: ten-minute block size', [1508377], '13:58:49;17'), ('partial repair probe: ten-minute block size', [451349], '04:10:59;29'), ('partial repair variant: ten-minute block size', [235565], '02:10:59;29'), ('boundary control', [-1], None), ('boundary control', [107892], '01:00:00;00'), ('normal control', [143856], '01:20:00;00'), ('normal control', [449552], '04:10:00;02'), ('normal control', [557441], '05:09:59;29')]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: ten-minute block size | 00:10:00;00 | 00:10:00;00 | Passed |
| regression variant: ten-minute block size | 10:58:05;23 | 10:58:05;23 | Passed |
| partial repair probe: ten-minute block size | 09:07:57;20 | 09:07:57;20 | Passed |
| partial repair variant: ten-minute block size | 07:20:59;29 | 07:20:59;29 | Passed |
| boundary control | 00:01:00;02 | 00:01:00;02 | Passed |
| boundary control | 00:00:00;00 | 00:00:00;00 | Passed |
| normal control | 00:00:59;29 | 00:00:59;29 | Passed |
| normal control | None | None | Passed |
| normal control | 00:59:59;29 | 00:59:59;29 | Passed |
SHA-256 / 93d8ef6c51b268434453149d2294c4ff644ec4d95a38c5ffb5a5c390fa12773e
Verification & scope
A deterministic bounded teaching model with a stipulated toy contract; it does not claim conformance to SMPTE or any broadcast standard. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:35.274194+00:00.
Case digest / 9e58d99b3a9e952a8445ea35ebeb918b20e09abd556a0486bfa5f1ba7c5b7b4b