Repository navigation
player: a film ends on the pipeline's end-of-stream - #865
Merged
Merged
Conversation
The player tore itself down at the credits only once the playhead came within a second of the container's duration. That duration is the longest track's: on the C1, a film whose audio ran 3 s past its last video frame pushed the EOS when the video lane drained, the pipeline refused the remaining audio, its clock stopped at 5894 s of 5897 s, and the player sat on the last frame for good. The pipeline had said `type=28 num=1 str=true` (ENDOFSTREAM, 0x1c) at that moment. That event, after a picture, now marks the stream played out alongside the arithmetic. A seek and a new session clear it. Signed-off-by: Tiago <1698241+tiper@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Oct 22, 2026
GLinnik21
added a commit
that referenced
this pull request
Oct 22, 2026
#865 ended a film on the pipeline's own end-of-stream (`type=28`) after a picture, because a film whose audio runs past its last video frame never gets its playhead within a second of the container's duration (the longest track's) and sat on the last frame for good. Nothing in the pipeline tier could see that: every clip it plays has picture and audio ending together. make_fixtures.py gets `pipe_h264_ac3_audio_tail`: 720x480 H.264 + AC-3 5.1, 20 s of picture and 23 s of audio. The knob is one declarative key, `audio_tail_s`, with `duration` staying the container's length so the duration check, the burned-in layout and the carried-forward records all keep agreeing with the file; only the testsrc2 input ends early. verify() reads both streams' last packet times back out of the finished file and fails the build unless the audio ends at least 2 s after the video, so a regenerated clip that lost the tail cannot pass quietly. The manifest gets `pipe_finish_audio_tail`, graded like `pipe_finish_eos` (`reaches_eos`) and separate from it for the same reason the replay case is: ending on the pipeline's word and ending on the playhead are different failures. The harness rule that only a `reaches_eos` case may name a clip that runs out no longer assumes one such clip; a static test also pins each such clip against the 0.6 x run_secs bound that _resolve_fixtures skips on. The prose that said `EOS reached` needs the playhead within a second of the duration, and that a truncated transfer cannot reach it, is corrected in tests/README.md and `a_finished`'s docstring. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
GLinnik21
added a commit
that referenced
this pull request
Oct 22, 2026
#865 made a film end on the pipeline's own end-of-stream (type=28), but the simulator's HostSink never sent one: its clock stops at the last fed VIDEO pts, so a film whose audio outlasts its video hung there exactly as on the television, and #865's arm could not fire. sf_push_eos now latches the push; once the clock has played out to the last fed video frame, the ticker sends type=28 num=1 str=true through the real callback, once per pushed EOS. The latch is cleared wherever the fed timeline restarts (Clock::rewind, sf_seek_ms). Clock::tick is split out of the ticker thread so a test can take a tick on its own thread. A hostsim regression test drives the real feed lanes and the real pump against HostSink (video to 20 s, audio to 23 s, duration 23 s) and asserts player::ended(); it also grades that nothing is sent before an EOS is pushed. Sink-level tests grade the latch. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before: a film whose audio runs more than a second past its last video frame never leaves the player. The EOS is pushed when the video lane drains, the pipeline refuses the remaining audio, its clock stops short of the container's duration, and the player sits on the last frame for good because
endedwaits for the playhead to come within a second of that duration.After: the pipeline's own end-of-stream event (
type=28,PF_EVENT_TYPE_STR_STATE_UPDATE__ENDOFSTREAM, 0x1c,str=true) received after a picture marks the stream played out alongside the existing arithmetic, so the player closes at the credits. A seek and a new session clear it.0x1c sits exactly at the point where the event numbering shifts between webOS 4 and 5+, so
28means the same on both (docs/webos5-port.md§5 is updated to say so).How: a
pipeline_eosflag onShared, raised insf_on_event_inneronly onceseen_frameis set, cleared byreset_sessionandrequest_seek; the pump's EOS check becomes a purestream_ended(pos, duration, pipeline_eos). Two new tests: the callback raises the flag only after a picture and a seek clears it, and the pure check ends a film 3 s short of its duration when the pipeline said so.Device evidence (LG C1, webOS 6.5.3, a 4K AV1 file whose audio ends 3 s after its last video frame). Before, the clock stopped at 5894 s of 5897 s and the player stayed on the last frame:
With this change, same file, same spot:
cargo test --lib -p plx_media: 1688 passed, 0 failed.