?? main.~pas
字號(hào):
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DSUtil, StdCtrls, DSPack, DirectShow9, Menus, ExtCtrls,lib_xvid;
type
TVideoForm = class(TForm)
FilterGraph: TFilterGraph;
VideoWindow: TVideoWindow;
MainMenu1: TMainMenu;
Devices: TMenuItem;
Filter: TFilter;
Image: TImage;
SampleGrabber: TSampleGrabber;
SnapShot: TButton;
CallBack: TCheckBox;
mmo1: TMemo;
lbl1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure SnapShotClick(Sender: TObject);
procedure SampleGrabberBuffer(sender: TObject; SampleTime: Double;
pBuffer: Pointer; BufferLen: Integer);
private
// XVID ENCODER
xvid_gbl: xvid_gbl_init_t;
xvid_enc : xvid_enc_create_t;
xvid_encFrame: xvid_enc_frame_t;
xvid_encStats: xvid_enc_stats_t;
xVid_decode : xvid_dec_create_t;
xvid_decFrame: xvid_dec_frame_t;
xvid_decStats: xvid_dec_stats_t;
public
procedure OnSelectDevice(sender: TObject);
end;
const
MaxPixelCount = 65536;
type
//Pf24bit真彩色位圖像素?cái)?shù)據(jù)結(jié)構(gòu)體
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..MaxPixelCount - 1] of TRGBTriple;
var
VideoForm: TVideoForm;
SysDev: TSysDevEnum;
FrameBuf:array [0..352*288*3 ] of Byte;
FrameImg:array [0..352*288*3 ] of Byte;
FrameSequece : LongWord= 0;
spf:TFileStream;
xvid_Version:Integer;
implementation
{$R *.dfm}
procedure TVideoForm.FormCreate(Sender: TObject);
var
i: integer;
Device: TMenuItem;
begin
xvid_Version :=XVID_MAKE_VERSION(1,1,0);
SysDev:= TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
if SysDev.CountFilters > 0 then
for i := 0 to SysDev.CountFilters - 1 do
begin
Device := TMenuItem.Create(Devices);
Device.Caption := SysDev.Filters[i].FriendlyName;
Device.Tag := i;
Device.OnClick := OnSelectDevice;
Devices.Add(Device);
end;
end;
procedure TVideoForm.OnSelectDevice(sender: TObject);
begin
FilterGraph.ClearGraph;
FilterGraph.Active := false;
Filter.BaseFilter.Moniker := SysDev.GetMoniker(TMenuItem(Sender).tag);
FilterGraph.Active := true;
with FilterGraph as ICaptureGraphBuilder2 do
begin
RenderStream(@PIN_CATEGORY_PREVIEW, nil, Filter as IBaseFilter, SampleGrabber as IBaseFilter, VideoWindow as IbaseFilter);
end;
try
//XVID庫(kù)初始化操作
xvid_gbl.version := xvid_Version; //Version:1.1.0
xvid_gbl.cpu_flags := 0; //Word(XVID_CPU_FORCE or XVID_CPU_ASM);//0:自動(dòng)檢查CPU,XVID_CPU_FORCE:強(qiáng)制使用ASM匯編優(yōu)化
xvid_gbl.debug := 0; //調(diào)試級(jí)別
//初始化編解碼
xvid_global(nil, XVID_GBL_INIT, @xvid_gbl, nil);
// XVID編碼器初始化
xvid_enc.version := xvid_Version;
//編碼器參數(shù)
xvid_enc.global := XVID_GLOBAL_PACKED; //全局標(biāo)志
xvid_enc.width := 320; //壓縮視頻寬度
xvid_enc.height := 240; //壓縮視頻高度
xvid_enc.fbase := 3; //基本幀率/每秒 = fbase * 10 = 30
xvid_enc.fincr := 1; //幀率增長(zhǎng)步長(zhǎng),0:可變步長(zhǎng),>1實(shí)際增長(zhǎng)步長(zhǎng)
xvid_enc.profile := XVID_PROFILE_AS_L4; //壓縮級(jí)別,MPEG4-ASP最高壓縮級(jí)別
xvid_enc.max_key_interval := 0; //最大關(guān)鍵幀間隔
xvid_enc.frame_drop_ratio := 0; //丟幀率;0~100
xvid_enc.max_bframes := 0; //是否采用B幀,一般采用I,P幀,如果1=PB幀
xvid_enc.bquant_offset := 0;
xvid_enc.bquant_ratio := 0;
//創(chuàng)建編碼器
xvid_encore(nil, XVID_ENC_CREATE, @xvid_enc, nil);
//初始化壓縮數(shù)據(jù)幀結(jié)構(gòu)
xvid_encFrame.version := xvid_Version;
// --- VOL FLAGS
xvid_encFrame.vol_flags := 0;
xvid_encFrame.vol_flags := xvid_encFrame.vol_flags or XVID_VOL_MPEGQUANT OR XVID_VOL_QUARTERPEL OR XVID_VOL_GMC;
//xvid_encFrame.vol_flags := xvid_encFrame.vol_flags OR XVID_VOL_MPEGQUANT; //允許MPEG量化
//xvid_encFrame.vol_flags := xvid_encFrame.vol_flags OR XVID_VOL_GMC; //允許GMC
//xvid_encFrame.vol_flags := xvid_encFrame.vol_flags OR XVID_VOL_QUARTERPEL; //采用1/4像素運(yùn)算
// --- VOP FLAGS
xvid_encFrame.vop_flags := 0;
xvid_encFrame.vop_flags := xvid_encFrame.vop_flags or XVID_VOP_CHROMAOPT ;
xvid_encFrame.motion := 0; //運(yùn)動(dòng)標(biāo)識(shí)
xvid_encFrame.quant := 0; //質(zhì)量控制=量化參數(shù),0~31,數(shù)值越小質(zhì)量越高
xvid_encFrame.coding_type := XVID_TYPE_AUTO; //XVID_TYPE_AUTO=讓編碼器自動(dòng)決定,I幀編碼是關(guān)鍵幀,P幀編碼是幀內(nèi)預(yù)測(cè)
//圖像壓縮編碼
xvid_encStats.version := xvid_Version;
// XVID解碼器初始化
xVid_decode.version := xvid_Version;
xVid_decode.width := 320;
xVid_decode.height := 240;
//創(chuàng)建解碼器
xvid_decore(xVid_decode.handle,XVID_DEC_CREATE,@xVid_decode, nil);
spf := TFileStream.Create('c:\test.mp4',fmCreate or fmOpenReadWrite);
except
Exit;
end;
FilterGraph.Play;
end;
procedure TVideoForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CallBack.Checked := False;
SysDev.Free;
FilterGraph.ClearGraph;
FilterGraph.Active := false;
//關(guān)閉編解碼器
xvid_encore(xvid_enc.handle,XVID_ENC_DESTROY, @xvid_enc, nil);
xvid_decore(xVid_decode.handle,XVID_DEC_DESTROY,@xvid_decode,nil);
end;
procedure TVideoForm.SnapShotClick(Sender: TObject);
begin
SampleGrabber.GetBitmap(Image.Picture.Bitmap);
end;
procedure TVideoForm.SampleGrabberBuffer(sender: TObject;
SampleTime: Double; pBuffer: Pointer; BufferLen: Integer);
var
SpBmp:TBitmap;
BmpLineData:prgbtriplearray;
yCount,uCount,vCount:Integer;
Row,Col:Integer;
Ret:Integer;
begin
if CallBack.Checked then
begin
try
xvid_encFrame.bitstream := @FrameBuf[0];
xvid_encFrame.length := BufferLen;
xvid_encFrame.input.csp := XVID_CSP_BGR; //輸入是rgb位圖
xvid_encFrame.input.plane[0] := pBuffer; //RGB位圖數(shù)據(jù),每個(gè)像素有3個(gè)字節(jié)
xvid_encFrame.input.stride[0] := 320 * 3; //每行字節(jié)數(shù)
//開(kāi)始?jí)嚎s
//Ret := xvid_encore(xvid_enc.handle, XVID_ENC_ENCODE, @xvid_encFrame,@xvid_encStats); //返回編碼之后的字節(jié)
Ret := xvid_encore(xvid_enc.handle, XVID_ENC_ENCODE, @xvid_encFrame,nil); //返回編碼之后的字節(jié)
spf.Write(FrameBuf,Ret);
mmo1.Lines.Add('Codec_num=' + IntToStr(FrameSequece) + ' Len=' + IntToStr(Ret));
Inc(FrameSequece);
//實(shí)時(shí)解碼部分
if Ret > 0 then
begin
try
SpBmp := TBitmap.Create;
SpBmp.PixelFormat := pf24bit;
//初始化解碼數(shù)據(jù)幀結(jié)構(gòu)
xvid_decFrame.version := xvid_Version;
xvid_decFrame.general := 0;
xvid_decFrame.bitstream := @FrameBuf[0]; //輸入解壓的位流
xvid_decFrame.length := Ret; //輸入位流長(zhǎng)度
xvid_decFrame.output.csp := XVID_CSP_I420; //色彩空間
xvid_decFrame.output.plane[0] := @FrameImg[0]; //解壓后輸出的緩沖區(qū)
xvid_decFrame.output.stride[0] := 320 * 3; //每行字節(jié)數(shù)
ret := xvid_decore(xVid_decode.handle , XVID_DEC_DECODE, @xvid_decFrame, nil);
if ret > 0 then
begin
//SampleGrabber.GetBitmap(SpBmp, @FrameImg, ret); //捕獲原始bmp位圖
//Image.Canvas.Draw(0,0,SpBmp);
mmo1.Lines.Add('decode_num=' + IntToStr(FrameSequece) + ' Len=' + IntToStr(Ret));
end;
finally
SpBmp.Free;
end;
end else begin
end;
except
end;
end;
end;
end.
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -