Author: Tomas Rutkauskas
How to open and read the first frame in an AVI file
Answer:
{File: AVIObjects.pas
Author: Liran Shahar
Purpose: AVI file objects routines to open,read and retrive poster frames (first
frame in AVI file)
Copyright(C) 2001, Com-N-Sense Ltd, all rights reserved
Note: this unit is released as freeware. In other words, you are free to use this
unit in your own applications, however I retain all copyright to the code. LS}
1 unit AVIObjects;
2
3 interface
4
5 uses
6 Windows, Graphics, Sysutils, Classes, VFW, Ole2;
7
8 type
9 TAviFileStream = class(TPersistent)
10 private
11 aviFile: IAviFile;
12 aviStream: IAviStream;
13 aviFrame: IGetFrame;
14 aviInfo: TAviStreamInfo;
15 protected
16 function GetFrameCount: cardinal; virtual;
17 function GetDuration: double; virtual;
18 function GetWidth: integer; virtual;
19 function GetHeight: integer; virtual;
20 function GetWantedBitmapFormat: PBitmapInfoHeader; virtual;
21 public
22 constructor Create; virtual;
23 destructor Destroy; override;
24 function Active: boolean; virtual;
25 procedure Open(const Filename: AnsiString); virtual;
26 procedure Close; virtual;
27 procedure GetFrame(FrameNumber: cardinal; var DIB: PBitmapInfoHeader); virtual;
28 property FrameCount: cardinal read GetFrameCount;
29 property Duration: double read GetDuration;
30 property ImageWidth: integer read GetWidth;
31 property ImageHeight: integer read GetHeight;
32 end;
33
34 implementation
35
36 constructor TAviFileStream.Create;
37 begin
38 inherited Create;
39 aviFile := nil;
40 aviStream := nil;
41 aviFrame := nil;
42 end;
43
44 destructor TAviFileStream.Destroy;
45 begin
46 Close;
47 inherited Destroy;
48 end;
49
50 function TAviFileStream.Active: boolean;
51 begin
52 Result := (aviStream <> nil) and (aviFrame <> nil);
53 end;
54
55 function TAviFileStream.GetFrameCount: cardinal;
56 begin
57 Result := aviInfo.dwLength;
58 end;
59
60 function TAviFileStream.GetDuration: double;
61 begin
62 if (aviInfo.dwRate <> 0) and (aviInfo.dwScale <> 0) then
63 Result := aviInfo.dwLength / (aviInfo.dwRate / aviInfo.dwScale)
64 else
65 Result := 0.0;
66 end;
67
68 function TAviFileStream.GetWidth: integer;
69 begin
70 Result := aviInfo.rcFrame.Right - aviInfo.rcFrame.Left;
71 end;
72
73 function TAviFileStream.GetHeight: integer;
74 begin
75 Result := aviInfo.rcFrame.Bottom - aviInfo.rcFrame.Top;
76 end;
77
78 function TAviFileStream.GetWantedBitmapFormat: PBitmapInfoHeader;
79 begin
80 Result := nil;
81 end;
82
83 procedure TAviFileStream.Open(const Filename: AnsiString);
84 var
85 iResult: integer;
86 BmpInfoHeader: PBitmapInfoHeader;
87 begin
88 Close;
89 fillchar(aviInfo, sizeof(aviInfo), 0);
90 iResult := AviFileOpen(aviFile, pchar(FileName), OF_READ + OF_SHARE_DENY_WRITE,
91 nil);
92 if iResult <> AVIERR_OK then
93 raise Exception.Create('Cannot open AVI file ' + Filename);
94 iResult := AVIFileGetStream(aviFile, aviStream, streamTypeVideo, 0);
95 if iResult <> AVIERR_OK then
96 raise Exception.Create('Cannot open stream for that file');
97 iResult := AVIStreamInfo(aviStream, aviInfo, sizeof(aviInfo));
98 if iResult <> AVIERR_OK then
99 raise Exception.Create('Cannot read stream info');
100 BmpInfoHeader := GetWantedBitmapFormat;
101 aviFrame := AVIStreamGetFrameOpen(aviStream, BmpInfoHeader);
102 if not assigned(aviFrame) then
103 raise Exception.Create('Cannot find suitable decompressor');
104 if assigned(BmpInfoHeader) then
105 dispose(BmpInfoHeader);
106 end;
107
108 procedure TAviFileStream.Close;
109 var
110 iResult: integer;
111 begin
112 aviFrame := nil;
113 aviStream := nil;
114 aviFile := nil;
115 end;
116
117 procedure TAviFileStream.GetFrame(FrameNumber: cardinal; var DIB:
118 PBitmapInfoHeader);
119 begin
120 DIB := aviStreamGetFrame(aviFrame, FrameNumber)
121 end;
122
123 initialization
124 CoInitialize(nil);
125 AVIFileInit;
126
127 finalization
128 AVIFileExit;
129 CoUninitialize;
130
131 end.
|