Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/CHANGES.TXT
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
0.96.6 (2026-02-19)
-------------------
- New: Allow output \0 terminated frames via --null-terminated
- FIX: spupng start numbering at sub0000, avoid index advance on empty EOD, normalize header filename
- New: 32-bit (x86) Windows build and installer (#2116)
- New: Add optional machine-readable JSON output for -out=report via --report-format json
Expand Down
1 change: 1 addition & 0 deletions src/lib_ccx/ccx_common_option.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ void init_options(struct ccx_s_options *options)
options->enc_cfg.trim_subs = 0; // " Remove spaces at sides? "
options->enc_cfg.in_format = 1;
options->enc_cfg.line_terminator_lf = 0; // 0 = CRLF
options->enc_cfg.frame_terminator_0 = 0; // 0 = frames terminated by line_terminator_lf
options->enc_cfg.start_credits_text = NULL;
options->enc_cfg.end_credits_text = NULL;
options->enc_cfg.encoding = CCX_ENC_UTF_8;
Expand Down
1 change: 1 addition & 0 deletions src/lib_ccx/ccx_common_option.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct encoder_cfg
int no_type_setting;
int cc_to_stdout; // If this is set to 1, the stdout will be flushed when data was written to the screen during a process_608 call.
int line_terminator_lf; // 0 = CRLF, 1=LF
int frame_terminator_0; // 0 = frames terminated by line_terminator_lf, 1 = frames terminated by \0
LLONG subs_delay; // ms to delay (or advance) subs
int program_number;
unsigned char in_format;
Expand Down
11 changes: 11 additions & 0 deletions src/lib_ccx/ccx_encoders_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,17 @@ struct encoder_ctx *init_encoder(struct encoder_cfg *opt)

ctx->encoded_br_length = encode_line(ctx, ctx->encoded_br, (unsigned char *)"<br>");

if (opt->frame_terminator_0)
{
ctx->encoded_end_frame[0] = '\0';
ctx->encoded_end_frame_length = 1;
}
else
{
memcpy(ctx->encoded_end_frame, ctx->encoded_crlf, ctx->encoded_crlf_length + 1);
ctx->encoded_end_frame_length = ctx->encoded_crlf_length;
}

for (i = 0; i < ctx->nb_out; i++)
write_subtitle_file_header(ctx, ctx->out + i);

Expand Down
2 changes: 2 additions & 0 deletions src/lib_ccx/ccx_encoders_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ struct encoder_ctx
unsigned int encoded_crlf_length;
unsigned char encoded_br[16];
unsigned int encoded_br_length;
unsigned char encoded_end_frame[16];
unsigned int encoded_end_frame_length;

// MCC File
int header_printed_flag;
Expand Down
10 changes: 5 additions & 5 deletions src/lib_ccx/ccx_encoders_transcript.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ int write_cc_bitmap_as_transcript(struct cc_subtitle *sub, struct encoder_ctx *c
}
}

write_wrapped(context->out->fh, context->encoded_crlf, context->encoded_crlf_length);
write_wrapped(context->out->fh, context->encoded_end_frame, context->encoded_end_frame_length);
}
}
#endif
Expand Down Expand Up @@ -200,8 +200,8 @@ int write_cc_subtitle_as_transcript(struct cc_subtitle *sub, struct encoder_ctx
mprint("Warning:Loss of data\n");
}

ret = write(context->out->fh, context->encoded_crlf, context->encoded_crlf_length);
if (ret < context->encoded_crlf_length)
ret = write(context->out->fh, context->encoded_end_frame, context->encoded_end_frame_length);
if (ret < context->encoded_end_frame_length)
{
mprint("Warning:Loss of data\n");
}
Expand Down Expand Up @@ -322,8 +322,8 @@ void write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx
mprint("Warning:Loss of data\n");
}

ret = write(context->out->fh, context->encoded_crlf, context->encoded_crlf_length);
if (ret < context->encoded_crlf_length)
ret = write(context->out->fh, context->encoded_end_frame, context->encoded_end_frame_length);
if (ret < context->encoded_end_frame_length)
{
mprint("Warning:Loss of data\n");
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib_ccx/params.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ void print_usage(void)
mprint(" to the output file.\n");
mprint(" --lf: Use LF (UNIX) instead of CRLF (DOS, Windows) as line\n");
mprint(" terminator.\n");
mprint(" --null-terminated: Use \\0 instead of CRLF or LF for frame termination (see '--lf').\n");
mprint(" e.g use '--txt --stdout --null-terminated' when piping to\n");
mprint(" 'websocat -0' (https://github.com/vi/websocat)\n");
mprint(" --df: For MCC Files, force dropframe frame count.\n");
mprint(" --autodash: Based on position on screen, attempt to determine\n");
mprint(" the different speakers and a dash (-) when each\n");
Expand Down
3 changes: 3 additions & 0 deletions src/rust/lib_ccxr/src/common/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ impl Default for EncoderConfig {
no_type_setting: false,
cc_to_stdout: false,
line_terminator_lf: false,
frame_terminator_0: false,
subs_delay: Timestamp::default(),
program_number: 0,
in_format: 1,
Expand Down Expand Up @@ -324,6 +325,8 @@ pub struct EncoderConfig {
pub cc_to_stdout: bool,
/// false = CRLF, true = LF
pub line_terminator_lf: bool,
/// false = frames terminated by line_terminator_lf, true = frames terminated by \0
pub frame_terminator_0: bool,
/// ms to delay (or advance) subs
pub subs_delay: Timestamp,
pub program_number: u32,
Expand Down
3 changes: 3 additions & 0 deletions src/rust/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,9 @@ pub struct Args {
/// terminator.
#[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)]
pub lf: bool,
/// Use \0 instead of CRLF or LF for frame termination (see '--lf')
#[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)]
pub null_terminated: bool,
/// For MCC Files, force dropframe frame count.
#[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)]
pub df: bool,
Expand Down
1 change: 1 addition & 0 deletions src/rust/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ impl CType<encoder_cfg> for EncoderConfig {
no_type_setting: self.no_type_setting as _,
cc_to_stdout: self.cc_to_stdout as _,
line_terminator_lf: self.line_terminator_lf as _,
frame_terminator_0: self.frame_terminator_0 as _,
subs_delay: self.subs_delay.millis(),
program_number: self.program_number as _,
in_format: self.in_format,
Expand Down
1 change: 1 addition & 0 deletions src/rust/src/ctorust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ impl FromCType<encoder_cfg> for EncoderConfig {
no_type_setting: cfg.no_type_setting != 0,
cc_to_stdout: cfg.cc_to_stdout != 0,
line_terminator_lf: cfg.line_terminator_lf != 0,
frame_terminator_0: cfg.frame_terminator_0 != 0,
subs_delay: Timestamp::from_millis(cfg.subs_delay),
program_number: cfg.program_number as u32,
in_format: cfg.in_format,
Expand Down
4 changes: 4 additions & 0 deletions src/rust/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,10 @@ impl OptionsExt for Options {
self.enc_cfg.line_terminator_lf = true;
}

if args.null_terminated {
self.enc_cfg.frame_terminator_0 = true;
}

if args.df {
self.enc_cfg.force_dropframe = true;
}
Expand Down
Loading