hozuki / MonoGame.Extended2

A collection of extensions for MonoGame
BSD 3-Clause Clear License
38 stars 8 forks source link

Error on looped video in Demo #3

Open Kabaril opened 5 years ago

Kabaril commented 5 years ago

I ran the VideoPlayback.DesktopGL Demo, with the VideoPlayer on loop, after a couple minutes it threw an ApplicationException in VideoPlayer.DecodingThread on line 98, with the message: Cannot access disposed object

hozuki commented 5 years ago

Looks like a rare racing condition. I'll look into this.

BrianBergh commented 4 years ago

I too get a nasty exception when looping or restarting. Its random but i get it every 2 or 3 loops no matter the video source. Its a pointer exception related to a buffer in audio, it says.

hozuki commented 4 years ago

@BrianBergh I tested multiple times and this problem did occur, but it's rare. It seems sometimes dstData[0] (in FFmpegHelper.TransmitAudioFrame) sometimes gets null from av_samples_alloc or swr_convert. I don't know which one because after I set the breakpoint the bug just hid itself. 😞 Needs more testing though. However the bug is not the same as what OP reported.

BrianBergh commented 4 years ago

This is the exception i get (i get it every time i set loop to true) System.NullReferenceException HResult=0x80004003 Message=Object reference not set to an instance of an object. Source=MonoGame.Framework StackTrace: at Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance.OnBufferEnd(IntPtr obj) at SharpDX.XAudio2.SourceVoice.VoiceCallbackImpl.SharpDX.XAudio2.VoiceCallback.OnBufferEnd(IntPtr context) at SharpDX.XAudio2.VoiceShadow.VoiceVtbl.OnBufferEndImpl(IntPtr thisObject, IntPtr address)

hozuki commented 4 years ago

Does this still happen using new looping mechanism?

BrianBergh commented 4 years ago

Nope, didn't know there were any changes to the subject. Will test it as soon as possible.

BrianBergh commented 4 years ago

I am unable to start the test project WindowsDX, i get this exception: System.EntryPointNotFoundException: 'Could not find the entrypoint for avformat_alloc_context.' I have copied the ffmpeg dll's, still it wont work.

hozuki commented 4 years ago

I am unable to start the test project WindowsDX, i get this exception: System.EntryPointNotFoundException: 'Could not find the entrypoint for avformat_alloc_context.' I have copied the ffmpeg dll's, still it wont work.

Maybe because of dll not found or version mismatch?

BrianBergh commented 4 years ago

Hi, after updating the nuget package "FFmpeg.AutoGen" it all worked :)

BrianBergh commented 4 years ago

Hi Hozuki. Loop seems a lot more stable now, however, when using the "Replay()" function a few times, i got this exception: vx_exception

After retrying a few times, i got this exception: vx_exception2

at Microsoft.Xna.Framework.Audio.DynamicSoundEffectInstance.SubmitBuffer(Byte[] buffer) at MonoGame.Extended.VideoPlayback.DecodeContext.ReadAudioUntilPlaybackIsAfter(DynamicSoundEffectInstance sound, Double presentationTime) in D:\Development\DotNet\ext_git\MonoGame.Extended2\Sources\MonoGame.Extended.VideoPlayback\DecodeContext.cs:line 548 at MonoGame.Extended.Framework.Media.VideoPlayer.DecodingThread.ThreadProc() in D:\Development\DotNet\ext_git\MonoGame.Extended2\Sources\MonoGame.Extended.VideoPlayback\Media\VideoPlayer.DecodingThread.cs:line 119

I don't care about the Replay() function, but it seems that the exception i get from the Replay() is the same i saw in "Loop" mode earlier.

I will continue to test the loop, to see if that can be provoked to produce the exception as well.

hozuki commented 4 years ago

The ObjectDisposedException is caused by accessing _soundEffectInstance in both main thread and decoding thread without "single access" guarantee. It should be fixed in 9baac981d52e76e7bf811a345b2847fb9c625677. (But pessimistic locking spreads everywhere, which may have a little impact on performance. Since the decoding thread is properly terminated in Replay(), you can consider removing those locks and leaving sound-related properties non-thread-safe in exchange of performance.)

And you are right. Looping was emulated by calling Replay() when the video ends.

About duplicate key, do you more information on the exception?

BrianBergh commented 4 years ago

Hi Hozuki. I thought so :)

Here is a more detailed exception on the "Key already exists" at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.SortedList2.Add(TKey key, TValue value) at MonoGame.Extended.VideoPlayback.Extensions.SortedListExtensions.Enqueue[TKey,TValue](SortedList2 list, TKey key, TValue value) in D:\Development\DotNet\ext_git\MonoGame.Extended2\Sources\MonoGame.Extended.VideoPlayback\Extensions\SortedList`2Extensions.cs:line 19 at MonoGame.Extended.VideoPlayback.DecodeContext.TryFetchVideoFrames(Int32 count) in D:\Development\DotNet\ext_git\MonoGame.Extended2\Sources\MonoGame.Extended.VideoPlayback\DecodeContext.cs:line 746 at MonoGame.Extended.VideoPlayback.DecodeContext.ReadVideoUntilPlaybackIsAfter(Double presentationTime) in D:\Development\DotNet\ext_git\MonoGame.Extended2\Sources\MonoGame.Extended.VideoPlayback\DecodeContext.cs:line 407 at MonoGame.Extended.Framework.Media.VideoPlayer.DecodingThread.ThreadProc() in D:\Development\DotNet\ext_git\MonoGame.Extended2\Sources\MonoGame.Extended.VideoPlayback\Media\VideoPlayer.DecodingThread.cs:line 122

vx_exception3

vx_exception4

Its actually easy to reproduce, start a longer video that the rabit one, and press R a few times.

BrianBergh commented 4 years ago

Hi again. Not sure if my previous post had code aligned, but this is from the latest head: vx_exception5

BrianBergh commented 4 years ago

Hi, i've just tested with a simple (but not necessary the best) solution: vx_exception6

It does the trick, now i can SPAM Replay as much as i like, without any issues :)

hozuki commented 4 years ago

@BrianBergh Thank you. I pushed the commit which fixes

BrianBergh commented 4 years ago

Great, thank you @hozuki :)