Witam.
Robie sobie programik który przechwytuje obraz z kamerki. Wszystko ok tylko denerwuje mnie to że aplikacja "zacina" się podczas przechwytywania. Jestem szczególnie wrażliwy na tego typu zamarzania. Odczuwa się to zwłaszcza wtedy kiedy pisze się coś w memo albo przesuwa okno. Probowałem to jakoś zrobić w wątku ale nie przechwytuje mi wtedy obrazu, kamera się łączy, wszystkie procedury zwracają true ale nic sie nie dzieje. W SDK AviCap przeczytałem że jeżeli w parametrach ustawi sie fYield na True to zrzucanie obrazu będzie miało miejsce w osobnym wątku. Jednak co bym nie ustawiał cały czas aplikacja "szarpie". Znalazłem także sposób aby co zrzucaną klatkę podpinać się do własnej procedury, tam chciałem wywoływać Application.ProcessMessage ale w ogóle mi do niej nie wchodzi. Jednym słowem poległem na całej linii. Czy to dlatego że okno jest typu MDIChild (chociaż wątpię aby było to przyczyną)? Może mi ktoś pomóc? To jest mój kod który wykonuje całe połączenie, dla osób które robiły już coś w AviCap wywoływane funkcje są znajome i nie muszę chyba pisać ich definicji (robią określone SendMessage), jak ktoś będzie ich potrzebował to wkleje.
//funkcja która powinna być wywoływana przy każdym zrzucaniu klatki ale do niej nie wchodzi
function CbYield(Wnd : HWnd) : longint; stdcall;
begin
Application.ProcessMessages;
result := 1;
end;
//funkcja wykonująca całe połączenie
function CapStart(x,y:Integer):Boolean;
var
CapParms: TCaptureParms;
begin
if gCapWnd<>0 then exit;
Result:=False;
gCapWnd:=capCreateCaptureWindowA ('Podgląd z kamerki',WS_CHILD or WS_VISIBLE,x,y,gCapVideoArea.Width,
gCapVideoArea.Height, gCapVideoArea.Handle,0);
//tutaj wysyłam wskaźnik do własnej funkcji ktora bedzie wywoływana przy każdej zrzucanej klatce
capSetCallbackOnYield(gCapWnd, Integer(@cbYield));
//łącze sie z kamerą
if gCapWnd<>0 then
Result:=(SendMessage (gCapWnd, WM_CAP_DRIVER_CONNECT, 0, 0)=1); //polacz z kamerka
//skaluje obraz do rozmiarów panela
capPreviewScale(gCapWnd, 1);
//określam ilość klatek na sekundę
capPreviewRate(gCapWnd, MS_FOR_25FPS);
//rozpoczynam zrzucanie
capPreview(gCapWnd, 1);
//to powinno zrzucać w osobnym wątku ale tak się nie dzieje
CapParms.fYield := True;
capCaptureSetSetup(gCapWnd, Longint(@CapParms), SizeOf(TCaptureParms));
end;
To fragment SDK na temat parametru fYield:
PCaptureParms = ^TCaptureParms;
TCaptureParms = record // Default values in parenthesis
dwRequestMicroSecPerFrame :DWORD; // Requested capture rate
fMakeUserHitOKToCapture :BOOL; // Show "Hit OK to cap" dlg?
wPercentDropForError :WORD; // Give error msg if > (10%)
fYield :BOOL; // Capture via background task?
dwIndexSize :DWORD; // Max index size in frames (32K)
wChunkGranularity :WORD; // Junk chunk granularity (2K)
fUsingDOSMemory :BOOL; // Use DOS buffers?
wNumVideoRequested :WORD; // # video buffers, If 0, autocalc
fCaptureAudio :BOOL; // Capture audio?
wNumAudioRequested :WORD; // # audio buffers, If 0, autocalc
vKeyAbort :WORD; // Virtual key causing abort
fAbortLeftMouse :BOOL; // Abort on left mouse?
fAbortRightMouse :BOOL; // Abort on right mouse?
fLimitEnabled :BOOL; // Use wTimeLimit?
wTimeLimit :WORD; // Seconds to capture
fMCIControl :BOOL; // Use MCI video source?
fStepMCIDevice :BOOL; // Step MCI device?
dwMCIStartTime :DWORD; // Time to start in MS
dwMCIStopTime :DWORD; // Time to stop in MS
fStepCaptureAt2x :BOOL; // Perform spatial averaging 2x
wStepCaptureAverageFrames :WORD; // Temporal average n Frames
dwAudioBufferSize :DWORD; // Size of audio bufs (0 = default)
fDisableWriteCache :BOOL; // Attempt to disable write cache
AVStreamMaster :WORD; // Indicates whether the audio stream
// controls the clock when writing an AVI file.
end;
fYield
Yield flag. If this member is TRUE, the capture window spawns a separate background thread to perform step and streaming capture. The default value is FALSE.
Applications that set this flag must handle potential reentry issues because the controls in the application are not disabled while capture is in progress.