Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

.NET 

Capture Webcam into memory using avicap32.dll

Hey guys! I need some help now; basically I am trying to capture the webcam stream directly into memory, without using no picturebox. What I have done is:

I made a class that Inherits NativeWindow, to get a handle.

Then I create a capture window to that handle. Then I use a capVideoStreamCallback delegate.

Here is something I've tried, which doesn't work:

Code
Public Class Webcam
    Inherits NativeWindow

#Region " P/Invokes "

    <DllImport("User32.dll")> _
    Private Shared Function SendMessage(hWnd As IntPtr, wMsg As UInteger, wParam As IntPtr, lParam As IntPtr) As IntPtr
    End Function

    <DllImport("avicap32.dll", EntryPoint:="capGetDriverDescription", CharSet:=CharSet.Auto)> _
    Private Shared Function GetDriverDescription(wDriver As Short, lpszName As String, cbName As Integer, lpszVer As String, cbVer As Integer) As Boolean
    End Function

    <DllImport("avicap32.dll", CharSet:=CharSet.Auto)> _
    Private Shared Function capCreateCaptureWindow(lpszWindowName As String, dwStyle As Integer, _
      x As Integer, y As Integer, nWidth As Integer, _
      nHeight As Integer, hWndParent As IntPtr, _
      nID As Integer) As IntPtr
    End Function

    <DllImport("user32.dll")> _
    Private Shared Function DestroyWindow(Handle As Integer) As Boolean
    End Function

#End Region

#Region " Constants "

    Private Const WM_CAP_START As Short = &H400
    Private Const WM_CAP_DRIVER_CONNECT As Integer = WM_CAP_START + 10
    Private Const WM_CAP_DRIVER_DISCONNECT As Integer = WM_CAP_START + 11
    Private Const WM_CAP_EDIT_COPY As Integer = WM_CAP_START + 30
    Private Const WM_CAP_GRAB_FRAME = WM_CAP_START + 60
    Private Const WM_CAP_SET_PREVIEW As Integer = WM_CAP_START + 50
    Private Const WM_CAP_SET_PREVIEWRATE As Integer = WM_CAP_START + 52
    Private Const WM_CAP_SET_SCALE As Integer = WM_CAP_START + 53
    Private Const WM_CAP_DLG_VIDEOSOURCE As Integer = WM_CAP_START + 42
    Private Const WM_CAP_STOP As Integer = WM_CAP_START + 68
    Private Const WS_CHILD As Integer = &H4000000
    Private Const WM_CAP_SET_CALLBACK_FRAME As Integer = WM_CAP_START + 5
    Private Const WM_CAP_SET_CALLBACK_VIDEO_STREAM As Integer = WM_CAP_START + 6
    Private Const WM_CAP_SEQUENCE_NOFILE As Integer = WM_CAP_START + 63
    Private Const WS_VISIBLE As Integer = &H1000000
    Private Const SWP_NOMOVE As Short = &H2S
    Private Const SWP_NOSIZE As Short = 1
    Private Const SWP_NOZORDER As Short = &H4S
    Private Const HWND_BOTTOM As Short = 1

#End Region

    Private iDevice As Integer = 0
    Private CamHandle As IntPtr
    Private FG As capVideoStreamCallback

    <StructLayout(LayoutKind.Sequential)> _
    Private Structure VIDEOHDR
      Public lpData As IntPtr
      Public dwBufferLength As UInteger
      Public dwBytesUsed As UInteger
      Public dwTimeCaptured As UInteger
      Public dwUser As UIntPtr
      Public dwFlags As UInteger
      <VBFixedArray(3)> Public dwReserved As UIntPtr()
    End Structure

    Private Sub Initialize()
      CreateHandle(New CreateParams)

      FG = New capVideoStreamCallback(AddressOf FrameGrabbedCallBack)

      EncoderParameters = New EncoderParameters(1)
      Encoder = Imaging.Encoder.Quality
      JPEGEncoder = GetEncoder(ImageFormat.Jpeg)

      CamHandle = capCreateCaptureWindow(iDevice.ToString, WS_VISIBLE Or WS_CHILD, 0, 0, 640, 480, Handle, 0)

      SendMessage(CamHandle, WM_CAP_DRIVER_CONNECT, iDevice, 0)

      Dim Ptr As IntPtr = Marshal.GetFunctionPointerForDelegate(FG)
      SendMessage(CamHandle, WM_CAP_SET_CALLBACK_VIDEO_STREAM, 0, Ptr)

      SendMessage(CamHandle, WM_CAP_SEQUENCE_NOFILE, 0, 0)

    End Sub

    Private Delegate Function capVideoStreamCallback(hWnd As IntPtr, lpVHdr As IntPtr) As IntPtr
    Private Function FrameGrabbedCallBack(hWnd As IntPtr, lpVHdr As IntPtr) As IntPtr
      'Convert lpVHdr to VIDEOHDR Structure using Marshal.PtrToStructure
      'Make bitmap from the lpdata pointer

      MsgBox("Callback!")
End Sub
End Class

Please help :D
Code
SendMessage(CamHandle, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0)
Will create a new Image besides of any visible or invisible Element and you don't have to use Clipboard.GetImage() afterwards

Just play around a bit I won't spoonfeed you :)


Another hint: you need a FrameCallback and you have to rotate the Image after capturing it (weird an no one knows why)
[Image: uzpE9zW.jpg]

You shouldn't use that API, it's really old although supported, the new replacement is Directshow and you got a library called Directshow.net that opens the native directshow unfriendly access from .net.
(Sep 30, 2014 10:37 AM)He B TeMy Wrote:  You shouldn't use that API, it's really old although supported, the new replacement is Directshow and you got a library called Directshow.net that opens the native directshow unfriendly access from .net.

Yea, I think so too, is the source code for DirectShow available?
I'd like to learn how it uses the WinAPI.
(Sep 30, 2014 10:43 AM)Proton! Wrote:  Yea, I think so too, is the source code for DirectShow available?
I'd like to learn how it uses the WinAPI.

You could've searched... http://directshownet.sourceforge.net/

It's a wrapper for the DirectShow (unfriendly imo) API.
those apis are hard to work with what i do is to save it to temp image
This API is kinda old but it works, still.

Nice..
What is the best API I can use? - DirectShow is a whole library that is 300KB when compiled, and I am using this for my RAT where my client is currently 90KB, and I dont want to increase it to 390...

Edit: I think AviCap is bad to use, after reading.
DirectShow is the one to go, you can opt for other "libraries" but they all use Directshow, i bet.

If you want an easier one, i suggest Aforge .net, but if you could grasp the DirectShow API you'd probably do a better job than that library does, just saying.
AviCap forget about that, it's an old, non-flexible API, it might work, it might not, you never know, if you want to support most of the Devices in modern computers an OS's, you have no choice but Directshow or even WIA, but the seconde one has some downsides. (search)
(Sep 30, 2014 01:33 PM)He B TeMy Wrote:  DirectShow is the one to go, you can opt for other "libraries" but they all use Directshow, i bet.

If you want an easier one, i suggest Aforge .net, but if you could grasp the DirectShow API you'd probably do a better job than that library does, just saying.
AviCap forget about that, it's an old, non-flexible API, it might work, it might not, you never know, if you want to support most of the Devices in modern computers an OS's, you have no choice but Directshow or even WIA, but the seconde one has some downsides. (search)

I ended up using aforge, good library indeed.


Possibly Related Threads...
Thread / Author Replies Views Last Post
[.NET] by SIM-4062753Dec 14, 2020 05:50 AM 1 372 Dec 14, 2020 05:50 AM
Last Post: HFDone
[C] by SecurifierJan 17, 2020 07:20 AM 12 416 Jan 17, 2020 07:20 AM
Last Post: SIM-3602340
[.NET] by iSevereJan 16, 2018 06:49 AM 6 276 Jan 16, 2018 06:49 AM
Last Post: Ninja