some code cleanup and changes in ffmpeg decoder thread

This commit is contained in:
Alexander Eckart committed 2012-03-10 09:30:23 +01:00
1 parent 1e9a6f0d3d
commit ad2fb1ddc5
1 file changed
+96 -80
+96 -80
View File
@@ -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);