unit VidInfo;
{
Retrieves information for given filenames.
Works with AVI and MPEG/VOB files as well as with
DVDAVI (.d2v) project files (as they are tracked down
to the source files, as you can see in getD2VVideo).
(c) 2004 by Marcel
last changes 2005-01-05 by Amnon82:
}
interface
Type
TVideoInfo =
Record
Width, Height,
//resolution of the video; might be different from
//correct display resolution (as NTSC SVCDs have a
//resolution of 480*480 but are displayed with e.g.
//640*480
FPS1000,
//Frames per second * 1000: for NTSC, FPS1000 = 29970
MPEGversion,
//1 for MPEG-1, 2 for MPEG-2, 0 for any other, like
//AVI files
AspectRatio,
//1 for square pixels (=AR_SQUARE_PIXEL)
//2 for 4:3 display aspect ratio, as for VCD and
// SVCD (=AR_4to3)
//3 for 16:9 display aspect ratio, as for most DVDs
// (=AR_16to9)
Streams
//Number of Streams (audio and video) - AVI only
: Integer;
FPS: Single;
//Frames per second in floating point format
Frames: LongInt;
//Number of frames - only detected for AVI files
PiDAR: Single;
//Pixel Display Aspect Ratio:
//when displaying the video, the width of a pixel
//should be its height multiplied by PiDAR
end;
Const
AR_SQUARE_PIXEL = 1;
AR_4to3 = 2;
AR_16to9 = 3;
function getD2VVideo(sFileName:
String):
String;
function getVideoInfo(sFileName:
String): TVideoInfo;
implementation
uses SysUtils, Classes;
function getD2VVideo(sFileName:
String):
String;
var slD2V: TStringList;
sFn:
String;
iBlankPos: Integer;
begin
Try
slD2V := TStringList.Create;
slD2V.Clear;
slD2V.LoadFromFile(sFileName);
if slD2V.Count > 2
then begin
if (slD2V.Strings[0] = '
DGIndexProjectFile06')
or (slD2V.Strings[0] = '
DVD2AVIProjectFile')
then sFn := slD2V.Strings[2];
iBlankPos := Pos('
', sFn);
if iBlankPos > 0
then delete(sFn,1,iBlankPos)
else sFn := '
';
end
else sFn := '
';
Finally
getD2VVideo := sFn;
slD2V.Free;
End;
end;
function getVideoInfo(sFileName:
String): TVideoInfo;
var f:
file of byte;
i: integer;
liMsPerFrame, liStreams, liWidth, liHeight, liFrames: LongInt;
bByte: Byte;
hex:
Array [0..15]
of Char;
buf:
String;
FPS: Single;
VI: TVideoInfo;
booDone1B3, booDone1BA: Boolean;
cnt: Integer;
begin
for i := 0
to 9
do hex[i] := IntToStr(i)[1];
hex[10]:='
A'; hex[11]:='
B'; hex[12]:='
C'; hex[13]:='
D'; hex[14]:='
E'; hex[15]:='
F';
FPS := 0;
cnt := 0;
vi.AspectRatio := AR_SQUARE_PIXEL;
vi.FPS := 0;
vi.FPS1000 := 0;
vi.MPEGversion := 0;
vi.Width := 0;
vi.Height := 0;
vi.Frames := 0;
vi.PiDAR := 1;
vi.Streams := 2;
if UpperCase(copy(sFileName, length(sFileName)-2,3)) = '
D2V'
then sFileName := getD2Vvideo(sFileName);
booDone1B3 := False;
booDone1BA := False;
AssignFile(f, sFileName);
Reset(f);
if UpperCase(copy(sFileName, length(sFileName)-2,3)) = '
AVI'
then begin
vi.MPEGversion := 0;
vi.AspectRatio := AR_SQUARE_PIXEL;
for i := 1
to 32
do if not EOF(f)
then Read(f,bByte);
if not EOF(f)
then Read(f,bByte); liMsPerFrame := bByte;
if not EOF(f)
then Read(f,bByte); liMsPerFrame := liMsPerFrame + bByte * 256;
if not EOF(f)
then Read(f,bByte); liMsPerFrame := liMsPerFrame + bByte * 256 * 256;
if not EOF(f)
then Read(f,bByte); liMsPerFrame := liMsPerFrame + bByte * 256 * 256 * 256;
vi.FPS := 1000000 / liMsPerFrame;
for i := 1
to 12
do if not EOF(f)
then Read(f,bByte);
if not EOF(f)
then Read(f,bByte); liFrames := bByte;
if not EOF(f)
then Read(f,bByte); liFrames := liFrames + bByte * 256;
if not EOF(f)
then Read(f,bByte); liFrames := liFrames + bByte * 256 * 256;
if not EOF(f)
then Read(f,bByte); liFrames := liFrames + bByte * 256 * 256 * 256;
vi.Frames := liFrames;
for i := 1
to 4
do if not EOF(f)
then Read(f,bByte);
if not EOF(f)
then Read(f,bByte); liStreams := bByte;
if not EOF(f)
then Read(f,bByte); liStreams := liStreams + bByte * 256;
if not EOF(f)
then Read(f,bByte); liStreams := liStreams + bByte * 256 * 256;
if not EOF(f)
then Read(f,bByte); liStreams := liStreams + bByte * 256 * 256 * 256;
vi.Streams := liStreams;
for i := 1
to 4
do if not EOF(f)
then Read(f,bByte);
if not EOF(f)
then Read(f,bByte); liWidth := bByte;
if not EOF(f)
then Read(f,bByte); liWidth := liWidth + bByte * 256;
if not EOF(f)
then Read(f,bByte); liWidth := liWidth + bByte * 256 * 256;
if not EOF(f)
then Read(f,bByte); liWidth := liWidth + bByte * 256 * 256 * 256;
vi.Width := liWidth;
if not EOF(f)
then Read(f,bByte); liHeight := bByte;
if not EOF(f)
then Read(f,bByte); liHeight := liHeight + bByte * 256;
if not EOF(f)
then Read(f,bByte); liHeight := liHeight + bByte * 256 * 256;
if not EOF(f)
then Read(f,bByte); liHeight := liHeight + bByte * 256 * 256 * 256;
vi.Height := liHeight;
end;
if (UpperCase(copy(sFileName, length(sFileName)-3,4)) = '
MPEG')
or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = '
MPG')
or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = '
MPE')
or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = '
VOB')
or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = '
M1V')
or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = '
M2V')
or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = '
MPV')
then begin
vi.AspectRatio := AR_SQUARE_PIXEL;
if length(buf) >= 8
then delete(buf,1,2);
while (EOF(f)=false)
and ((booDone1B3 = false)
or (booDone1BA = false))
do begin
if length(buf) >= 8
then delete(buf,1,2);
Read(f,bByte);
Inc(cnt);
buf := buf + hex[bByte
DIV 16] + hex[bByte
MOD 16];
if buf = '
000001B3'
then begin // FPS and Res
if not EOF(f)
then Read(f,bByte);
vi.Width := bByte * 16;
if not EOF(f)
then Read(f,bByte);
vi.Width := vi.Width + bByte
DIV 16;
vi.Height := (bByte
MOD 16) * 256;
if not EOF(f)
then Read(f,bByte);
vi.Height := vi.Height + bByte;
if not EOF(f)
then Read(f,bByte);
vi.AspectRatio := bByte
DIV 16;
if vi.AspectRatio = 8
then vi.AspectRatio := 3;
if vi.AspectRatio = 12
then vi.AspectRatio := 2;
bByte := bByte
MOD 16;
Case bByte
of
1: vi.FPS := 23.976;
2: vi.FPS := 24;
3: vi.FPS := 25;
4: vi.FPS := 29.97;
5: vi.FPS := 30;
6: vi.FPS := 50;
7: vi.FPS := 59.94;
8: vi.FPS := 60;
end;
booDone1B3 := True;
end;
if buf = '
000001BA'
then begin
if not EOF(f)
then Read(f,bByte)
else bByte := 0;
if bByte
AND $F0 = $20
then vi.MPEGversion := 1;
if bByte
AND $C0 = $40
then vi.MPEGversion := 2;
booDone1BA := True;
end;
if cnt > 16384
then begin
booDone1B3 := True;
booDone1BA := True;
end;
end;
end;
CloseFile(f);
vi.FPS := round(vi.FPS*1000)/1000;
vi.FPS1000 := round(vi.FPS*1000);
case vi.AspectRatio
of
AR_SQUARE_PIXEL:
vi.PiDAR := 1;
AR_4to3:
vi.PiDAR := (vi.Height * 4 / 3) / vi.Width;
AR_16to9:
vi.PiDAR := (vi.Height * 16 / 9) / vi.Width;
end;
getVideoInfo := vi;
end;
end.