diff --git a/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs index bb232ffa..e922e565 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs @@ -40,7 +40,7 @@ namespace Vocaluxe.Lib.Video.Acinerella private float _FrameDuration; // frame time in s private float _LastDecodedTime; // time of last decoded frame - private float _LastShownTime; // current video position + private float _LastShownTime; // time if the last shown frame in s private float _Time; private float _Gap; @@ -123,12 +123,6 @@ namespace Vocaluxe.Lib.Video.Acinerella public bool GetFrame(ref CTexture frame, float time, out float videoTime) { - if (_Paused) - { - videoTime = 0; - return false; - } - if (Loop) { lock (_MutexSyncSignals) @@ -137,17 +131,17 @@ namespace Vocaluxe.Lib.Video.Acinerella _LoopTimer.Restart(); } } - else if (Math.Abs(_SetTime - time) > float.Epsilon) + else if (Math.Abs(_SetTime - time) >= 1f / 1000f) //Check 1 ms difference { lock (_MutexSyncSignals) { _SetTime = time; } } - else + else if (Math.Abs(_LastShownTime - time) < 1f / 1000 && frame != null) //Check 1 ms difference { - videoTime = 0; - return false; //Check if this false is right. But should as we don't give a frame here + videoTime = _LastShownTime; + return true; } _UploadNewFrame(ref frame); videoTime = _LastShownTime; @@ -185,11 +179,6 @@ namespace Vocaluxe.Lib.Video.Acinerella } _LastDecodedTime = _SkipTime; - lock (_MutexSyncSignals) - { - _LastShownTime = _LastDecodedTime; - } - lock (_MutexFramebuffer) { _Framebuffer.Clear(); @@ -425,13 +414,15 @@ namespace Vocaluxe.Lib.Video.Acinerella float now = _SetTime + _Gap; float maxEnd = now - _FrameDuration * 2; //Get only frames younger than 2 CFrame frame; + bool paused = _Paused; while ((frame = _Framebuffer.Get()) != null) { float frameEnd = frame.Time + _FrameDuration; //Don't show frames that are shown during or after now if (frameEnd >= now) break; //All following frames are after that one - + if (paused) // Don't modify anything + break; _Framebuffer.SetRead(); //Get the last(newest) possible frame and skip the rest to force in-order showing if (frameEnd <= maxEnd) diff --git a/Vocaluxe/Lib/Video/IVideoDecoder.cs b/Vocaluxe/Lib/Video/IVideoDecoder.cs index 3731081b..72d12ecd 100644 --- a/Vocaluxe/Lib/Video/IVideoDecoder.cs +++ b/Vocaluxe/Lib/Video/IVideoDecoder.cs @@ -21,31 +21,94 @@ namespace Vocaluxe.Lib.Video { interface IVideoDecoder { + /// + /// Initializes videodecoder. Got to be called before usage + /// + /// True on success, false if something went wrong. bool Init(); + + /// + /// Close all video streams + /// void CloseAll(); + /// + /// Loads the file with the given file path. + /// + /// Absolute file path of the video file + /// StreamID >=0 on success or -1 on failure int Load(string videoFileName); + + /// + /// Closes the stream with the given ID + /// + /// ID of the stream + /// true if stream was closed, false if stream doesn't exist or already closed bool Close(int streamID); + + /// + /// Gets the number of streams currently active + /// + /// int GetNumStreams(); + /// + /// Gets the length of the video in s + /// + /// Id of the stream + /// Length of the video in s float GetLength(int streamID); /// + /// Gets a frame of the video and sets the current video time /// - /// - /// - /// - /// - /// True if frame is valid + /// Id of the stream + /// Reference to already initialized video texture (from previous calls). If null, one will be created.
+ /// Returns the current video frame which might be outdated if time != current (internal) video position or unchanged (even null) if none is available. + /// The position in s of the video you want to get a frame of. If != current (internal) video position, it will seek to get to right position.
+ /// Note:Will be ignored for looped playback! + /// The actual position in s of the returned frame. Should be ~ time+VideoGap + /// True if frame is valid, false: frame and videoTime might be unchanged or invalid bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime); + /// + /// Seeks to given position + /// + /// Id of the stream + /// Position to seek to + /// New video gap -> Actual position will be start+gap + /// True on success bool Skip(int streamID, float start, float gap); + + /// + /// Set if the video should be looped + /// + /// Id of the stream + /// True if it should be looped void SetLoop(int streamID, bool loop); + + /// + /// Pauses the video (no new frames will be decoded) + /// + /// Id of the stream void Pause(int streamID); + + /// + /// Resumes a paused video + /// + /// Id of the stream void Resume(int streamID); + /// + /// Check if the given video is finished + /// + /// Id of the stream + /// True if all frames are shown bool Finished(int streamID); + /// + /// Do a step of the decoder in unthreaded decoders. Should be called once every frame. + /// void Update(); } } \ No newline at end of file