Skip to content

Commit 8b9acf1

Browse files
authored
Merge branch 'master' into refactor/move-demuxer-options-to-struct
2 parents 51bc942 + dd29311 commit 8b9acf1

13 files changed

Lines changed: 134 additions & 59 deletions

docs/CHANGES.TXT

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
0.96.6 (unreleased)
22
-------------------
3+
- Fix: DVB EIT start time BCD decoding in XMLTV output causing invalid timestamps (#1835)
34
- New: Add Snap packaging support with Snapcraft configuration and GitHub Actions CI workflow.
45
- Fix: Clear status line output on Linux/WSL to prevent text artifacts (#2017)
56
- Fix: Prevent infinite loop on truncated MKV files
@@ -8,6 +9,7 @@
89
- Fix: --mkvlang now supports BCP 47 language tags (e.g., en-US, zh-Hans-CN) and multiple codes
910
- Refactor: Move demuxer-related options (live_stream, buffer_input, input_source, binary_concat)
1011
from global ccx_options to ccx_demuxer struct for better encapsulation and testability
12+
- Fix: segmentation fault when using --multiprogram
1113

1214
0.96.5 (2026-01-05)
1315
-------------------

src/lib_ccx/ccx_encoders_common.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ int write_subtitle_file_footer(struct encoder_ctx *ctx, struct ccx_s_write *out)
176176
case CCX_OF_CCD:
177177
ret = write(out->fh, ctx->encoded_crlf, ctx->encoded_crlf_length);
178178
break;
179+
case CCX_OF_WEBVTT:
180+
// Ensure WebVTT header is written even if no subtitles were found (issue #1743)
181+
// This is required for HLS compatibility
182+
if (!ctx->wrote_webvtt_header)
183+
{
184+
write_webvtt_header(ctx);
185+
}
186+
break;
179187
default: // Nothing to do, no footer on this format
180188
break;
181189
}

src/lib_ccx/ccx_encoders_common.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ struct encoder_ctx
184184
int nospupngocr;
185185
int is_pal;
186186

187-
struct ccx_s_write *tlt_out[MAX_TLT_PAGES_EXTRACT]; // Output files per teletext page
188-
uint16_t tlt_out_pages[MAX_TLT_PAGES_EXTRACT]; // Page numbers for each output slot
187+
struct ccx_s_write *tlt_out[MAX_TLT_PAGES_EXTRACT]; // Output files per teletext page
188+
uint16_t tlt_out_pages[MAX_TLT_PAGES_EXTRACT]; // Page numbers for each output slot
189189
unsigned int tlt_srt_counter[MAX_TLT_PAGES_EXTRACT]; // SRT counter per page
190190
int tlt_out_count; // Number of teletext output files
191191
};
@@ -263,6 +263,9 @@ int write_cc_bitmap_as_libcurl(struct cc_subtitle *sub, struct encoder_ctx *cont
263263
void write_spumux_header(struct encoder_ctx *ctx, struct ccx_s_write *out);
264264
void write_spumux_footer(struct ccx_s_write *out);
265265

266+
// WebVTT header writer (issue #1743 - ensures header is written even for empty files)
267+
void write_webvtt_header(struct encoder_ctx *context);
268+
266269
struct cc_subtitle *reformat_cc_bitmap_through_sentence_buffer(struct cc_subtitle *sub, struct encoder_ctx *context);
267270

268271
void set_encoder_last_displayed_subs_ms(struct encoder_ctx *ctx, LLONG last_displayed_subs_ms);

src/lib_ccx/ccx_encoders_webvtt.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,9 @@ void write_webvtt_header(struct encoder_ctx *context)
220220
millis_to_time(context->timing->sync_pts2fts_fts, &h1, &m1, &s1, &ms1);
221221

222222
// If the user has enabled X-TIMESTAMP-MAP
223-
snprintf(header_string, sizeof(header_string), "X-TIMESTAMP-MAP=MPEGTS:%ld,LOCAL:%02u:%02u:%02u.%03u%s",
224-
context->timing->sync_pts2fts_pts, h1, m1, s1, ms1,
223+
// LOCAL must come before MPEGTS for HLS compatibility (issue #1743)
224+
snprintf(header_string, sizeof(header_string), "X-TIMESTAMP-MAP=LOCAL:%02u:%02u:%02u.%03u,MPEGTS:%ld%s",
225+
h1, m1, s1, ms1, context->timing->sync_pts2fts_pts,
225226
ccx_options.enc_cfg.line_terminator_lf ? "\n\n" : "\r\n\r\n");
226227

227228
used = encode_line(context, context->buffer, (unsigned char *)header_string);

src/lib_ccx/lib_ccx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ struct encoder_ctx *update_encoder_list_cinfo(struct lib_ccx_ctx *ctx, struct ca
473473
}
474474

475475
list_add_tail(&(enc_ctx->list), &(ctx->enc_ctx_head));
476-
freep(ccx_options.enc_cfg.output_filename);
476+
freep(&ccx_options.enc_cfg.output_filename);
477477
}
478478
// DVB related
479479
enc_ctx->prev = NULL;

src/lib_ccx/output.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,22 @@ void writercwtdata(struct lib_cc_decode *ctx, const unsigned char *data, struct
249249
LLONG currfts = ctx->timing->fts_now + ctx->timing->fts_global;
250250
static uint16_t cbcount = 0;
251251
static int cbempty = 0;
252-
static unsigned char cbbuffer[0xFFFF * 3]; // TODO: use malloc
252+
static unsigned char *cbbuffer = NULL;
253+
static int cbbuffer_initialized = 0;
253254
static unsigned char cbheader[8 + 2];
254255

256+
if (!cbbuffer_initialized)
257+
{
258+
cbbuffer = (unsigned char *)malloc(0xFFFF * 3);
259+
if (cbbuffer == NULL)
260+
{
261+
mprint("Error: Failed to allocate memory for cbbuffer\n");
262+
return;
263+
}
264+
cbbuffer_initialized = 1;
265+
dbg_print(CCX_DMT_VERBOSE, "Allocated RCWT buffer (%d bytes)\n", 0xFFFF * 3);
266+
}
267+
255268
if ((prevfts != currfts && prevfts != -1) || data == NULL || cbcount == 0xFFFF)
256269
{
257270
// Remove trailing empty or 608 padding caption blocks

src/lib_ccx/ts_tables_epg.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ void EPG_DVB_calc_start_time(struct EPG_event *event, uint64_t time)
136136
if (mjd > 0)
137137
{
138138
long y, m, d, k;
139+
struct tm timeinfo = {0};
139140

140141
// algo: ETSI EN 300 468 - ANNEX C
141142
y = (long)((mjd - 15078.2) / 365.25);
@@ -145,7 +146,32 @@ void EPG_DVB_calc_start_time(struct EPG_event *event, uint64_t time)
145146
y = y + k + 1900;
146147
m = m - 1 - k * 12;
147148

148-
snprintf(event->start_time_string, sizeof(event->start_time_string), "%02ld%02ld%02ld%06" PRIu64 "+0000", y, m, d, time & 0xffffff);
149+
timeinfo.tm_year = y - 1900;
150+
timeinfo.tm_mon = m - 1;
151+
timeinfo.tm_mday = d;
152+
153+
// Decode BCD time (lower 24 bits: HHMMSS)
154+
uint32_t bcd = (uint32_t)(time & 0xFFFFFF);
155+
156+
timeinfo.tm_sec = (bcd & 0x0f) + (10 * ((bcd & 0xf0) >> 4));
157+
158+
timeinfo.tm_min = ((bcd & 0x0f00) >> 8) + (10 * ((bcd & 0xf000) >> 12));
159+
160+
timeinfo.tm_hour = ((bcd & 0x0f0000) >> 16) + (10 * ((bcd & 0xf00000) >> 20));
161+
162+
timeinfo.tm_isdst = -1;
163+
164+
mktime(&timeinfo);
165+
166+
snprintf(event->start_time_string,
167+
sizeof(event->start_time_string),
168+
"%04d%02d%02d%02d%02d%02d +0000",
169+
timeinfo.tm_year + 1900,
170+
timeinfo.tm_mon + 1,
171+
timeinfo.tm_mday,
172+
timeinfo.tm_hour,
173+
timeinfo.tm_min,
174+
timeinfo.tm_sec);
149175
}
150176
}
151177

src/rust/Cargo.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ tesseract-sys = { version = "0.5.15", optional = true, default-features = false
1818
leptonica-sys = { version = "= 0.4.6", optional = true, default-features = false }
1919
clap = { version = "4.5.31", features = ["derive"] }
2020
strum_macros = "0.25.3"
21-
time = "0.3.39"
21+
time = "0.3.47"
2222
cfg-if = "1.0.0"
2323
num-integer = "0.1.46"
2424
lib_ccxr = { path = "lib_ccxr" }

src/rust/lib_ccxr/Cargo.lock

Lines changed: 24 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)