mirror of
https://github.com/shaka-project/shaka-packager.git
synced 2026-04-02 19:30:21 +00:00
I've finally generated test material and tests to make a PR to fix text segment generation for MPEG-2 TS streams with sparse teletext data, making a big improvement compared to the original teletext support in #1344. ## Problem When packaging MPEG-TS input containing DVB-Teletext subtitles for DASH/HLS output, two fundamental issues arise: 1. **Sparse input handling** - Teletext streams only contain data when subtitles are displayed. During gaps (which can span multiple segments), no PES packets arrive, leaving the text chunker with no timing information to drive segment generation. This results in missing segments or segments with incorrect timing. 2. **Misaligned segment boundaries** - Even when segments are generated, the text segment timestamps and boundaries differ from video/audio segments. This causes `<SegmentTimeline>` mismatches in the MPD, playback issues on some players, and sometimes fewer text segments than video segments. ## Solution This PR introduces two complementary mechanisms: ### 1. Heartbeat mechanism (sparse input handling) The `Mp2tMediaParser` now sends periodic "heartbeat" signals to text streams: - Video PTS timestamps are forwarded to all text PIDs as `MediaHeartBeat` samples - `EsParserTeletext` emits `TextHeartBeat` samples when PES packets arrive without displayable content - `TextChunker` uses these heartbeats to drive segment generation even during gaps in subtitle content - Ongoing cues that span segment boundaries are properly split and continued A new `heartbeat_shift` stream descriptor parameter (default: 2 seconds at 90kHz) controls the timing offset between video PTS and text segment generation, compensating for pipeline processing delays. ### 2. SegmentCoordinator (segment boundary alignment) A new N-to-N media handler (`SegmentCoordinator`) ensures text segments align precisely with video: - Passes all streams through unchanged - Replicates `SegmentInfo` from video/audio `ChunkingHandler` to registered teletext streams - `TextChunker` in "coordinator mode" uses received `SegmentInfo` events to determine segment boundaries instead of calculating from text timestamps This guarantees identical segment timelines across all adaptation sets. ## Testing - **Integration tests** in `packager_test.cc`: - `TeletextSegmentAlignmentTest.VideoAndTextSegmentsAligned` - Verifies segment count, start times, and durations match between video and text - `TeletextSegmentAlignmentTest.VideoAndTextSegmentsAlignedWithWrapAround` - Same verification with PTS timestamps near the 33-bit wrap-around point (~26.5 hours) - **Test files** (synthetic teletext with known cue timings at 1.0s, 3.5s, 13.0s): - `test_teletext_live.ts` - Normal PTS range - `test_teletext_live_wrap.ts` - PTS near wrap-around boundary - **Unit tests** for `SegmentCoordinator` and updated `TextChunker` tests ## Documentation - Extended `docs/source/tutorials/text.rst` with DVB-Teletext section covering: - Page numbering (3-digit cc_index format) - Heartbeat mechanism explanation - Segment alignment behavior - `--ts_ttx_heartbeat_shift` parameter tuning - Troubleshooting guide - Added teletext processing pipeline diagram to `docs/source/design.rst` ## Future work The heartbeat and `SegmentCoordinator` mechanisms would likely benefit **DVB-SUB (bitmap subtitles)** as well (Issue #1477) , which faces similar challenges with sparse subtitle data in MPEG-TS input and segment alignment. The infrastructure is now in place to extend this support. ## Example usage ```bash packager \ --segment_duration 6 \ --mpd_output manifest.mpd \ 'in=input.ts,stream=video,init_segment=video/init.mp4,segment_template=video/$Number$.m4s' \ 'in=input.ts,stream=audio,init_segment=audio/init.mp4,segment_template=audio/$Number$.m4s' \ 'in=input.ts,stream=text,cc_index=888,lang=en,init_segment=text/init.mp4,segment_template=text/$Number$.m4s,dash_only=1' ``` Fixes #1428 Fixes #1401 Fixes #1355 Fixes #1430