0

I have this class to handle my webcam and want know how can stop the webcam started in a separated thread. Camera.Destroy not is working and the camera keep on.

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Panel1: TPanel;
    Image1: TImage; // To load camera Bitmap from stream
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  TCameraThread = class(TThread)
  protected
    procedure Execute; override;
  end;

var
  Form1: TForm1;

implementation

uses
  Webcam;

{$R *.dfm}

procedure TCameraThread.Execute;
begin
  Camera := TCamera.Create(Form1.Panel1);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  mCamera: TCameraThread;
begin
  mCamera := TCameraThread.Create(False);
  mCamera.Resume;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if Assigned(Camera) then
    Camera.Destroy;
end;

end.
FLASHCODER
  • 1
  • 7
  • 24
  • 1
    One does not call ``Destroy`` in Delphi. Instead ``.Free`` is to be used, which checks internally for ``Assigned`` and then calls ``Destroy``, if necessary! – Delphi Coder Jul 25 '22 at 05:00
  • 1
    The `TCamera` class as it is written cannot be used in threads. Remove the thread and you will not have a problem. Which brings up another question why you need a thread? I don't know much about the API you are using, so it is possible that it can be made to work with threads, but there are many things that would need to be done for that to work. In any case, it cannot directly interact with VCL controls and you would have to not only construct a Camera in a background thread, you would have to fully handle its lifetime in the thread including implementing message processing in the thread. – Dalija Prasnikar Jul 25 '22 at 08:07
  • If you just want to start/stop (aka pause/continue) capturing from the camera then call the commands directly instead of wrapping it in a thread. – AmigoJack Jul 25 '22 at 09:01
  • @DalijaPrasnikar, _italic_`"why you need a thread?"`_italic_ - Because i not want UI thread locking when use **WM_CAP_SEQUENCE_NOFILE** with **WM_CAP_SET_CALLBACK_VIDEOSTREAM**. – FLASHCODER Jul 25 '22 at 09:01
  • See the [answer](https://stackoverflow.com/a/72986886/13342557). "`To capture frames continuously, you would have to either: use WM_CAP_SEQUENCE_NOFILE with WM_CAP_SET_CALLBACK_VIDEOSTREAM, rather than using WM_CAP_GRAB_FRAME(_NOSTOP) with WM_CAP_SET_CALLBACK_FRAME. Between the suggestions"`. – FLASHCODER Jul 25 '22 at 09:12
  • I may be mistaken, but the API that uses messages and callbacks is commonly not a blocking API. Most likely it is blocking UI because you are doing too much work in the callback (for instance you have memory stream there that serves no purpose) Your frame rate is also set to 1 millisecond which is way too fast. Also running in preview mode and grabbing a frames sounds fishy (I don't know the API, so I may be wrong). Before throwing everything in a thread you need to figure out whether you really, really need a thread. If you do then you need to completely reorganize TCamera and TCameraThread. – Dalija Prasnikar Jul 25 '22 at 09:44
  • @DalijaPrasnikar, _"`you have memory stream`"_ - Negative, MemoryStream not is guilty. – FLASHCODER Jul 25 '22 at 10:00
  • 1
    Saving bitmap to memory stream certainly takes time. But that was not the main point why I mentioned memory stream. Point is that your code may be doing too much work in callback and your frame rate is too fast - callback is triggered too often so everything is blocked because of that. Your code shows that you don't have much experience with threads and threads bring in a whole a lot of complexity. Your best option would be figuring out what causes issues in your non-threaded code and avoiding threads if possible. – Dalija Prasnikar Jul 25 '22 at 11:06
  • 2
    If you want to use a thread, then Camera must be owned by a thread (it must be field or local variable in TCameraThread class) and it must be constructed and destroyed in the Execute method and in between you must write a message processing loop. And then when you want to stop the camera feed you would destroy the thread. – Dalija Prasnikar Jul 25 '22 at 11:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/246751/discussion-between-remy-lebeau-and-dalija-prasnikar). – Remy Lebeau Jul 25 '22 at 20:50

0 Answers0