mrmarman
15th June 2006, 19:23
Hi-
- I'm studying computer programming and want to produce a tiny application. I'm using Delphi Programming language.
- I have a Hardware DivX player that not supports GMC and QPEL.
- I want to check QPEL and GMC from AVI files and send result to a Database that I createted automatically.
- I made an AVI file Info Structure viewer with OpenDML AVI Info Structure pdf documentation, but didn't see any information about determining these specs from an avi.
- I have a couple of DivX AVI that contains QPEL and/or GMC.
- MPEG4 Modifier says below
Packed bitstream: Yes
QPel: Yes
GMC: Yes (2 warp points)
Interlaced: No
Aspect ratio: Square pixels
Quant type: H.263
I-VOPs: 1 (0,72%)
P-VOPs: 41 (29,71%)
B-VOPs: 68 (49,28%)
S-VOPs: 28 (20,29%)
N-VOPs: 0 (0,00%)
Max consecutive B-VOPs: 1
Warp points used:
1: 100,00%
- I can access a file with binary mode and made an tiny utility for this operation and cropped an AVI file until QuarterPixel result No.
- MPEG4 Modifier does not support truncated AVI's so that I tried other two program AVICheck and GSPOT.
- The result; size limitation of detection for AVICheck is 38.427 bytes. This test for GSpot program was 121.675 bytes.
- So, I understood that the QPEL record is not in AVI header chunk, in the data chunks.
- Now, please give me a trick about how to find and detect QPEL and GMC from AVI. Which part of AVI chunk ( for example you say : first 00dc (Video Frame) you must pass nn bytes and read or search blabla hex Flag and read next bit )
- I check MPEG4 Modifier Source but I lost between "BitStream Class" and "ParseVOP". Java is foreign for me very much. :(
- I can read and report AVI Info like below..
[AVI]
AvihSize=56
dwMicroSecPerFrame=40000
dwMaxBytesPerFrame=0
dwPaddingGranularity=0
dwFlags=0x00000110
dwTotalFrames=33156
dwInitialFrames=0
dwStreams=2
dwSuggestedBufferSize=0
dwWidth=480
dwHeight=352
[STRL_01]
StrlSize=4244
StrhSize=56
fccType=vids
fccHandler=divx
dwFlags=0x00000000
wPriority=0
wLanguage=0
dwInitialFrames=0
dwScale=1000
dwRate=25000
dwStart=0
dwLength=33156
dwSuggestedBufferSize=75292
dwQuality=10000
dwSampleSize=0
rcFrame_wX1=0
rcFrame_wY1=0
rcFrame_wX2=480
rcFrame_wY2=352
[STRL_01_Video]
StrfSize=40
biSize=40
biWidth=480
biHeight=352
biPlanes=1
biBitCount=24
biCompression=DX50
biSizeImage=506880
biXPelsPerMeter=0
biYPelsPerMeter=0
biClrUsed=0
biClrImportant=0
[STRL_02]
StrlSize=4234
StrhSize=56
fccType=auds
fccHandler=
dwFlags=0x00000000
wPriority=0
wLanguage=0
dwInitialFrames=1
dwScale=1152
dwRate=48000
dwStart=0
dwLength=55260
dwSuggestedBufferSize=768
dwQuality=-1
dwSampleSize=0
rcFrame_wX1=0
rcFrame_wY1=0
rcFrame_wX2=1136
rcFrame_wY2=0
[STRL_02_Audio]
StrfSize=30
wFormatTag=0x0055
nChannels=2
nSamplesPerSec=48000
nAvgBytesPerSec=16000
nBlockAlign=1152
wBitsPerSample=0
cbSize=12
- I try to make a function below.. I'm seeking 00dc chunk and starting GMC and/or QPEL flag detection.
Function FrameType(InFile:String) : Integer;
Var
AVIFile : File;
Chunk1,
Chunk2 : string[4];
Position,
Size : dWord;
FlagResult: Byte;
Two : Word;
begin
Result := -1;
AssignFile( AVIFile, InFile );
FileMode := 0; // read only
Reset(AVIFile, 1);
Position := 12;
While (Chunk2 <> 'movi') AND (Position < 50000) do
begin // 50000 is precaution for infinite loop
Chunk1[0] := #4;
Chunk2[0] := #4;
Seek(AVIFile, Position);
BlockRead(AVIFile, Chunk1[1], 4);
BlockRead(AVIFile, Size, SizeOf(Size));
BlockRead(AVIFile, Chunk2[1], 4);
if Chunk2 <> 'movi' then Inc(Position, Size + 8);
end;
If Chunk2 <> 'movi' then
begin
ShowMessage('File Truncated');
Exit;
end;
Inc(Position, 8); // Start Position -> 'movi'
Inc(Position, 4); // Start Position -> '01wb'
Seek(AVIFile, Position);
BlockRead(AVIFile, Chunk1[1], 4);
BlockRead(AVIFile, Size, SizeOf(Size));
Inc(Position, Size + 8); // NOW Start Position ->'00dc' (Video Frame)
While (Chunk1 <> '00dc') AND (Position < 50000) do
begin // 50000 is precaution for infinite loop
Chunk1[0] := #4; // Reset variable
Seek(AVIFile, Position);
BlockRead(AVIFile, Chunk1[1], 4);
BlockRead(AVIFile, Size, SizeOf(Size));
if Chunk1 <> '00dc' then Inc(Position, Size + 8);
end;
If Chunk1 <> '00dc' then
begin
ShowMessage('!File Truncated');
Exit;
end;
// Message for trace: are we really positioned on '00dc'
// and chunk size what we read.
ShowMessageFmt('%xh: %s -> %x', [Position, Chunk1, Size]);
//_____________________________________
// These section is not complete...
Two := 0;
FlagResult := 0;
Inc(Position, 8 + 38); // one file can find 'B601' but its changing place
Seek(AVIFile, Position);
BlockRead(AVIFile, Two, SizeOf(Two));
BlockRead(AVIFile, FlagResult, SizeOf(FlagResult));
ShowMessageFmt('%xh: Founded Flag -> %.4x and Result : %x', [Position, Two, FlagResult]);
//_____________________________________
Case FlagResult of
$00 : Result := 0;
$01 : Result := 1;
$10 : Result := 2;
$11 : Result := 3;
end; // Case
CloseFile(AVIFile);
end;
- Please help ...
- Best regards Muharrem ARMAN
mrmarman
17th June 2006, 13:22
@sysKin thank you for this opinion.
- I really light up now and take the your route.
Sample GMC + QPEL http://img265.imageshack.us/img265/8387/qpelgmcsamplevw7.png
- I trace the 0x00000120 and found the VOL (Video Object Layer) programmatically and get and next four bytes converted to the binary format. The result is below.
[00]00dc Offset: 000085D4-0000D163
VOLoffset : 85E0
0000000000000000
0000000001001000
0000000000001000
0000000010111010
Function CheckIt( InFile:String; MaxBytes:dWord ) : Integer;
Function HexToBin(const S: string): string; // sub function needed for bit op.
var I: integer; T: string;
begin
Result:='';
for I:=1 to Length(S) do
begin
case S[I] of
'0': T:='0000';
'1': T:='0001';
'2': T:='0010';
'3': T:='0011';
'4': T:='0100';
'5': T:='0101';
'6': T:='0110';
'7': T:='0111';
'8': T:='1000';
'9': T:='1001';
'A': T:='1010';
'B': T:='1011';
'C': T:='1100';
'D': T:='1101';
'E': T:='1110';
'F': T:='1111';
else T:= 'xxxx';
end; // Case
Result:=Concat(Result,T)
end
end;
Const
VOLStart = $20010000; //0x00000120 Video Object Layer (VOL)
UserData = $B2010000; //0x000001B2 User Data
VOPStart = $B6010000; //0x000001B6 Video Object Plane (VOP)
Var
AVIFile : File;
Chunk : string[4];
dValue,
Position,
dSize : dWord;
bByte : Byte;
dcCounter : Integer;
dcStart,
dcEnd : dWord;
MaxSize : dWord;
begin
Form1.Memo1.Lines.Clear;
Result := -1;
Position := 12;
dcCounter := 00;
AssignFile( AVIFile, InFile );
FileMode := 0; // read only
Reset(AVIFile, 1);
If MaxBytes = 0 then MaxSize := FileSize(AVIFile)
else MaxSize := MaxBytes;
While (Chunk <> 'movi') AND (Position < MaxSize) do
begin
Chunk[0] := #4;
Seek(AVIFile, Position);
BlockRead(AVIFile, Chunk[1], 4);
BlockRead(AVIFile, dSize, SizeOf(dSize));
Chunk[0] := #4;
BlockRead(AVIFile, Chunk[1], 4);
if Chunk <> 'movi' then Inc(Position, dSize + 8);
end;
If Chunk <> 'movi' then
begin
ShowMessage('File Truncated');
Exit;
end;
Inc(Position, 8); // Position 'movi'
Inc(Position, 4); // Position '01wb'
Seek(AVIFile, Position);
Chunk[0] := #4;
BlockRead(AVIFile, Chunk[1], 4);
BlockRead(AVIFile, dSize, SizeOf(dSize));
Inc(Position, dSize + 8); // now we are prior position of "00dc" (Video Frame)
Repeat
Chunk := '';
While (Chunk <> '00dc') AND (Position < MaxSize) do
begin
Chunk[0] := #4; // Reset variable
Seek(AVIFile, Position);
BlockRead(AVIFile, Chunk[1], 4);
BlockRead(AVIFile, dSize, SizeOf(dSize));
if Chunk <> '00dc' then Inc(Position, dSize + 8);
end;
If Chunk <> '00dc' then
begin
//ShowMessage('!File Truncated');
Exit;
end;
dcStart := Position;
dcEnd := Position + dSize + 8;
Form1.Memo1.Lines.Add('');
Form1.Memo1.Lines.Add( Format('[%.2d]00dc Offset: %.8x-%.8x', [dcCounter, dcStart, dcEnd]) );
While ( dWord(FilePos(AVIFile)) < dcEnd ) do
begin
BlockRead(AVIFile, dValue, SizeOf(dValue));
If ( dValue = VOLStart ) AND (NOT EOF(AVIFile) ) then
begin
Form1.Memo1.Lines.Add( Format('VOLoffset : %.4x', [FilePos(AVIFile)-4]) );
// Byte-1
BlockRead(AVIFile, bByte, SizeOf(bByte));
Form1.Memo1.Lines.Add( HexToBin(Format('%.4x', [bByte])) );
// Byte-2
BlockRead(AVIFile, bByte, SizeOf(bByte));
Form1.Memo1.Lines.Add( HexToBin(Format('%.4x', [bByte])) );
// Byte-3
BlockRead(AVIFile, bByte, SizeOf(bByte));
Form1.Memo1.Lines.Add( HexToBin(Format('%.4x', [bByte])) );
// Byte-4
BlockRead(AVIFile, bByte, SizeOf(bByte));
Form1.Memo1.Lines.Add( HexToBin(Format('%.4x', [bByte])) );
end
else Seek(AVIFile, FilePos(AVIFile)-3); // three bytes rewind
end; // While
Inc(dcCounter);
If dcEnd MOD 2 = 0 then Position := dcEnd
else Position := dcEnd + 1;
Until ( dcCounter > 0 ) or ( Position >= MaxSize );
CloseFile(AVIFile);
end;
- How many bytes must I get. Is four bytes right otherwise only the next one byte.
Regards, Muharrem
mrmarman
20th June 2006, 04:23
Hello...
Thanks again @sysKin my brain lights up again...
- I studied my lesson... :sly: I started to learn C language to solve this problem.
- There are a few good Web Sites that teaching and/or reference for C language that helped me like this C# Programmer's Reference (http://www.nedcomp.nl/support/origdocs/dotnetsdk/csref/vclrfconditionaloperator.htm)
- I started to convert VOLParse function C to delphi. There was a hard work for me. Result is below...But there is a little problem. Does not work perfect. :confused:
- I want to share the code. May be another delphi programmer want to look and may be give his/her opinion.
- I checked code a lot of times but did not find what the wrong is... Some files finds GMC - some files not. QPEL detection is awful.
Function CheckIt( InFile:String; MaxBytes:dWord ) : Integer;
Function Backwise(Bin:String):String;
begin
Result := '';
While Length(Bin) > 0 do
begin
Result := Result + Copy(Bin, Length(Bin)-1, 2);
Delete(Bin, Length(Bin)-1, 2);
end;
end;
Function HexToBin(const S: string): string; // sub function needed for bit op.
var I: integer; T: string;
begin
Result:='';
for I:=1 to Length(S) do
begin
case S[I] of
'0': T:='0000';
'1': T:='0001';
'2': T:='0010';
'3': T:='0011';
'4': T:='0100';
'5': T:='0101';
'6': T:='0110';
'7': T:='0111';
'8': T:='1000';
'9': T:='1001';
'A': T:='1010';
'B': T:='1011';
'C': T:='1100';
'D': T:='1101';
'E': T:='1110';
'F': T:='1111';
else T:= 'xxxx';
end; // Case
Result:=Concat(Result,T)
end
end;
function Binary2Int( const Value: String ) : Integer;
var I: Integer;
begin
Result := 0;
for I := 1 to Length( Value ) do
begin
if Value[ I ] in [ '0'..'1' ] then
Result := Result * 2 + Ord( Value[ I ] ) - Ord( '0' )
else break;
end;
end;
Function ReadBit(BitStream:String; Var Pos:Int64; BitCount:Int64):Integer;
begin
// Read and Step to Next number of BitCount Bits
Result := Binary2Int( Copy(BitStream, Pos, BitCount) );
Inc(Pos, BitCount);
end;
Function BitsUsed(x:Integer): Integer;
Var
numBits : Integer;
begin
numBits := 0;
While NOT (x = 0) do
begin
x:= x shr 1;
Inc(numBits);
end;
Result := numBits;
end;
Function ToBool(x:Integer): Boolean;
begin
Result := Boolean(x <> 0);
end;
Const _zigzag_scan : Array [1..64] of word = (
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63 );
_ar_desc : Array [0..15] of String = (
'Invalid aspect_ratio setting',
'Square pixels',
'4:3 PAL pixel shape',
'4:3 NTSC pixel shape',
'16:9 PAL pixel shape',
'16:9 NTSC pixel shape',
'Invalid aspect_ratio setting',
'Invalid aspect_ratio setting',
'Invalid aspect_ratio setting',
'Invalid aspect_ratio setting',
'Invalid aspect_ratio setting',
'Invalid aspect_ratio setting',
'Invalid aspect_ratio setting',
'Invalid aspect_ratio setting',
'Invalid aspect_ratio setting',
'Custom pixel shape' );
Function CopyQuantMatrix(BitStream:String; Var BitPos:Int64) : dWord;
Var
Val : dWord;
qm : Array [1..64] of Integer Absolute Val;
last : Integer;
coef : Integer;
i : Integer;
begin
Last := 0;
For i := 1 to 64 do
begin
coef := ReadBit(BitStream, BitPos, 8);
If coef = 0 then break;
last := coef;
qm[_zigzag_scan[i]] := coef;
end;
qm[_zigzag_scan[i]] := coef;
while (i < 64) do begin
Inc(i);
qm[_zigzag_scan[i]] := last;
end;
ShowMessageFmt('%d', [Val]);
Result := Val;
end;
Type TVOLInfo = Packed Record
ver_id,
aspect_ratio,
par_width,
par_height,
shape,
time_inc_res : dWord;
time_inc_bits : Integer;
interlaced : Boolean;
sprite_enable,
sprite_warping_points : dWord;
mpeg_quant,
load_intra_quant_mat,
load_inter_quant_mat : Boolean;
intra_quant_mat,
inter_quant_mat : dWord;
quarterpel,
newpred_enable,
reduced_resolution_enable : Boolean;
end;
Type TVOPType = ( I_VOP, P_VOP, B_VOP, S_VOP, N_VOP, N_VOP_D );
Type TVOLShape = Packed Record
Rectangular,
Binary,
BinaryOnly,
Grayscale : Word;
end;
Type TPARType = Packed Record
VGA_1_1,
PAL_4_3,
NTSC_4_3,
PAL_16_9,
NTSC_16_9,
Custom : Word;
end;
Type TSprite = Packed Record
None,
Static,
GMC : Word;
end;
Type TVOPInfo = Packed Record
frame_num : Integer;
coding_type : dWord;
coded : Boolean;
vop_type : TVOPType;
is_reference_vop : Boolean;
modulo_time_base,
time_inc : dWord;
disp_time_ticks : Int64;
disp_time_secs : Double;
top_field_first : Boolean;
warping_points_used : dWord;
end;
Const
VOLstart = $20010000; //0x00000120 Video Object Layer (VOL)
UserData = $B2010000; //0x000001B2 User Data
VOPstart = $B6010000; //0x000001B6 Video Object Plane (VOP)
Var
AVIFile : File;
Chunk : string[4];
d32Bits : dWord;
s32Bits : String;
d64Bits : Int64; // 8 bytes - 64 bits
sType : String;
First : Boolean;
dValue,
Position,
dSize : dWord;
dcCounter : Integer;
dcEnd : dWord;
MaxSize : dWord;
VOL : TVOLinfo;
VOLshape : TVOLshape;
PARtype : TPARtype;
Sprite : TSprite;
BitStream : String;
BitPos : Int64;
begin
VolShape.Rectangular := 0;
VolShape.Binary := 1;
VolShape.BinaryOnly := 2;
VolShape.Rectangular := 3;
PARtype.VGA_1_1 := 1;
PARtype.PAL_4_3 := 2;
PARtype.NTSC_4_3 := 3;
PARtype.PAL_16_9 := 4;
PARtype.NTSC_16_9 := 5;
PARtype.Custom :=15;
Sprite.None := 0;
Sprite.Static := 1;
Sprite.GMC := 3;
BitPos := 0;
FillChar(VOl, SizeOf(Vol), #0);
Form1.Memo1.Lines.Clear;
Result := -1;
Position := 12;
dcCounter := 00;
AssignFile( AVIFile, InFile );
FileMode := fmOpenRead;
Reset(AVIFile, 1);
If MaxBytes = 0 then MaxSize := FileSize(AVIFile)
else MaxSize := MaxBytes;
While (Chunk <> 'movi') AND (Position < MaxSize) do
begin
Chunk[0] := #4;
Seek(AVIFile, Position);
BlockRead(AVIFile, Chunk[1], 4);
BlockRead(AVIFile, dSize, SizeOf(dSize));
Chunk[0] := #4;
BlockRead(AVIFile, Chunk[1], 4);
if Chunk <> 'movi' then Inc(Position, dSize + 8);
end;
If Chunk <> 'movi' then
begin
ShowMessage('File Truncated');
Exit;
end;
Inc(Position, 8); // Position 'movi'
Inc(Position, 4); // Position '01wb'
Seek(AVIFile, Position);
Chunk[0] := #4;
BlockRead(AVIFile, Chunk[1], 4);
BlockRead(AVIFile, dSize, SizeOf(dSize));
Inc(Position, dSize + 8); // now we are prior position of "00dc" (Video Frame)
Repeat
Chunk := '';
While (Chunk <> '00dc') AND (Position < MaxSize) do
begin
Chunk[0] := #4; // Reset variable
Seek(AVIFile, Position);
BlockRead(AVIFile, Chunk[1], 4);
BlockRead(AVIFile, dSize, SizeOf(dSize));
if Chunk <> '00dc' then Inc(Position, dSize + 8);
end;
If Chunk <> '00dc' then
begin
//ShowMessage('!File Truncated');
Exit;
end;
//dcStart := Position;
dcEnd := Position + dSize + 8;
First := True;
While ( dWord(FilePos(AVIFile)) < dcEnd ) do
begin
BlockRead(AVIFile, dValue, SizeOf(dValue));
If ( dValue = VOLstart ) then //VOLstart:0x00000120 VideoObjectLayer(VOL)
begin //_ParseVOL_//
// 3x8 byte = 24 byte (192 bits will be read)
BlockRead(AVIFile, d64Bits, SizeOf(d64Bits));
BitStream := Backwise(Format('%.16x', [d64Bits]));
BlockRead(AVIFile, d64Bits, SizeOf(d64Bits));
BitStream := BitStream + Backwise(Format('%.16x', [d64Bits]));
BlockRead(AVIFile, d64Bits, SizeOf(d64Bits));
BitStream := BitStream + Backwise(Format('%.16x', [d64Bits]));
BitStream := HexToBin(BitStream);
BitPos := 1;
Inc(BitPos, 9); // first 9 bits random_accessible_vol bit and video_object_type_indication
// 10th bit -> if Object Layer Identifier is present
If ReadBit(BitStream, BitPos, 1) = 1 then begin
Vol.ver_id := ReadBit(BitStream, BitPos, 4); // type of VOL
Inc(BitPos, 3); // Skip VOL priority
end
else Vol.ver_id := 1;
// PAR info
Vol.aspect_ratio := ReadBit(BitStream, BitPos, 4);
If Vol.aspect_ratio = PARType.Custom then begin // Custom PARType
Vol.par_width := ReadBit(BitStream, BitPos, 8);
Vol.par_height := ReadBit(BitStream, BitPos, 8);
end;
If ReadBit(BitStream, BitPos, 1) = 1 then begin
Inc(BitPos, 3);
If ReadBit(BitStream, BitPos, 1) = 1 then begin
//79 bits
Inc(BitPos, 32);
Inc(BitPos, 32);
Inc(BitPos, 15);
end;
end;
vol.shape := ReadBit(BitStream, BitPos, 2);
if ( (vol.ver_id <> 1) AND (vol.shape = VOLShape.Grayscale) ) then begin
Inc(BitPos, 4);
end;
Inc(BitPos, 1);
vol.time_inc_res := ReadBit(BitStream, BitPos, 16);
vol.time_inc_bits := Max(BitsUsed(vol.time_inc_res - 1), 1); // Uses Math
// 412, 9
Inc(BitPos, 1);
if ReadBit(BitStream, BitPos, 1) = 1 then
begin
Inc(BitPos, vol.time_inc_bits);
end;
if ( vol.shape <> VOLShape.BinaryOnly) then begin
if (vol.shape = VOLShape.Rectangular) then begin
Inc(BitPos, 29);
end;
vol.interlaced := ToBool(ReadBit(BitStream, BitPos, 1));
Inc(BitPos, 1);
// Alternative for --> vol.sprite_enable = bits.Copy( vol.ver_id == 1 ? 1 : 2 );
If vol.ver_id = 1
then vol.sprite_enable := ReadBit(BitStream, BitPos, 1)
else vol.sprite_enable := ReadBit(BitStream, BitPos, 2);
if (vol.sprite_enable <> Sprite.None) then begin
if (vol.sprite_enable = Sprite.Static) then begin
// 56 bits
Inc(BitPos, 32);
Inc(BitPos, 24);
end;
vol.sprite_warping_points := ReadBit(BitStream, BitPos, 6);
if (vol.sprite_warping_points > 4) then begin
ShowMessage('Invalid VOL (too many warping points)');
end;
Inc(BitPos, 3);
if (vol.sprite_enable = Sprite.Static) then begin
Inc(BitPos, 1);
end;
end;
if ((vol.ver_id <> 1) AND (vol.shape <> VOLShape.Rectangular)) then begin
Inc(BitPos, 1);
end;
if ReadBit(BitStream, BitPos, 1) = 1 then begin
Inc(BitPos, 8);
end;
if (vol.shape = VOLShape.Grayscale) then begin
Inc(BitPos, 3);
end;
vol.mpeg_quant := ToBool(ReadBit(BitStream, BitPos, 1));
if (vol.mpeg_quant) then begin
vol.load_intra_quant_mat := ToBool(ReadBit(BitStream, BitPos, 1));
if (vol.load_intra_quant_mat) then begin
vol.intra_quant_mat := CopyQuantMatrix(BitStream, BitPos);
end;
vol.load_inter_quant_mat := ToBool(ReadBit(BitStream, BitPos, 1));
if (vol.load_inter_quant_mat) then begin
vol.inter_quant_mat := CopyQuantMatrix(BitStream, BitPos);
end;
if (vol.shape = VOLShape.Grayscale) then begin
ShowMessage('Grayscale matrix isn''t supported');
end;
end;
if (vol.ver_id <> 1) then begin
vol.quarterpel := ToBool(ReadBit(BitStream, BitPos, 1));
end;
if ReadBit(BitStream, BitPos, 1) = 0 then begin
ShowMessage('Complexity estimation isn''t supported');
end;
Inc(BitPos, 1);
if ReadBit(BitStream, BitPos, 1) = 1 then begin
Inc(BitPos, 1);
end;
if (vol.ver_id <> 1) then begin
vol.newpred_enable := ToBool(ReadBit(BitStream, BitPos, 1));
if (vol.newpred_enable) then begin
Inc(BitPos, 3);
end;
vol.reduced_resolution_enable := ToBool(ReadBit(BitStream, BitPos, 1));
end;
if ReadBit(BitStream, BitPos, 1) = 1 then begin
ShowMessage('Scalability isn''t supported');
end;
end
else begin
if (vol.ver_id <> 1) then begin
if ReadBit(BitStream, BitPos, 1) = 1 then begin
ShowMessage('Scalability isn''t supported');
end;
end;
Inc(BitPos, 1);
end;
// Check padding (padding should be present even if the data already ends on
// a byte boundary, but if there's no padding we will just ignore it)
// if ((bits.Remaining < 0) || (bits.Remaining > 8)) {
// throw new Exception("Invalid VOL");
//}
//bits.Copy(bits.Remaining);
//_vol = vol;
//return modify ? bitsOut.GetBytes(bitsOut.Position / 8) : null;
// QPEL
If Vol.QuarterPel then ShowMessage('QPEL : Yes');
// GMC
if (vol.sprite_enable = Sprite.GMC) then ShowMessage('GMC : Yes');
// Quant type
If (vol.mpeg_quant) then begin
If (vol.load_intra_quant_mat OR vol.load_inter_quant_mat)
then ShowMessage('Quant Type : MPEG Custom')
else ShowMessage('Quant Type : MPEG')
end
else begin
ShowMessage('Quant Type : H.263');
end;
end else
If ( dValue = VOPstart ) then
begin // VOPstart = $B6010000; //0x000001B6 Video Object Plane (VOP)
break;
//____ !!! ____//
BlockRead(AVIFile, d32Bits, SizeOf(d32Bits));
s32Bits := HexToBin(Backwise(Format('%.8x', [d32Bits])));
sType := '';
If s32Bits[1]+s32Bits[2] = '00' then sType := 'I-VOP';
If s32Bits[1]+s32Bits[2] = '10' then sType := 'B-VOP';
If s32Bits[1]+s32Bits[2] = '11' then sType := 'S-VOP';
If s32Bits[1]+s32Bits[2] = '01' then sType := 'P-VOP';
If First then Form1.Memo1.Lines.Add( Format('[%.3d] %s-%.8s (%x)', [dcCounter, s32Bits, sType, d32Bits] ) )
else Form1.Memo1.Lines.Add( Format(' %s-%.8s (%x)', [ s32Bits, sType, d32Bits] ) );
First := False;
end
else Seek(AVIFile, FilePos(AVIFile)-3); // three bytes rewind
end; // While
Inc(dcCounter);
If dcEnd MOD 2 = 0 then Position := dcEnd
else Position := dcEnd + 1;
Until ( dcCounter > 3 ) or ( Position >= MaxSize );
CloseFile(AVIFile);
end;
- Best regards Muharrem
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.