some code cleanup and changes in ffmpeg decoder thread
This commit is contained in:
1 parent
1e9a6f0d3d
commit
ad2fb1ddc5
1 file changed
+96
-80
@@ -214,33 +214,34 @@ namespace Vocaluxe.Lib.Video
|
||||
|
||||
class Decoder
|
||||
{
|
||||
private IntPtr _instance = IntPtr.Zero;
|
||||
private IntPtr _videodecoder = IntPtr.Zero;
|
||||
private IntPtr _package = IntPtr.Zero;
|
||||
private Stopwatch _Timer = new Stopwatch();
|
||||
private CLOSEPROC _Closeproc;
|
||||
private int _StreamID;
|
||||
private string _FileName;
|
||||
private IntPtr _instance = IntPtr.Zero; // acinerella instance
|
||||
private IntPtr _videodecoder = IntPtr.Zero; // acinerella video decoder instance
|
||||
|
||||
private Stopwatch _LoopTimer = new Stopwatch();
|
||||
private CLOSEPROC _Closeproc; // delegate for stream closing
|
||||
private int _StreamID; // stream ID for stream closing
|
||||
private string _FileName; // current video file name
|
||||
|
||||
private FileStream _fs;
|
||||
private TAc_read_callback _rc;
|
||||
private TAc_seek_callback _sc;
|
||||
private FileStream _fs; // video file stream
|
||||
private TAc_read_callback _rc; // read callback for acinerella
|
||||
private TAc_seek_callback _sc; // seek callback for acinerella
|
||||
|
||||
private bool _FileOpened = false;
|
||||
|
||||
private float _VideoTimeBase = 0f;
|
||||
private float _VideoTime = 0f;
|
||||
private float _ActualVideoTime = 0f;
|
||||
private bool _waiting = false;
|
||||
private bool _skip = false;
|
||||
private float _VideoTimeBase = 0f; // frame time
|
||||
private float _VideoDecoderTime = 0f; // time of last decoded frame
|
||||
private float _CurrentVideoTime = 0f; // current video position
|
||||
private bool _BufferFull = false; // buffer is full, waiting for free frame slot
|
||||
|
||||
private bool _skip = false; // do skip
|
||||
private float _Time = 0f;
|
||||
private float _Gap = 0f;
|
||||
private float _Start = 0f;
|
||||
private bool _Loop = false;
|
||||
private float _Duration = 0f;
|
||||
private float _VideoSkipTime = 0f;
|
||||
private float _NegativeSkipTime = 0f;
|
||||
private float _SkipTime = 0f;
|
||||
private float _VideoSkipTime = 0f; // = VideoGap
|
||||
private float _SkipTime = 0f; // = Start + VideoGap
|
||||
|
||||
private bool _Paused = false;
|
||||
private bool _NoMoreFrames = false;
|
||||
private bool _Finished = false;
|
||||
@@ -292,15 +293,16 @@ namespace Vocaluxe.Lib.Video
|
||||
get { return _Paused; }
|
||||
set
|
||||
{
|
||||
_Paused = value;
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
_Paused = value;
|
||||
if (_Paused)
|
||||
_Timer.Stop();
|
||||
{
|
||||
_LoopTimer.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
_Timer.Start();
|
||||
EventDecode.Set();
|
||||
_LoopTimer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -329,7 +331,7 @@ namespace Vocaluxe.Lib.Video
|
||||
return false;
|
||||
|
||||
_FileName = FileName;
|
||||
_thread.Priority = ThreadPriority.Highest;
|
||||
_thread.Priority = ThreadPriority.Normal;
|
||||
_thread.Name = Path.GetFileName(FileName);
|
||||
_thread.Start();
|
||||
return true;
|
||||
@@ -347,12 +349,12 @@ namespace Vocaluxe.Lib.Video
|
||||
{
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
_SetTime += _Timer.ElapsedMilliseconds / 1000f;
|
||||
_SetTime += _LoopTimer.ElapsedMilliseconds / 1000f;
|
||||
VideoTime = _SetTime;
|
||||
|
||||
_Timer.Stop();
|
||||
_Timer.Reset();
|
||||
_Timer.Start();
|
||||
_LoopTimer.Stop();
|
||||
_LoopTimer.Reset();
|
||||
_LoopTimer.Start();
|
||||
}
|
||||
|
||||
|
||||
@@ -361,12 +363,12 @@ namespace Vocaluxe.Lib.Video
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_Time - _SetTime >= 0 || _SetTime > Time)
|
||||
if (_SetTime != Time)
|
||||
{
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
_SetTime = Time;
|
||||
VideoTime = _VideoTime;
|
||||
VideoTime = _CurrentVideoTime;
|
||||
}
|
||||
UploadNewFrame(ref frame);
|
||||
EventDecode.Set();
|
||||
@@ -394,17 +396,14 @@ namespace Vocaluxe.Lib.Video
|
||||
private void DoSkip()
|
||||
{
|
||||
string extension = Path.GetExtension(_FileName); //just a workaround for the mkv-search-bug in ffmpeg
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
_VideoSkipTime = _Gap;
|
||||
_NegativeSkipTime = _Start + _Gap;
|
||||
_SkipTime = _Start + _Gap;
|
||||
_BeforeLoop = false;
|
||||
}
|
||||
|
||||
_VideoSkipTime = _Gap;
|
||||
_SkipTime = _Start + _Gap;
|
||||
_BeforeLoop = false;
|
||||
|
||||
if (_SkipTime > 0 && extension != ".mkv")
|
||||
{
|
||||
_VideoTime = _SkipTime;
|
||||
_VideoDecoderTime = _SkipTime;
|
||||
try
|
||||
{
|
||||
CAcinerella.ac_seek(_videodecoder, -1, (Int64)(_SkipTime * 1000f));
|
||||
@@ -417,7 +416,7 @@ namespace Vocaluxe.Lib.Video
|
||||
}
|
||||
else
|
||||
{
|
||||
_VideoTime = 0f;
|
||||
_VideoDecoderTime = 0f;
|
||||
try
|
||||
{
|
||||
if (extension != ".mkv")
|
||||
@@ -429,7 +428,10 @@ namespace Vocaluxe.Lib.Video
|
||||
}
|
||||
}
|
||||
|
||||
_ActualVideoTime = _VideoTime;
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
_CurrentVideoTime = _VideoDecoderTime;
|
||||
}
|
||||
|
||||
lock (MutexFramebuffer)
|
||||
{
|
||||
@@ -440,46 +442,41 @@ namespace Vocaluxe.Lib.Video
|
||||
}
|
||||
}
|
||||
|
||||
_waiting = false;
|
||||
_BufferFull = false;
|
||||
_skip = false;
|
||||
EventDecode.Set();
|
||||
}
|
||||
|
||||
private void Execute()
|
||||
{
|
||||
DoOpen();
|
||||
|
||||
EventDecode.Set();
|
||||
|
||||
while (!_terminated)
|
||||
{
|
||||
if (EventDecode.WaitOne(1) || !_waiting)
|
||||
{
|
||||
if (_skip)
|
||||
{
|
||||
DoSkip();
|
||||
_skip = false;
|
||||
}
|
||||
|
||||
if (!_waiting)
|
||||
{
|
||||
DoDecode();
|
||||
}
|
||||
|
||||
if (_waiting)
|
||||
Copy();
|
||||
}
|
||||
if (!_terminated)
|
||||
if (EventDecode.WaitOne(10))
|
||||
{
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
_Time = _SetTime;
|
||||
if (_SetSkip)
|
||||
_skip = true;
|
||||
|
||||
|
||||
_SetSkip = false;
|
||||
_Gap = _SetGap;
|
||||
_Start = _SetStart;
|
||||
_Loop = _SetLoop;
|
||||
}
|
||||
|
||||
if (_skip)
|
||||
DoSkip();
|
||||
|
||||
if (!_BufferFull)
|
||||
DoDecode();
|
||||
|
||||
if (_BufferFull)
|
||||
Copy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DoFree();
|
||||
@@ -545,7 +542,7 @@ namespace Vocaluxe.Lib.Video
|
||||
if (Videodecoder.stream_info.video_info.frames_per_second > 0)
|
||||
_VideoTimeBase = 1f / (float)Videodecoder.stream_info.video_info.frames_per_second;
|
||||
|
||||
_VideoTime = 0f;
|
||||
_VideoDecoderTime = 0f;
|
||||
_Time = 0f;
|
||||
|
||||
for (int i = 0; i < _FrameBuffer.Length; i++)
|
||||
@@ -564,14 +561,14 @@ namespace Vocaluxe.Lib.Video
|
||||
if (!_FileOpened)
|
||||
return;
|
||||
|
||||
if (_Paused || _NoMoreFrames)
|
||||
if (_Paused || _NoMoreFrames || _BufferFull)
|
||||
return;
|
||||
|
||||
if ((_NegativeSkipTime < 0f) && (_Time + _NegativeSkipTime >= 0f))
|
||||
_NegativeSkipTime = 0f;
|
||||
if ((_SkipTime < 0f) && (_Time + _SkipTime >= 0f))
|
||||
_SkipTime = 0f;
|
||||
|
||||
float myTime = _Time + _VideoSkipTime;
|
||||
float TimeDifference = myTime - _VideoTime;
|
||||
float TimeDifference = myTime - _VideoDecoderTime;
|
||||
|
||||
bool DropFrame = false;
|
||||
if (TimeDifference >= (FRAMEDROPCOUNT - 1) * _VideoTimeBase)
|
||||
@@ -634,7 +631,6 @@ namespace Vocaluxe.Lib.Video
|
||||
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
_ActualVideoTime = 0f;
|
||||
_Start = 0f;
|
||||
_Gap = 0f;
|
||||
_SetTime = 0f;
|
||||
@@ -655,6 +651,7 @@ namespace Vocaluxe.Lib.Video
|
||||
private void Copy()
|
||||
{
|
||||
int num = -1;
|
||||
|
||||
lock (MutexFramebuffer)
|
||||
{
|
||||
for (int i = 0; i < _FrameBuffer.Length; i++)
|
||||
@@ -667,24 +664,38 @@ namespace Vocaluxe.Lib.Video
|
||||
}
|
||||
|
||||
if (num == -1)
|
||||
_waiting = true;
|
||||
{
|
||||
_BufferFull = true;
|
||||
EventDecode.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
TAc_decoder Videodecoder = (TAc_decoder)Marshal.PtrToStructure(_videodecoder, typeof(TAc_decoder));
|
||||
|
||||
_VideoTime = (float)Videodecoder.timecode;
|
||||
_FrameBuffer[num].time = _VideoTime;
|
||||
_VideoDecoderTime = (float)Videodecoder.timecode;
|
||||
_FrameBuffer[num].time = _VideoDecoderTime;
|
||||
|
||||
if (Videodecoder.buffer != IntPtr.Zero)
|
||||
{
|
||||
Marshal.Copy(Videodecoder.buffer, _FrameBuffer[num].data, 0, _Width * _Height * 4);
|
||||
|
||||
|
||||
_FrameBuffer[num].displayed = false;
|
||||
}
|
||||
|
||||
_waiting = false;
|
||||
|
||||
int numfull = 0;
|
||||
for (int i = 0; i < _FrameBuffer.Length; i++)
|
||||
{
|
||||
if (!_FrameBuffer[i].displayed)
|
||||
numfull++;
|
||||
}
|
||||
|
||||
if (numfull < _FrameBuffer.Length)
|
||||
_BufferFull = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_BufferFull)
|
||||
EventDecode.Set();
|
||||
}
|
||||
|
||||
private void UploadNewFrame(ref STexture frame)
|
||||
@@ -707,8 +718,13 @@ namespace Vocaluxe.Lib.Video
|
||||
{
|
||||
CDraw.UpdateTexture(ref frame, ref _FrameBuffer[num].data);
|
||||
}
|
||||
_ActualVideoTime = _FrameBuffer[num].time;
|
||||
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
_CurrentVideoTime = _FrameBuffer[num].time;
|
||||
}
|
||||
_Finished = false;
|
||||
EventDecode.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -716,7 +732,6 @@ namespace Vocaluxe.Lib.Video
|
||||
_Finished = true;
|
||||
}
|
||||
}
|
||||
EventDecode.Set();
|
||||
}
|
||||
|
||||
private int FindFrame()
|
||||
@@ -728,27 +743,28 @@ namespace Vocaluxe.Lib.Video
|
||||
{
|
||||
float td = _SetTime + _VideoSkipTime - _FrameBuffer[i].time;
|
||||
|
||||
if (td > _VideoTimeBase * 2 || td < -1f * _VideoTimeBase * (_FrameBuffer.Length + 1))
|
||||
{
|
||||
_FrameBuffer[i].displayed = true;
|
||||
}
|
||||
|
||||
if (!_FrameBuffer[i].displayed && (td < diff) && (td > _VideoTimeBase))
|
||||
{
|
||||
diff = Math.Abs(_FrameBuffer[i].time - _SetTime - _VideoSkipTime);
|
||||
Result = i;
|
||||
}
|
||||
|
||||
if (td > _VideoTimeBase * 2)
|
||||
_FrameBuffer[i].displayed = true;
|
||||
}
|
||||
|
||||
if (Result != -1)
|
||||
{
|
||||
_FrameBuffer[Result].displayed = true;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
private void DoFree()
|
||||
{
|
||||
if (_package != IntPtr.Zero)
|
||||
CAcinerella.ac_free_package(_package);
|
||||
|
||||
if (_videodecoder != IntPtr.Zero)
|
||||
CAcinerella.ac_free_decoder(_videodecoder);
|
||||
|
||||
|
||||
Reference in new issue
Block a user