Error getting AVI file

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.

0
source share
2 answers

The functions are paired, AVIFileOpen() and AVIFileRelease() belong to each other. Before AVIFileOpen() is called the lFile variable, there is nil , then (if everything goes well), it contains an interface pointer. It has a reference count of 1. After calling AVIFileRelease() variable should again contain nil , but it is not. Now, when your method exits from the code provided by the compiler to free the interface pointers, it will try to decrease the reference count of the already issued interface.

You have basically two ways to fix this:

  • Increase the interface pointer reference count after AVIFileOpen() .

  • Reset variable without trying to decrease the reference count. Use a pointer to a pointer:

    pointer (lFile): = nil;

Also, add an AVIFileExit() call to match your AVIFileInit() call.

+3
source

98 minutes - an hour and 38 minutes. What is about two hours?

As for the crash on FreeAndNil (), it is intended to free the child of TObject and set the variable containing it to nil. Where do you create a TObject descendant in your code? It looks like lFile is an interface, so just setting the variable to nil should be enough to decrease the reference count:

 lFile := nil; 

A call to Free inside FreeAndNil () is probably the cause of the failure.

EDIT: Based on the changes to the original question, this is obviously not true. However, I suspect that calling AVIFileRelease() has already freed up the interface, and therefore you have nothing to do. lFile is still out of scope, and the link count will automatically decrease.

Regarding the MSDN quote on AVIFileOpen() , note that it says it “returns the file interface address”. This is a COM interface that is by no means a form or form that is a descendant of Delphi TObject . This JEDI code snippet also talks about this since it says that IAviFile is interface(IUnknown)

+1
source

Source: https://habr.com/ru/post/1393925/


All Articles