I am using the VFW module from the JEDI shell in WinAPI.
The code I'm writing is for finding user drives and defining warez. We do MP3, WMA and some image file search. Now we want to find illegal films. I want to open an AVI file, read some details and close it. I have the following code:
uses WFV; //from JEDI api wrappers procedure TForm1.Button1Click(Sender: TObject); var lInfo : TAVIFILEINFO lFile : IAVIFILE; lFileType : string; lLenMinutes : integer; lFPS : integer; begin {init file} AVIFileInit; {Open file - note: since we search for warez this is perfely "warezy" file} AVIFileOpen(lFile, 'e:\Sideways KLAXXON\Sideways KLAXXON.avi', OF_READ, nil); {Get file info} AVIFileInfoW(lFile, lInfo, sizeof(lInfo)); lFPS:=Round(lInfo.dwRate /lInfo.dwScale); lLenMinutes := Round(lInfo.dwLength / lFPS / 60); lFileType := lInfo.szFileType; {just for show: prepare some memo to see what we get} memo1.Lines.Clear; memo1.Lines.Add('File lenght [min]: ' + IntToStr(lLenMinutes)); memo1.Lines.Add('Width: ' + IntToStr(lInfo.dwWidth)); memo1.Lines.Add('Height: ' + IntToStr(lInfo.dwHeight)); memo1.Lines.Add('File type: ' + lFileType); {Closing the file} AVIFileRelease (lFile); {and here goes the crash} FreeAndNil(lFile); end;
There are two problems:
- lLenMinutes is something equal to 98, and the movie is about two hours. dwRate is 1 million and dwScale is 40k, so FPS is excellent 25. MSDN says : "The units are determined by dwRate and dwScale."
- Code Failure on the FreeAndNil Line. What for? I believe that I am responsible for freeing lFile (and at least I feel should release the file). Without line with FreeAndNil, I have an Acces Violation when exiting a procedure.
So, do you have any tips on how to correctly get the movie duration from an AVI file? And why the accident?
Edit
The film is 2 hours per minute, so the result should be really close to 120. lFile is declared in the Jedi as:
IAVIFile = interface(IUnknown)
AVIFileOpen is declared in JEDI as:
function AVIFileOpen (var ppfile: IAVIFILE; szFile: LPCWSTR; uMode: UINT; lpHandler: PCLSID): HResult; STDCALL; AVIFILDLL external name 'AVIFileOpenW';
and on MSDN:
STDAPI AVIFileOpen (PAVIFILE * ppfile, LPCTSTR szFile, UINT mode, CLSID pclsidHandler);
MSDN says:
"The AVIFileOpen function opens an AVI file and returns the address of the file the interface used to access it."
therefore, I assume that the object is created by this function.
Edit 2
The length of the avi file has shifted to a new question since mghie answered this question.