Interrupt blocked FFmpeg I/O when a load is closed or replaced - #99
Interrupt blocked FFmpeg I/O when a load is closed or replaced#99Blackspirits wants to merge 2 commits into
Conversation
Blackspirits
left a comment
There was a problem hiding this comment.
Independent adversarial re-check: the FFmpeg player accepts URLs unchanged and can block in avformat_open_input/find_stream_info/av_read_frame. The callback is installed on a preallocated AVFormatContext before open, uses a GCHandle-backed cancellation state that outlives native I/O, and is signalled by close/replacement before disposal. Real open failures remain logged while expected cancellation is quiet. FFmpeg's failure contract for a preallocated AVFormatContext is compatible with the cleanup path. Full CI #34779660270 passed restore, build and the complete suite on the first run; UITests reported 5,151 passed, 9 skipped, 0 failed. Retry was not used. Residual risk remains only if a protocol/driver ignores the interrupt callback; that is being handled separately rather than weakening this PR. Keep draft; no merge performed.
Blackspirits
left a comment
There was a problem hiding this comment.
Independent adversarial re-check: the player accepts URL-backed media unchanged, while FFmpeg open/stream-info/demux calls are blocking by default. The final patch installs AVIOInterruptCB before avformat_open_input, keeps callback state alive with GCHandle through avformat_close_input, cancels old load state before close/replacement, and distinguishes expected cancellation from real open failures. The stale-load generation gate from #95 remains the publication authority. Full CI #34779660270 passed restore, build and the complete suite on the first run; UITests reported 5,151 passed, 9 skipped, 0 failed. Retry was not used. No blocker identified in the callback lifetime/cancellation contract. Keep draft; no merge performed.
Summary
The FFmpeg player performs
avformat_open_input,avformat_find_stream_infoandav_read_frameon worker threads. FFmpeg I/O is blocking by default, whileSession.Disposecurrently gives workers 5 seconds to stop and then releases their native resources.A close/replacement therefore needs a way to interrupt blocking FFmpeg I/O, especially because
NativeMediaPath.ForMpvdeliberately leaves URLs unchanged and the player can receive network-backed media.This change, layered on the generation-safe load ownership from #95 and partial-construction cleanup from #98:
AVFormatContextand installsAVIOInterruptCBbeforeavformat_open_input, as required by FFmpeg for protocol-level interruption;GCHandle;avformat_close_input, then releases it;Evidence
FFmpeg documents
AVIOInterruptCBas the callback used to abort blocking I/O; returning 1 causes the blocked function to returnAVERROR_EXIT.AVFormatContext.interrupt_callbackis explicitly caller-supplied for demuxing and should be installed beforeavformat_open_input.Validation
IVideoPlayercontract changeAI assistance: ChatGPT was used to audit FFmpeg blocking-I/O teardown semantics and design the callback lifetime/cancellation contract.