Solved

Read a frame for an avi movie

Posted on 2000-03-22
6
477 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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 100 total points
ID: 2648793
Nick, I just sent you the sample project.

Ciao, Mike
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

707 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