Benim geliştirdiğim bir screenrecorder component projem var, hazır kullanmayı tercih etmediğimden kendim yazmayı uygun gördüm hemde tecrübe kazanmak açısından faydalı olacağını düşündüm.
Component'de FPS desteği mevcut, örneğin teorik olarak saniyede 20 FPS isteniyorsa 1000ms / 20kare = 50 ms zaman aralıklarıyla tick oluyor ve thread vasıtasıyla kare yakalanıyor, tetikleme için zaman hassasiyeti yüksek olan bir timer yazdım, malum TTimer mesaj tabanlı ve zamanlama çok önemli, bu timer oldukça başarılı fakat 50ms de bir thread oluşuyor ve karenin büyüklüğüne göre oluşturulan yeni thread o zaman zarfında çalışmış oluyor, ortalama olarak 25 ms civarı sürüyor tabi her makinada bu değişebilir, 25 ms süren işlem 50 ms de bir tetiklenme zamanı diliminin içerisinde kalıyor, örneğin 50 ms sonra yeni bir thread açıldı ve yakaladı 25 ms sonra bu bitti ve totalde 25 ms sonra 2. thread çalışacak... bu yüzden aynı anda yüzlerce thread çalışmıyor fakat bu kadar kısa sürelerde thread oluşturup işleme almak ağır bir yük oluşturuyordur (?) tabi burada CriticalSection kullanıp o an başka bir kare alım işlemi var ise bloklanıyor.. bazı sorunlarım var örneğin 15 saniye sonra kare yakalayıcı threadlarını oluşturan threadı sonlandırıp kare yakalama işlemini sonlandırıyorum, kod şu şekilde
Kod: Tümünü seç
procedure TScreenRecorder.OnWaitableTimer_FPS_Tick(Sender: TObject);
begin
TThread.CreateAnonymousThread(procedure
var
FrameIndex:Integer;
Bmp:PPBitmap;
begin
try
CriticalSection_For_SynchronousCapture.Acquire;
if not IsStopSignal then
begin
Bmp := AllocateNewBitmap;
GrabberGrabProc(Bmp^);
InterlockedExchange(FrameIndex,InterlockedIncrement(FrameCount));
if IsStopSignal then
tthread.CreateAnonymousThread(procedure
begin
TThread.Current.Synchronize(tthread.Current,procedure
begin
Application.MainForm.Caption := 'IsStopSignal True ama girdi...';
end);
end).Start;
AddToFrameList(Bmp,TFrameDelay.GetDelay,FrameIndex);
end
else
begin
Inc(totalesc,1);
end;
finally
CriticalSection_For_SynchronousCapture.Release;
end;
end).Start;
end;
bundan sonra da kare yakalayıcıyı durduruyorum yani Enabled False yapıyorum yakalayıcı olan timer duruyor bunda problem yok, fakat program ağır yükte çalışırken IsStopSignal true olmasına rağmen bahsettiğim "isstopsignal true ama girdi" kısmı işliyor, burada dikkat etmenizi istediğim nokta yukarıdaki prosedüra baştan girmiyor yani AddToFrameList den önce ki if not IsStopSignal then kod bloğunun içine zaten durmadan önce girmiş oluyor ki sonradan bahsettiğim kod bloğu işliyor... bu durum Debug modda ve ağır yükte oluşuyor.
Thread'lar belirli algoritmalara göre belli bir süre çalışıp belirli süreler sonucunda OS tarafından kaldığı yerden çalışmalarına devam eden yapılar bunun farkındayım, bu noktada bu sorun hakkında öneri yapabilecek üstadlara şimdiden teşekkür ederim, bir diğer fikrinizi istediğim nokta ise belirli süre aralıklarıyla thread tetikleyip kare yakalamak yerine FPS olayını daha estetik nasıl çözebilirim ?
Umarım anlatabilmişimdir.
Teşekkürler.