Skip to content

Keep FFmpeg final teardown off the UI thread - #138

Draft
Blackspirits wants to merge 1 commit into
audit/ffmpeg-session-lifecycle-3e4dfrom
audit/ffmpeg-ui-teardown-background-af88
Draft

Blackspirits wants to merge 1 commit into
audit/ffmpeg-session-lifecycle-3e4dfrom
audit/ffmpeg-ui-teardown-background-af88

Conversation

@Blackspirits

@Blackspirits Blackspirits commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Purpose

Dependent lifetime/UI follow-up to #115 ("Harden FFmpeg session startup and teardown lifetime").

#115 made Session teardown fail closed when workers do not stop, but definitive VideoPlayerControl teardown still called FFmpeg CloseFile() synchronously on the UI thread before the existing background Dispose().

Current upstream SubtitleEdit/subtitleedit main was rechecked at d6917286e355976da953d0ee22208b4bf9461699; its latest change is unrelated and no open upstream PR was found for this boundary.

Finding fixed

For FFmpeg, CloseFile() calls Session.Dispose(). #115 safely joins demux, video, audio and presenter workers with a 5-second timeout per thread before releasing worker-visible resources.

VideoPlayerControl.CloseAndDisposePlayer() previously called Close() first, so a stuck worker could freeze layout rebuild, fullscreen/undock teardown or window close on the UI thread before execution ever reached the background Dispose already intended to protect UI responsiveness.

Fix

IVideoPlayer now has a default-false final-teardown capability, DeferCloseFileToDispose; only FFmpeg opts in.

During definitive teardown:

  • polling/autohide activity and visible closed-state UI are reset immediately;
  • deferred players skip synchronous CloseFile();
  • normal reusable Close() remains unchanged and synchronous;
  • FfmpegSoftwareControl explicitly relinquishes the player and unsubscribes FrameReady before content detach;
  • this prevents the render-host detach callback and VideoPlayerControl from scheduling concurrent Dispose calls;
  • VideoPlayerControl becomes the single background Dispose owner;
  • CloseAndDisposePlayer() itself is now idempotent, so repeated teardown cannot schedule a second Dispose.

Native mpv/VLC keep the old ordering because the capability defaults false.

Regression coverage

Tests pin that:

  • deferred final close runs through the background Dispose thread rather than the caller/UI thread;
  • reusable Close() still closes synchronously;
  • real FfmpegPlayer + FfmpegSoftwareControl teardown transfers disposal ownership before content removal;
  • repeated final teardown performs exactly one CloseFile/Dispose;
  • existing timer-stop, render-host detach, background-dispose and reusable-close behavior remains covered.

Scope / branch state

  • dependency/base PR: Harden FFmpeg session startup and teardown lifetime #115
  • base HEAD: af88aa7d7591721f6c509d5432f9a07d532bbeae
  • HEAD: 0db53f219c3e929752416e6dead7bdaca24b0def
  • 1 commit
  • 5 files
  • +140 / -10
  • current upstream main checked: d6917286e355976da953d0ee22208b4bf9461699
  • audit draft only; no merge/promotion intended

AI assistance: ChatGPT was used for adversarial teardown/thread-affinity review, render-host disposal ownership modelling, idempotency analysis and focused concurrency regression design.

Final CI

Authoritative run: SubtitleEdit#277 on 0db53f219c3e929752416e6dead7bdaca24b0def

  • SeConv: 488 passed / 2 skipped / 0 failed
  • LibUiLogic: 905 passed / 0 skipped / 0 failed
  • LibSE: 2017 passed / 0 skipped / 0 failed
  • UI: 5237 passed / 9 skipped / 0 failed
  • build: 0 errors / 7 pre-existing warnings
  • retry step skipped
  • failure-artifact upload skipped

Final adversarial review was performed on this exact HEAD after CI; no blocker found.

@Blackspirits
Blackspirits force-pushed the audit/ffmpeg-ui-teardown-background-af88 branch from a22d999 to 0db53f2 Compare September 15, 2026 20:45

@Blackspirits Blackspirits left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Final adversarial review on 0db53f219c3e929752416e6dead7bdaca24b0def after CI SubtitleEdit#277: no blocker found. Verified final teardown is exactly-once, FFmpeg render-host ownership is transferred before detach, normal reusable Close remains synchronous, an already-posted FrameReady can only invalidate a detached control and cannot retain the player, and mpv/VLC retain their existing ordering. No merge/promotion performed.

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.

1 participant