Problems with calling avifil32.dll function in vb.net



Hello, I have been struggling for days now to write a VB.Net
application which converts BMP Images to AVI. This program works just
fine in VB but will not run in VB.Net. The problem lies with the
conversion of VarPtr() in VB to some other means in VB.Net.

The main problem begins when calling the avifil32.dll function
AVISaveOptions Defined as follow:
Public Declare Function AVISaveOptions Lib "avifil32.dll" (ByVal hWnd
As Integer, ByVal uiFlags As Integer, ByVal nStreams As Integer, ByRef
ppavi As Integer, ByRef ppOptions As Integer) As Integer 'TRUE if user
pressed OK, False if cancel, or error if error

This function wants to receive a pointer to a pointer to an
AVI_COMPRESS_OPTIONS Structure. The problem is that with VB.Net we are
working with managed memory and it seems this function wants a pointer
to a pointer to unmanaged memory.

It has been suggested to use the following algorithm in order to get
the VarPtr within .Net:

Public Function VarPtr(ByVal o As Object) As Integer
Dim oGC As GCHandle = GCHandle.Alloc(o, GCHandleType.Pinned)
Dim ret As Integer = oGC.AddrOfPinnedObject.ToInt32
oGC.Free()
Return ret
End Function


I have attempted to use this method with no luck at all... I then came
across another trick for allocating the memory of the
AVI_COMPRESS_OPTIONS to unmanaged memory, and then passing a pointer to
that memory location to the AVISaveOptions function. Once the function
has completed I then read the memory location back in and I can get the
updated valued from the AVISaveOptions call. Here is the code that
accomplishes this for me:


Dim opts As AVI_COMPRESS_OPTIONS
'//Allocate enough memory on the global heap
Dim lpB As IntPtr = Marshal.AllocHGlobal(Len(opts))

Dim source(11) As Integer ' 11 elements in AVI_COMPRESS_OPTIONS, all of
type Integer
Dim destination(11) As Integer
source(0) = opts.fccType
source(1) = opts.fccHandler
source(2) = opts.dwKeyFrameEvery
source(3) = opts.dwQuality
source(4) = opts.dwBytesPerSecond
source(5) = opts.dwFlags
source(6) = opts.lpFormat
source(7) = opts.cbFormat
source(8) = opts.lpParms
source(9) = opts.cbParms
source(10) = opts.dwInterleaveEvery

'//Copy the managed array to the un-managed pointer
Marshal.Copy(source, 0, lpB, 11) 'Len(opts))

Dim pOpts As Integer
pOpts = lpB.ToInt32()

res = AVISaveOptions(Me.Handle.ToInt32, ICMF_CHOOSE_KEYFRAME Or
ICMF_CHOOSE_DATARATE, 1, ps, pOpts)

' Get the data back out of unmanaged memory
Marshal.Copy(lpB, destination, 0, 11)
opts.fccType = destination(0)
opts.fccHandler = destination(1)
opts.dwKeyFrameEvery = destination(2)
opts.dwQuality = destination(3)
opts.dwBytesPerSecond = destination(4)
opts.dwFlags = destination(5)
opts.lpFormat = destination(6)
opts.cbFormat = destination(7)
opts.lpParms = destination(8)
opts.cbParms = destination(9)
opts.dwInterleaveEvery = destination(10)

At this point my opts object has valid information after the user has
chosen their AVI format to save as. Everything seems to be going ok at
this point, the following code executes without error:

res = AVIMakeCompressedStream(psCompressed, ps, opts, 0)

I am still wondering if passing opts at this point if valid, have I
updated the object properly to pass it into this function call?

Then, once I try to call AVIStreamSetFormat the application fails with
a return HRESULT which has a value of -2147205018. Here is how I call
that function:


Dim B() As Byte = bmp.GetBitmapInfo()
Dim iLength As Integer = B.Length

'//Allocate enough memory on the global heap
Dim lpB2 As IntPtr = Marshal.AllocHGlobal(iLength)

'//Copy the managed array to the un-managed pointer
Marshal.Copy(B, 0, lpB2, iLength)

res = AVIStreamSetFormat(psCompressed, 0, lpB2.ToInt32(), iLength)

This code fails totally when selecting the MPEG4 compression format, it
seems to succeed with some other formats but the file is never written
to with my calls to AVIStreamWrite. It would seem that the problem lies
somehow with the opts.lpParms value which is created by the AVI dll
since the code passes the AVIStreamSetFormat when this value is set to
0, and not otherwise. Just for completeness, here is how I call the
AVIStreamWrite method:

' Now write out each video frame
For i = 0 To listBoxImageList.Items.Count - 1
listBoxImageList.SelectedIndex = i
bmp.CreateFromFile(listBoxImageList.Text) 'load the bitmap (ignore
errors)
' bmp.PointerToBits uses the same technique as above with using the
Marshal class to get a pointer the an unmanaged memory location holding
the bitmap info.
res = AVIStreamWrite(psCompressed, i, 1, bmp.PointerToBits,
bmp.SizeImage, AVIIF_KEYFRAME, 0, 0)
If (res <> AVIERR_OK) Then
MsgBox("AVIStreamWrite failed.")
Exit Function
End If
Next

Can anyone help me out and tell me what I am doing wrong in my code.
Has anyone had success with writing bmp images to an AVI file after
choosing a compression type in .NET? Any help would be greatly
appreciated.

.



Relevant Pages

  • Structure to Byte Array in VB.NET
    ... Dim TimeFrameCounter As Int16 ... I need to use this as a byte array so I can send it over a ethernet ... 'copy myStruct from the heap pointer into fsdata array ... 'release the heap memory ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Modify a .doc document with a macro without Word ?
    ... Const LL_ITEMPTR = 4 ' Pointer to the item ... Public Sub Add(Item As Variant, Optional Key As String, Optional Before As Variant, Optional After As Variant) ... Dim lpArray As Long ' Pointer to the first element of the array ... Dim lpItem As Long ' Pointer to the item ...
    (microsoft.public.scripting.vbscript)
  • Re: Very Slow reading excel data into an array (while opened in ne
    ... How can I read an excel file into memory without opening it? ... data array gets recycled each time it opens a new file so I don't have to ... Dim rowsMaster, colsMaster, lastCellMaster ...
    (microsoft.public.excel.programming)
  • Re: Is this math test too easy?
    ... > communications glitch; one of the more laughable cartoons ... it was loaded into physical memory and, ... > Or one can interpret the character string as one of the values ... A pointer to an integer? ...
    (sci.math)
  • Re: grow list by tail, pointer example recipe -- please comment
    ... manufacturing a pointer with that address. ... the next cons cell. ... believe these lists are in consecutive memory locations. ...
    (comp.lang.lisp)