📄 avcompress.~pas
字号:
unit AVCompress;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
ComCtrls, StdCtrls , Dialogs, DirectShow9, DSUtil, GlobalUnit, AnyQV, g729, math,
mmsystem;
type
TAVCompressor = class(TObject)
private
KeyFlag: Boolean;
AudioDrvIndex:integer;
AudioBuf: array[0..3000 - 1] of Byte; //缓存3S的声音数据,超过则抛弃
AudioSize: Integer;
AudioDecBuf: array[0..3 * 16000 - 1] of Byte;
FOnAudioOut: TOnAudioOut;
FOnVideoOut: TOnVideoOut;
procedure SetOnAudioOut(const Value: TOnAudioOut);
procedure SetOnVideoOut(const Value: TOnVideoOut);
public
VideoMode:TVideoDispMode;
VideoSize:TVideoSize;
IsActive: Boolean;
property OnAudioOut: TOnAudioOut read FOnAudioOut write SetOnAudioOut;
property OnVideoOut: TOnVideoOut read FOnVideoOut write SetOnVideoOut;
constructor Create; overload;
destructor Destroy; override;
function Open: Boolean;
procedure Close;
procedure VCompressor(pvIn: TBitmapInfoHeader; pBuffer: Pointer);
procedure ACompressor(data: Pointer; size: Integer);
end;
TAVDecompressor = class(TObject)
private
info: TBitmapInfoHeader;
VideoWidth: Word;
VideoHeight: Word;
VideoSize : Integer;
VideoData : array of byte;
AudioSize : Integer;
AudioData : array of byte;
AudioDecBuf: array[0..3 * 16000 - 1] of Byte;
FOnAudioOut: TOnAudioOut;
FOnVideoOut: TOnVideoShowOut;
procedure SetOnAudioOut(const Value: TOnAudioOut);
procedure SetOnVideoOut(const Value: TOnVideoShowOut);
public
constructor Create; overload;
destructor Destroy; override;
property OnAudioOut: TOnAudioOut read FOnAudioOut write SetOnAudioOut;
property OnVideoOut: TOnVideoShowOut read FOnVideoOut write SetOnVideoOut;
procedure VDecompressor(Buf: pointer; ASize: Integer);
procedure ADecompressor(Buf: pointer; ASize: Integer);
end;
const
BI_I420 = $30323449;
BI_I420l = $30323469;
BI_YUY2 = $32595559;
BI_YUY2l = $32797579;
implementation
//
constructor TAVCompressor.Create;
begin
KeyFlag:=true;
end;
destructor TAVCompressor.Destroy;
begin
unInitCode;
end;
procedure TAVCompressor.SetOnAudioOut(const Value: TOnAudioOut);
begin
FOnAudioOut:= Value;
end;
procedure TAVCompressor.SetOnVideoOut(const Value: TOnVideoOut);
begin
FOnVideoOut := Value;
end;
function TAVCompressor.Open: Boolean;
begin
if VideoMode=vm320 then begin
VideoSize.Width := 320;
VideoSize.Height:= 240;
end;
if VideoMode=vm352 then begin
VideoSize.Width:=352;
VideoSize.Height:=288;
end;
if VideoMode=vm160 then begin
VideoSize.Width:=160;
VideoSize.Height:=120
end;
if VideoMode=vm176 then begin
VideoSize.Width:=176;
VideoSize.Height:=144;
end;
if VideoMode=vm640 then begin
VideoSize.Width:=640;
VideoSize.Height:=480;
end;
if not InitCode(VideoSize.Width, VideoSize.Height) then begin
Exit;
end;
IsActive:= true;
end;
procedure TAVCompressor.Close;
begin
IsActive:= false;
unInitCode;
end;
procedure TAVCompressor.VCompressor(pvIn: TBitmapInfoHeader; pBuffer: Pointer);
var
FRAME: xvid_enc_frame_t;
Eimg_t : xvid_image_t;
W,H: Word;
Buf: array of Byte;
begin
if not IsActive then exit;
if not CodeInited then exit;
W := pvIn.biWidth;
H := pvIn.biHeight;
FillMemory(@Eimg_t, Sizeof(Eimg_t), 0);
case pvIn.biCompression of
BI_RGB:begin
Eimg_t.csp := XVID_CSP_BGR or XVID_CSP_VFLIP;
Eimg_t.stride[0] := W*3;
end;
BI_I420, BI_I420l:
begin
Eimg_t.csp := XVID_CSP_I420;
Eimg_t.stride[0] := W;
end;
BI_YUY2, BI_YUY2l:
begin
Eimg_t.csp := XVID_CSP_YUY2;
Eimg_t.stride[0] := W*2;
end;
end;
Eimg_t.plane[0] := pBuffer;
FillMemory(@FRAME, sizeof(FRAME), 0);
FRAME.version := XVID_VERSION;
FRAME.vol_flags := XVID_VOL_QUARTERPEL;
FRAME.vop_flags := XVID_VOP_HALFPEL or XVID_VOP_CHROMAOPT or XVID_VOP_TRELLISQUANT; //or XVID_VOP_DEBUG;
FRAME.quant_intra_matrix := nil;
FRAME.quant_inter_matrix := nil;
FRAME.motion := XVID_ME_QUARTERPELREFINE16 or XVID_ME_CHROMA_BVOP;
FRAME.input := Eimg_t;
FRAME._type := XVID_TYPE_AUTO;
FRAME.bitstream := @outbuf[0];
if KeyFlag then FRAME._type := 1;
FRAME.length := 0;
if not assigned(Vencodeproc) then exit;
try
FRAME.length := Vencodeproc(ENCodehandle, XVID_ENC_ENCODE, @FRAME, nil);
except
KeyFlag := true;
exit;
end;
setlength(Buf, sizeof(FRAME.length)+4+FRAME.length);
Move(FRAME.length, BUF[0], sizeof(FRAME.length));
Move(W, BUF[sizeof(FRAME.length)], Sizeof(W));
Move(H, BUF[sizeof(FRAME.length)+2], Sizeof(H));
Move(outbuf[0], BUF[sizeof(FRAME.length)+4], FRAME.length);
if FRAME.length>0 then begin
if Assigned(FOnVideoOut) then
FOnVideoOut(BUF, sizeof(FRAME.length)+FRAME.length+4);
KeyFlag := false;
end;
end;
procedure TAVCompressor.ACompressor(data: Pointer; size: Integer);
var
pi, po: Pchar;
BUF: array of Byte;
UDPHead:TUDPHead;
begin
pi := data;
po := @Audiobuf;
po := po + AudioSize;
va_g729a_encoder(pi, po);
AudioSize := AudioSize + 10;
if AudioSize >= 3000 then
AudioSize := 0;
if AudioSize < 60 then exit;
setlength(Buf, sizeof(AudioSize)+AudioSize);
Move(AudioSize, BUF[0], sizeof(AudioSize));
Move(AudioBuf, BUF[sizeof(AudioSize)], AudioSize);
if Assigned(FOnAudioOut) then
FOnAudioOut(BUF, sizeof(AudioSize) + AudioSize);
audiosize := 0;
end;
// ---------Decompressor -----------
constructor TAVDecompressor.Create;
begin
end;
destructor TAVDecompressor.Destroy;
begin
if InitCode then unInitCode;
end;
procedure TAVDecompressor.SetOnAudioOut(const Value: TOnAudioOut);
begin
FOnAudioOut:= Value;
end;
procedure TAVDecompressor.SetOnVideoOut(const Value: TOnVideoShowOut);
begin
FOnVideoOut := Value;
end;
procedure TAVDecompressor.VDecompressor(Buf: pointer; ASize: Integer);
var
DFRAM: xvid_dec_frame_t;
Dimg_t: xvid_image_t;
W,H: word;
BIHeaderPtr: PBitmapInfoHeader;
BitMapHandle: HBitmap;
DIBPtr: Pointer;
BufferLen:integer;
ShowVideoSize:TVideoSize;
begin
if Asize >= sizeof(VideoSize) then begin
move(Buf^,VideoSize, sizeof(VideoSize));
move((pchar(buf) + sizeof(VideoSize))^,W,Sizeof(W));
move((pchar(buf) + sizeof(VideoSize)+2)^,H,Sizeof(H));
if (W<>VideoWidth) or (H<>VideoHeight) then
begin
VideoWidth := W;
ShowVideoSize.Width := W;
VideoHeight := H;
ShowVideoSize.Height :=H;
if CodeInited then unInitCode;
if not InitCode(VideoWidth, VideoHeight) then Exit;
end;
SetLength(VideoData, VideoSize);
move((pchar(buf) + sizeof(VideoSize)+4)^,VideoData[0], VideoSize);
if CodeInited and (VideoSize > 0) then begin
FillMemory(@Dimg_t, Sizeof(Dimg_t), 0);
Dimg_t.csp := XVID_CSP_BGR or XVID_CSP_VFLIP;
Dimg_t.plane[0] := @Decbuf[0];
Dimg_t.stride[0] := VideoWidth*3;
FillMemory(@DFRAM, sizeof(DFRAM), 0);
DFRAM.version := XVID_VERSION;
DFRAM.general := XVID_LOWDELAY or XVID_DEBLOCKY or XVID_DEBLOCKUV;
DFRAM.bitstream := @VideoData[0];
DFRAM.length := VideoSize;
DFRAM.output := Dimg_t;
VideoSize := 0;
if not assigned(VDecodeproc) then exit;
try
VDecodeproc(DECodehandle, XVID_DEC_DECODE, @DFRAM, nil);
if Assigned(FOnVideoOut) then
FOnVideoOut(ShowVideoSize, @Decbuf[0], sizeof(Decbuf));
except
Exit;
end;
end;
end;
end;
procedure TAVDecompressor.ADecompressor(Buf: pointer; ASize: Integer);
var
i: integer;
begin
if ASize <= 0 then exit;
if ASize >= sizeof(AudioSize) then begin
move(Buf^,AudioSize, sizeof(AudioSize));
SetLength(AudioData, AudioSize);
move((pchar(buf) + sizeof(AudioSize))^,AudioData[0],AudioSize);
if AudioSize > 0 then begin
for i := 0 to (AudioSize div 10) - 1 do
va_g729a_decoder(pchar(@AudioData[0]) + I * 10, pchar(@AudioDecBuf) + i * 160, 0);
if Assigned(FOnAudioOut) then
FOnAudioOut(@AudioDecBuf, AudioSize * 16);
end;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -