Skip to content

Release detached FFmpeg seek frame on video-loop exit - #141

Draft
Blackspirits wants to merge 1 commit into
upl/review-base-3e4dfrom
audit/ffmpeg-last-dropped-release-3e4d
Draft

Blackspirits wants to merge 1 commit into
upl/review-base-3e4dfrom
audit/ffmpeg-last-dropped-release-3e4d

Conversation

@Blackspirits

@Blackspirits Blackspirits commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Purpose

Independent FFmpeg ownership follow-up to merged upstream PR SubtitleEdit#14878 on the common audited base 3e4d052adc78464e71bbd5154880d935fd592960.

This is a current-base revalidation/port of the previously-audited #94 finding. VideoLoop() keeps one converted seek frame in lastDropped outside VideoFrameQueue; if the loop exits or throws before a normal path consumes it, that unmanaged BGRA buffer becomes unreachable.

Current upstream SubtitleEdit/subtitleedit main was rechecked at d6917286e355976da953d0ee22208b4bf9461699; no relevant drift or open upstream PR was found.

Finding fixed

During seek decode, frames before the requested target are skipped while the most recent converted frame is retained in lastDropped, outside both the active queue and reusable pool.

Normal paths already return/push it and set it to null. The missing path was video-loop exit/exception while ownership was still detached. VideoFrame owns unmanaged memory and has no finalizer, so a 1080p retained frame can leak several megabytes.

Fix

  • move lastDropped to the full VideoLoop() lifetime;
  • return any still-owned detached frame from finally;
  • leave all normal transfer paths unchanged.

VideoFrameQueue.Return() disposes instead of repooling when the queue is already closed, so the finally path is safe on both normal and teardown exits.

Scope / branch state

AI assistance: ChatGPT was used to compare detached-frame ownership against the current FFmpeg stack, revalidate #94 and verify queue-close return semantics.

Final CI

Authoritative run: SubtitleEdit#280 on 4b6cb9ff2762facb2ae3dfb0c09937ef6af5f48d

  • SeConv: 488 passed / 2 skipped / 0 failed
  • LibUiLogic: 905 passed / 0 skipped / 0 failed
  • LibSE: 2017 passed / 0 skipped / 0 failed
  • UI: 5230 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 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 4b6cb9ff2762facb2ae3dfb0c09937ef6af5f48d after CI SubtitleEdit#280: no blocker found. lastDropped remains singly owned on every normal path; the finally only sees it when ownership is still detached. VideoFrameQueue.Return() disposes safely after queue shutdown, so teardown cannot repool a dead-session buffer. 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