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
20 changes: 20 additions & 0 deletions src/lib_ccx/ccx_decoders_608.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ ccx_decoder_608_context *ccx_decoder_608_init_library(struct ccx_decoder_608_set
data->my_channel = channel;
data->have_cursor_position = 0;
data->rollup_from_popon = 0;
data->ts_first_char_rollup_transition = -1;
data->output_format = output_format;
data->cc_to_stdout = cc_to_stdout;
data->textprinted = 0;
Expand Down Expand Up @@ -246,6 +247,12 @@ void write_char(const unsigned char c, ccx_decoder_608_context *context)
context->cursor_column++;
if (context->ts_start_of_current_line == -1)
context->ts_start_of_current_line = get_fts(context->timing, context->my_field);
// First char after a pop-on -> roll-up transition: remember its FTS so
// write_cc_buffer can use it if EOF fires before a scrolling CR.
// Unlike ts_start_of_current_line, this field is NOT touched by
// intermediate CR commands (changes=0 CRs overwrite ts_start_of_current_line).
if (context->rollup_from_popon && context->ts_first_char_rollup_transition == -1)
context->ts_first_char_rollup_transition = get_fts(context->timing, context->my_field);
context->ts_last_char_received = get_fts(context->timing, context->my_field);
}
}
Expand Down Expand Up @@ -311,6 +318,17 @@ int write_cc_buffer(ccx_decoder_608_context *context, struct cc_subtitle *sub)
context->ts_start_of_current_line != -1)
context->current_visible_start_ms = context->ts_start_of_current_line;

// Pop-on -> roll-up transition that never saw a scrolling CR (e.g. EOF
// with fewer lines than the roll-up window). The CR handler never ran,
// so back-fill current_visible_start_ms from the first-char FTS instead
// of emitting a caption starting at 0.
if (context->rollup_from_popon && context->ts_first_char_rollup_transition > 0)
{
context->current_visible_start_ms = context->ts_first_char_rollup_transition;
context->rollup_from_popon = 0;
context->ts_first_char_rollup_transition = -1;
}

start_time = context->current_visible_start_ms;
end_time = get_visible_end(context->timing, context->my_field);
sub->type = CC_608;
Expand Down Expand Up @@ -758,6 +776,7 @@ void handle_command(unsigned char c1, const unsigned char c2, ccx_decoder_608_co
// Start time will be set when CR causes scrolling (matching FFmpeg behavior)
context->rollup_from_popon = 1;
context->ts_start_of_current_line = -1;
context->ts_first_char_rollup_transition = -1;
}
erase_memory(context, false);

Expand Down Expand Up @@ -817,6 +836,7 @@ void handle_command(unsigned char c1, const unsigned char c2, ccx_decoder_608_co
{
context->current_visible_start_ms = context->ts_start_of_current_line;
context->rollup_from_popon = 0;
context->ts_first_char_rollup_transition = -1;
}

// Only if the roll up would actually cause a line to disappear we write the buffer
Expand Down
1 change: 1 addition & 0 deletions src/lib_ccx/ccx_decoders_608.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ typedef struct ccx_decoder_608_context
int my_field; // Used for sanity checks
int my_channel; // Used for sanity checks
int rollup_from_popon; // Track transition from pop-on/paint-on to roll-up mode
LLONG ts_first_char_rollup_transition; // FTS of first char after pop-on -> roll-up (EOF fallback when no scrolling CR fires). -1 if unset.
int64_t bytes_processed_608; // To be written ONLY by process_608
int have_cursor_position;

Expand Down
Loading