⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avcompress.~pas

📁 音视频控件SunAM-V1.0 音视频控件SunAM-V1.0 音视频控件SunAM-V1.0 音视频控件SunAM-V1.0
💻 ~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 + -