Sign in to follow this  
Followers 0
monoceres

Help with Avi Api's

4 posts in this topic

#1 ·  Posted (edited)

I'm having the worst debugging process in my life. I have spent literally hours on this piece of code. The most annoying part about the whole thing is that I have a working C++ code I wrote earlier today but for some reason I have missed some step in the translation process. Oh and another annoying thing is that none of the functions are throwing an error and a avi is actually written, however when I look at it in a hex editor it seems that the header is missing or something. Really weird stuff.

Anyways here's my non-working autoit code:

#include <array.au3>
#include <GDIPlus.au3>
#include <winapi.au3>

Global Const $mmioFOURCC_M_S_V_C = 1129730893
Global Const $BITMAPFILEHEADER = "align 2;char magic[2];int size;short res1;short res2;ptr offset;"
Global Const $BITMAPINFOHEADER = "align 2;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 $streamtypeVIDEO=1935960438
Global COnst $AVIIF_KEYFRAME=0x00000010
Global $Avi32_Dll

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];"


LoadBitmap("C:\\ocean.bmp",true,true)
FileDelete("C:\\fuling.avi")
_StartAvi()
$avi=_CreateAvi("C:\\fuling.avi",1,"C:\\ocean.bmp")
_AddBitmapToAvi($avi,"C:\\ocean.bmp")
_CloseAvi($avi)
_StopAvi()

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

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


Func _AddBitmapToAvi($Avi_Handle,$sBitmap)
    $bm=LoadBitmap($sBitmap,True)
    ConsoleWrite(DllStructGetSize($bm[2])&@CRLF)
  ; $Avi_Handle[2] is just a counter
    $ret=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)
;~   _ArrayDisplay($ret)
    $Avi_Handle[2]+=1
EndFunc



Func _CloseAvi($Avi_Handle)
    DllCall($Avi32_Dll,"int","AVIStreamClose","ptr",$Avi_Handle[1])
    DllCall($Avi32_Dll,"int","AVIFileClose","ptr",$Avi_Handle[0])
EndFunc


; Returns array:
; [0]=avi file handle
; [1]=stream handle
; [2]=bitmap counter
Func _CreateAvi($sFilename,$FrameRate,$sBitmapStencil)
    Local $RetArr[3]; avi file handle, stream handle, bitmap count
    
    $ret=DllCall($Avi32_Dll,"int","AVIFileOpenW","ptr*",0,"wstr",$sFilename,"uint",$OF_CREATE,"ptr",0)
    $pfile=$ret[1]
    
    $bm=LoadBitmap($sBitmapStencil)
    
    $asi=DllStructCreate($AVISTREAMINFO)
    DllStructSetData($asi,"fccType",$streamtypeVIDEO)
    DllStructSetData($asi,"fccHandler",$mmioFOURCC_M_S_V_C)
    DllStructSetData($asi,"dwScale",1)
    DllStructSetData($asi,"dwRate",$FrameRate)
    DllStructSetData($asi,"dwQuality",1000)
    DllStructSetData($asi,"rright",DllStructGetData($bm[1],"biWidth"))
    DllStructSetData($asi,"rbottom",DllStructGetData($bm[1],"biHeight"))
    
;~   MsgBox(0,"",DllStructGetSize($asi))
    
    $ret=DllCall($Avi32_Dll,"int","AVIFileCreateStream","ptr",$pfile,"ptr*",0,"ptr",DllStructGetPtr($asi))
;~   _ArrayDisplay($ret)  
    $pstream=$ret[2]
    
  ; The format for the stream is the same as BITMAPINFOHEADER
    $ret=DllCall($Avi32_Dll,"int","AVIStreamSetFormat","ptr",$pstream,"long",0,"ptr",DllStructGetPtr($bm[1]),"long",DllStructGetSize($bm[1]))
;~   _ArrayDisplay($ret)
    
    $RetArr[0]=$pfile
    $RetArr[1]=$pstream
    Return $RetArr
EndFunc



; Returns array with 3 elements
; [0]=BITMAPFILEHEADER
; [1]=BITMAPINFOHEADER
; [2]=Bitmap data buffer (if specified)
Func LoadBitmap($sFilename, $LoadData = False,$debug=false)
    Local $RetArr[3]
    Local $byref
    Local $bih, $bfg, $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($bih, "biSizeImage") & "]")
    $RetArr[2]=$buffer
    _WinAPI_ReadFile($fhandle, DllStructGetPtr($buffer), DllStructGetSize($buffer), $byref)
    _WinAPI_CloseHandle($fhandle)
    
    If $debug Then
        $f=_WinAPI_CreateFile("C:\\debug_autoit.dat",1,4,0)
        _WinAPI_WriteFile($f,DllStructGetPtr($bih),DllStructGetSize($bih),$byref)
        
    EndIf
    
    
    Return $RetArr
EndFunc ;==>LoadBitmap

And my working C++ code:

#include <windows.h>
#include <iostream>
#include <Vfw.h>
#pragma comment (lib,"Vfw32.lib")
using namespace std;

int main ()
{
    DWORD meh;
    HANDLE fhandle;
    fhandle=CreateFile(L"C:\\ocean.bmp",GENERIC_READ,0,NULL,3,0,NULL);
    cout << "File handle: "<< fhandle << endl;

    BITMAPFILEHEADER bfh;
    ReadFile(fhandle,&bfh,sizeof(bfh),&meh,NULL);




    BITMAPINFOHEADER bih;
    ReadFile(fhandle,&bih,sizeof(bih),&meh,NULL);

    BYTE *bitmapdata = new BYTE[bih.biSizeImage];
    ReadFile(fhandle,bitmapdata,bih.biSizeImage,&meh,NULL);

    cout << sizeof(bih) << endl;


    

    AVIFileInit();

    PAVIFILE pfile;
    PAVISTREAM pstream;
    
    AVIFileOpen(&pfile,L"C:\\kebab.avi",OF_CREATE,NULL);
    cout << "AVI File handle: " << pfile << endl;

    AVISTREAMINFO asi;
    memset(&asi,0,sizeof(asi));
    asi.fccType=streamtypeVIDEO;
    cout << "hello " << streamtypeVIDEO << endl;
    asi.fccHandler=mmioFOURCC('M','S','V','C');
    cout << asi.fccHandler << endl;
    asi.dwScale=1;
    asi.dwRate=15;
    asi.dwQuality=1000;
    asi.rcFrame.right=bih.biWidth;
    asi.rcFrame.bottom=bih.biHeight;

    cout << bih.biSizeImage << endl;

    
    AVIFileCreateStream(pfile,&pstream,&asi);
    cout << "Stream handle: " << pfile << endl;

    if(AVIStreamSetFormat(pstream,0,&bih,sizeof(bih)))
        cout << "Error setting format!" << endl;


    AVIStreamWrite(pstream,0,1,bitmapdata,bih.biSizeImage,AVIIF_KEYFRAME,NULL,NULL);


    delete [bih.biSizeImage]bitmapdata;
    CloseHandle(fhandle);
    AVIStreamClose(pstream);
    AVIFileClose(pfile);
    AVIFileExit();
    return 0;
}

Really appreciate it if someone took the time to look at it.

:)

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites



Oh my fucking god.

Would you believe that AVIStreamClose and AVIStreamClose was just alias's for the real functions (AViStreamRelease & AVIFileRelease)?

Worst "bug" I ever killed.

I mean how often do you check if the uninitialization of interfaces was successful?


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

so is it possible to screen record into .avi files using autoit now or no..??

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0