Jump to content

Recommended Posts

Posted (edited)

I was trying to capture my webcam with escapi.dll and perform some object detection with yolo3.

I have this working on Win8.

The problem on Win10: Escapi 64bit does not work for me, so I have to use the 32bit dll.
But yolo3 is 64bit only. So if I compile the script 32bit, escapi works, but yolo3 fails.
And if I compile the script 64bit, escapi fails.
Is there any way to get this working in one script?
Has anyone escapi 64bit working in Win10?

I didn't find a way, so I tried the following:
Use one 32bit for capturing and send the pointer/handle to a 64bit to get the captured image and perform
the object detection. But it doesn't work.

Here are 2 scripts I have - without object detection, just to get the captured image from one script to the other.

Script 1 captures the webcam, displays it and sends the pointer to the buffer or the handle of the bitmap to the other script:

#include <GUIConstantsEx.au3>
#include <AppInteract.au3>
#include <GDIPlus.au3>

Opt("GUIOnEventMode", 1)


Init()

GUI_Setup()

Main()



Func Init()

    Global $device = 0 ;change this number to select captured cam

    ;GUI
    Global $hCam_Window
    Global $hInfo_Window

    Global $label1
    Global $label2
    Global $label3

    Global $hGfx                    ; graphic "canvas" to work on in Webcam window
    Global $hBitmap                 ; bitmap containing captured image
    Global $hImage                  ; GDI+ bitmap containing captured image




    ;--------------------------------------------------------------------------
    #region --- variables required for dshow escapi

    Global $Width = 640, $Height = 480, $hGraphics

        Global $tagSimpleCapParams = "ptr mTargetBuf;" & "int mWidth;" & "int mHeight;"
        Global $tSimpleCapParams = DllStructCreate($tagSimpleCapParams)
        Global $tTargetBuf = DllStructCreate("BYTE[" & $Width*$Height*4 & "]")          ;buffer for captured webcam image
    Global $pTargetBuf = DllStructGetPtr($tTargetBuf)                                   ;pointer to this buffer

    DllStructSetData($tSimpleCapParams, 1, $pTargetBuf)
    DllStructSetData($tSimpleCapParams, 2, $Width)
    DllStructSetData($tSimpleCapParams, 3, $Height)
        Global $pSimpleCapParams = DllStructGetPtr($tSimpleCapParams)

    #endregion


    ;---------------------------------------------------------------------------
    #region --- Escapi init

    Global $_escapi_Dll = DllOpen("escapi.dll")
    $return = DllCall($_escapi_Dll,"int","initCOM")                                                         ; --- init ESCAPI.dll

    $return = DllCall($_escapi_Dll,"int","countCaptureDevices")                                             ; --- get number of available video devices
    MsgBox(0,"ESCAPI info", @error)
    Consolewrite("Number of devices = " & $return[0] & @CRLF)
    Local $CamInfo = $return[0] & " Cams" & @CRLF

    Local $tCam = DllStructCreate("CHAR v[20]")                                                             ; --- buffer used to get ESCAPI device names
    Local $pCam = DllStructGetPtr($tCam)
    For $i = 0 To $return[0]-1                                                                              ; --- get names of all available devices
        DllCall($_escapi_Dll,"none:cdecl","getCaptureDeviceName", "uint" , $i, "ptr" , $pCam  , "int" , 20)
        Local $vCam = DllStructGetData($tCam , 1)
        $CamInfo &= $i & ": " & $vCam & @CRLF
    Next
    MsgBox(0,"ESCAPI info", $CamInfo)                                                                       ; --- show device names

    $return = DllCall($_escapi_Dll,"int:cdecl","initCapture", "int", $device, "ptr", $pSimpleCapParams)     ; --- init ESCAPI capture functions
    ;---------------------------------------------------------------------------
    _GDIPlus_Startup()

    #endregion


EndFunc


Func Main()

    GUICtrlSetData($label1, "$pTargetBuf: " & $pTargetBuf)                              ;display pointer
    _AppInteract_Send("Receiver", $pTargetBuf, '', '')                                  ;send pointer to other script

    While 1

        $hGfx = _GDIPlus_GraphicsCreateFromHWND($hCam_Window)

        DllCall($_escapi_Dll,"none:cdecl","doCapture", "int", $device)                      ; --- capture image from video device into $tTargetBuf

        Do
            $return = DllCall($_escapi_Dll,"int:cdecl","isCaptureDone", "int", $device)     ; --- check if capturing is finished
        Until $return[0] = 1


        $hBitmap = _WinAPI_CreateBitmap($Width, $Height , 1 , 32 , $pTargetBuf)
                ;_AppInteract_Send("Receiver", $hBitmap, '', '')                                    ;or send handle to other script
        $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
                ;_AppInteract_Send("Receiver", $hImage, '', '')                                     ;or send this handle to other script


        GUICtrlSetData($label2, "$hBitmap: " & $hBitmap)                                    ;display handle bitmap
        GUICtrlSetData($label3, "$hImage:  " & $hImage)                                     ;display handle GDI+ bitmap

        _GDIPlus_GraphicsDrawImageRect($hGfx, $hImage, 0, 0, $Width, $Height)               ; --- write captured image to window

        Sleep(1000)

        _GDIPlus_BitmapDispose($hImage)
        _WinAPI_DeleteObject($hBitmap)
        _GDIPlus_GraphicsDispose($hGraphics)
        _GDIPlus_ImageDispose($hImage)

    WEnd

EndFunc


Func GUI_Setup()
    $hCam_Window = GUICreate("WebCam", $Width, $Height)             ; --- Webcam Window
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetState(@SW_SHOW,$hCam_Window)

    $Info_Window = GUICreate("Info", 320, 280, 10, 10, -1, -1, $hCam_Window)        ; --- Info Window
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

    $label1 = GUICtrlCreateLabel ("-", 10, 190, 300, 20)
    $label2 = GUICtrlCreateLabel ("-", 10, 210, 300, 20)
    $label3 = GUICtrlCreateLabel ("-", 10, 230, 300, 20)

    GUISetState()

EndFunc


Func _Exit()
   _GDIPlus_GraphicsDispose($hGfx)
   _GDIPlus_ImageDispose($hImage)
   _GDIPlus_Shutdown()
   DllCall($_escapi_Dll,"none:cdecl","deinitCapture", "int", 0)
   GUIDelete($hCam_Window)
   Exit
EndFunc


Script 2 takes the received pointer or handle and tries to access the captured image to display it, too.
In the posted scripts I transmit the pointer to the buffer containing the image captured by escapi.
 

#include <GUIConstantsEx.au3>
#include <AppInteract.au3>
#include <GDIPlus.au3>


Global $hCopy_Cam
Global $hInfo_Window
Global $label1
Global $hGfx2
Global $hBitmap
Global $hImage
Global $Received_Data

Global $sApp_Name = 'Receiver'

Opt("GUIOnEventMode", 1)
GUI_Setup()
_GDIPlus_Startup()
$hGfx2 = _GDIPlus_GraphicsCreateFromHWND($hCopy_Cam)

_AppInteract_SetReceiver($sApp_Name, '_Received')

While 1

    If $Received_Data Then
        $hBitmap = _WinAPI_CreateBitmap(640, 480 , 1 , 32 , $Received_Data)     ;use received pointer/handle
        $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)

        _GDIPlus_GraphicsDrawImageRect($hGfx2, $hImage, 0, 0, 640, 480)
        $Received_Data = ""
    EndIf

WEnd


Func _Received($vData)

    GUICtrlSetData($label1, $vData)
    $Received_Data = $vData             ;get received pointer/handle

EndFunc


Func GUI_Setup()

    $hCopy_Cam = GUICreate("Copy Cam", 640, 480)                ; --- Webcam Window
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetState(@SW_SHOW,$hCopy_Cam)

    $hInfo_Window = GUICreate("Receive Data", 320, 280, 200, 10, -1, -1, $hCopy_Cam)        ; --- Info Window

    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

    $label1 = GUICtrlCreateLabel ("-", 10, 190, 300, 20)

    GUISetState(@SW_SHOW,$hInfo_Window)

EndFunc

Func _Exit()
    Exit
EndFunc


But Script 2 just displays random stuff, nothing or crashes, depending on what pointer or handle I transmit from Script 1.

Any thoughts on this?

 

Edited by coupe70
Posted
5 minutes ago, Nine said:

Just get escapi.dll for x64 on the web.  Just google it, got it as the top element...

It does not work for me, don't know why. I never get a picture on Win10.
 

DllCall($_escapi_Dll,"none:cdecl","doCapture", "int", $device)                      ; --- capture image from video device into $tTargetBuf

        Do
            $return = DllCall($_escapi_Dll,"int:cdecl","isCaptureDone", "int", $device)     ; --- check if capturing is finished
        Until $return[0] = 1


I narrowed it down to the Do-loop running indefinitely - seems like capturing never finishes...
Do I have to change anything in the setup for x64?

Posted (edited)
4 minutes ago, Nine said:

nope, just put some error handling after each call (statement) so you know what is going on...

That's what did - all good until I trigger capturing. "isCaptureDone" just doesn't become true.
I also bypassed checking "isCaptureDone", but there is really nothing in the capturing buffer.
I'll double-check...

Edited by coupe70
Posted (edited)
2 hours ago, Nine said:

nope, just put some error handling after each call (statement) so you know what is going on...

Ok, I was wrong.
$return = DllCall($_escapi_Dll,"int:cdecl","c", "int", $device, "ptr", $pSimpleCapParams)
already fails for x64 while working in 32bit. So calling doCapture afterwards fails too in x64 of course.

initCapture returns @error = 0, but $return[0] is also 0 which is supposed to be 1 on success.

Still don't know why it fails.

And this seems to break something as afterwards initCapture also fails in 32bit and
I have to restart my PC.

Edited by coupe70
Posted (edited)

That means that your DLL in not x64.  You should confirm with dllopen returns.  It is clear that you haven't put enough error handling in your code and you have not the appropriate dll.

edit : maybe you do not know that, but you need 2 dlls, one for 32 bits and one for x64.  You cannot do both with a single dll.

Edited by Nine
Posted
3 minutes ago, Nine said:

That means that your DLL in not x64.  You should confirm with dllopen returns (after thoughts no need for that).  It is clear that you haven't put enough error handling in your code and you have not the appropriate dll.

Well, I have the escapi.dll from the folder x64.

And before initCapture fails I successfully call
DllOpen("escapi.dll")
DllCall($_escapi_Dll,"int","initCOM")
DllCall($_escapi_Dll,"int","countCaptureDevices")
DllCall($_escapi_Dll,"none:cdecl","getCaptureDeviceName", "uint" , $i, "ptr" , $pCam  , "int" , 20)

So the dll obviously works.

Posted
2 minutes ago, Nine said:

How do you know ?  You have no error handling in the posted code.  The code you are showing is ZERO proof of working.  Don't tell me you expect AutoIt to inform you of a problem ?

I don't have it in the posted code as it doesn't help here in the forum.
In my version I have a message box showing @error and the return value after every single dll call.
As you can see in the code here I also output the result of countCaptureDevices and getCaptureDeviceName.
Everything is normal until I call initCapture which fails as described above.
 

Posted
3 minutes ago, Nine said:

What is stopping you to show the real code your are using with the console output, so we can see what your are doing.  I am done with this guessing game,  Maybe someone else will try to help you.

Well I told you that the first calls are successful and where it fails and what it returns when failing.
What would be the use seeing some extra MsgBox lines? How would this help to solve the problem?
 

Posted
2 minutes ago, coupe70 said:

Well I told you that the first calls are successful and where it fails and what it returns when failing.
What would be the use seeing some extra MsgBox lines? How would this help to solve the problem?
 

As @Nine Say's Check your Device if was x32bit or x64bit that working for proper dll & Also Make sure you have dll that is Working with Your OS type..

none

Posted
33 minutes ago, ad777 said:

As @Nine Say's Check your Device if was x32bit or x64bit that working for proper dll & Also Make sure you have dll that is Working with Your OS type..

Well the dll is x64 and I use it on Win10 and have other x64 dlls running without problems.
The webcam device I'm using is actually this vitual webcam device to capture a NDI stream:
https://www.ndi.tv/tools/  (-> Webcam Input).
It works with the 32bit dll and as it is up to date and only running on Windows 10 I would
be surprised if it wouldn't work with the x64 dll - but I contacted the developer to be sure...
 

Posted (edited)
21 hours ago, coupe70 said:

Has anyone escapi 64bit working in Win10?

Yes, the escapi API executes successfully on my Win10 x64 PC, with my PC's webcam.  Below is a sample of the console messages from a test execution that I just ran.  The test script was basically a scaled down (stripped) version of your script that only executes the escapi functions, with console messages.

I have no experience with the virtual webcam device that you mentioned.  It is quite possible that escapi is not compatible with your virtual webcam's drivers.  You also need to make sure that your Windows 10 Camera Privacy settings are set to allow desktop applications access to your webcam.  If not, the initCapture() will fail.

>Running:(3.3.14.5):C:\Portable Apps\AutoIt3\autoit3_x64.exe "C:\Users\...\escapi\escapi_test.au3"    
DllOpen successful
initCOM successful
ESCAPIVersion successful
escapi version = 0x300
countCaptureDevices successful
Number of devices = 1
Devices
0: HD WebCam
initCapture successful
doCapture successful
isCaptureDone loop done
deinitCapture successful
+>21:49:58 AutoIt3.exe ended.rc:0
+>21:49:58 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 1.765

 

Hopefully you saw the troubleshooting caveat on the escapi web page:

I've received reports on several issues with a common element of 64bit windows - win2k, xp and vista. Since I've successfully run ESCAPI as is on 64bit win7 with a new webcam, I'm relatively certain it's a driver issue.

I've been involved in several projects that use ESCAPI, and webcam drivers do vary a lot. In some cases you couldn't run several cameras at once, even if they're from the same manufacturer; other times drivers would hang after running capture for about 8 hours straight.

 

Edited by TheXman

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...