Skip to content
Merged
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.7 (unreleased)
-------------------
- New: Allow output \0 terminated frames via --null-terminated
- New: Added ASS/SSA \pos-based positioning for CEA-608 captions when layout is simple (1–2 rows) (#1726)
- Fix: Remove strdup() memory leaks in WebVTT styling encoder, fix invalid CSS rgba(0,256,0) green value, fix missing free(unescaped) on write-error path (#2154)
- Fix: Prevent crash in Rust timing module when logging out-of-range PTS/FTS timestamps from malformed streams.
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 @@ -843,6 +843,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
52 changes: 39 additions & 13 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 @@ -134,6 +134,7 @@ int write_cc_subtitle_as_transcript(struct cc_subtitle *sub, struct encoder_ctx

str = sub->data;

int wrote_something = 0;
str = strtok_r(str, "\r\n", &save_str);
do
{
Expand All @@ -143,6 +144,15 @@ int write_cc_subtitle_as_transcript(struct cc_subtitle *sub, struct encoder_ctx
continue;
}

if (wrote_something)
{
ret = write(context->out->fh, context->encoded_crlf, context->encoded_crlf_length);
if (ret < context->encoded_crlf_length)
{
mprint("Warning:Loss of data\n");
}
}

if (context->transcript_settings->showStartTime)
{
char buf[80];
Expand Down Expand Up @@ -200,14 +210,16 @@ 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)
{
mprint("Warning:Loss of data\n");
}
wrote_something = 1;

} while ((str = strtok_r(NULL, "\r\n", &save_str)));

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");
}

freep(&sub->data);
lsub = sub;
sub = sub->next;
Expand Down Expand Up @@ -321,29 +333,43 @@ 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)
{
mprint("Warning:Loss of data\n");
}
}
// fprintf (wb->fh,encoded_crlf);
}

int write_cc_buffer_as_transcript2(struct eia608_screen *data, struct encoder_ctx *context)
{
int ret;
int wrote_something = 0;
dbg_print(CCX_DMT_DECODER_608, "\n- - - TRANSCRIPT caption - - -\n");

for (int i = 0; i < 15; i++)
{
if (data->row_used[i])
{
if (wrote_something)
{
ret = write(context->out->fh, context->encoded_crlf, context->encoded_crlf_length);
if (ret < context->encoded_crlf_length)
{
mprint("Warning:Loss of data\n");
}
}

write_cc_line_as_transcript2(data, context, i);
wrote_something = 1;
}
wrote_something = 1;
}

if (wrote_something)
{
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");
}
}

dbg_print(CCX_DMT_DECODER_608, "- - - - - - - - - - - -\r\n");
return wrote_something;
}
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
6 changes: 4 additions & 2 deletions src/rust/src/decoder/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use log::{debug, warn};
pub struct Writer<'a> {
pub cea_708_counter: &'a mut u32,
pub subs_delay: LLONG,
pub crlf: String,
pub end_frame: Vec<u8>,
pub write_format: ccx_output_format,
pub writer_ctx: &'a mut dtvcc_writer_ctx,
pub no_font_color: bool,
Expand All @@ -25,6 +25,7 @@ pub struct Writer<'a> {

impl<'a> Writer<'a> {
/// Create a new writer context
#[allow(clippy::too_many_arguments)]
pub fn new(
cea_708_counter: &'a mut u32,
subs_delay: LLONG,
Expand All @@ -33,11 +34,12 @@ impl<'a> Writer<'a> {
no_font_color: i32,
transcript_settings: &'a ccx_encoders_transcript_format,
no_bom: i32,
encoded_end_frame: &[u8],
) -> Self {
Self {
cea_708_counter,
subs_delay,
crlf: "\r\n".to_owned(),
end_frame: encoded_end_frame.to_vec(),
write_format,
writer_ctx,
no_font_color: is_true(no_font_color),
Expand Down
4 changes: 4 additions & 0 deletions src/rust/src/decoder/service_decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,7 @@ impl dtvcc_service_decoder {
} else {
&ccx_encoders_transcript_format::default()
};
let end_frame = &encoder.encoded_end_frame[..encoder.encoded_end_frame_length as usize];
let mut writer = Writer::new(
&mut encoder.cea_708_counter,
encoder.subs_delay,
Expand All @@ -881,6 +882,7 @@ impl dtvcc_service_decoder {
encoder.no_font_color,
transcript_settings,
encoder.no_bom,
end_frame,
);
tv.writer_output(&mut writer).unwrap();
tv.clear();
Expand Down Expand Up @@ -1202,6 +1204,7 @@ impl dtvcc_service_decoder {
let sn = tv.service_number;
let writer_ctx = &mut encoder.dtvcc_writers[(sn - 1) as usize];

let end_frame = &encoder.encoded_end_frame[..encoder.encoded_end_frame_length as usize];
let mut writer = Writer::new(
&mut encoder.cea_708_counter,
encoder.subs_delay,
Expand All @@ -1210,6 +1213,7 @@ impl dtvcc_service_decoder {
encoder.no_font_color,
transcript_settings,
encoder.no_bom,
end_frame,
);
writer.write_done();
}
Expand Down
11 changes: 10 additions & 1 deletion src/rust/src/decoder/tv_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,13 @@ impl dtvcc_tv_screen {
let time_show = get_time_str(self.time_ms_show);
let time_hide = get_time_str(self.time_ms_hide);

let mut wrote_something = false;
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
if !self.is_row_empty(row_index) {
if wrote_something {
writer.write_to_file(b"\r\n")?;
}

let mut buf = String::new();

if is_true(writer.transcript_settings.showStartTime) {
Expand All @@ -350,9 +355,11 @@ impl dtvcc_tv_screen {
}
writer.write_to_file(buf.as_bytes())?;
self.write_row(writer, row_index, false)?;
writer.write_to_file(b"\r\n")?;
wrote_something = true;
}
}
let end_frame = writer.end_frame.clone();
writer.write_to_file(&end_frame)?;
Ok(())
}

Expand Down Expand Up @@ -800,6 +807,7 @@ mod test {
0,
&transcript_settings,
0,
b"\r\n",
);

// This should succeed without error (fd is valid, not -1)
Expand Down Expand Up @@ -835,6 +843,7 @@ mod test {
0,
&transcript_settings,
0,
b"\r\n",
);

// This should return an error, not panic
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 @@ -1257,6 +1257,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