Hello,
I did a simple little test:
A four dimensional array is allocated:
The input/output is split into:
Color Component (R/G/B), Bit(0 to 7), Y, X
Then for compression this array is processed twice. (Read/Write)
Then for decompression this array is processed twice. (Read/Write)
( To mimic compression/decompression )
Playback for a 640x480 rgb file is just too slow.
Here is a code snippet:
// fields of object used:
// components, bit, y, x
mCompressWork : array of array of array of array of byte;
mDeCompressWork : array of array of array of array of byte;
mCompressInputWidth : integer;
mCompressInputHeight : integer;
mCompressInput : pointer;
mCompressOutput : pointer;
mCompressOutputSize : longword;
mDeCompressOutputWidth : integer;
mDeCompressOutputHeight : integer;
mDeCompressInputSize : longword;
mDeCompressInput : pointer;
mDeCompressOutput : pointer;
// object methods:
// this will be called just once for the first frame and maybe once for
last
frame for some reason
procedure TUniversalVideoCodec.CompressBegin;
begin
// allocate stuff for compression
SetLength( mCompressWork, 3, 8, mCompressInputHeight,
mCompressInputWidth );
end;
// ok simple example, maybe later try splitting it up into components
{
procedure TUniversalVideoCodec.Compress;
var
vX, vY : integer;
begin
// compress stuff
for vY := 0 to mCompressInputHeight-1 do
begin
for vX := 0 to mCompressInputWidth-1 do
begin
move( mCompressInput^, mCompressOutput^, 3 );
longword(mCompressInput) := longword(mCompressInput) + 3;
longword(mCompressOutput) := longword(mCompressOutput) + 3;
end;
end;
mCompressOutputSize := mCompressInputWidth * mCompressInputHeight * 3;
end;
}
// more advanced example, split stuff up.
// will be called for each frame
procedure TUniversalVideoCodec.Compress;
var
vX, vY : integer;
vC, vP : longword;
begin
// copy information to work array
for vY := 0 to mCompressInputHeight-1 do
begin
for vX := 0 to mCompressInputWidth-1 do
begin
for vC := 0 to 2 do // component
begin
for vP := 0 to 7 do // bit
begin
mCompressWork[vC, vP, vY, vX] := ( byte( pointer(
longword(mCompressInput) + vC )^ ) shr vP) and 1;
end;
end;
longword(mCompressInput) := longword(mCompressInput) + 3;
end;
end;
// copy information from work array to output
for vY := 0 to mCompressInputHeight-1 do
begin
for vX := 0 to mCompressInputWidth-1 do
begin
for vC := 0 to 2 do // component
begin
byte( pointer( longword(mCompressOutput) + vC )^ ) := 0;
for vP := 0 to 7 do // bit
begin
byte( pointer( longword(mCompressOutput) + vC )^ ) :=
byte( pointer( longword(mCompressOutput) + vC )^ ) or
(mCompressWork[vC, vP, vY, vX] shl vP);
end;
end;
longword(mCompressOutput) := longword(mCompressOutput) + 3;
end;
end;
mCompressOutputSize := mCompressInputWidth * mCompressInputHeight * 3;
end;
procedure TUniversalVideoCodec.CompressEnd;
begin
// free stuff for compression
mCompressWork := nil;
end;
// this will be called just once for the first frame and maybe once for
last
frame for some reason
procedure TUniversalVideoCodec.DeCompressBegin;
begin
// allocate stuff for decompression
SetLength( mDeCompressWork, 3, 8, mDeCompressOutputHeight,
mDeCompressOutputWidth );
end;
// simple example
{
procedure TUniversalVideoCodec.DeCompress;
var
vX, vY : integer;
begin
// decompress stuff
for vY := 0 to mDeCompressOutputHeight-1 do
begin
for vX := 0 to mDeCompressOutputWidth-1 do
begin
move( mDeCompressInput^, mDeCompressOutput^, 3 );
longword(mDeCompressInput) := longword(mDeCompressInput) + 3;
longword(mDeCompressOutput) := longword(mDeCompressOutput) + 3;
end;
end;
end;
}
// more advanced example
// will be called for each frame.
procedure TUniversalVideoCodec.DeCompress;
var
vX, vY : integer;
vC, vP : longword;
begin
// copy information to work array
for vY := 0 to mDeCompressOutputHeight-1 do
begin
for vX := 0 to mDeCompressOutputWidth-1 do
begin
for vC := 0 to 2 do // component
begin
for vP := 0 to 7 do // bit
begin
mDeCompressWork[vC, vP, vY, vX] := ( byte( pointer(
longword(mDeCompressInput) + vC )^ ) shr vP) and 1;
end;
end;
longword(mDeCompressInput) := longword(mDeCompressInput) + 3;
end;
end;
// copy information from work array to output
for vY := 0 to mDeCompressOutputHeight-1 do
begin
for vX := 0 to mDeCompressOutputWidth-1 do
begin
for vC := 0 to 2 do // component
begin
byte( pointer( longword(mDeCompressOutput) + vC )^ ) := 0;
for vP := 0 to 7 do // bit
begin
byte( pointer( longword(mDeCompressOutput) + vC )^ ) :=
byte( pointer( longword(mDeCompressOutput) + vC )^ ) or
(mDeCompressWork[vC, vP, vY, vX] shl vP);
end;
end;
longword(mDeCompressOutput) := longword(mDeCompressOutput) + 3;
end;
end;
end;
// this will be called just once for the first frame and maybe once for
last
frame for some reason
procedure TUniversalVideoCodec.DeCompressEnd;
begin
// free stuff for decompression
mDeCompressWork := nil;
end;
Maybe the code can somehow be re-written/modified for more speed ?
How ?
Bye,
Skybuck.


|