Jump to content

[Solved] How to activate compression for AVI streams


UEZ
 Share

Recommended Posts

I'm trying to activate the compression feature in AVIFIL32.DLL using monoceres'

My problem is that the return value of the call

$aRet = DllCall($Avi32_Dll, "int", "AVIMakeCompressedStream", "ptr*", 0, "ptr", $pstream, "ptr", DllStructGetPtr($aco), "ptr*", 0)

is always 0x80040154 which is an error.

You can check out at MSDN how the AVI functions have to be called. Further I tried understand the VB5 code how the code is activating the compression.

Here the modified AVIWriter code which will take for 5 seconds at 15 fps screenshots from active window and put it to the avi container:

#AutoIt3Wrapper_UseX64=n
#include <WinAPI.au3>
 
#region AVIWriter UDF
;Global Const $mmioFOURCC_M_S_V_C = _Create_mmioFOURCC("MSVC") ;1129730893
Global Const $BITMAPFILEHEADER = "align 2;char magic[2];int size;short res1;short res2;ptr offset;"
Global Const $BITMAPINFOHEADER = "dword biSize;long biWidth;long biHeight;short biPlanes;short biBitCount;" & _
"dword biCompression;dword biSizeImage;long biXPelsPerMeter;long biYPelsPerMeter;dword biClrUsed;dword biClrImportant;"
Global Const $OF_CREATE = 0x00001000
Global Const $AVIIF_KEYFRAME = 0x00000010
Global Const $ICMF_CHOOSE_KEYFRAME = 1, $ICMF_CHOOSE_DATARATE = 2
Global Const $AVIERR_UNSUPPORTED = 0x80044065
Global Const $AVIERR_MEMORY = 0x80044067
Global Const $AVIERR_NOCOMPRESSOR = 0x80044071
Global Const $AVIERR_CANTCOMPRESS = 0x80044075
Global Const $AVIERR_ERROR = 0x800440C7
Global Const $AVIERR_OK = 0
Global $Avi32_Dll
 
;http://msdn.microsoft.com/en-us/library/ms899423.aspx
Global Const $AVISTREAMINFO = "dword fccType;dword fccHandler;dword dwFlags;dword dwCaps;short wPriority;short wLanguage;dword dwScale;" & _
"dword dwRate;dword dwStart;dword dwLength;dword dwInitialFrames;dword dwSuggestedBufferSize;dword dwQuality;" & _
"dword dwSampleSize;int rleft;int rtop;int rright;int rbottom;dword dwEditCount;dword dwFormatChangeCount;wchar[64];"
 
 
;http://msdn.microsoft.com/en-us/library/dd756791(v=VS.85).aspx
Global Const $AVICOMPRESSOPTIONS = "DWORD fccType;DWORD fccHandler;DWORD dwKeyFrameEvery;DWORD dwQuality;DWORD dwBytesPerSecond;" & _
"DWORD dwFlags;PTR lpFormat;DWORD cbFormat;PTR lpParms;DWORD cbParms;DWORD dwInterleaveEvery;"
 
Func _Create_mmioFOURCC($FOURCC) ;http://www.fourcc.org/codecs.php
If StringLen($FOURCC) <> 4 Then Return SetError(1, 0, 0)
Local $aFOURCC = StringSplit($FOURCC, "", 2)
Return BitOR(Asc($aFOURCC[0]), BitShift(Asc($aFOURCC[1]), -8), BitShift(Asc($aFOURCC[2]), -16), BitShift(Asc($aFOURCC[3]), -24))
EndFunc   ;==>_Create_mmioFOURCC
 
Func _DecodeFOURCC($iFOURCC)
If Not IsInt($iFOURCC) Then Return SetError(1, 0, 0)
Return Chr(BitAND($iFOURCC, 0xFF)) & Chr(BitShift(BitAND(0x0000FF00, $iFOURCC), 8)) & Chr(BitShift(BitAND(0x00FF0000, $iFOURCC), 16)) & Chr(BitShift($iFOURCC, 24))
EndFunc   ;==>_DecodeFOURCC
 
; monoceres, Prog@ndy
Func _CreateAvi($sFilename, $FrameRate, $Width, $Height, $BitCount = 24, $mmioFOURCC = "MSVC")
Local $RetArr[5] ; avi file handle, stream handle, bitmap count, BitmapInfoheader, Stride
 
Local $aRet, $pfile, $asi, $aco, $pstream, $psCompressed
 
$aRet = DllCall($Avi32_Dll, "int", "AVIFileOpenW", "ptr*", 0, "wstr", $sFilename, "uint", $OF_CREATE, "ptr", 0)
$pfile = $aRet[1]
 
Local $stride = BitAND(($Width * ($BitCount / 8) + 3), BitNOT(3))
 
Local $bi = DllStructCreate($BITMAPINFOHEADER)
DllStructSetData($bi, "biSize", DllStructGetSize($bi))
DllStructSetData($bi, "biWidth", $Width)
DllStructSetData($bi, "biHeight", $Height)
DllStructSetData($bi, "biPlanes", 1)
DllStructSetData($bi, "biBitCount", $BitCount)
DllStructSetData($bi, "biSizeImage", $stride * $Height)
 
$asi = DllStructCreate($AVISTREAMINFO)
DllStructSetData($asi, "fccType", _Create_mmioFOURCC("vids"))
DllStructSetData($asi, "fccHandler", 0) ;_Create_mmioFOURCC($mmioFOURCC))
DllStructSetData($asi, "dwScale", 1)
DllStructSetData($asi, "dwRate", $FrameRate)
;~  DllStructSetData($asi, "dwQuality", $Quality) ;Quality is represented as a number between 0 and 10,000. For compressed data, this typically represents the value of the quality parameter passed to the compression software. If set to –1, drivers use the default quality value.
DllStructSetData($asi, "rright", $Width)
DllStructSetData($asi, "rbottom", $Height)
;~  DllStructSetData($asi, "dwSuggestedBufferSize", $stride * $Height)
 
$aRet = DllCall($Avi32_Dll, "int", "AVIFileCreateStream", "ptr", $pfile, "ptr*", 0, "ptr", DllStructGetPtr($asi))
$pstream = $aRet[2]
 
$aco = DllStructCreate($AVICOMPRESSOPTIONS)
Local $hWnd= GUICreate("")
$aRet =  DllCall($Avi32_Dll, "int_ptr", "AVISaveOptions", "hwnd", $hWnd, "uint", BitOR($ICMF_CHOOSE_DATARATE, $ICMF_CHOOSE_KEYFRAME), "int", 1, "ptr*", $pstream, "ptr*", DllStructGetPtr($aco))
GUIDelete($hWnd)
If $aRet[0] <> 1 Then
$RetArr[0] = $pfile
$RetArr[1] = $pstream
Return SetError(1, 0, $RetArr)
EndIf
 
ConsoleWrite(_DecodeFOURCC(DllStructGetData($aco, "fccHandler")) & @CRLF)
 
$aRet = DllCall($Avi32_Dll, "int", "AVIMakeCompressedStream", "ptr*", 0, "ptr", $pstream, "ptr", DllStructGetPtr($aco), "ptr*", 0)
;~  ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aRet = ' & $aRet & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aRet = ' & Hex($aRet[0]) & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
If $aRet[0]  <> $AVIERR_OK Then
$RetArr[0] = $pfile
$RetArr[1] = $pstream
Return SetError(2, 0, $RetArr)
EndIf
$psCompressed = $aRet[1]
 
; The format for the stream is the same as BITMAPINFOHEADER
$aRet = DllCall($Avi32_Dll, "int", "AVIStreamSetFormat", "ptr", $psCompressed, "long", 0, "ptr", DllStructGetPtr($bi), "long", DllStructGetSize($bi))
 
$RetArr[0] = $pfile
$RetArr[1] = $psCompressed
$RetArr[2] = 0
$RetArr[3] = $bi
$RetArr[4] = $stride
Return $RetArr
EndFunc   ;==>_CreateAvi
 
; Adds a bitmap file to an already opened avi file.
; monoceres, Prog@ndy
Func _AddHBitmapToAvi(ByRef $Avi_Handle, $hBitmap)
Local $DC = _WinAPI_GetDC(0)
Local $hDC = _WinAPI_CreateCompatibleDC($DC)
_WinAPI_ReleaseDC(0, $DC)
 
Local $OldBMP = _WinAPI_SelectObject($hDC, $hBitmap)
Local $bits = DllStructCreate("byte[" & DllStructGetData($Avi_Handle[3], "biSizeImage") & "]")
_WinAPI_GetDIBits($hDC, $hBitmap, 0, Abs(DllStructGetData($Avi_Handle[3], "biHeight")), DllStructGetPtr($bits), DllStructGetPtr($Avi_Handle[3]), 0)
_WinAPI_SelectObject($hDC, $OldBMP)
_WinAPI_DeleteDC($hDC)
 
DllCall($Avi32_Dll, "int", "AVIStreamWrite", "ptr", $Avi_Handle[1], "long", $Avi_Handle[2], "long", 1, "ptr", DllStructGetPtr($bits), _
"long", DllStructGetSize($bits), "long", $AVIIF_KEYFRAME, "ptr*", 0, "ptr*", 0)
$Avi_Handle[2] += 1
EndFunc   ;==>_AddHBitmapToAvi
 
; Adds a bitmap file to an already opened avi file.
Func _AddBitmapToAvi(ByRef $Avi_Handle, $sBitmap)
Local $bm = LoadBitmap($sBitmap, True)
DllCall($Avi32_Dll, "int", "AVIStreamWrite", "ptr", $Avi_Handle[1], "long", $Avi_Handle[2], "long", 1, "ptr", DllStructGetPtr($bm[2]), _
"long", DllStructGetSize($bm[2]), "long", $AVIIF_KEYFRAME, "ptr*", 0, "ptr*", 0)
$Avi_Handle[2] += 1
EndFunc   ;==>_AddBitmapToAvi
 
; Returns array with 3 elements
; [0]=BITMAPFILEHEADER
; [1]=BITMAPINFOHEADER
; [2]=Bitmap data buffer (if specified)
Func LoadBitmap($sFilename, $LoadData = False)
Local $RetArr[3]
Local $byref
Local $bih, $bfh, $buffer, $fhandle
$bfh = DllStructCreate($BITMAPFILEHEADER)
$bih = DllStructCreate($BITMAPINFOHEADER)
$fhandle = _WinAPI_CreateFile($sFilename, 2, 2, 0, 0)
_WinAPI_ReadFile($fhandle, DllStructGetPtr($bfh), DllStructGetSize($bfh), $byref)
_WinAPI_ReadFile($fhandle, DllStructGetPtr($bih), DllStructGetSize($bih), $byref)
$RetArr[0] = $bfh
$RetArr[1] = $bih
 
If Not $LoadData Then
_WinAPI_CloseHandle($fhandle)
Return $RetArr
EndIf
 
$buffer = DllStructCreate("byte[" & DllStructGetData($bfh, "size") - 54 & "]")
$RetArr[2] = $buffer
_WinAPI_ReadFile($fhandle, DllStructGetPtr($buffer), DllStructGetSize($buffer), $byref)
_WinAPI_CloseHandle($fhandle)
 
Return $RetArr
EndFunc   ;==>LoadBitmap
 
; Init the avi library
Func _StartAviLibrary()
$Avi32_Dll = DllOpen("Avifil32.dll")
DllCall($Avi32_Dll, "none", "AVIFileInit")
;~  MsgBox(0,"",@error)
EndFunc   ;==>_StartAviLibrary
 
; Release the library
Func _StopAviLibrary()
DllCall($Avi32_Dll, "none", "AVIFileExit")
DllClose($Avi32_Dll)
EndFunc   ;==>_StopAviLibrary
 
Func _CloseAvi($Avi_Handle)
DllCall($Avi32_Dll, "int", "AVIStreamRelease", "ptr", $Avi_Handle[1])
DllCall($Avi32_Dll, "int", "AVIFileRelease", "ptr", $Avi_Handle[0])
EndFunc   ;==>_CloseAvi
#endregion
 
#region example
#include <Array.au3>
#include <Memory.au3>
#include <ScreenCapture.au3>
 
_GDIPlus_Startup()
HotKeySet("{ESC}", "close")
 
Break(0)
 
FileDelete(@ScriptDir & "\test.avi")
 
$tPoint = DllStructCreate($tagPOINT)
$aMPos = MouseGetPos()
DllStructSetData($tPoint, 1, $aMPos[0])
DllStructSetData($tPoint, 2, $aMPos[1])
$hWin = _WinAPI_WindowFromPoint($tPoint)
$hWinAncestor = _WinAPI_GetAncestor($hWin, 2)
$hWnd = HWnd($hWinAncestor)
$aPos  = WinGetPos($hWnd)
 
$rec_duration = 1000 * 1
 
ConsoleWrite("Starting...." & @CRLF)
 
_StartAviLibrary()
$aAVI = _CreateAvi(@ScriptDir & "\test.avi", 15, $aPos[2], $aPos[3])
If @error Then close()
 
$t = TimerInit()
 
Do
$hBmp = _ScreenCapture_CaptureWnd("", $hWnd)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
_AddHBitmapToAvi($aAVI, $hBmp)
_WinAPI_DeleteObject($hBmp)
If TimerDiff($t) > $rec_duration Then close()
Until False
 
Func close()
_GDIPlus_Shutdown()
_CloseAvi($aAVI)
_StopAviLibrary()
ConsoleWrite("AVI filesize: " & Round(FileGetSize(@ScriptDir & "\test.avi") / 1024^2, 2) & " MB" & @CRLF)
Exit
EndFunc   ;==>close
#endregion

When you start it you can select the codec for the compression but the script will stop because the return code of the function AVIMakeCompressedStream is not 0.

Any ideas how to pass properly the parameter of that function call?

Thanks,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

I'm trying to activate the compression feature in AVIFIL32.DLL using monoceres'

My problem is that the return value of the call

$aRet = DllCall($Avi32_Dll, "int", "AVIMakeCompressedStream", "ptr*", 0, "ptr", $pstream, "ptr", DllStructGetPtr($aco), "ptr*", 0)

is always 0x80040154 which is an error.

You can check out at MSDN how the AVI functions have to be called. Further I tried understand the VB5 code how the code is activating the compression.

Here the modified AVIWriter code which will take for 5 seconds at 15 fps screenshots from active window and put it to the avi container:

#AutoIt3Wrapper_UseX64=n
#include <WinAPI.au3>
 
#region AVIWriter UDF
;Global Const $mmioFOURCC_M_S_V_C = _Create_mmioFOURCC("MSVC") ;1129730893
Global Const $BITMAPFILEHEADER = "align 2;char magic[2];int size;short res1;short res2;ptr offset;"
Global Const $BITMAPINFOHEADER = "dword biSize;long biWidth;long biHeight;short biPlanes;short biBitCount;" & _
"dword biCompression;dword biSizeImage;long biXPelsPerMeter;long biYPelsPerMeter;dword biClrUsed;dword biClrImportant;"
Global Const $OF_CREATE = 0x00001000
Global Const $AVIIF_KEYFRAME = 0x00000010
Global Const $ICMF_CHOOSE_KEYFRAME = 1, $ICMF_CHOOSE_DATARATE = 2
Global Const $AVIERR_UNSUPPORTED = 0x80044065
Global Const $AVIERR_MEMORY = 0x80044067
Global Const $AVIERR_NOCOMPRESSOR = 0x80044071
Global Const $AVIERR_CANTCOMPRESS = 0x80044075
Global Const $AVIERR_ERROR = 0x800440C7
Global Const $AVIERR_OK = 0
Global $Avi32_Dll
 
;http://msdn.microsoft.com/en-us/library/ms899423.aspx
Global Const $AVISTREAMINFO = "dword fccType;dword fccHandler;dword dwFlags;dword dwCaps;short wPriority;short wLanguage;dword dwScale;" & _
"dword dwRate;dword dwStart;dword dwLength;dword dwInitialFrames;dword dwSuggestedBufferSize;dword dwQuality;" & _
"dword dwSampleSize;int rleft;int rtop;int rright;int rbottom;dword dwEditCount;dword dwFormatChangeCount;wchar[64];"
 
 
;http://msdn.microsoft.com/en-us/library/dd756791(v=VS.85).aspx
Global Const $AVICOMPRESSOPTIONS = "DWORD fccType;DWORD fccHandler;DWORD dwKeyFrameEvery;DWORD dwQuality;DWORD dwBytesPerSecond;" & _
"DWORD dwFlags;PTR lpFormat;DWORD cbFormat;PTR lpParms;DWORD cbParms;DWORD dwInterleaveEvery;"
 
Func _Create_mmioFOURCC($FOURCC) ;http://www.fourcc.org/codecs.php
If StringLen($FOURCC) <> 4 Then Return SetError(1, 0, 0)
Local $aFOURCC = StringSplit($FOURCC, "", 2)
Return BitOR(Asc($aFOURCC[0]), BitShift(Asc($aFOURCC[1]), -8), BitShift(Asc($aFOURCC[2]), -16), BitShift(Asc($aFOURCC[3]), -24))
EndFunc   ;==>_Create_mmioFOURCC
 
Func _DecodeFOURCC($iFOURCC)
If Not IsInt($iFOURCC) Then Return SetError(1, 0, 0)
Return Chr(BitAND($iFOURCC, 0xFF)) & Chr(BitShift(BitAND(0x0000FF00, $iFOURCC), 8)) & Chr(BitShift(BitAND(0x00FF0000, $iFOURCC), 16)) & Chr(BitShift($iFOURCC, 24))
EndFunc   ;==>_DecodeFOURCC
 
; monoceres, Prog@ndy
Func _CreateAvi($sFilename, $FrameRate, $Width, $Height, $BitCount = 24, $mmioFOURCC = "MSVC")
Local $RetArr[5] ; avi file handle, stream handle, bitmap count, BitmapInfoheader, Stride
 
Local $aRet, $pfile, $asi, $aco, $pstream, $psCompressed
 
$aRet = DllCall($Avi32_Dll, "int", "AVIFileOpenW", "ptr*", 0, "wstr", $sFilename, "uint", $OF_CREATE, "ptr", 0)
$pfile = $aRet[1]
 
Local $stride = BitAND(($Width * ($BitCount / 8) + 3), BitNOT(3))
 
Local $bi = DllStructCreate($BITMAPINFOHEADER)
DllStructSetData($bi, "biSize", DllStructGetSize($bi))
DllStructSetData($bi, "biWidth", $Width)
DllStructSetData($bi, "biHeight", $Height)
DllStructSetData($bi, "biPlanes", 1)
DllStructSetData($bi, "biBitCount", $BitCount)
DllStructSetData($bi, "biSizeImage", $stride * $Height)
 
$asi = DllStructCreate($AVISTREAMINFO)
DllStructSetData($asi, "fccType", _Create_mmioFOURCC("vids"))
DllStructSetData($asi, "fccHandler", 0) ;_Create_mmioFOURCC($mmioFOURCC))
DllStructSetData($asi, "dwScale", 1)
DllStructSetData($asi, "dwRate", $FrameRate)
;~  DllStructSetData($asi, "dwQuality", $Quality) ;Quality is represented as a number between 0 and 10,000. For compressed data, this typically represents the value of the quality parameter passed to the compression software. If set to –1, drivers use the default quality value.
DllStructSetData($asi, "rright", $Width)
DllStructSetData($asi, "rbottom", $Height)
;~  DllStructSetData($asi, "dwSuggestedBufferSize", $stride * $Height)
 
$aRet = DllCall($Avi32_Dll, "int", "AVIFileCreateStream", "ptr", $pfile, "ptr*", 0, "ptr", DllStructGetPtr($asi))
$pstream = $aRet[2]
 
$aco = DllStructCreate($AVICOMPRESSOPTIONS)
Local $hWnd= GUICreate("")
$aRet =  DllCall($Avi32_Dll, "int_ptr", "AVISaveOptions", "hwnd", $hWnd, "uint", BitOR($ICMF_CHOOSE_DATARATE, $ICMF_CHOOSE_KEYFRAME), "int", 1, "ptr*", $pstream, "ptr*", DllStructGetPtr($aco))
GUIDelete($hWnd)
If $aRet[0] <> 1 Then
$RetArr[0] = $pfile
$RetArr[1] = $pstream
Return SetError(1, 0, $RetArr)
EndIf
 
ConsoleWrite(_DecodeFOURCC(DllStructGetData($aco, "fccHandler")) & @CRLF)
 
$aRet = DllCall($Avi32_Dll, "int", "AVIMakeCompressedStream", "ptr*", 0, "ptr", $pstream, "ptr", DllStructGetPtr($aco), "ptr*", 0)
;~  ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aRet = ' & $aRet & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aRet = ' & Hex($aRet[0]) & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
If $aRet[0]  <> $AVIERR_OK Then
$RetArr[0] = $pfile
$RetArr[1] = $pstream
Return SetError(2, 0, $RetArr)
EndIf
$psCompressed = $aRet[1]
 
; The format for the stream is the same as BITMAPINFOHEADER
$aRet = DllCall($Avi32_Dll, "int", "AVIStreamSetFormat", "ptr", $psCompressed, "long", 0, "ptr", DllStructGetPtr($bi), "long", DllStructGetSize($bi))
 
$RetArr[0] = $pfile
$RetArr[1] = $psCompressed
$RetArr[2] = 0
$RetArr[3] = $bi
$RetArr[4] = $stride
Return $RetArr
EndFunc   ;==>_CreateAvi
 
; Adds a bitmap file to an already opened avi file.
; monoceres, Prog@ndy
Func _AddHBitmapToAvi(ByRef $Avi_Handle, $hBitmap)
Local $DC = _WinAPI_GetDC(0)
Local $hDC = _WinAPI_CreateCompatibleDC($DC)
_WinAPI_ReleaseDC(0, $DC)
 
Local $OldBMP = _WinAPI_SelectObject($hDC, $hBitmap)
Local $bits = DllStructCreate("byte[" & DllStructGetData($Avi_Handle[3], "biSizeImage") & "]")
_WinAPI_GetDIBits($hDC, $hBitmap, 0, Abs(DllStructGetData($Avi_Handle[3], "biHeight")), DllStructGetPtr($bits), DllStructGetPtr($Avi_Handle[3]), 0)
_WinAPI_SelectObject($hDC, $OldBMP)
_WinAPI_DeleteDC($hDC)
 
DllCall($Avi32_Dll, "int", "AVIStreamWrite", "ptr", $Avi_Handle[1], "long", $Avi_Handle[2], "long", 1, "ptr", DllStructGetPtr($bits), _
"long", DllStructGetSize($bits), "long", $AVIIF_KEYFRAME, "ptr*", 0, "ptr*", 0)
$Avi_Handle[2] += 1
EndFunc   ;==>_AddHBitmapToAvi
 
; Adds a bitmap file to an already opened avi file.
Func _AddBitmapToAvi(ByRef $Avi_Handle, $sBitmap)
Local $bm = LoadBitmap($sBitmap, True)
DllCall($Avi32_Dll, "int", "AVIStreamWrite", "ptr", $Avi_Handle[1], "long", $Avi_Handle[2], "long", 1, "ptr", DllStructGetPtr($bm[2]), _
"long", DllStructGetSize($bm[2]), "long", $AVIIF_KEYFRAME, "ptr*", 0, "ptr*", 0)
$Avi_Handle[2] += 1
EndFunc   ;==>_AddBitmapToAvi
 
; Returns array with 3 elements
; [0]=BITMAPFILEHEADER
; [1]=BITMAPINFOHEADER
; [2]=Bitmap data buffer (if specified)
Func LoadBitmap($sFilename, $LoadData = False)
Local $RetArr[3]
Local $byref
Local $bih, $bfh, $buffer, $fhandle
$bfh = DllStructCreate($BITMAPFILEHEADER)
$bih = DllStructCreate($BITMAPINFOHEADER)
$fhandle = _WinAPI_CreateFile($sFilename, 2, 2, 0, 0)
_WinAPI_ReadFile($fhandle, DllStructGetPtr($bfh), DllStructGetSize($bfh), $byref)
_WinAPI_ReadFile($fhandle, DllStructGetPtr($bih), DllStructGetSize($bih), $byref)
$RetArr[0] = $bfh
$RetArr[1] = $bih
 
If Not $LoadData Then
_WinAPI_CloseHandle($fhandle)
Return $RetArr
EndIf
 
$buffer = DllStructCreate("byte[" & DllStructGetData($bfh, "size") - 54 & "]")
$RetArr[2] = $buffer
_WinAPI_ReadFile($fhandle, DllStructGetPtr($buffer), DllStructGetSize($buffer), $byref)
_WinAPI_CloseHandle($fhandle)
 
Return $RetArr
EndFunc   ;==>LoadBitmap
 
; Init the avi library
Func _StartAviLibrary()
$Avi32_Dll = DllOpen("Avifil32.dll")
DllCall($Avi32_Dll, "none", "AVIFileInit")
;~  MsgBox(0,"",@error)
EndFunc   ;==>_StartAviLibrary
 
; Release the library
Func _StopAviLibrary()
DllCall($Avi32_Dll, "none", "AVIFileExit")
DllClose($Avi32_Dll)
EndFunc   ;==>_StopAviLibrary
 
Func _CloseAvi($Avi_Handle)
DllCall($Avi32_Dll, "int", "AVIStreamRelease", "ptr", $Avi_Handle[1])
DllCall($Avi32_Dll, "int", "AVIFileRelease", "ptr", $Avi_Handle[0])
EndFunc   ;==>_CloseAvi
#endregion
 
#region example
#include <Array.au3>
#include <Memory.au3>
#include <ScreenCapture.au3>
 
_GDIPlus_Startup()
HotKeySet("{ESC}", "close")
 
Break(0)
 
FileDelete(@ScriptDir & "\test.avi")
 
$tPoint = DllStructCreate($tagPOINT)
$aMPos = MouseGetPos()
DllStructSetData($tPoint, 1, $aMPos[0])
DllStructSetData($tPoint, 2, $aMPos[1])
$hWin = _WinAPI_WindowFromPoint($tPoint)
$hWinAncestor = _WinAPI_GetAncestor($hWin, 2)
$hWnd = HWnd($hWinAncestor)
$aPos  = WinGetPos($hWnd)
 
$rec_duration = 1000 * 1
 
ConsoleWrite("Starting...." & @CRLF)
 
_StartAviLibrary()
$aAVI = _CreateAvi(@ScriptDir & "\test.avi", 15, $aPos[2], $aPos[3])
If @error Then close()
 
$t = TimerInit()
 
Do
$hBmp = _ScreenCapture_CaptureWnd("", $hWnd)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
_AddHBitmapToAvi($aAVI, $hBmp)
_WinAPI_DeleteObject($hBmp)
If TimerDiff($t) > $rec_duration Then close()
Until False
 
Func close()
_GDIPlus_Shutdown()
_CloseAvi($aAVI)
_StopAviLibrary()
ConsoleWrite("AVI filesize: " & Round(FileGetSize(@ScriptDir & "\test.avi") / 1024^2, 2) & " MB" & @CRLF)
Exit
EndFunc   ;==>close
#endregion

When you start it you can select the codec for the compression but the script will stop because the return code of the function AVIMakeCompressedStream is not 0.

Any ideas how to pass properly the parameter of that function call?

Thanks,

UEZ

I have writed sth about it by C++, I pasted it here, maybe it could help you.

Some comments were writed by Chinese.

// AVITools.cpp : implementation file  
//  
   
#include "stdafx.h"  
#include "AVITools.h"  
   
/////////////////////////////////////////////////////////////////////////////  
// CAVITools  
   
/* 
     构造函数初始化环境以及数据 
*/  
CAVITools::CAVITools()  
{  
     //  初始化 AVI 库  
     ::AVIFileInit();  
   
     m_strAviFileName       = _T("");      //  AVI 文件名  
     m_iCurrentFrameCount    = 0;           //  当前侦  
     m_iWidth               = -1;          //  侦宽度(像素)  
     m_iHeight             = -1;           //  侦高度(像素)  
   
     m_pAviFile           = NULL;        //  PAVIFILE  
     m_pAviStream           = NULL;      //  PAVISTREAM  
     m_pCompressedAviStream  = NULL;         //  PCOMPRESSAVISTREAM  
     m_pBuffer             = NULL;       //  缓冲区  
     m_pFormat             = NULL;       //  格式指针  
   
     //  初始化结构变量  
     memset(&m_AviStreamInfo, 0, sizeof(AVISTREAMINFO));  
     memset(&m_AviCompressOptions, 0, sizeof(AVICOMPRESSOPTIONS));  
}  
   
/* 
     析构函数清理内存,退出 AVI 库 
*/  
CAVITools::~CAVITools()  
{  
     CleanUp();  
     ::AVIFileExit();  
}  
   
/* 
     CREATE A AVI FILE ON DISK 
     ARGUMENTS: 
         sFileName         -   THE PATHNAME OF AVI FILE THAT YOU WANT TO CREATE 
     RETURN VALUE: 
         ERR_OK           -   SUCCESS 
         ERR_FORMAT_NOT_SET  -   UNKNOWN AVI STREAM FORMAT, SUCH AS PATTLE,WIDTH AND HEIGHT, ETC. 
                                 YOU SHOULD CALL 'SetStreamFormatFromFile' OR 'SetStreamFormatFromMemory' 
                                 IN ORDER TO SET STREAM FORMAT BEFORE YOU CALL THIS FUNCTION 
         ERR_AVI_FILE_ERROR  -   POSSIBLE RESEAN: 
                                 1. AVIFileOpen Error 
                                 2. AVIFileCreateStream Error 
                                 3. AVISaveOptions Error 
                                 4. AVIMakeCompressedStream Error 
                                 5. AVIStreamSetFormat Error 
*/  
HRESULT  
CAVITools::CreateAviFile(CHAR *sFileName, DWORD dwRate)  
{  
     m_strAviFileName    = sFileName;  
   
     HRESULT         hr;  
   
     if  (NULL   == m_pFormat)  
     {  
         m_iLastErrorNumber  = ERR_FORMAT_NOT_SET;  
         m_sLastErrorDescribe.Format("没有设置 AVI 流格式,例如调色板、图象大小等");  
         return ERR_FORMAT_NOT_SET;  
     }  
   
     m_iWidth    = m_pFormat->biWidth;  
     m_iHeight   = m_pFormat->biHeight;  
   
     //  创建 AVI 文件  
     hr  = ::AVIFileOpen(&m_pAviFile, m_strAviFileName, OF_CREATE | OF_WRITE, NULL);  
     if  (AVIERR_OK  != hr)  
     //  创建文件失败  
     {  
         CleanUp();  
         m_iLastErrorNumber  = ERR_AVI_FILE_ERROR;  
         m_sLastErrorDescribe.Format("AVIFileOpen 函数出错:%ld",hr);  
         return ERR_AVI_FILE_ERROR;  
     }  
       
     //  初始化流信息结构  
     m_AviStreamInfo.fccType                 = streamtypeVIDEO;  
     m_AviStreamInfo.fccHandler           = 0;  
     m_AviStreamInfo.dwScale                 = 1;  
     m_AviStreamInfo.dwRate               = dwRate;  
     m_AviStreamInfo.dwSuggestedBufferSize   = m_pFormat->biSizeImage;  
     ::SetRect(&m_AviStreamInfo.rcFrame, 0, 0, (INT)m_pFormat->biWidth, (INT)m_pFormat->biHeight);  
   
     //  创建 AVI 视频流  
     hr  = ::AVIFileCreateStream(m_pAviFile,&m_pAviStream,&m_AviStreamInfo);  
     if  (AVIERR_OK  != hr)  
     //  创建视频流失败  
     {  
         CleanUp();  
         m_iLastErrorNumber  = ERR_AVI_FILE_ERROR;  
         m_sLastErrorDescribe.Format("AVIFileCreateStream 函数出错:%ld",hr);  
         return ERR_AVI_FILE_ERROR;  
     }  
   
     //  创建压缩信息  
     LPAVICOMPRESSOPTIONS FAR    m_pFar[1];  
     m_pFar[0]   = &m_AviCompressOptions;  
   
     BOOL    bResult;  
   
//  bResult = ::AVISaveOptions(NULL, ICMF_CHOOSE_KEYFRAME|ICMF_CHOOSE_DATARATE|ICMF_CHOOSE_PREVIEW, 1, &m_pAviStream, m_pFar);  
     bResult = TRUE;  
   
     m_AviCompressOptions.fccType           = 0;  
     m_AviCompressOptions.fccHandler         = 1684633187; // 1668707181;  
     m_AviCompressOptions.dwKeyFrameEvery    = 0;  
     m_AviCompressOptions.dwQuality       = 10000; // 8500;  
     m_AviCompressOptions.dwBytesPerSecond   = 0;  
     m_AviCompressOptions.dwFlags           = 8;  
     m_AviCompressOptions.lpFormat         = NULL; // 0x0;  
     m_AviCompressOptions.cbFormat         = 0;  
     m_AviCompressOptions.lpParms           = (VOID *)(4806108); // (VOID *)(0x00509e60);  
     m_AviCompressOptions.cbParms           = 0;//4  
     m_AviCompressOptions.dwInterleaveEvery  = 0;  
   
/* 
CString  sInfo; 
CHAR        sBuf[100]; 
  
sprintf(sBuf, "fccType        = %ld\r\n", m_AviCompressOptions.fccType); 
sInfo      += sBuf; 
sprintf(sBuf, "fccHandler      = %ld\r\n", m_AviCompressOptions.fccHandler); 
sInfo      += sBuf; 
sprintf(sBuf, "dwKeyFrameEvery    = %ld\r\n", m_AviCompressOptions.dwKeyFrameEvery); 
sInfo      += sBuf; 
sprintf(sBuf, "dwQuality        = %ld\r\n", m_AviCompressOptions.dwQuality); 
sInfo      += sBuf; 
sprintf(sBuf, "dwBytesPerSecond = %ld\r\n", m_AviCompressOptions.dwBytesPerSecond); 
sInfo      += sBuf; 
sprintf(sBuf, "dwFlags        = %ld\r\n", m_AviCompressOptions.dwFlags); 
sInfo      += sBuf; 
sprintf(sBuf, "lpFormat  = %ld\r\n", (DWORD)(m_AviCompressOptions.lpFormat)); 
sInfo      += sBuf; 
sprintf(sBuf, "cbFormat  = %ld\r\n", m_AviCompressOptions.cbFormat); 
sInfo      += sBuf; 
sprintf(sBuf, "lpParms        = %ld\r\n", (DWORD)(m_AviCompressOptions.lpParms)); 
sInfo      += sBuf; 
sprintf(sBuf, "cbParms        = %ld\r\n", (DWORD)(m_AviCompressOptions.cbParms)); 
sInfo      += sBuf; 
sprintf(sBuf, "dwInterleaveEvery    = %ld\r\n", (DWORD)(m_AviCompressOptions.dwInterleaveEvery)); 
sInfo      += sBuf; 
FILE    *fp = fopen("c:\\bxx\\temp.txt", "w"); 
if  (NULL != fp) 
{ 
     fprintf(fp, sInfo.GetBuffer(sInfo.GetLength())); 
     fclose(fp); 
} 
*/  
//AfxMessageBox(sInfo);  
   
//    DWORD    fccType;                 /* stream type, for consistency */  
//    DWORD    fccHandler;               /* compressor */  
//    DWORD    dwKeyFrameEvery;         /* keyframe rate */  
//    DWORD    dwQuality;                 /* compress quality 0-10,000 */  
//    DWORD    dwBytesPerSecond;           /* bytes per second */  
//    DWORD    dwFlags;                 /* flags... see below */  
//    LPVOID      lpFormat;                /* save format */  
//    DWORD    cbFormat;  
//    LPVOID      lpParms;                  /* compressor options */  
//    DWORD    cbParms;  
//    DWORD    dwInterleaveEvery;         /* for non-video streams only */  
   
     if  (FALSE  == bResult)  
     //  创建压缩信息失败  
     {  
         CleanUp();  
         m_iLastErrorNumber  = ERR_AVI_FILE_ERROR;  
         m_sLastErrorDescribe.Format("AVISaveOptions 函数出错");  
         return ERR_AVI_FILE_ERROR;  
     }  
   
   
     //  创建压缩的视频流  
     hr  = ::AVIMakeCompressedStream(&m_pCompressedAviStream, m_pAviStream, &m_AviCompressOptions, NULL);  
   
     if  (AVIERR_OK  != hr)  
     //  创建压缩视频流失败  
     {  
         CleanUp();  
         m_iLastErrorNumber  = ERR_AVI_FILE_ERROR;  
         m_sLastErrorDescribe.Format("AVIMakeCompressedStream 函数出错:%ld", hr);  
         return ERR_AVI_FILE_ERROR;  
     }  
   
     //  设置视频流格式  
     hr  = ::AVIStreamSetFormat(m_pCompressedAviStream, 0, m_pFormat, m_iFormatLength);  
     if  (AVIERR_OK  != hr)  
     //  设置视频流格式错误  
     {  
         CleanUp();  
         m_iLastErrorNumber  = ERR_AVI_FILE_ERROR;  
         m_sLastErrorDescribe.Format("AVIStreamSetFormat 函数出错:%ld", hr);  
         return ERR_AVI_FILE_ERROR;  
     }  
   
     //  创建 AVI 文件正确  
     return ERR_OK;  
}  
   
/* 
     APPEND A SAMPLE AT THE END OF THE CREATED AVI STREAM FROM A BITMAP FILE 
     ARGUMENTS: 
         sBitmapFilePathName     -   THE PATHNAME OF A BITMAP FILE THAT YOU WANT TO APPEND TO THE STREAM 
     RETURN VALUE: 
         ERR_OK               -   SUCCESS 
         ERR_CANNOT_OPEN_FILE    -   CANNOT OPEN THE SPECIFIED FILE 
         ERR_READ_FILE_ERROR     -   READ FILE ERROR 
         ERR_BAD_FORMAT       -   FILE FORMAT ERROR, SUCH AS NO BITMAP IDENTITY 'BM' 
         ERR_OUT_OF_MEMORY     -   OUT OF MEMORY 
         ERR_IMAGE_SIZE_ERROR    -   IMAGE SIZE CONFLICT WITH THE PREDEFINE SIZE IN STREAM FORMAT 
         ERR_AVI_FILE_ERROR   -   ERROR OCCUR WHEN WRITE DATA TO STREAM 
*/  
HRESULT  
CAVITools::AddFileFrame(CHAR *sBitmapFilePathName)  
{  
     BITMAPFILEHEADER    bfh;  
     long               datasize;  
     HRESULT             hr;  
     CHAR               *pBuffer;  
   
     //  没有创建的成功压缩流  
     if (NULL == m_pCompressedAviStream)  
     {  
         m_iLastErrorNumber  = ERR_AVI_FILE_NOT_CREATE;  
         m_sLastErrorDescribe.Format("AVI 文件没有创建");  
         return  ERR_AVI_FILE_NOT_CREATE;  
     }  
   
     //  没有指定正确的位图文件名  
     if (NULL == sBitmapFilePathName)  
     {  
         m_iLastErrorNumber  = ERR_ARGUMENTS_ERROR;  
         m_sLastErrorDescribe.Format("参数错误:文件名指针为空");  
         return  ERR_ARGUMENTS_ERROR;  
     }  
       
     //  打开指定的位图文件  
     FILE    *fp = fopen(sBitmapFilePathName, "rb");  
     if (NULL == fp)  
     //  无法正确打开文件  
     {  
         m_iLastErrorNumber  = ERR_CANNOT_OPEN_FILE;  
         m_sLastErrorDescribe.Format("无法打开文件 %s",sBitmapFilePathName);  
         return ERR_CANNOT_OPEN_FILE;  
     }  
   
     //  读取文件头  
     if  (1 != fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp))  
     {  
         fclose(fp);  
         m_iLastErrorNumber  = ERR_READ_FILE_ERROR;  
         m_sLastErrorDescribe.Format("读取文件头出错:%s",sBitmapFilePathName);  
         return ERR_READ_FILE_ERROR;  
     }  
   
     //  Validate File Type  
     if (0x4d42 != bfh.bfType)  
     {  
         fclose(fp);  
         m_iLastErrorNumber  = ERR_BAD_FORMAT;  
         m_sLastErrorDescribe.Format("文件格式错误:文件 %s 的前两个字节不是 'BM'",sBitmapFilePathName);  
         return ERR_BAD_FORMAT;  
     }  
   
     //  Alloc Memory  
     datasize    = bfh.bfSize - sizeof(BITMAPFILEHEADER);  
     pBuffer     = new CHAR[datasize];  
     if (NULL == pBuffer)  
     {  
         fclose(fp);  
         m_iLastErrorNumber  = ERR_OUT_OF_MEMORY;  
         m_sLastErrorDescribe.Format("内存溢出");  
         return ERR_OUT_OF_MEMORY;  
     }  
   
     //  Read Entire File  
     if (1 != fread(m_pBuffer,datasize,1,fp))  
     {  
         fclose(fp);  
         delete pBuffer;  
         m_iLastErrorNumber  = ERR_READ_FILE_ERROR;  
         m_sLastErrorDescribe.Format("读取文件内容出错:%s",sBitmapFilePathName);  
         return ERR_READ_FILE_ERROR;  
     }  
   
     //  Close File  
     fclose(fp);  
   
     BITMAPINFOHEADER    *pbih     = NULL;  
     RGBQUAD             *pPattle    = NULL;  
     CHAR               *pBits    = NULL;  
   
     //  Init Pointer  
     pbih    = (BITMAPINFOHEADER *)pBuffer;  
     pBits   = pBuffer + bfh.bfOffBits - sizeof(BITMAPFILEHEADER);  
     if (8 == pbih->biBitCount)  
     {  
         pPattle = (RGBQUAD *)(m_pBuffer + pbih->biClrUsed * sizeof(RGBQUAD));  
     }  
     else if (16 == pbih->biBitCount || 24 == pbih->biBitCount)  
     {  
         pPattle     = NULL;  
     }  
     else  
     {  
         delete pBuffer;  
         m_iLastErrorNumber  = ERR_BAD_FORMAT;  
         m_sLastErrorDescribe.Format("文件格式错误:不支持 %d 位颜色的图象",(INT)pbih->biBitCount);  
         return ERR_BAD_FORMAT;  
     }  
   
     //  Validate Image Size  
     if (pbih->biWidth != m_iWidth || pbih->biHeight != m_iHeight)  
     {  
         delete pBuffer;  
         m_iLastErrorNumber  = ERR_IMAGE_SIZE_ERROR;  
         m_sLastErrorDescribe.Format("该图象的大小与预定义的大小不匹配");  
         return ERR_IMAGE_SIZE_ERROR;  
     }  
   
     //  Write Compressed Avi Stream  
     hr  = ::AVIStreamWrite(m_pCompressedAviStream,  
         m_iCurrentFrameCount,  
         1,  
         (LPBYTE)pBits,  
         pbih->biSizeImage,  
         AVIIF_KEYFRAME,  
         NULL,  
         NULL);  
   
     if (AVIERR_OK != hr)  
     {  
         delete pBuffer;  
         m_iLastErrorNumber  = ERR_IMAGE_SIZE_ERROR;  
         m_sLastErrorDescribe.Format("AVIStreamWrite 函数出错:%ld",hr);  
         return ERR_AVI_FILE_ERROR;  
     }  
   
     delete pBuffer;  
     m_iCurrentFrameCount++;  
   
     m_iLastErrorNumber  = ERR_OK;  
     m_sLastErrorDescribe.Empty();  
     return ERR_OK;  
}  
   
/* 
     从内存中向 AVI 流中增加一侦 
     输入参数: 
         pBits                 -   位图数据内存地址 
     返回值: 
         ERR_OK               -   执行成功 
         ERR_AVI_FILE_NOT_CREATE -   文件没有创建 
         ERR_ARGUMENTS_ERROR     -   参数错误 
         ERR_AVI_FILE_ERROR   -   添加时出现错误 
  
*/  
HRESULT  
CAVITools::AddMemFrame(CHAR *pBits)  
{  
     HRESULT     hr;  
   
     //  验证压缩流是否可用  
     if (NULL == m_pCompressedAviStream)  
     {  
         m_iLastErrorNumber  = ERR_AVI_FILE_NOT_CREATE;  
         m_sLastErrorDescribe.Format("AVI 文件没有创建");  
         return  ERR_AVI_FILE_NOT_CREATE;  
     }  
   
     //  验证位图数据是否可能可用  
     if (NULL == pBits)  
     {  
         m_iLastErrorNumber  = ERR_ARGUMENTS_ERROR;  
         m_sLastErrorDescribe.Format("参数错误:指针为空");  
         return  ERR_ARGUMENTS_ERROR;  
     }  
   
     //  增加侦  
     hr  = ::AVIStreamWrite(m_pCompressedAviStream,  
         m_iCurrentFrameCount,  
         1,  
         (LPBYTE)pBits,  
         m_iFrameSize,  
         AVIIF_KEYFRAME,  
         NULL,  
         NULL);  
       
     if (AVIERR_OK != hr)  
     {  
         m_iLastErrorNumber  = ERR_AVI_FILE_ERROR;  
         m_sLastErrorDescribe.Format("AVIStreamWrite 函数执行失败:%ld",hr);  
         return  ERR_AVI_FILE_ERROR;  
     }  
   
     //  增加侦数量  
     m_iCurrentFrameCount++;  
   
     //  返回成功标志  
     m_iLastErrorNumber  = ERR_OK;  
     m_sLastErrorDescribe.Empty();  
     return ERR_OK;  
}  
   
/* 
     释放资源 
*/  
BOOL  
CAVITools::CleanUp()  
{  
     //  释放压缩流  
     if (NULL != m_pCompressedAviStream)  
     {  
         ::AVIStreamRelease(m_pCompressedAviStream);  
         m_pCompressedAviStream  = NULL;  
     }  
   
     //  释放 AVI 流  
     if (NULL != m_pAviStream)  
     {  
         ::AVIStreamRelease(m_pAviStream);  
         m_pAviStream    = NULL;  
     }  
   
     //  释放文件  
     if (NULL != m_pAviFile)  
     {  
         ::AVIFileRelease(m_pAviFile);  
         m_pAviFile   = NULL;  
     }  
   
     //  释放分配的内存  
     if (NULL != m_pBuffer)  
     {  
         delete m_pBuffer;  
         m_pBuffer     = NULL;  
     }  
   
     //  成员数据初始化  
     m_strAviFileName       = _T("");  
     m_iCurrentFrameCount    = 0;  
     memset(&m_AviStreamInfo, 0, sizeof(AVISTREAMINFO));  
     memset(&m_AviCompressOptions, 0, sizeof(AVICOMPRESSOPTIONS));  
   
     return  (TRUE);  
}  
   
/* 
     从位图文件中读取格式,设置流格式 
     输入参数: 
         sBmpFile       -   用于设置格式的位图文件磁盘位置 
     返回值: 
*/  
HRESULT  
CAVITools::SetStreamFormatFromFile(CHAR *sBmpFile)  
{  
     INT                 needlength;  
     INT                 pattlelength;  
     BITMAPFILEHEADER    bfh;  
     BITMAPINFOHEADER    bih;  
     CHAR               *pattlebuf  = NULL;  
     FILE               *fp = NULL;  
   
     //  如果曾经设置过格式,将其删除  
     if (NULL != m_pFormat)  
     {  
         delete m_pFormat;  
         m_pFormat   = NULL;  
     }  
   
     //  打开文件  
     if (NULL == (fp = fopen(sBmpFile,"rb")))  
     {  
         m_iLastErrorNumber  = ERR_CANNOT_OPEN_FILE;  
         m_sLastErrorDescribe.Format("无法打开文件:%s",sBmpFile);  
         return ERR_CANNOT_OPEN_FILE;  
     }  
   
     //  读取文件头数据  
     if (1 != fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp))  
     {  
         fclose(fp);  
   
         m_iLastErrorNumber  = ERR_READ_FILE_ERROR;  
         m_sLastErrorDescribe.Format("读取文件头出错:%s",sBmpFile);  
         return ERR_READ_FILE_ERROR;  
     }  
   
     //  验证文件格式 'BM'  
     if (0x4d42 != bfh.bfType)  
     {  
         fclose(fp);  
   
         m_iLastErrorNumber  = ERR_BAD_FORMAT;  
         m_sLastErrorDescribe.Format("文件格式错误:没有 'BM' 标志:%s",sBmpFile);  
         return ERR_BAD_FORMAT;  
     }  
   
     //  读取信息头数据  
     if (1 != fread(&bih,sizeof(BITMAPINFOHEADER),1,fp))  
     {  
         fclose(fp);  
   
         m_iLastErrorNumber  = ERR_READ_FILE_ERROR;  
         m_sLastErrorDescribe.Format("读取信息头数据:%s",sBmpFile);  
         return ERR_READ_FILE_ERROR;  
     }  
       
     // 8 bits bitmap  
     if (8 == bih.biBitCount)  
     {  
         pattlelength    = bih.biClrUsed * sizeof(RGBQUAD);  
     }  
   
     //  16 or 24 bits bitmap  
     else if (16 == bih.biBitCount || 24 == bih.biBitCount)  
     {  
         pattlelength    = 0;  
     }  
       
     //  other  
     else  
     {  
         fclose(fp);  
   
         m_iLastErrorNumber  = ERR_BAD_FORMAT;  
         m_sLastErrorDescribe.Format("不能处理该图象,颜色错误:%s",sBmpFile);  
         return ERR_BAD_FORMAT;  
     }  
     needlength  = sizeof(BITMAPINFOHEADER) + pattlelength;  
   
     if (0 < pattlelength)  
     {  
         pattlebuf   = new CHAR[pattlelength];  
         if (NULL == pattlebuf)  
         {  
             fclose(fp);  
   
             m_iLastErrorNumber  = ERR_OUT_OF_MEMORY;  
             m_sLastErrorDescribe.Format("内存溢出");  
             return ERR_OUT_OF_MEMORY;  
         }  
   
         if (1 != fread(pattlebuf,pattlelength,1,fp))  
         {  
             delete pattlebuf;  
             fclose(fp);  
   
             m_iLastErrorNumber  = ERR_READ_FILE_ERROR;  
             m_sLastErrorDescribe.Format("读取调色板出错:%s",sBmpFile);  
             return ERR_READ_FILE_ERROR;  
         }  
     }  
     fclose(fp);  
   
     //  为流格式分配空间,包括信息头和可选调色板  
     m_pFormat   = (BITMAPINFOHEADER *)(new CHAR[needlength]);  
     if (NULL == m_pFormat)  
     {  
         delete pattlebuf;  
   
         m_iLastErrorNumber  = ERR_OUT_OF_MEMORY;  
         m_sLastErrorDescribe.Format("内存溢出");  
         return ERR_OUT_OF_MEMORY;  
     }  
   
     //  复制格式内容  
     memcpy(m_pFormat,&bih,sizeof(BITMAPINFOHEADER));  
     if (0 < pattlelength)  
     {  
         memcpy((CHAR *)m_pFormat + sizeof(BITMAPINFOHEADER),pattlebuf,pattlelength);  
         delete pattlebuf;  
     }  
       
     m_iFormatLength = needlength;  
     m_iFrameSize    = bih.biSizeImage;  
   
     m_iLastErrorNumber  = ERR_OK;  
     m_sLastErrorDescribe.Empty();  
     return ERR_OK;  
}  
   
//  Unfinished  
HRESULT  
CAVITools::SetStreamFormatFromMemory(BITMAPINFOHEADER *pData,BOOL bHasPattle)  
{  
     INT needlength;  
   
     if (NULL != m_pFormat)  
     {  
         delete m_pFormat;  
         m_pFormat   = NULL;  
     }  
   
     if (8 == pData->biBitCount)  
     {  
         needlength  = sizeof(BITMAPINFOHEADER) + pData->biClrUsed * sizeof(RGBQUAD);  
     }  
     else if (16 == pData->biBitCount || 24 == pData->biBitCount)  
     {  
         if (FALSE != bHasPattle)  
             return FALSE;  
         needlength  = sizeof(BITMAPINFOHEADER);  
     }  
     else  
     {  
         return FALSE;  
     }  
   
     m_pFormat   = (BITMAPINFOHEADER *)(new CHAR[needlength]);  
     if (NULL == m_pFormat)  
     {  
         return FALSE;  
     }  
   
     memcpy(m_pFormat,pData,needlength);  
   
     m_iFormatLength = needlength;  
     m_iFrameSize    = pData->biSizeImage;  
   
     return TRUE;  
}  
   
/* 
     分解 AVI 文件为位图文件 
     输入参数: 
         sAviFileName           -   需要分解的 AVI 文件位置 
         sTargetPath             -   目标路径 
         iCount               -   分解的位图文件数目 
     返回值: 
         ERR_OK               -   分解成功 
*/  
HRESULT  
CAVITools::SplitAvi(CHAR *sAviFileName, CHAR *sTargetPath, INT *iCount)  
{  
//  long            lBytes,lSamples;                    //  Samples And Bytes That Read From Stream  
     AVIFILEINFO     AviFileInfo;                       //  Avi File Info  
     AVISTREAMINFO   AviStreamInfo;                   //  Avi Stream Info  
     PAVIFILE       pAviFile        = NULL;  
     PAVISTREAM   pAviStream      = NULL;  
     PGETFRAME     pGetFrame       = NULL;  
     HDRAWDIB       hDrawDib        = NULL;  
     FILE           *fp          = NULL;  
     CHAR           *sBmpFileName   = NULL;  
     HRESULT         hr           = NULL;            // Common Var, The Function's Result Handle  
     HRESULT         hReturnValue    = ERR_OK;  
     LPVOID       lpFrameBuffer   = NULL;  
       
     //  Open An Avi File, Get It's Handle Pointer  
     hr  = ::AVIFileOpen(&pAviFile,sAviFileName,OF_READ,NULL);  
     if (hr)  
     {  
         hReturnValue    = ERR_AVI_OPEN_ERROR;  
         goto _ReleaseMemory;  
     }  
   
     //  Get Avi File Info  
     hr  = ::AVIFileInfo(pAviFile,&AviFileInfo,sizeof(AVIFILEINFO));  
     if (hr)  
     {  
         hReturnValue    = ERR_AVI_INFO_ERROR;  
         goto _ReleaseMemory;  
     }  
   
     // Open A Stream From An Opened File, Get It's Handle Pointer  
     hr  = ::AVIFileGetStream(pAviFile,&pAviStream,streamtypeVIDEO,0);  
     if (hr)  
     {  
         if (AVIERR_NODATA == hr)  
         {  
         }  
         else if (AVIERR_MEMORY == hr)  
         {  
         }  
         hReturnValue    = ERR_AVI_GETSTREAM_ERROR;  
         goto _ReleaseMemory;  
     }  
   
     // Get Stream Information  
     hr  = ::AVIStreamInfo(pAviStream,&AviStreamInfo,sizeof(AVISTREAMINFO));  
     if (hr)  
     {  
         hReturnValue    = ERR_AVI_STREAMINFO_ERROR;  
         goto _ReleaseMemory;  
     }  
   
     // Get Frame Open  
     pGetFrame   = ::AVIStreamGetFrameOpen(pAviStream,(LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT);  
     if (!pGetFrame)  
     {  
         hReturnValue    = ERR_AVI_GETFRAME_ERROR;  
         goto _ReleaseMemory;  
     }  
   
     sBmpFileName    = new CHAR[strlen(sTargetPath) + 12];  
     if (NULL == sBmpFileName)  
     {  
         hReturnValue    = ERR_OUT_OF_MEMORY;  
         goto _ReleaseMemory;  
     }  
   
     strcpy(sBmpFileName,sTargetPath);  
     if ('\\' != sBmpFileName[strlen(sBmpFileName) - 1])  
     {  
         strcat(sBmpFileName,"\\");  
     }  
     strcat(sBmpFileName,"00000.bmp");  
//////////////////////////////  
     INT     n,i;  
   
     n   = strlen(sBmpFileName) - 5;  
   
     for (i = 0;; i++)  
     {  
         if ((INT)AviStreamInfo.dwLength <= i)  
         {  
             *iCount = i;  
             hReturnValue    = ERR_OK;  
             goto _ReleaseMemory;  
         }  
   
         sBmpFileName[n - 4] = '0' + i % 100000  / 10000;  
         sBmpFileName[n - 3] = '0' + i % 10000   / 1000;  
         sBmpFileName[n - 2] = '0' + i % 1000    / 100;  
         sBmpFileName[n - 1] = '0' + i % 100     / 10;  
         sBmpFileName[n - 0] = '0' + i % 10   / 1;  
   
         lpFrameBuffer   = ::AVIStreamGetFrame(pGetFrame,i);  
         if (NULL == lpFrameBuffer)  
         {  
             hReturnValue    = ERR_AVI_GETFRAME_ERROR;  
             goto _ReleaseMemory;  
         }  
   
         // Save The Memory Frame To A Specified File  
//    SaveDib(fn,framebuffer,width,height,colorbits);  
     }  
   
     hReturnValue    = ERR_OK;  
   
_ReleaseMemory:  
     if (NULL != sBmpFileName)   delete sBmpFileName;  
     if (NULL != pGetFrame)   ::AVIStreamGetFrameClose(pGetFrame);  
     if (NULL != pAviStream)     ::AVIStreamRelease(pAviStream);  
     if (NULL != pAviFile)     ::AVIFileRelease(pAviFile);  
     return hReturnValue;  
}  
   
/* 
     SAVE BITMAP FILE TO DISK 
     ARGUMENTS: 
         sFileName             -   THE PATHNAME OF BITMAP THAT YOU WANT TO SAVE 
         pData                 -   ADDRESS OF BITMAP BUFFER, INCLUDE INFOHEADER,  
                                     OPTIONAL PATTLE AND BITSDATA 
     RETURN VALUE: 
         ERR_OK               -   SUCCESS 
         ERR_BAD_FORMAT       -   BUFFER HAS BAD OR UNKNOWN FORMAT 
         ERR_CANNOT_OPEN_FILE    -   CANNOT OPEN FILE TO WRITE 
         ERR_WRITE_FILE_ERROR    -   AN ERROR OCCUR WHILE WRITING FILE 
*/  
HRESULT  
CAVITools::SaveBMP(CHAR *sFileName, BITMAPINFOHEADER *pData)  
{  
     BITMAPFILEHEADER    bfh;  
     FILE               *fp  = NULL;  
   
     //  SUPPORT ONLY 8 bits, 16 bits AND 24 bits FORMAT  
     if (8 != pData->biBitCount && 16 != pData->biBitCount && 24 != pData->biBitCount)  
     {  
         m_iLastErrorNumber   = ERR_BAD_FORMAT;  
         m_sLastErrorDescribe    = "不支持该图象的颜色数目";  
         return ERR_BAD_FORMAT;  
     }  
   
     bfh.bfType  = 0x4d42; // "BM";  
     bfh.bfReserved1 = 0;  
     bfh.bfReserved2 = 0;  
   
     //  CALCULATE FILE SIZE AND BITSDATA OFFSET ADDRESS  
     bfh.bfSize  = sizeof(bfh);  
     bfh.bfSize  += pData->biSize;  
     if (8 == pData->biBitCount)  
         bfh.bfSize  += pData->biClrUsed * sizeof(RGBQUAD);  
   
     bfh.bfOffBits   = bfh.bfSize;  
   
     bfh.bfSize  += pData->biSizeImage;  
   
     //  OPEN FILE FOR BINARY WRITE  
     if (NULL == (fp = fopen(sFileName,"wb")))  
     {  
         m_iLastErrorNumber  = ERR_CANNOT_OPEN_FILE;  
         m_sLastErrorDescribe.Format("无法打开文件 %s",sFileName);  
         return ERR_CANNOT_OPEN_FILE;  
     }  
       
     //  WRITE DATA  
     if (1 != fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fp) ||  
         1 != fwrite((CHAR *)pData,bfh.bfSize - sizeof(BITMAPFILEHEADER),1,fp))  
     {  
         fclose(fp);  
         m_iLastErrorNumber  = ERR_WRITE_FILE_ERROR;  
         m_sLastErrorDescribe.Format("无法写入文件 %s",sFileName);  
         return ERR_WRITE_FILE_ERROR;  
     }  
     fclose(fp);  
   
     //  SUCCESS, RETURN OK  
     m_iLastErrorNumber  = ERR_OK;  
     m_sLastErrorDescribe.Empty();  
     return ERR_OK;  
}  
   
/* 
     RETURN THE ERROR NUMBER AND DESCRIBE OF THE LAST ERROR 
     ARGUMENTS: 
         sDescribe     -   REFERS TO A CSTRING VARIABLE TO RETURN ERROR DESCRIBE 
         iErrorNumber    -   REFERS TO A INTEGER VARIABLE TO RETURN ERROR NUMBER 
     RETURN VALUE: 
         TRUE           -   HAS ERROR 
         FALSE         -   THERE ISN'T ANY ERROR 
*/  
BOOL  
CAVITools::GetLastError(CString &sDescribe, INT &iErrorNumber)  
{  
     sDescribe     = m_sLastErrorDescribe;  
     iErrorNumber    = m_iLastErrorNumber;  
     return  (ERR_OK == m_iLastErrorNumber) ? (FALSE) : (TRUE);  
}  
   
BOOL  
CAVITools::GetLastError(CString &sDescribe)  
{  
     sDescribe     = m_sLastErrorDescribe;  
     return  (ERR_OK == m_iLastErrorNumber) ? (FALSE) : (TRUE);  
}  
   
/* 
     在指定的设备上显示 AVI 图象 
     参数: 
     sFileName         -   AVI 文件名 
     hWnd               -   指定的设备 
*/  
BOOL  
CAVITools::ShowAvi(CHAR *sFileName, HWND hWnd,   
                    INT iVideoID, INT iDelay,  
                    INT iBeginFrame, INT iEndFrame,  
                    int xDst, int yDst, int dxDst, int dyDst,  
                    int xSrc, int ySrc, int dxSrc, int dySrc)  
{  
     memset(&m_ShowAviArg, 0, sizeof(SHOW_AVI_ARG));  
       
     strcpy(m_ShowAviArg.sFileName, sFileName);  
     SHOW_AVI_ARG    *p  = &m_ShowAviArg;  
     p->xDst              = xDst;  
     p->yDst              = yDst;  
     p->dxDst        = dxDst;  
     p->dyDst        = dyDst;  
     p->xSrc              = xSrc;  
     p->ySrc              = ySrc;  
     p->dxSrc        = dxSrc;  
     p->dySrc        = dySrc;  
     p->hWnd              = hWnd;  
     p->iDelay          = iDelay;  
     p->bLoop        = TRUE;  
     p->iVideoID          = iVideoID;  
     p->iBeginFrame    = iBeginFrame;  
     p->iEndFrame    = iEndFrame;  
     p->iControl          = CONTROL_PLAY;  
   
     ::AfxBeginThread(ShowAviThread, (LPVOID)p);  
   
     return  TRUE;  
}  
   
UINT  
ShowAviThread(LPVOID lParam)  
{  
     SHOW_AVI_ARG*   pArg           = (SHOW_AVI_ARG *)lParam;  
     HDRAWDIB       hDrawDib        = NULL;  
     HDC             hDC             = NULL;  
     PAVIFILE       pAviFile        = NULL;  
     PAVISTREAM   pAviStream      = NULL;  
     PGETFRAME     pGetFrame       = NULL;  
     LPVOID       lpFrameBuf      = NULL;  
     HRESULT         hr           = NULL;  
     BOOL           bReturnValue    = FALSE;  
     INT             iCurrentFrame   = -1;  
     AVISTREAMINFO   AviStreamInfo;  
   
     hr       = ::AVIFileOpen(&pAviFile, pArg->sFileName, OF_READ, NULL);  
     if  (AVIERR_OK  != hr)       goto    _ReleaseMemory;  
   
     hr       = ::AVIFileGetStream(pAviFile, &pAviStream, streamtypeVIDEO, pArg->iVideoID);  
     if  (AVIERR_OK  != hr)       goto    _ReleaseMemory;  
   
     hr       = ::AVIStreamInfo(pAviStream, &AviStreamInfo, sizeof(AVISTREAMINFO));  
     if  (AVIERR_OK  != hr)       goto    _ReleaseMemory;  
   
     pGetFrame   = ::AVIStreamGetFrameOpen(pAviStream, NULL);  
     if  (NULL     == pGetFrame)   goto    _ReleaseMemory;  
   
     hDrawDib    = ::DrawDibOpen();  
     if  (NULL     == hDrawDib)    goto    _ReleaseMemory;  
   
     hDC         = ::GetDC(pArg->hWnd);  
     if  (NULL     == hDC)       goto    _ReleaseMemory;  
   
     if  ((INT)AviStreamInfo.dwLength <= 0)   goto    _ReleaseMemory;  
   
     if  (pArg->iBeginFrame < 0)  
         pArg->iBeginFrame    = 0;  
     else if (pArg->iBeginFrame >= (INT)AviStreamInfo.dwLength)  
         pArg->iBeginFrame    = (INT)AviStreamInfo.dwLength - 1;  
   
     if  (pArg->iEndFrame < 0)  
         pArg->iEndFrame      = (INT)AviStreamInfo.dwLength - 1;  
     else if (pArg->iEndFrame >= (INT)AviStreamInfo.dwLength)  
         pArg->iEndFrame      = (INT)AviStreamInfo.dwLength - 1;  
   
     if  (pArg->iEndFrame < pArg->iBeginFrame)  
         goto    _ReleaseMemory;  
   
     iCurrentFrame   = pArg->iBeginFrame;  
     for (;;)  
     {  
         if  (CONTROL_PLAY   != pArg->iControl)  
         {  
             if  (CONTROL_PAUSE  == pArg->iControl)  
             {  
                 while   (CONTROL_PAUSE  == pArg->iControl)   ::Sleep(100);  
                 if   (CONTROL_STOP   == pArg->iControl)   goto    _ReleaseMemory;  
             }  
             else if (CONTROL_STOP   == pArg->iControl)  
             {  
                 goto    _ReleaseMemory;  
             }  
         }  
   
         if  (iCurrentFrame >= (INT)AviStreamInfo.dwLength)  
         {  
             if  (FALSE  == pArg->bLoop)      break;  
             else                           iCurrentFrame   = pArg->iBeginFrame;  
         }  
         lpFrameBuf   = ::AVIStreamGetFrame(pGetFrame, iCurrentFrame);  
         if  (NULL     == lpFrameBuf)  goto    _ReleaseMemory;  
       
         ::DrawDibDraw(hDrawDib, hDC,  
             pArg->xDst, pArg->yDst, pArg->dxDst, pArg->dyDst,  
             (BITMAPINFOHEADER *)lpFrameBuf, NULL,  
             pArg->xSrc, pArg->ySrc, pArg->dxSrc, pArg->dySrc,  
             0);  
   
         ::Sleep(pArg->iDelay);  
         iCurrentFrame++;  
     }  
     bReturnValue    = TRUE;  
   
_ReleaseMemory:  
     if  (NULL   != hDC)         ::ReleaseDC(pArg->hWnd, hDC);  
     if  (NULL   != hDrawDib)    ::DrawDibClose(hDrawDib);  
     if  (NULL   != pGetFrame)   ::AVIStreamGetFrameClose(pGetFrame);  
     if  (NULL   != pAviStream)  ::AVIStreamRelease(pAviStream);  
     if  (NULL   != pAviFile)    ::AVIFileRelease(pAviFile);  
   
     return  UINT(bReturnValue);  
}
Link to comment
Share on other sites

Currently reading C++ for me is similar reading Chinese text. :mellow:

Anyway thanks for the code, I will try to understand it.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

UEZ, here is something that might help you.

I took a quick look: why do you need a GUI for that, since you delete it after? Modified it a little AVIMakeCompressedStream and (it generates the avi, BUT it's something wrong with the init part). I'm at the office right now and don't have time:

#AutoIt3Wrapper_UseX64=n
#include <WinAPI.au3>

#region AVIWriter UDF
;Global Const $mmioFOURCC_M_S_V_C = _Create_mmioFOURCC("MSVC") ;1129730893
Global Const $BITMAPFILEHEADER = "align 2;char magic[2];int size;short res1;short res2;ptr offset;"
Global Const $BITMAPINFOHEADER = "dword biSize;long biWidth;long biHeight;short biPlanes;short biBitCount;" & _
"dword biCompression;dword biSizeImage;long biXPelsPerMeter;long biYPelsPerMeter;dword biClrUsed;dword biClrImportant;"
Global Const $OF_CREATE = 0x00001000
Global Const $AVIIF_KEYFRAME = 0x00000010
Global Const $ICMF_CHOOSE_KEYFRAME = 1, $ICMF_CHOOSE_DATARATE = 2
Global Const $AVIERR_UNSUPPORTED = 0x80044065
Global Const $AVIERR_MEMORY = 0x80044067
Global Const $AVIERR_NOCOMPRESSOR = 0x80044071
Global Const $AVIERR_CANTCOMPRESS = 0x80044075
Global Const $AVIERR_ERROR = 0x800440C7
Global Const $AVIERR_OK = 0
Global $Avi32_Dll

;http://msdn.microsoft.com/en-us/library/ms899423.aspx
Global Const $AVISTREAMINFO = "dword fccType;dword fccHandler;dword dwFlags;dword dwCaps;short wPriority;short wLanguage;dword dwScale;" & _
"dword dwRate;dword dwStart;dword dwLength;dword dwInitialFrames;dword dwSuggestedBufferSize;dword dwQuality;" & _
"dword dwSampleSize;int rleft;int rtop;int rright;int rbottom;dword dwEditCount;dword dwFormatChangeCount;wchar[64];"


;http://msdn.microsoft.com/en-us/library/dd756791(v=VS.85).aspx
Global Const $AVICOMPRESSOPTIONS = "DWORD fccType;DWORD fccHandler;DWORD dwKeyFrameEvery;DWORD dwQuality;DWORD dwBytesPerSecond;" & _
"DWORD dwFlags;PTR lpFormat;DWORD cbFormat;PTR lpParms;DWORD cbParms;DWORD dwInterleaveEvery;"

Func _Create_mmioFOURCC($FOURCC) ;http://www.fourcc.org/codecs.php
If StringLen($FOURCC) <> 4 Then Return SetError(1, 0, 0)
Local $aFOURCC = StringSplit($FOURCC, "", 2)
Return BitOR(Asc($aFOURCC[0]), BitShift(Asc($aFOURCC[1]), -8), BitShift(Asc($aFOURCC[2]), -16), BitShift(Asc($aFOURCC[3]), -24))
EndFunc ;==>_Create_mmioFOURCC

Func _DecodeFOURCC($iFOURCC)
If Not IsInt($iFOURCC) Then Return SetError(1, 0, 0)
Return Chr(BitAND($iFOURCC, 0xFF)) & Chr(BitShift(BitAND(0x0000FF00, $iFOURCC), 8)) & Chr(BitShift(BitAND(0x00FF0000, $iFOURCC), 16)) & Chr(BitShift($iFOURCC, 24))
EndFunc ;==>_DecodeFOURCC

; monoceres, Prog@ndy
Func _CreateAvi($sFilename, $FrameRate, $Width, $Height, $BitCount = 24, $mmioFOURCC = "MSVC")
Local $RetArr[5] ; avi file handle, stream handle, bitmap count, BitmapInfoheader, Stride

Local $aRet, $pfile, $asi, $aco, $pstream, $psCompressed

$aRet = DllCall($Avi32_Dll, "int", "AVIFileOpenW", "ptr*", 0, "wstr", $sFilename, "uint", $OF_CREATE, "ptr", 0)
$pfile = $aRet[1]

Local $stride = BitAND(($Width * ($BitCount / 8) + 3), BitNOT(3))

Local $bi = DllStructCreate($BITMAPINFOHEADER)
DllStructSetData($bi, "biSize", DllStructGetSize($bi))
DllStructSetData($bi, "biWidth", $Width)
DllStructSetData($bi, "biHeight", $Height)
DllStructSetData($bi, "biPlanes", 1)
DllStructSetData($bi, "biBitCount", $BitCount)
DllStructSetData($bi, "biSizeImage", $stride * $Height)

$asi = DllStructCreate($AVISTREAMINFO)
DllStructSetData($asi, "fccType", _Create_mmioFOURCC("vids"))
DllStructSetData($asi, "fccHandler", 0) ;_Create_mmioFOURCC($mmioFOURCC))
DllStructSetData($asi, "dwScale", 1)
DllStructSetData($asi, "dwRate", $FrameRate)
;~ DllStructSetData($asi, "dwQuality", $Quality) ;Quality is represented as a number between 0 and 10,000. For compressed data, this typically represents the value of the quality parameter passed to the compression software. If set to –1, drivers use the default quality value.
DllStructSetData($asi, "rright", $Width)
DllStructSetData($asi, "rbottom", $Height)
;~ DllStructSetData($asi, "dwSuggestedBufferSize", $stride * $Height)

$aRet = DllCall($Avi32_Dll, "int", "AVIFileCreateStream", "ptr", $pfile, "ptr*", 0, "ptr", DllStructGetPtr($asi))
$pstream = $aRet[2]

$aco = DllStructCreate($AVICOMPRESSOPTIONS)
;Local $hWnd = GUICreate("")
;$aRet = DllCall($Avi32_Dll, "int_ptr", "AVISaveOptions", "hwnd", $hWnd, "uint", BitOR($ICMF_CHOOSE_DATARATE, $ICMF_CHOOSE_KEYFRAME), "int", 1, "ptr*", $pstream, "ptr*", DllStructGetPtr($aco))
;GUIDelete($hWnd)
$aRet = DllCall($Avi32_Dll, "int_ptr", "AVISaveOptions", "hwnd", 0, "uint", BitOR($ICMF_CHOOSE_DATARATE, $ICMF_CHOOSE_KEYFRAME), "int", 1, "ptr*", $pstream, "ptr*", DllStructGetPtr($aco))

If $aRet[0] <> 1 Then
$RetArr[0] = $pfile
$RetArr[1] = $pstream
Return SetError(1, 0, $RetArr)
EndIf

ConsoleWrite(_DecodeFOURCC(DllStructGetData($aco, "fccHandler")) & @CRLF)

$aRet = DllCall($Avi32_Dll, "int", "AVIMakeCompressedStream", "ptr*", 0, "ptr", $pstream, "ptr*", DllStructGetPtr($aco), "ptr", 0)
;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aRet = ' & $aRet & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $aRet = ' & Hex($aRet[0]) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
If $aRet[0] <> $AVIERR_OK Then
$RetArr[0] = $pfile
$RetArr[1] = $pstream
Return SetError(2, 0, $RetArr)
EndIf
$psCompressed = $aRet[1]

; The format for the stream is the same as BITMAPINFOHEADER
$aRet = DllCall($Avi32_Dll, "int", "AVIStreamSetFormat", "ptr", $psCompressed, "long", 0, "ptr", DllStructGetPtr($bi), "long", DllStructGetSize($bi))

$RetArr[0] = $pfile
$RetArr[1] = $psCompressed
$RetArr[2] = 0
$RetArr[3] = $bi
$RetArr[4] = $stride
Return $RetArr
EndFunc ;==>_CreateAvi

; Adds a bitmap file to an already opened avi file.
; monoceres, Prog@ndy
Func _AddHBitmapToAvi(ByRef $Avi_Handle, $hBitmap)
Local $DC = _WinAPI_GetDC(0)
Local $hDC = _WinAPI_CreateCompatibleDC($DC)
_WinAPI_ReleaseDC(0, $DC)

Local $OldBMP = _WinAPI_SelectObject($hDC, $hBitmap)
Local $bits = DllStructCreate("byte[" & DllStructGetData($Avi_Handle[3], "biSizeImage") & "]")
_WinAPI_GetDIBits($hDC, $hBitmap, 0, Abs(DllStructGetData($Avi_Handle[3], "biHeight")), DllStructGetPtr($bits), DllStructGetPtr($Avi_Handle[3]), 0)
_WinAPI_SelectObject($hDC, $OldBMP)
_WinAPI_DeleteDC($hDC)

DllCall($Avi32_Dll, "int", "AVIStreamWrite", "ptr", $Avi_Handle[1], "long", $Avi_Handle[2], "long", 1, "ptr", DllStructGetPtr($bits), _
"long", DllStructGetSize($bits), "long", $AVIIF_KEYFRAME, "ptr*", 0, "ptr*", 0)
$Avi_Handle[2] += 1
EndFunc ;==>_AddHBitmapToAvi

; Adds a bitmap file to an already opened avi file.
Func _AddBitmapToAvi(ByRef $Avi_Handle, $sBitmap)
Local $bm = LoadBitmap($sBitmap, True)
DllCall($Avi32_Dll, "int", "AVIStreamWrite", "ptr", $Avi_Handle[1], "long", $Avi_Handle[2], "long", 1, "ptr", DllStructGetPtr($bm[2]), _
"long", DllStructGetSize($bm[2]), "long", $AVIIF_KEYFRAME, "ptr*", 0, "ptr*", 0)
$Avi_Handle[2] += 1
EndFunc ;==>_AddBitmapToAvi

; Returns array with 3 elements
; [0]=BITMAPFILEHEADER
; [1]=BITMAPINFOHEADER
; [2]=Bitmap data buffer (if specified)
Func LoadBitmap($sFilename, $LoadData = False)
Local $RetArr[3]
Local $byref
Local $bih, $bfh, $buffer, $fhandle
$bfh = DllStructCreate($BITMAPFILEHEADER)
$bih = DllStructCreate($BITMAPINFOHEADER)
$fhandle = _WinAPI_CreateFile($sFilename, 2, 2, 0, 0)
_WinAPI_ReadFile($fhandle, DllStructGetPtr($bfh), DllStructGetSize($bfh), $byref)
_WinAPI_ReadFile($fhandle, DllStructGetPtr($bih), DllStructGetSize($bih), $byref)
$RetArr[0] = $bfh
$RetArr[1] = $bih

If Not $LoadData Then
_WinAPI_CloseHandle($fhandle)
Return $RetArr
EndIf

$buffer = DllStructCreate("byte[" & DllStructGetData($bfh, "size") - 54 & "]")
$RetArr[2] = $buffer
_WinAPI_ReadFile($fhandle, DllStructGetPtr($buffer), DllStructGetSize($buffer), $byref)
_WinAPI_CloseHandle($fhandle)

Return $RetArr
EndFunc ;==>LoadBitmap

; Init the avi library
Func _StartAviLibrary()
$Avi32_Dll = DllOpen("Avifil32.dll")
DllCall($Avi32_Dll, "none", "AVIFileInit")
;~ MsgBox(0,"",@error)
EndFunc ;==>_StartAviLibrary

; Release the library
Func _StopAviLibrary()
DllCall($Avi32_Dll, "none", "AVIFileExit")
DllClose($Avi32_Dll)
EndFunc ;==>_StopAviLibrary

Func _CloseAvi($Avi_Handle)
DllCall($Avi32_Dll, "int", "AVIStreamRelease", "ptr", $Avi_Handle[1])
DllCall($Avi32_Dll, "int", "AVIFileRelease", "ptr", $Avi_Handle[0])
EndFunc ;==>_CloseAvi
#endregion AVIWriter UDF

#region example
#include <Array.au3>
#include <Memory.au3>
#include <ScreenCapture.au3>

_GDIPlus_Startup()
HotKeySet("{ESC}", "close")

Break(0)

FileDelete(@ScriptDir & "\test.avi")

$tPoint = DllStructCreate($tagPOINT)
$aMPos = MouseGetPos()
DllStructSetData($tPoint, 1, $aMPos[0])
DllStructSetData($tPoint, 2, $aMPos[1])
$hWin = _WinAPI_WindowFromPoint($tPoint)
$hWinAncestor = _WinAPI_GetAncestor($hWin, 2)
$hWnd = HWnd($hWinAncestor)
$aPos = WinGetPos($hWnd)

$rec_duration = 1000 * 1

ConsoleWrite("Starting...." & @CRLF)

_StartAviLibrary()
$aAVI = _CreateAvi(@ScriptDir & "\test.avi", 15, $aPos[2], $aPos[3])
If @error Then close()

$t = TimerInit()

Do
$hBmp = _ScreenCapture_CaptureWnd("", $hWnd)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBmp)
_AddHBitmapToAvi($aAVI, $hBmp)
_WinAPI_DeleteObject($hBmp)
If TimerDiff($t) > $rec_duration Then close()
Until False

Func close()
_GDIPlus_Shutdown()
_CloseAvi($aAVI)
_StopAviLibrary()
ConsoleWrite("AVI filesize: " & Round(FileGetSize(@ScriptDir & "\test.avi") / 1024 ^ 2, 2) & " MB" & @CRLF)
Exit
EndFunc ;==>close
#endregion example
Link to comment
Share on other sites

@taietel: forget that with the GUI - it was only a test but the code is creating the AVI but not compressed using the settings from the Video Compression window! As mentioned above I cannot understand C++ very well and thus the transformation from C++ to AutoIt is very hard for me.

Yes, there is something wrong but what?

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

  • 2 weeks later...

This one seems to be working properly:

AVIWriter Extented Example.au3

#include "AVIWriter Extented.au3"
#include <Misc.au3>
#include <ScreenCapture.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()

Global Const $sFile = @ScriptDir & "\test.avi"
FileDelete($sFile)

Global $rec_duration = 5 ;5 seconds
Global $fps = 5

Global Const $dll = DllOpen("user32.dll")
Global $hGUI_Grab2AVI = GUICreate("", 0, 0, 0, 0, $WS_POPUP, $WS_EX_TOPMOST + $WS_EX_TOOLWINDOW, WinGetHandle(AutoItWinGetTitle()))
GUISetBkColor(0xFF0000, $hGUI_Grab2AVI)
GUISetState(@SW_SHOW, $hGUI_Grab2AVI)
Global $aMPos, $hWin, $hWinAncestor, $hWnd, $aRet_prev, $aPos
Global Const $frame_size = 3
Global $tPoint = DllStructCreate($tagPOINT)
Global $esc = True
Global $mxo, $myo

While Not _IsPressed("1B", $dll) * Sleep(30)
    $aMPos = MouseGetPos()
    DllStructSetData($tPoint, 1, $aMPos[0])
    DllStructSetData($tPoint, 2, $aMPos[1])
    $hWin = _WinAPI_WindowFromPoint($tPoint)
    $hWinAncestor = _WinAPI_GetAncestor($hWin, 2)
    $hWnd = HWnd($hWinAncestor)
    $aRet_prev = -1
    $aPos  = WinGetPos($hWnd)
    If $hWnd <> $hGUI_Grab2AVI And $hWnd <> $aRet_prev Then
        $aRet_prev = $hWnd
        If $aMPos[0] <> $mxo Or $aMPos[1] <> $myo Then
            WinMove($hGUI_Grab2AVI, "", $aPos[0], $aPos[1], $aPos[2], $aPos[3], 1)
            _GuiHole($hGUI_Grab2AVI, $frame_size, $frame_size, $aPos[2] - 2 * $frame_size, $aPos[3] - 2 * $frame_size, $aPos[2], $aPos[3])
            WinSetOnTop($hGUI_Grab2AVI, 0, 1)
            ToolTip("Press CTRL to start capturing of" & @LF & "marked window to a AVI file!" & @LF & @LF & _
                         "Duration: " & $rec_duration & " seconds @ " & $fps & " fps" & @LF & _
                          "Windows Size: " & $aPos[2] & " x " & $aPos[3], $aMPos[0] + 20, $aMPos[1] + 20)
            $mxo = $aMPos[0]
            $myo = $aMPos[1]
        EndIf
    EndIf
    If _IsPressed("11", $dll) Then
        $esc = False
        ExitLoop
    EndIf
WEnd
ToolTip("")
GUIDelete($hGUI_Grab2AVI)
If $esc Then Exit MsgBox(0, "Information", "Aborted", 10)

_StartAviLibrary()
Global $aAVI = _CreateAvi($sFile, $fps, $aPos[2], $aPos[3])
If @error Then close()

Global $hBmp

Global $fSleep = 1000 / $fps, $t, $td
Global $total_FPS = $rec_duration * $fps, $fps_c = 1
$k32_dll = DllOpen("kernel32.dll")

Do
    $fTimer = TimerInit()

    $hBmp = _ScreenCapture_CaptureWnd("", $hWnd)
    _AddHBitmapToAvi($aAVI, $hBmp)
    _WinAPI_DeleteObject($hBmp)

    $fps_c += 1
    $td = $fSleep - TimerDiff($fTimer)
    If $td > 0 Then
        DllCall($k32_dll, "none", "Sleep", "dword", $td)
    EndIf

    If $fps_c > $total_FPS Then
        Close()
    EndIf

Until False

Func Close()
    DllClose($dll)
    _GDIPlus_Shutdown()
    _CloseAvi($aAVI)
    _StopAviLibrary()
    ConsoleWrite("AVI filesize: " & Round(FileGetSize($sFile) / 1024 ^ 2, 2) & " MB" & @CRLF)
    Exit MsgBox(0, "Information", "Done!", 15)
EndFunc   ;==>close

Func _GuiHole($hWnd, $i_x, $i_y, $i_sizew, $i_sizeh, $width, $height)
    Local $outer_rgn, $inner_rgn, $combined_rgn
    $outer_rgn = _WinAPI_CreateRectRgn(0, 0, $width, $height)
    $inner_rgn = _WinAPI_CreateRectRgn($i_x, $i_y, $i_x + $i_sizew, $i_y + $i_sizeh)
    $combined_rgn = _WinAPI_CreateRectRgn(0, 0, 0, 0)
    _WinAPI_CombineRgn($combined_rgn, $outer_rgn, $inner_rgn, $RGN_DIFF)
    _WinAPI_DeleteObject($outer_rgn)
    _WinAPI_DeleteObject($inner_rgn)
    _WinAPI_SetWindowRgn($hWnd, $combined_rgn)
EndFunc   ;==>_GuiHole


AVIWriter Extented.au3

#include-once
#include <WinAPI.au3>

#region AVIWriter UDF
Global Const $OF_CREATE = 0x00001000
Global Const $AVIIF_KEYFRAME = 0x00000010
Global Const $ICMF_CHOOSE_KEYFRAME = 1, $ICMF_CHOOSE_DATARATE = 2
Global Const $AVIERR_UNSUPPORTED = 0x80044065
Global Const $AVIERR_BADPARAM = 0x80044066
Global Const $AVIERR_MEMORY = 0x80044067
Global Const $AVIERR_NOCOMPRESSOR = 0x80044071
Global Const $AVIERR_CANTCOMPRESS = 0x80044075
Global Const $AVIERR_ERROR = 0x800440C7
Global Const $AVIERR_OK = 0
Global $Avi32_Dll

Global Const $ICINFO = _
    "DWORD dwSize;DWORD fccType;DWORD fccHandler;DWORD dwFlags;DWORD dwVersion;DWORD dwVersionICM;" & _
    "WCHAR szName[16];WCHAR szDescription[128];WCHAR szDriver[128];"

;http://msdn.microsoft.com/en-us/library/dd183374(v=vs.85).aspx
Global Const $BITMAPFILEHEADER = "WORD bfType;DWORD bfSize;WORD bfReserved1;WORD bfReserved2;DWORD bfOffBits;"
;~ Global Const $BITMAPFILEHEADER = "align 2;char magic[2];int size;short res1;short res2;ptr offset;"

;http://msdn.microsoft.com/en-us/library/dd183376(v=vs.85).aspx
Global Const $BITMAPINFOHEADER = _
        "dword biSize;long biWidth;long biHeight;short biPlanes;short biBitCount;dword biCompression;" & _
        "dword biSizeImage;long biXPelsPerMeter;long biYPelsPerMeter;dword biClrUsed;dword biClrImportant;"

;http://msdn.microsoft.com/en-us/library/ms899423.aspx
Global Const $AVISTREAMINFO = _
        "dword fccType;dword fccHandler;dword dwFlags;dword dwCaps;short wPriority;short wLanguage;dword dwScale;" & _
        "dword dwRate;dword dwStart;dword dwLength;dword dwInitialFrames;dword dwSuggestedBufferSize;dword dwQuality;" & _
        "dword dwSampleSize;int rleft;int rtop;int rright;int rbottom;dword dwEditCount;dword dwFormatChangeCount;wchar[64];"

;http://msdn.microsoft.com/en-us/library/dd756791(v=VS.85).aspx
Global Const $AVICOMPRESSOPTIONS = _
        "DWORD fccType;DWORD fccHandler;DWORD dwKeyFrameEvery;DWORD dwQuality;DWORD dwBytesPerSecond;" & _
        "DWORD dwFlags;PTR lpFormat;DWORD cbFormat;PTR lpParms;DWORD cbParms;DWORD dwInterleaveEvery;"

;http://www.fourcc.org/codecs.php
Func _Create_mmioFOURCC($FOURCC) ;coded by UEZ
    If StringLen($FOURCC) <> 4 Then Return SetError(1, 0, 0)
    Local $aFOURCC = StringSplit($FOURCC, "", 2)
    Return BitOR(Asc($aFOURCC[0]), BitShift(Asc($aFOURCC[1]), -8), BitShift(Asc($aFOURCC[2]), -16), BitShift(Asc($aFOURCC[3]), -24))
EndFunc   ;==>_Create_mmioFOURCC

Func _DecodeFOURCC($iFOURCC);coded by UEZ
    If Not IsInt($iFOURCC) Then Return SetError(1, 0, 0)
    Return Chr(BitAND($iFOURCC, 0xFF)) & Chr(BitShift(BitAND(0x0000FF00, $iFOURCC), 8)) & Chr(BitShift(BitAND(0x00FF0000, $iFOURCC), 16)) & Chr(BitShift($iFOURCC, 24))
EndFunc   ;==>_DecodeFOURCC

;monoceres, Prog@ndy, UEZ
Func _CreateAvi($sFilename, $FrameRate, $Width, $Height, $BitCount = 24, $mmioFOURCC = "MSVC", $iKeyFrameEvery = 10)
    Local $RetArr[6] ;avi file handle, compressed stream handle, bitmap count, BitmapInfoheader, Stride, stream handle

    Local $aRet, $pFile, $tASI, $tACO, $pStream, $psCompressed

    Local $stride = BitAND(($Width * ($BitCount / 8) + 3), BitNOT(3))

    Local $tBI = DllStructCreate($BITMAPINFOHEADER)
    DllStructSetData($tBI, "biSize", DllStructGetSize($tBI))
    DllStructSetData($tBI, "biWidth", $Width)
    DllStructSetData($tBI, "biHeight", $Height)
    DllStructSetData($tBI, "biPlanes", 1)
    DllStructSetData($tBI, "biBitCount", $BitCount)
    DllStructSetData($tBI, "biSizeImage", $stride * $Height)

    $tASI = DllStructCreate($AVISTREAMINFO)
    DllStructSetData($tASI, "fccType", _Create_mmioFOURCC("vids"))
    DllStructSetData($tASI, "fccHandler", _Create_mmioFOURCC($mmioFOURCC))
    DllStructSetData($tASI, "dwScale", 1)
    DllStructSetData($tASI, "dwRate", $FrameRate)
    DllStructSetData($tASI, "dwQuality", -1) ;Quality is represented as a number between 0 and 10,000. For compressed data, this typically represents the value of the quality parameter passed to the compression software. If set to &#8211;1, drivers use the default quality value.
    DllStructSetData($tASI, "dwSuggestedBufferSize", $stride * $Height)
    DllStructSetData($tASI, "rright", $Width)
    DllStructSetData($tASI, "rbottom", $Height)


;~  $tParms = DllStructCreate($ICINFO)
;~  DllCall("Msvfw32.dll", "BOOL", "ICInfo", "DWORD", _Create_mmioFOURCC("vidc"), "DWORD", _Create_mmioFOURCC($mmioFOURCC), "ptr", DllStructGetPtr($tParms))

;~     $tACO = DllStructCreate($AVICOMPRESSOPTIONS)
;~     DllStructSetData($tACO, "fccType", _Create_mmioFOURCC("vids"))
;~     DllStructSetData($tACO, "fccHandler", _Create_mmioFOURCC($mmioFOURCC))
;~     DllStructSetData($tACO, "dwKeyFrameEvery", 10)
;~     DllStructSetData($tACO, "dwQuality", 10000)
;~     DllStructSetData($tACO, "dwBytesPerSecond", 0)
;~     DllStructSetData($tACO, "dwFlags", 8)
;~     DllStructSetData($tACO, "lpFormat", 0)
;~     DllStructSetData($tACO, "cbFormat", 0)
;~     DllStructSetData($tACO, "lpParms", DllStructGetPtr($tParms))
;~     DllStructSetData($tACO, "cbParms", DllStructGetSize($tParms))
;~     DllStructSetData($tACO, "dwInterleaveEvery", 0)

    $tACO = DllStructCreate($AVICOMPRESSOPTIONS)
;~     DllStructSetData($tACO, "fccType", _Create_mmioFOURCC("vids"))
;~     DllStructSetData($tACO, "fccHandler", _Create_mmioFOURCC($mmioFOURCC))
;~     DllStructSetData($tACO, "dwKeyFrameEvery", $iKeyFrameEvery)


    $aRet = DllCall($Avi32_Dll, "int", "AVIFileOpenW", "ptr*", 0, "wstr", $sFilename, "uint", $OF_CREATE, "ptr", 0)
    $pFile = $aRet[1]

    $aRet = DllCall($Avi32_Dll, "int", "AVIFileCreateStream", "ptr", $pFile, "ptr*", 0, "ptr", DllStructGetPtr($tASI))
    $pStream = $aRet[2]

    $aRet = DllCall($Avi32_Dll, "int_ptr", "AVISaveOptions", "hwnd", 0, "uint", BitOR($ICMF_CHOOSE_DATARATE, $ICMF_CHOOSE_KEYFRAME), "int", 1, "ptr*", $pStream, "ptr*", DllStructGetPtr($tACO))
    If $aRet[0] <> 1 Then
        $RetArr[0] = $pFile
        $RetArr[1] = $pStream
        $RetArr[2] = 0
        $RetArr[3] = $tBI
        $RetArr[4] = $Stride
        $RetArr[5] = $pStream
        Return SetError(1, 0, $RetArr)
    EndIf

    ;http://msdn.microsoft.com/en-us/library/dd756811(v=VS.85).aspx
    $aRet = DllCall($Avi32_Dll, "int", "AVIMakeCompressedStream", "ptr*", 0, "ptr", $pStream, "ptr", DllStructGetPtr($tACO), "ptr", 0)
    If $aRet[0] <> $AVIERR_OK Then
            $RetArr[0] = $pFile
            $RetArr[1] = $pStream
            $RetArr[2] = 0
            $RetArr[3] = $tBI
            $RetArr[4] = $stride
            $RetArr[5] = $pStream
        Return SetError(2, 0, $RetArr)
    EndIf
    $psCompressed = $aRet[1]

    ;The format for the stream is the same as BITMAPINFOHEADER
    $aRet = DllCall($Avi32_Dll, "int", "AVIStreamSetFormat", "ptr", $psCompressed, "long", 0, "ptr", DllStructGetPtr($tBI), "long", DllStructGetSize($tBI))

    $RetArr[0] = $pFile
    $RetArr[1] = $psCompressed
    $RetArr[2] = 0
    $RetArr[3] = $tBI
    $RetArr[4] = $stride
    $RetArr[5] = $pStream

    ConsoleWrite("$AVISTREAMINFO: " & @CRLF)
    ConsoleWrite("fccHandler: " & _DecodeFOURCC(DllStructGetData($tASI, "fccHandler")) & @CRLF)
    ConsoleWrite("fccType: " & DllStructGetData($tASI, "fccType") & @CRLF)
    ConsoleWrite("dwFlags: " & DllStructGetData($tASI, "dwFlags") & @CRLF)
    ConsoleWrite("dwCaps: " & DllStructGetData($tASI, "dwCaps") & @CRLF)
    ConsoleWrite("wPriority: " & DllStructGetData($tASI, "wPriority") & @CRLF)
    ConsoleWrite("wLanguage: " & DllStructGetData($tASI, "wLanguage") & @CRLF)
    ConsoleWrite("dwScale: " & DllStructGetData($tASI, "dwScale") & @CRLF)
    ConsoleWrite("dwStart: " & DllStructGetData($tASI, "dwStart") & @CRLF)
    ConsoleWrite("dwLength: " & DllStructGetData($tASI, "dwLength") & @CRLF)
    ConsoleWrite("dwInitialFrames: " & DllStructGetData($tASI, "dwInitialFrames") & @CRLF)
    ConsoleWrite("dwSuggestedBufferSize: " & DllStructGetData($tASI, "dwSuggestedBufferSize") & @CRLF)
    ConsoleWrite("dwQuality: " & DllStructGetData($tASI, "dwQuality") & @CRLF)
    ConsoleWrite("dwRate: " & DllStructGetData($tASI, "dwRate") & @CRLF)
    ConsoleWrite("dwSampleSize: " & DllStructGetData($tASI, "dwSampleSize") & @CRLF)
    ConsoleWrite("rleft: " & DllStructGetData($tASI, "rleft") & @CRLF)
    ConsoleWrite("rtop: " & DllStructGetData($tASI, "rtop") & @CRLF)
    ConsoleWrite("rright: " & DllStructGetData($tASI, "rright") & @CRLF)
    ConsoleWrite("rbottom: " & DllStructGetData($tASI, "rbottom") & @CRLF)
    ConsoleWrite("dwEditCount: " & DllStructGetData($tASI, "dwEditCount") & @CRLF)
    ConsoleWrite("dwFormatChangeCount: " & DllStructGetData($tASI, "dwFormatChangeCount") & @CRLF & @CRLF)

    ConsoleWrite("$AVICOMPRESSOPTIONS: " & @CRLF)
    ConsoleWrite("fccType: " & DllStructGetData($tACO, "fccType") & @CRLF)
    ConsoleWrite("fccHandler: " & _DecodeFOURCC(DllStructGetData($tACO, "fccHandler")) & @CRLF)
    ConsoleWrite("dwKeyFrameEvery: " & DllStructGetData($tACO, "dwKeyFrameEvery") & @CRLF)
    ConsoleWrite("dwQuality: " & DllStructGetData($tACO, "dwQuality") & @CRLF)
    ConsoleWrite("dwBytesPerSecond: " & DllStructGetData($tACO, "dwBytesPerSecond") & @CRLF)
    ConsoleWrite("dwFlags: " & DllStructGetData($tACO, "dwFlags") & @CRLF)
    ConsoleWrite("lpFormat: " & DllStructGetData($tACO, "lpFormat") & @CRLF)
    ConsoleWrite("cbFormat: " & DllStructGetData($tACO, "cbFormat") & @CRLF)
    ConsoleWrite("lpParms: " & DllStructGetData($tACO, "lpParms") & @CRLF)
    ConsoleWrite("cbParms: " & DllStructGetData($tACO, "cbParms") & @CRLF)
    ConsoleWrite("dwInterleaveEvery: " & DllStructGetData($tACO, "dwInterleaveEvery") & @CRLF & @CRLF)

    ConsoleWrite("$ICINFO: " & @CRLF)
    ConsoleWrite("dwSize: " & DllStructGetData($ICINFO, "dwSize") & @CRLF)
    ConsoleWrite("fccType: " & DllStructGetData($ICINFO, "fccType") & @CRLF)
    ConsoleWrite("fccHandler: " & DllStructGetData($ICINFO, "fccHandler") & @CRLF)
    ConsoleWrite("dwFlags: " & DllStructGetData($ICINFO, "dwFlags") & @CRLF)
    ConsoleWrite("dwVersion: " & DllStructGetData($ICINFO, "dwVersion") & @CRLF)
    ConsoleWrite("dwVersionICM: " & DllStructGetData($ICINFO, "dwVersionICM") & @CRLF)
    ConsoleWrite("szName: " & DllStructGetData($ICINFO, "szName") & @CRLF)
    ConsoleWrite("szDescription: " & DllStructGetData($ICINFO, "szDescription") & @CRLF)
    ConsoleWrite("szDriver: " & DllStructGetData($ICINFO, "szDriver") & @CRLF & @CRLF)

    Return $RetArr
EndFunc   ;==>_CreateAvi

;Adds a bitmap file to an already opened avi file.
;monoceres, Prog@ndy
Func _AddHBitmapToAvi(ByRef $Avi_Handle, $hBitmap)
    Local $DC = _WinAPI_GetDC(0)
    Local $hDC = _WinAPI_CreateCompatibleDC($DC)
    _WinAPI_ReleaseDC(0, $DC)

    Local $OldBMP = _WinAPI_SelectObject($hDC, $hBitmap)
    Local $bits = DllStructCreate("byte[" & DllStructGetData($Avi_Handle[3], "biSizeImage") & "]")
    _WinAPI_GetDIBits($hDC, $hBitmap, 0, Abs(DllStructGetData($Avi_Handle[3], "biHeight")), DllStructGetPtr($bits), DllStructGetPtr($Avi_Handle[3]), 0)
    _WinAPI_SelectObject($hDC, $OldBMP)
    _WinAPI_DeleteDC($hDC)

    DllCall($Avi32_Dll, "int", "AVIStreamWrite", "ptr", $Avi_Handle[1], "long", $Avi_Handle[2], "long", 1, "ptr", DllStructGetPtr($bits), _
                                        "long", DllStructGetSize($bits), "long", $AVIIF_KEYFRAME, "ptr*", 0, "ptr*", 0)
    $Avi_Handle[2] += 1
EndFunc   ;==>_AddHBitmapToAvi

;Adds a bitmap file to an already opened avi file.
Func _AddBitmapToAvi(ByRef $Avi_Handle, $sBitmap)
    Local $bm = LoadBitmap($sBitmap, True)
    DllCall($Avi32_Dll, "int", "AVIStreamWrite", "ptr", $Avi_Handle[1], "long", $Avi_Handle[2], "long", 1, "ptr", DllStructGetPtr($bm[2]), _
                                        "long", DllStructGetSize($bm[2]), "long", $AVIIF_KEYFRAME, "ptr*", 0, "ptr*", 0)
    $Avi_Handle[2] += 1
EndFunc   ;==>_AddBitmapToAvi

;Returns array with 3 elements
;[0]=BITMAPFILEHEADER
;[1]=BITMAPINFOHEADER
;[2]=Bitmap data buffer (if specified)
Func LoadBitmap($sFilename, $LoadData = False)
    Local $RetArr[3]
    Local $byref
    Local $tBIH, $tBFH, $buffer, $fhandle
    $tBFH = DllStructCreate($BITMAPFILEHEADER)
    $tBIH = DllStructCreate($BITMAPINFOHEADER)
    $fhandle = _WinAPI_CreateFile($sFilename, 2, 2, 0, 0)
    _WinAPI_ReadFile($fhandle, DllStructGetPtr($tBFH), DllStructGetSize($tBFH), $byref)
    _WinAPI_ReadFile($fhandle, DllStructGetPtr($tBIH), DllStructGetSize($tBIH), $byref)
    $RetArr[0] = $tBFH
    $RetArr[1] = $tBIH

    If Not $LoadData Then
        _WinAPI_CloseHandle($fhandle)
        Return $RetArr
    EndIf

    $buffer = DllStructCreate("byte[" & DllStructGetData($tBFH, "size") - 54 & "]")
    $RetArr[2] = $buffer
    _WinAPI_ReadFile($fhandle, DllStructGetPtr($buffer), DllStructGetSize($buffer), $byref)
    _WinAPI_CloseHandle($fhandle)

    Return $RetArr
EndFunc   ;==>LoadBitmap

;Init the avi library
Func _StartAviLibrary()
    $Avi32_Dll = DllOpen("Avifil32.dll")
    DllCall($Avi32_Dll, "none", "AVIFileInit")
EndFunc   ;==>_StartAviLibrary

;Release the library
Func _StopAviLibrary()
    DllCall($Avi32_Dll, "none", "AVIFileExit")
    DllClose($Avi32_Dll)
EndFunc   ;==>_StopAviLibrary

Func _CloseAvi($Avi_Handle)
    DllCall($Avi32_Dll, "int", "AVIStreamRelease", "ptr", $Avi_Handle[1])
    DllCall($Avi32_Dll, "int", "AVIStreamRelease", "ptr", $Avi_Handle[5])
    DllCall($Avi32_Dll, "int", "AVIFileRelease", "ptr", $Avi_Handle[0])
EndFunc   ;==>_CloseAvi
#endregion AVIWriter UDF

Or look here: 

 

Thanks to trancexx for pointing me to the right direction! :graduated:

Br,
UEZ

Edit: fixed issues from below.
Edit2: updated UDF and example code

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Really nice :graduated: , thanks to you and the lady, maybe you should repost this in the examples section ;)!

Also this line

$sFile = @ScriptDir & "test.avi"

should be this

$sFile = @ScriptDir & "\test.avi"

Link to comment
Share on other sites

:graduated: @UEZ: You forgot also the $hBitmap, but that and the backslash was the easy part, and not important. The hard part was really needed. I will take a look in the near future at Aviwcx plugin of TC to see the part of frame extraction.
Link to comment
Share on other sites

  • 1 year later...

I updated the example and the UDF from

The example is working for me - tested on Win7 x64 with Aero enabled running AutoIt v3.3.8.1.

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

  • 1 month later...

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
 Share

×
×
  • Create New...