Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 09-11-2022
elcigarra elcigarra is offline
Miembro
 
Registrado: may 2005
Posts: 269
Poder: 19
elcigarra Va por buen camino
Dos cámaras en paralelo

Estimados, estoy intentando hacer una aplicación en DXE3, que necesita capturar video, en principio de 2 cámaras (que pueden ser la misma mostrada dos veces). Como no sé nada del tema de video, encontré en internet un código bastante simple con el que se podía capturar una cámara que funciona bien (en realidad más que capturar la cámara toma fotogramas con un timer y los muestra en un TPanel.

Para el objetivo de las dos cámaras, lo que hice fue duplicar las partes relevantes y el timer para mostrar las dos capturas, pero lo que me pasa es que solo se ve una y la otra se muestra un plano verde. Les pongo el código a ver qué opinan.

Código:
unit TwoCamsMain;
interface
uses
   Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,ExtCtrls,
   StdCtrls,Menus, Buttons;
const
   WM_CAP_START                  = WM_USER;
   WM_CAP_STOP                   = WM_CAP_START+68;
   WM_CAP_DRIVER_CONNECT         = WM_CAP_START+10;
   WM_CAP_DRIVER_DISCONNECT      = WM_CAP_START+11;
   WM_CAP_SAVEDIB                = WM_CAP_START+25;
   WM_CAP_GRAB_FRAME             = WM_CAP_START+60;
   WM_CAP_SEQUENCE               = WM_CAP_START+62;
   WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START+20;
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Panel1: TPanel;
    Panel2: TPanel;
    Timer2: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Timer1Timer(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
  private
    hWndC:THandle;
    hWndC_B:THandle;
    FPS:integer;
    procedure ConectarDrive;
    procedure CreaHandle;
    procedure DesconectarDrive;
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;


  function capCreateCaptureWindowA(lpszWindowName : PCHAR;
                                 dwStyle : longint;
                                 x : integer;
                                 y : integer;
                                 nWidth : integer;
                                 nHeight : integer;
                                 ParentWin  : HWND;
                                 nId : integer): HWND;
                                 STDCALL EXTERNAL 'AVICAP32.DLL';

implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
   FPS:=24;
   Timer1.Interval:=1000 div FPS;
   Timer2.Interval:=1000 div FPS;
   hWndC:=0;
   hWndC_B:=0;
   CreaHandle;
   ConectarDrive;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
   Application.ProcessMessages;
   if hWndC<>0 then begin
      SendMessage(hWndC, WM_CAP_GRAB_FRAME, 0, 0);
      Timer1.Enabled:=True;
   end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
//   Application.ProcessMessages;
   if hWndC_B<>0 then begin
      SendMessage(hWndC_B, WM_CAP_GRAB_FRAME, 0, 0);
      Timer2.Enabled:=True;
   end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   DesconectarDrive;
end;

procedure TForm1.CreaHandle;
begin
     try
        hWndC:=capCreateCaptureWindowA(' Video',
                                       WS_CHILD or WS_VISIBLE,
                                       0,
                                       0,
                                       Width,
                                       Height,
                                       Panel1.Handle,
                                       0);
        hWndC_B:=capCreateCaptureWindowA(' Video',
                                       WS_CHILD or WS_VISIBLE,
                                       0,
                                       0,
                                       Width,
                                       Height,
                                       Panel2.Handle,
                                       0);
     except
           ShowMessage('error en handle');
     end;
end;
procedure TForm1.ConectarDrive;
begin
     try
        if hWndC<>0 then begin
           SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
        end;
        if hWndC_B<>0 then begin
           SendMessage(hWndC_B, WM_CAP_DRIVER_CONNECT, 0, 0);
        end;
        Timer1.Enabled:=True;
        Timer2.Enabled:=True;
     except
           ShowMessage('error al desconectar'); // error mesg
     end;
end;
procedure TForm1.DesconectarDrive; // Disconnect
begin
   try
      if hWndC<>0 then begin
         SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
         hWndC:=0;
         SendMessage(hWndC_B, WM_CAP_DRIVER_DISCONNECT, 0, 0);
         hWndC_B:=0;
      end;
   except
      ShowMessage('error al desconectar'); // error message
   end;
end;
end.
Responder Con Cita
  #2  
Antiguo 09-11-2022
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.040
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
¿Cuál es la pregunta o la duda?
Responder Con Cita
  #3  
Antiguo 09-11-2022
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
¿Esta cadena ' Video' de dónde sale?

Código Delphi [-]
hWndC:=capCreateCaptureWindowA(' Video', ...

¿Qué valen los 2 handles (hWndC, hWndC_B) una vez capturadas?
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 09-11-2022
elcigarra elcigarra is offline
Miembro
 
Registrado: may 2005
Posts: 269
Poder: 19
elcigarra Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
¿Cuál es la pregunta o la duda?
Que, como dije, no funciona para las dos cámaras, solo se ve una y la otra sale verde. La pregunta es si alguien sabe por qué.

Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
¿Esta cadena ' Video' de dónde sale?
Esa cadena 'Video' es un nombre cualquiera para la ventana de captura de la función esa capCreateCaptureWindowA pero aclaro que no sé mucho del tema (igual decir 'no se mucho' es casi soberbio, mas bien no se nada).

Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
¿Qué valen los 2 handles (hWndC, hWndC_B) una vez capturadas?
No entiendo bien tu pregunta, seguramente debido a mi ignorancia en el tema. ¿Esto handles no son los lugares donde se volcara las capturas de los dos videos?. Según entiendo cada video se muestra en el handle de un TPanel. No sé por qué si el código es igual solo puede mostrarse una.

Pero igualmente, si alguien conoce otra forma de acceder a dos cámaras de video en paralelo y tiene de donde aprender agradezco la referencia. Yo solo he encontrado explicaciones para una cámara sola. Gracias.
Responder Con Cita
  #5  
Antiguo 10-11-2022
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por elcigarra Ver Mensaje
¿Esto handles no son los lugares donde se volcara las capturas de los dos videos?. Según entiendo cada video se muestra en el handle de un TPanel. No sé por qué si el código es igual solo puede mostrarse una.
Los handles son los identificadores de ventana. Se almacenan como un integer.
Una vez que has hecho la llamada a la función los 2 handles deben ser diferentes y positivos, por eso te preguntaba. Si hay algun problema con esa captura, o serán los 2 iguales o alguno será negativo o cero (imagino).

Lo que veo extraño es que haces las 2 llamadas a la función de forma igual (parámetros) cambiando simplemente el panel para recibir las capturas. Con esas 2 llamadas no veo forma de que tu programa Delphi sepa discernir entre las 2 cámaras que tienes instaladas.

NOTA: Sólo para probar, prueba a pasar un valor distinto en el primer parámetro cuando haces la conexion y/o la captura:
Código Delphi [-]
...
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 1, 0);
...
SendMessage(hWndC_B, WM_CAP_GRAB_FRAME, 0, 0);
SendMessage(hWndC_B, WM_CAP_GRAB_FRAME, 1, 0);
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #6  
Antiguo 10-11-2022
elcigarra elcigarra is offline
Miembro
 
Registrado: may 2005
Posts: 269
Poder: 19
elcigarra Va por buen camino
Gracias chicos. Probé cambiar ese parámetro, cambiar el último parámetro (el identificador de windows) en capCreateCaptureWindowA, cambiar algunos, cambiarlos todos, pero siempre obtengo el mismo resultado, solo una cámara funciona.

Aclaro que el código que puse arriba está completo y aislado porque es lo único que me resta resolver, es un form con dos TPanel y dos TTimer . Lo digo porque capaz que algún experto en procesos de windows de tantos que hay aquí aprovecha un rato de ocio activo, lo puede probar y dejarlo funcionando. Harían feliz a un pobre programador aficcionado ya entrado en años .
Responder Con Cita
  #7  
Antiguo 10-11-2022
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por elcigarra Ver Mensaje
Gracias chicos. Probé cambiar ese parámetro, cambiar el último parámetro (el identificador de windows) en capCreateCaptureWindowA, cambiar algunos, cambiarlos todos, pero siempre obtengo el mismo resultado, solo una cámara funciona..
Yo me refería a cambiar los parámetros cuando llamas al SendMessage.
Revisa los valores en rojo (de más arriba).

Aqui:
https://learn.microsoft.com/en-us/wi...driver-connect

Habla de esto:
Index of the capture driver. The index can range from 0 through 9.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #8  
Antiguo 14-11-2022
elcigarra elcigarra is offline
Miembro
 
Registrado: may 2005
Posts: 269
Poder: 19
elcigarra Va por buen camino
Thread-safe postmessage

Sigo con mi asunto de las dos cámaras en paralelo. Para empezar digo que estoy usando la librería VFrames de GRBLize de aquí:
https://github.com/MakeMagazinDE/GRB...er/VFrames.pas

Lo que me pasa es que si yo llamo a ambas cámaras desde el hilo principal de la aplicación funciona correctamente (veo las dos cámaras) pero el programa es una carreta y refrescan cada 5 segundos. Lo que se me ocurrió es meter cada llamada en un hilo. El problema es que haciéndolo así cuando seteo la fuente de la segunda cámara me cambia las dos y me muestran la misma imagen (de la segunda cámara). Me da la sensación que esto es porque esta biblioteca VFrames no es Thread safe. En mi ignorancia (hago agua en threads y océanos en procesos de windows, mi excusa es que programo como hobby nada más ) me da la sensación que el problema está en la linea
Código:
PostMessage(fMessageHWND, fMsgNewFrame, Size, integer(fImagePtr[i]));
Hay un comentario en esta linea de código
// This routine is called by the video software and therefore runs within their thread.
// Posting a message to our own HWND will transport the information to the main thread.


No me queda claro por qué si fMessageHWND para cada hilo se carga en el constructor, como el segundo hilo puede cambiar el identificador del primero.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
multiples camaras web JULIPO FireMonkey 0 09-05-2014 20:34:43
Camaras Ip raul.rojas Internet 5 25-01-2012 18:22:05
Cámaras WIA monina2112 Gráficos 5 02-06-2011 17:39:22
camaras ip martinchooozzz Varios 0 08-04-2009 00:17:03
Sistema con Camaras Ip Rabata Varios 1 07-09-2006 09:22:07


La franja horaria es GMT +2. Ahora son las 21:49:08.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi