[FIX] Use fixed-width format specifiers for 64-bit values (corrupted X-TIMESTAMP-MAP on Windows) - #2337
Conversation
X-TIMESTAMP-MAP emitted a truncated MPEGTS value on every Windows build. sync_pts2fts_pts is LLONG (int64_t) but was printed with %ld, and long is 32 bits on Windows (LLP64 on x64, ILP32 on Win32). A 90kHz PTS of 2^33 printed as "MPEGTS:0"; 2^31 printed as "MPEGTS:-2147483648". On Win32 the argument slots also desynchronise, so the trailing %s reads the PTS high dword as a char *. HLS players use this field to anchor a WebVTT segment to the transport clock, so the result is caption desync. Linux and macOS are LP64, where long is 64 bits and %ld happens to be correct, which is why this went unnoticed. For the same reason %lld would be wrong there, since int64_t is long on LP64. Use the <inttypes.h> macros instead, which are correct on every target and already used elsewhere in the tree; ccx_common_platform.h already includes <inttypes.h>. The same defect class appears at 22 sites across 10 files. They are invisible to the build because mprint() and dbg_print() carry no format(printf) attribute, so the compiler never checks those call sites. Adding the attributes locally surfaced all of them; this commit fixes them with PRId64/PRIu64/PRIx64 for fixed-width types, %zu for size_t, and an explicit (long long) cast for pointer differences. Also fixes ts_readpacket() printing payload->start, an unsigned char *, under the label "PES start". The intended field is payload->pesstart; the pointer was truncated to int and shifted the three arguments after it, so counter, payload length and adapt length were all wrong in the trace. Output on Linux and macOS is byte-identical before and after. No signature, struct, option or output-format change. Refs CCExtractor#2336
CCExtractor CI platform finished running the test files on linux. 171/237 tests matched the approved output:
66 tests do not match the approved output. That is the pass/fail verdict. Whether this branch caused it is a separate question, answered below.
Compared with the tip of master — test 9528, commit 205cfb0:
Compared with the commit this branch was cut from: the same run as the tip of master (test 9528), so the comparison above already covers it. No test changes behaviour relative to the tip of master: every failure above fails there too, byte for byte. The approved output for those tests is out of date, which is a baseline to review rather than a regression in this branch. |
CCExtractor CI platform finished running the test files on windows. 171/237 tests matched the approved output:
66 tests do not match the approved output. That is the pass/fail verdict. Whether this branch caused it is a separate question, answered below.
Compared with the tip of master — test 9525, commit 3875e84:
Compared with the commit this branch was cut from: the same run as the tip of master (test 9525), so the comparison above already covers it. No test changes behaviour relative to the tip of master: every failure above fails there too, byte for byte. The approved output for those tests is out of date, which is a baseline to review rather than a regression in this branch. |
Fixes #2336
Reason for this PR:
Sanity check:
What was wrong
X-TIMESTAMP-MAPcarried a corrupted MPEGTS value on every Windows build:sync_pts2fts_ptsisLLONG→int64_t, printed with%ld.longis 32 bits on Windows (LLP64 on x64, ILP32 on Win32), so the value is truncated. HLS players use this field to anchor a WebVTT segment to the transport clock.Linux/macOS are LP64 where
longis 64 bits, so%ldis accidentally correct there — which is why this survived.Repro instructions
No media sample is needed — this is a type/format mismatch that the compiler itself diagnoses. I understand the template asks for a sample and why; I'm happy to hunt one down for the regression suite if you want it, but I don't think a file is what makes this one verifiable. Here is the proof instead.
1. The compiler flags the real line. Building the actual file with MinGW-w64 (same LLP64 ABI as the shipped MSVC binaries):
2. Standalone runnable reproduction (
gcc -Wall repro.c && ./reproon Windows x86_64):Actual output:
A PTS of 2^31 (≈6.6 h of 90 kHz ticks) prints
MPEGTS:-2147483648— negative, which is invalid for this field. On Win32 it is worse: cdecl varargs are stack-packed, so%ldeats 4 of 8 bytes and the trailing%sreads the PTS high dword as achar *.Why
PRId64and not%lld%lldwould fix Windows but break Linux, whereint64_tislong, notlong long. The<inttypes.h>macros are correct on every target, are already used inccx_demuxer_mxf.c,ccx_encoders_curl.c,dvb_subtitle_decoder.candtelxcc.c, andccx_common_platform.halready includes<inttypes.h>, so no new include is needed.Scope: 22 sites, one root cause
mprint()anddbg_print()carry no__attribute__((format(printf, ...))), so the compiler never checks those call sites — the whole class is invisible to the build. I added the attributes locally, rebuiltsrc/lib_ccx/*.cwith-Wformat, and fixed everything it found:PRId64/PRIu64/PRIx64forint64_t/uint64_t/LLONG/ULLONG%zuforsize_t(long long)cast for pointer differencesAfter the fix that build is clean (the only three diagnostics left are checker artifacts, not defects — details in #2336).
One genuine second bug
ts_functions.c:345printedpayload->start, anunsigned char *, under the label "PES start". The intended field ispayload->pesstart. The pointer was truncated tointand shifted the three arguments after it, socounter,payload lengthandadapt lengthwere all wrong in every-debugTS trace.Risk
Output on Linux and macOS is byte-identical before and after. Only Windows output changes, from wrong to right. No signature, struct, option or output-format change.
clang-formatclean.Deliberately left out
matroska.c:1348/1594use theLLDmacro, which expands to%I64don Windows and is correct. GCC only reported it because itsgnu_printfchecker skips the MSVCI64modifier. Untouched.format(printf)attributes tomprint/dbg_printin this PR, even though that is what would stop this class from coming back. I can only test the Windows leg locally, and I'd rather not surface unknown warnings on the Linux build without your say-so. Happy to send it as a follow-up if you want it.Disclosure: I found this with AI assistance, then verified every claim on real hardware — the compiler diagnostics and program output above are captured from actual runs on Windows, not inferred. I saw the note in the PR template about theoretical AI-generated fixes and tried to make this one carry its own proof.