Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Read a frame for an avi movie

Posted on 2000-03-22
6
Medium Priority
?
491 Views
Last Modified: 2010-04-04
I need to display a frame into a canvas from an avi without display the movie and without TMediaPlayer .

For example I wish to display frame 1400 into a canvas .
But VERY IMPORTANT :
I DON'T WISH TO USE TMEDIAPLAYER .
I need an algorithm for read directly from avi .

In same time I need to know the number of frames from avi file .
0
Comment
Question by:ginsonic
  • 3
  • 2
6 Comments
 
LVL 10

Expert Comment

by:Lischke
ID: 2645288
Hi Ginsonic,

here is code I have used a while ago. For some function calls you need a stripped down version of VfW.h (do a search for VfW.pas on the web or download www.lischke-online.de/Download/GLScene044.zip) for this unit and the following code:

type TAVIGraphic = class(TBitmap)
     private
       FAviFile       : PAVIFile;
       FAviStream     : PAVIStream;
       FGetFrameIntf  : PGetFrame;
       FAviFileInfo   : TAVIFileInfoW;
       FAviStreamInfo : TAVIStreamInfo;
       FFrame         : Pointer;
       FCurrentFrame  : Longint;
       FFrames        : Longint;
       FTimer         : TTimer;
       FSpeedFactor   : Single;
     protected
       procedure CloseAVIFile;
       procedure GetNextFrame(Sender: TObject);
       procedure LoadFrame;
       procedure OpenAVIFile(AName: TFileName; Animate: Boolean);
     public
       constructor Create; override;
       destructor Destroy; override;
       procedure LoadFromFile(const FileName: String); override;
       procedure Start;
       procedure Stop;
       property CurrentFrame: Longint read FCurrentFrame;
     published
       property SpeedFactor: Single read FSpeedFactor write FSpeedFactor;
     end;

//----------------- TAVIGraphic ------------------------------------------------

procedure TAVIGraphic.CloseAVIFile;

begin
  FTimer.enabled:=False;
  if assigned(FGetFrameIntf) then AVIStreamGetFrameClose(FGetFrameIntf);
  FGetFrameIntf:=nil;
  if assigned(FAVIStream) then AVIStreamRelease(FAVIStream);
  FAVIStream:=nil;
  if assigned(FAVIFile) then AVIFileRelease(FAVIFile);
  FAVIFile:=nil;
end;

//------------------------------------------------------------------------------

constructor TAVIGraphic.Create;

begin
  inherited Create;
  FTimer:=TTimer.Create(nil);
  FTimer.enabled:=False;
  FTimer.OnTimer:=GetNextFrame;
  FSpeedFactor:=1;
end;

//------------------------------------------------------------------------------

destructor TAVIGraphic.Destroy;

begin
  CloseAVIFile;
  FTimer.Free;
  inherited Destroy;
end;

//------------------------------------------------------------------------------

procedure TAVIGraphic.GetNextFrame(Sender: TObject);

begin
  LoadFrame;
  Changed(Self);
end;

//------------------------------------------------------------------------------

procedure TAVIGraphic.LoadFrame;

var Position : Longint;

begin
  if assigned(FGetFrameIntf) then AVIStreamGetFrameClose(FGetFrameIntf);
  FGetFrameIntf:=AVIStreamGetFrameOpen(FAVIStream,nil);
  FFrame:=AVIStreamGetFrame(FGetFrameIntf,FCurrentFrame);
  if FFrame = nil then Exit;
  Inc(FCurrentFrame);
  if FCurrentFrame = FFrames then FCurrentFrame:=FAVIStreamInfo.dwStart;
  with TBitmapInfo(FFrame^).bmiHeader do
  begin
    Position:=Longint(FFrame)+SizeOf(TBitmapInfoHeader);
    if biClrUsed > 0 then Inc(Position,biClrUsed*Sizeof(TRGBQuad));
    StretchDIBits(Canvas.Handle,0,0,biWidth,biHeight,0,0,biWidth,biHeight,
                  Pointer(Position),TBitmapInfo(FFrame^),DIB_RGB_COLORS,SRCCOPY);
  end;
end;

//------------------------------------------------------------------------------

procedure TAVIGraphic.LoadFromFile(const FileName: String);

begin
  CloseAVIFile;
  OpenAVIFile(FileName,True);
end;

//------------------------------------------------------------------------------

procedure TAVIGraphic.OpenAVIFile(AName: TFileName; Animate: Boolean);

var Result : HResult;

begin
  try
    Result:=AVIFileOpen(FAVIFile,PChar(AName), OF_READ or OF_SHARE_DENY_WRITE,nil);
    if Result <> 0 then Abort;
    Result:=AVIFileInfo(FAVIFile,@FAVIFileInfo,SizeOf(TAVIFileInfoW));
    if Result <> 0 then Abort;
    AVIFileGetStream(FAVIFile,FAVIStream,streamtypeVIDEO,0);
    if FAVIStream = nil then Abort;
    AVIStreamInfo(FAVIStream,@FAVIStreamInfo,Sizeof(TAVIStreamInfo));
    with FAVIStreamInfo do
    begin
      FFrames:=dwLength;
      FCurrentFrame:=dwStart;
      Width:=rcFrame.Right-rcFrame.Left;
      Height:=rcFrame.Bottom-rcFrame.Top;
      LoadFrame;
      if FSpeedFactor <= 0 then FSpeedFactor:=1;
      FTimer.Interval:=Round(1000*dwScale/(dwRate*FSpeedFactor));
      if FTimer.Interval = 0 then FTimer.Interval:=1;
      if Animate then FTimer.enabled:=True;
    end;
  except
    raise Exception.Create('Could not open AVI file '''+AName+'''');
  end;
end;

//------------------------------------------------------------------------------

procedure TAVIGraphic.Start;

begin
  FTimer.enabled:=True;
end;

//------------------------------------------------------------------------------

procedure TAVIGraphic.Stop;

begin
  FTimer.enabled:=False;
end;

//------------------------------------------------------------------------------



Note: This stuff is quite old and may not be the optimal implementation. But at least it works :-)

Ciao, Mike
0
 
LVL 17

Expert Comment

by:inthe
ID: 2645883
0
 
LVL 9

Author Comment

by:ginsonic
ID: 2647947
where can I find the Microsoft Video SDK ?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 10

Expert Comment

by:Lischke
ID: 2648299
You have to download a 10MB package from http://msdn.microsoft.com/downloads/sdks/platform/dxmedia.asp (take the Platform SDK build environment). From the file you get you can extract INCLUDE_VfW.h etc. using WinZip (it's in Win32-B.cab).

Ciao, Mike
0
 
LVL 9

Author Comment

by:ginsonic
ID: 2648588
Houston we have a problem !

Hi Mike .
I try your code but I think I wrong somewhere .
Can you send me a project file at nick@radioterra.ro ?

I will add 100 points for that .

A sample code with a Panel and a button .
When I press the button to see the movie in panel.

But important .
I don't with to see the avi file .
Just to extract the frames directly ( without capture ) from avi and to display the bmps in Panel .

Regards,
Nick
0
 
LVL 10

Accepted Solution

by:
Lischke earned 400 total points
ID: 2648793
Nick, I just sent you the sample project.

Ciao, Mike
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses

824 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question