views:

47

answers:

0

I've got a simple VB.NET app that captures video from a Webcam and saves it to a file using avicap32.dll. I've also one callback working that handles capStatusCallback.

My next step is set up the capVideoStreamCallback callback so I can do things with individual frames as they're captured.

I'm just going to show the code for the video stream callback for now. I can provide more of the rest of the code if needed.

Step 1 is defining the VIDEOHDR struct

Public Structure VIDEOHDR
    Dim lpData As IntPtr
    Dim dwBufferLength As Integer
    Dim dwBytesUsed As Integer
    Dim dwTimeCaptured As Integer
    Dim dwUser As Integer
    Dim dwFlags As Integer
    <VBFixedArray(3)> Dim dwReserved() As Integer
End Structure

Then I have my function delegate:

Public Delegate Sub VideoStreamCallback(ByVal hwnd As Integer, _
                                      ByRef lpVHdr As VIDEOHDR)

Then I have a declare function that points to SendMessageA but uses the delegate function as the type for the fourth parameter:

Public Declare Function SendVideoStreamCallbackMessage Lib "user32" _
                                               Alias "SendMessageA" _
   (ByVal hwnd As Integer, ByVal Msg As Integer, _
    ByVal wParam As Integer, _
    ByVal lParam As VideoStreamCallback) As Integer

After that, I have the function that should actually get called:

Public Sub HandleVideoStreamCallback(ByVal hwnd As Integer, _
                                     ByRef lpVHdr As VIDEOHDR)
    Debug.Print("Here!")
End Sub

Then I actually send the message to wire up the callback

SendVideoStreamCallbackMessage(Me.hWnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, _
                                   0, AddressOf HandleVideoStreamCallback)

Sending the message appears to work.

But HandleVideoStreamCallback never actually gets called while video is recording.

Then, when I send a WM_CAP_FILE_SAVEAS message to the capture window to save the captured video, I get an NullReferenceException: Object reference not set to an instance of an object. I should mention that the WM_CAP_FILE_SAVES works perfectly if I don't try to set the video stream callback.

The capStatusCallback is set up in exactly the same way and works the way it's supposed to. The biggest difference is that it only involves a string and not a data structure like VIDEOHDR.

Does anyone see anything obviously wrong? Any suggestions for things to try?


Update

I've made some progress.

After doing a bit of research, I've tried changing things around so that I'm declaring the callback like this:

<MarshalAs(UnmanagedType.FunctionPtr)> _
Public delVideoStreamCallback As VideoStreamCallback = _
                New VideoStreamCallback(AddressOf HandleVideoStreamCallback)

And then sending the message like this:

SendVideoStreamCallbackMessage(hWnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, delVideoStreamCallback)

It seems to like that better but then I get the exception below when I try to start capturing video.

SafeArrayTypeMismatchException:  Specified array was not of the expected type.

That sounds like something is going screwy with the VIDEOHDR structure.

Any thoughts?