I am using VFW unit from JEDI wrapper on WinAPI.
The code I am writing is intended to search user drives and detect warez. We do MP3, WMA and some graphic file search. Now we want to detect illegal movies. I want to open AVI file, read some details from it 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:
- The lLenMinutes is something equal to 98 while the movie is about two hours. dwRate is 1 million and dwScale is 40k, so the FPS is perfectly 25. MSDN says: “The units are defined by dwRate and dwScale”.
- The code crashes on FreeAndNil line. Why? I assume I am responsible for freeing lFile (and at least I feel supposed to release file). Without line with FreeAndNil, I have Acces Violation on exit from a procedure.
So, do you have any clue how to correctly obtain movie duration from AVI file? And why the crash?
Edit
The movie is 2hours one minute, so the result should be really close to 120.The lFile is declared in Jedi as:
IAVIFile = interface(IUnknown)
the AVIFileOpen is declared in JEDI as:
function AVIFileOpen(var ppfile: IAVIFILE; szFile: LPCWSTR; uMode: UINT; lpHandler: PCLSID): HResult; stdcall; external AVIFILDLL name 'AVIFileOpenW';
and in 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 a file interface used to access it."
so I assume object is created by this function.
Edit 2
The avi file length has been move to new question, since mghie answered this question.