I use the standard code to initialize TVideoCaptureDevice and start capturing.
const M_LAUNCH_CAMERA = WM_APP + 450;
type
TCamSF1 = class(TForm)
...
protected
procedure LaunchCamera(var Message: TMessage); message M_LAUNCH_CAMERA;
...
end;
...
procedure TCamSF1.LaunchCamera(var Message: TMessage);
begin
if VideoCamera = nil then
begin
VideoCamera := TCaptureDeviceManager.Current.DefaultVideoCaptureDevice;
if VideoCamera <> nil then
begin
VideoCamera.OnSampleBufferReady := CameraReady;
VideoCamera.StartCapture;
end
else
begin
Caption := 'Video capture devices not available.';
end;
end
else
begin
VideoCamera.StartCapture;
end;
end;
procedure TCamSF1.IdTCPServer1Execute(AContext: TIdContext);
var
S: AnsiString;
Command: TAnsiStrings;
Msg: TMessage;
begin
if (AContext <> nil) and (AContext.Connection.Socket.Connected) and
(not AContext.Connection.Socket.InputBufferIsEmpty) then
S := AContext.Connection.Socket.ReadLn;
if S = '' then
exit;
Memo1.Lines.Add(S);
Command := ParseCommandString(S, '#');
if Command[0] = 'camresol' then
begin
CamShotParams := Command;
Msg.Msg := M_LAUNCH_CAMERA;
Dispatch(Msg);
end;
end;
The code properly works when I dispatch a message from a button OnClick event but when the message is dispatched from TIdTCPServer OnExecute the camera does not start and Caption := 'Video capture devices not available.'
is run. Moreover, after this the camera does not initialize even from the Button OnClick event.
The code also does not work in case of direct calling of
VideoCamera := TCaptureDeviceManager.Current.DefaultVideoCaptureDevice;
if VideoCamera <> nil then
begin
VideoCamera.OnSampleBufferReady := CameraReady;
VideoCamera.StartCapture;
end;
from within Server OnExecute event. Though it works fine when run from the Button OnClick. Using of TCameraComponent cause the same problems. This issue could be reolved if camera initialization is handled in Form OnCreate event but this is not suitable as simultaneous usage of camera is not allowed by two or more applications.
It seems, capture device should be initialized and manipulated from the main thread. Try to wrap capture manipulating in TThread.Synchronize class procedure, smth like this: