Skip to content

scc/writer: delay colliding pop-on captions instead of dropping them - #548

Open
jason-valenzuela wants to merge 1 commit into
sandflow:masterfrom
jason-valenzuela:fix/scc-writer-delay-not-drop
Open

scc/writer: delay colliding pop-on captions instead of dropping them#548
jason-valenzuela wants to merge 1 commit into
sandflow:masterfrom
jason-valenzuela:fix/scc-writer-delay-not-drop

Conversation

@jason-valenzuela

@jason-valenzuela jason-valenzuela commented Sep 1, 2026

Copy link
Copy Markdown

Problem

scc_writer.from_model silently drops whole pop-on captions when a caption's line-21 packets cannot be transmitted back-to-back with the previous caption's (the Skipping ISD … due to overlap in line 21 packets path). On dense content this loses caption text with only a log warning.

Fix

When a pop-on caption collides with the previous one, delay its onset to sit right after the previous caption's packets instead of dropping it, carrying the preceding erase (EDM) into the delayed chunk so no stale erase wipes it and the emitted timecodes stay monotonic and non-overlapping. The pull-back of the preceding erase is bounded to the minimum needed, so the previous caption keeps as much of its authored on-screen time as possible (and an author-written short cue is never itself penalised). A caption that still cannot achieve a minimum readable window even after delaying is dropped honestly (the existing warning) rather than emitted as a two-frame flash.

The minimum readable window is exposed as a new SccWriterConfiguration field min_popon_display_frames (default 15 ≈ 0.5 s at 29.97 fps; 0 disables dropping entirely, preserving maximal text at the cost of possible flashes). The common, non-colliding path is unchanged — existing golden-SCC tests are untouched.

Tests

  • test_dense_popon_no_line_drop — dense captions previously dropped now survive a write→read round-trip (exact SCC asserted)
  • test_dense_popon_emitted_scc_is_ordered — emitted timecodes monotonic and non-overlapping
  • test_dense_popon_cascade_all_emitted_captions_displayable — every emitted caption meets the display floor
  • test_dense_popon_authored_short_prev_not_dropped — a short authored cue no longer forces an unnecessary drop
  • test_dense_popon_drop_only_when_infeasible — a caption is dropped only when no readable window exists
  • test_dense_popon_erase_pullback — the bounded erase pull-back path (erase moved minimally, both captions keep a window above the floor)
  • test_min_popon_display_frames — config parse/default/validation

Full suite: 617 passed, 0 failures, 0 errors, 6 pre-existing skips.

Notes

  • Unrelated pre-existing bug noticed nearby (not addressed here): from_model indexes chunks[-2] under a len(chunks) > 0 guard, which raises IndexError when exactly one chunk exists — happy to file a separate issue.

@jason-valenzuela
jason-valenzuela force-pushed the fix/scc-writer-delay-not-drop branch 5 times, most recently from 1113d90 to d917292 Compare September 1, 2026 21:52
@palemieux

Copy link
Copy Markdown
Contributor

@jason-valenzuela I would be tempted to wait until all chunks are collected before moving them.

@jason-valenzuela
jason-valenzuela marked this pull request as ready for review September 1, 2026 22:01
@jason-valenzuela

Copy link
Copy Markdown
Author

@jason-valenzuela I would be tempted to wait until all chunks are collected before moving them.

Got it! Will adjust my approach here.

@jason-valenzuela
jason-valenzuela force-pushed the fix/scc-writer-delay-not-drop branch from d917292 to f9bce80 Compare September 2, 2026 15:29
@jason-valenzuela

Copy link
Copy Markdown
Author

@palemieux Updated the approach here, let me know what you think! The chunk-moving logic is now run after the all the pop-on chunks are collected.

@palemieux palemieux left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the issue happening with content that was originally authored for 608, or content that was authored in other formats?

Comment thread src/main/python/ttconv/scc/writer.py Outdated
# pop-on captions are collected here at their natural (undelayed) positions and
# line 21 collisions are resolved in a post-pass below, once the whole list is
# known: (enm chunk, its erase chunk or None, caption begin time)
popon_captions: List = []

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why create a popon_captions list when chunks could be sufficient?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the intermediate list to keep each caption's (paint, erase) pair and its begin explicit for the delay pass and the warning. But I can build the paint/erase chunks straight into chunks in the loop and run the collision pass over chunks directly, pairing them there, and remove the extra list.

Comment thread src/main/python/ttconv/scc/config.py Outdated

return decoded_value

def _decode_min_popon_display_frames(value: str) -> int:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure there is every a correct value here since the duration of a caption is related to the amount of text present. I would define a simply boolean (by default true) that indicates whether overlapping captions should be dropped.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, will switch this over to a boolean config!

@jason-valenzuela

Copy link
Copy Markdown
Author

Is the issue happening with content that was originally authored for 608, or content that was authored in other formats?

This issue is happening for content that was authored in other formats! I've been seeing this issue when we're doing VTT -> SCC conversions.

@jason-valenzuela
jason-valenzuela force-pushed the fix/scc-writer-delay-not-drop branch from f9bce80 to 9beb6f2 Compare September 2, 2026 21:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants