From 6b4a8a94f640dbeff47b059955a4f45529d07555 Mon Sep 17 00:00:00 2001 From: Chandragupt Singh Date: Mon, 10 Aug 2026 01:08:46 +0530 Subject: [PATCH 1/2] fix(608): guard transcript CR-time anchor in pop-on to roll-up transition In the pop-on -> roll-up transition with changes==0 (roll-up window not yet full), only set ts_start_of_current_line to the CR time when in transcript mode. SRT leaves it for write_char()'s existing == -1 guard to set on the first character typed, which is what the SRT reference corpus anchors to. Fixes a 133 ms transcript timing regression on RT29/RT30 introduced by the earlier condition flip, while preserving the RT84 fix. --- src/lib_ccx/ccx_decoders_608.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib_ccx/ccx_decoders_608.c b/src/lib_ccx/ccx_decoders_608.c index 5147e5865..88019ab39 100644 --- a/src/lib_ccx/ccx_decoders_608.c +++ b/src/lib_ccx/ccx_decoders_608.c @@ -854,7 +854,10 @@ void handle_command(unsigned char c1, const unsigned char c2, ccx_decoder_608_co // not the character typing time. This matches FFmpeg's timing behavior. if (context->rollup_from_popon && !changes) { - context->ts_start_of_current_line = get_fts(context->timing, context->my_field); + // Transcript: anchor to CR time for the next write_cc_line(). + // SRT: preserve first-char time already set by write_char() for cvm at changes=1. + if (context->output_format == CCX_OF_TRANSCRIPT) + context->ts_start_of_current_line = get_fts(context->timing, context->my_field); } else { From 1782e17e8ceca232d8ab76bc5add0bc2f563c7bb Mon Sep 17 00:00:00 2001 From: Chandragupt Singh Date: Mon, 10 Aug 2026 01:08:54 +0530 Subject: [PATCH 2/2] fix(transcript): skip encoded_end_frame when write_cc_line_as_transcript2 writes nothing 03ad9e8e refactored write_cc_buffer_as_transcript2 to write encoded_end_frame at the end of each caption block. It set wrote_something = 1 unconditionally after calling write_cc_line_as_transcript2, even when that function returned without writing anything (blank cursor row, length = 0). Result: a bare newline (encoded_end_frame) was emitted for every blank cursor row, producing spurious blank lines in transcript output. Fix: change write_cc_line_as_transcript2 from void to int (returns 1 if it wrote, 0 if not) and use wrote_something |= to only set the flag when content was actually emitted. Fixes RT41 blank line regression introduced by PR #2105. --- src/lib_ccx/ccx_encoders_common.h | 2 +- src/lib_ccx/ccx_encoders_transcript.c | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib_ccx/ccx_encoders_common.h b/src/lib_ccx/ccx_encoders_common.h index d2b87cee6..be82c38ca 100644 --- a/src/lib_ccx/ccx_encoders_common.h +++ b/src/lib_ccx/ccx_encoders_common.h @@ -238,7 +238,7 @@ void write_cc_buffer_to_gui(struct eia608_screen *data, struct encoder_ctx *cont int write_cc_buffer_as_g608(struct eia608_screen *data, struct encoder_ctx *context); int write_cc_buffer_as_transcript2(struct eia608_screen *data, struct encoder_ctx *context); -void write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx *context, int line_number); +int write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx *context, int line_number); int write_cc_subtitle_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context); int write_cc_subtitle_as_ssa(struct cc_subtitle *sub, struct encoder_ctx *context); diff --git a/src/lib_ccx/ccx_encoders_transcript.c b/src/lib_ccx/ccx_encoders_transcript.c index 3e13652cf..b98e7ea85 100644 --- a/src/lib_ccx/ccx_encoders_transcript.c +++ b/src/lib_ccx/ccx_encoders_transcript.c @@ -236,7 +236,7 @@ int write_cc_subtitle_as_transcript(struct cc_subtitle *sub, struct encoder_ctx } // TODO Convert CC line to TEXT format and remove this function -void write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx *context, int line_number) +int write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx *context, int line_number) { int ret = 0; int length = get_str_basic(context->subline, data->characters[line_number], @@ -255,7 +255,7 @@ void write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx // is set for example by the write_char function, it possible that we don't have one in empty lines (unclear) // For now, let's not consider this a bug as before and just return. // fatal (EXIT_BUG_BUG, "Bug in timedtranscript (ts_start_of_current_line==-1). Please report."); - return; + return 0; } if (context->transcript_settings->showStartTime) @@ -333,7 +333,9 @@ void write_cc_line_as_transcript2(struct eia608_screen *data, struct encoder_ctx { mprint("Warning:Loss of data\n"); } + return 1; } + return 0; // fprintf (wb->fh,encoded_crlf); } @@ -356,8 +358,7 @@ int write_cc_buffer_as_transcript2(struct eia608_screen *data, struct encoder_ct } } - write_cc_line_as_transcript2(data, context, i); - wrote_something = 1; + wrote_something |= write_cc_line_as_transcript2(data, context, i); } }