Skip to content

Commit 1c781c2

Browse files
cfsmp3claude
andcommitted
fix: Correct progress time display for multi-program TS files
Multi-program transport stream files can have different PCR (Program Clock Reference) bases for each program. For example, one program might have timestamps starting at 23 hours, another at 25 hours. This caused the progress time display to show wildly incorrect values like "265:45" for a 6-second file. The fix tracks the minimum timestamp offset seen across all programs and uses that as the baseline. When timestamps from programs with higher PCR bases are encountered (offset > 60 seconds from minimum), the display falls back to showing time relative to the minimum baseline. Changes: - Add min_global_timestamp_offset field to lib_ccx_ctx to track the minimum PCR-based offset seen - Update progress display logic in general_loop.c to normalize times relative to the minimum offset - Apply same fix to both live stream and file processing modes Test results with multi-program DVB teletext sample (dvbt.ts): - Before: 1% | 265:45, 2% | 00:00, 3% | 263:11, ... (jumping wildly) - After: 1% | 00:00, 2% | 00:00, ... 87% | 00:05, 100% | 00:00 (stable) Single-program files continue to work correctly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 126835d commit 1c781c2

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

src/lib_ccx/file_functions.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ void prepare_for_new_file(struct lib_ccx_ctx *ctx)
6666
{
6767
// Init per file variables
6868
ctx->last_reported_progress = -1;
69+
ctx->min_global_timestamp_offset = -1; // -1 means not yet initialized
6970
ctx->stat_numuserheaders = 0;
7071
ctx->stat_dvdccheaders = 0;
7172
ctx->stat_scte20ccheaders = 0;

src/lib_ccx/general_loop.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,24 @@ int general_loop(struct lib_ccx_ctx *ctx)
15081508
}
15091509
if (ctx->live_stream)
15101510
{
1511-
int cur_sec = (int)(get_fts(dec_ctx->timing, dec_ctx->current_field) / 1000);
1511+
LLONG t = get_fts(dec_ctx->timing, dec_ctx->current_field);
1512+
if (!t && ctx->demux_ctx->global_timestamp_inited)
1513+
t = ctx->demux_ctx->global_timestamp - ctx->demux_ctx->min_global_timestamp;
1514+
// Handle multi-program TS timing
1515+
if (ctx->demux_ctx->global_timestamp_inited)
1516+
{
1517+
LLONG offset = ctx->demux_ctx->global_timestamp - ctx->demux_ctx->min_global_timestamp;
1518+
if (ctx->min_global_timestamp_offset < 0 || offset < ctx->min_global_timestamp_offset)
1519+
ctx->min_global_timestamp_offset = offset;
1520+
// Only use timestamps from the program with the lowest base
1521+
if (offset - ctx->min_global_timestamp_offset < 60000)
1522+
t = offset - ctx->min_global_timestamp_offset;
1523+
else
1524+
t = ctx->min_global_timestamp_offset > 0 ? 0 : t;
1525+
if (t < 0)
1526+
t = 0;
1527+
}
1528+
int cur_sec = (int)(t / 1000);
15121529
int th = cur_sec / 10;
15131530
if (ctx->last_reported_progress != th)
15141531
{
@@ -1526,6 +1543,28 @@ int general_loop(struct lib_ccx_ctx *ctx)
15261543
LLONG t = get_fts(dec_ctx->timing, dec_ctx->current_field);
15271544
if (!t && ctx->demux_ctx->global_timestamp_inited)
15281545
t = ctx->demux_ctx->global_timestamp - ctx->demux_ctx->min_global_timestamp;
1546+
// For multi-program TS files, different programs can have different
1547+
// PCR bases (e.g., one at 25h, another at 23h). This causes the
1548+
// global_timestamp to jump between different bases, resulting in
1549+
// wildly different offset values. Track the minimum offset seen
1550+
// and only display times from the program with the lowest base.
1551+
if (ctx->demux_ctx->global_timestamp_inited)
1552+
{
1553+
LLONG offset = ctx->demux_ctx->global_timestamp - ctx->demux_ctx->min_global_timestamp;
1554+
// Track minimum offset (this is the PCR base of the program
1555+
// with the lowest timestamp, which represents true file time)
1556+
if (ctx->min_global_timestamp_offset < 0 || offset < ctx->min_global_timestamp_offset)
1557+
ctx->min_global_timestamp_offset = offset;
1558+
// Only use timestamps from the program with the lowest base.
1559+
// If current offset is significantly larger than minimum (by > 60s),
1560+
// it's from a program with a higher PCR base - use minimum instead.
1561+
if (offset - ctx->min_global_timestamp_offset < 60000)
1562+
t = offset - ctx->min_global_timestamp_offset;
1563+
else
1564+
t = ctx->min_global_timestamp_offset > 0 ? 0 : t; // fallback to minimum-based time
1565+
if (t < 0)
1566+
t = 0;
1567+
}
15291568
int cur_sec = (int)(t / 1000);
15301569
activity_progress(progress, cur_sec / 60, cur_sec % 60);
15311570
ctx->last_reported_progress = progress;

src/lib_ccx/lib_ccx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ struct lib_ccx_ctx
9090
LLONG total_past; // Only in binary concat mode
9191

9292
int last_reported_progress;
93+
LLONG min_global_timestamp_offset; // Track minimum (global - min) for multi-program TS
9394

9495
/* Stats */
9596
int stat_numuserheaders;

0 commit comments

Comments
 (0)