ffmpeginteropx / FFmpegInteropX

FFmpeg decoding library for Windows 10 UWP and WinUI 3 Apps
Apache License 2.0
212 stars 53 forks source link

Disposing FFmpegMedisSource may block for a long period of time #323

Closed yikuo123 closed 2 years ago

yikuo123 commented 2 years ago
  1. Create a FFmpegMedisSource instance by FFmpegMediaSource.CreateFromUriAsync(uri)
  2. Play the media source
  3. Seek to any position, and when it is buffering call ffmpegMedisSource.Dispose()

It will block for an unknown period of time.

I don't know if it is for design, but it bothered me.

Workaround:

var ffmpegMedisSource = this.ffmpegMediaSource;
this.ffmpegMediaSource = null;
Task.Run(() => ffmpegMedisSource.Dispose());
lukasf commented 2 years ago

Streaming souces are usually divided into chunks of data. When seeking and the next sample is requested, the nearest chunk will be read by ffmpeg until the target position inside that chunk was found. It depends on the actual seek position inside the chunk how fast the desired sample is available. Our instance is locked during each sample read, so disposing will only happen after the first sample was read.

There might be a way to interrupt the ffmpeg internal reading. But we cannot simply access our instance without locking. So even if it is possible to interrupt ffmpeg, we'd have to introduce a different locking concept to make this work.

We are working on a new approach where the FFmpegMediaSource will be disposed automatically as soon as playback stops (#320). This is not finished yet, but if it works, you might not have to call Dispose at all. So I am not sure if it makes sense to put much work into faster disposing, when it might be unneccessary at all in future.

brabebhin commented 2 years ago

This is probably an issue with URI sources, local playback should be mostly fast enough. I don't think ffmpeg provides a cancel mechanism so that we can cancel seek or read operations.

lukasf commented 2 years ago

There is an AVIOInterruptCB on the AVFormatContext, which we can theoretically use to cancel long running operations. But I need to see if/how we can safely use it when our instance is locked.

lukasf commented 2 years ago

Hi @yikuo123, can you please check the branch "fast-dispose" to see if the behavior has been improved?

yikuo123 commented 2 years ago

Hi @yikuo123, can you please check the branch "fast-dispose" to see if the behavior has been improved?

OK, I'll have a try.

Thanks!

yikuo123 commented 2 years ago

@lukasf That's awesome! It works!

lukasf commented 2 years ago

Closing after merge of #325