Open Kabaril opened 5 years ago
Looks like a rare racing condition. I'll look into this.
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.
@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.
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)
Does this still happen using new looping mechanism?
Nope, didn't know there were any changes to the subject. Will test it as soon as possible.
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.
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?
x86
and/or x64
(names depend on arguments of InitializeFFmpeg()
).FFmpeg.AutoGen
to a newer version, and choose corresponding FFmpeg dlls. Anyway, the versions must match. See FFmpeg's versioning rules.Hi, after updating the nuget package "FFmpeg.AutoGen" it all worked :)
Hi Hozuki. Loop seems a lot more stable now, however, when using the "Replay()" function a few times, i got this exception:
After retrying a few times, i got this exception:
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.
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?
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](SortedList
2 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
Its actually easy to reproduce, start a longer video that the rabit one, and press R a few times.
Hi again. Not sure if my previous post had code aligned, but this is from the latest head:
Hi, i've just tested with a simple (but not necessary the best) solution:
It does the trick, now i can SPAM Replay as much as i like, without any issues :)
@BrianBergh Thank you. I pushed the commit which fixes
Stop()
Great, thank you @hozuki :)
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