Y
ysfy
Unregistered / Unconfirmed
GUEST, unregistred user!
视频采集后用Divx压缩当前帧,然后解压查看效果。无法显示!!!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls,VFW, IdBaseComponent, IdComponent, IdUDPBase,
IdUDPClient;
const VBS=8179;//videoBufsize
type
TForm1 = class(TForm)
Button2: TButton;
Button1: TButton;
Panel1: TPanel;
IdUDPClient1: TIdUDPClient;
Button3: TButton;
IdUDPClient2: TIdUDPClient;
Memo1: TMemo;
Memo2: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TVIDEO_DATA=record
bKeyFrame:bool;
SampleNum:Word;
BufSizeWord;
buf:array[0..VBS] of byte;
end;
var
Form1: TForm1;
CapWnd:THandle;
CapVar:TCompVars;
OutFormatSize,OutBufferSize,SampleNumWord;
BmpInInfo:TBitmapInfo;
BmpOutInfoBitmapInfo;
VideoData:TVIDEO_DATA;
SCapVar:TCOMPVARS;
SOutFormatSize,SOutBufferSizeWord;
SOutBufferointer;
SBmpInInfo:TBitmapInfo;
SBmpOutInfoBitmapInfo;
ResultTestWord;
implementation
{$R *.dfm}
procedure mydraw;//解压并显示
var SVideodata:TVideo_Data;
begin
//把BmpOutInfo当作SBmpInInfo来取得解压输出的图像头BmpOutInfo
copymemory(@SVideoData,@VideoData,sizeof(videoData));
// copymemory(@sBmpInInfo,BmpOutInfo,sizeof(BmpOutInfo));
SBmpInInfo:=BmpOutInfo^;
SOutFormatSize:=ICDecompressGetFormatSize(SCapVar.hic,@SBmpInInfo.bmiHeader);
if not assigned(SBmpOutInfo) then
GetMem(SBmpOutInfo,SOutFormatSize);
zeromemory(SBmpOutInfo,SOutFormatSize);
ICDecompressGetFormat(SCapVar.hic, @SBmpInInfo.bmiHeader, @SBmpOutInfo^.bmiHeader);
SOutBufferSize:=SBmpOutInfo^.bmiHeader.biSizeImage;
if not assigned(SOutBuffer) then
getmem(SOutBuffer,SOutBufferSize);
zeromemory(SOutBuffer,SOutBufferSize);
ICDecompressbegin
(SCapVar.hic,@SBmpInInfo.bmiHeader, @SBmpOutInfo^.bmiHeader);
if VIDEODATA.bKeyFrame then
ResultTest:=ICDecompress(SCapVar.hic,0,@SBmpInInfo,@SVIDEODATA.Buf,
@SBmpOutInfo.bmiHeader,SOutBuffer)
else
ResultTest:=ICDecompress(SCapVar.hic,ICDECOMPRESS_NOTKEYFRAME,@SBmpInInfo,
@SVIDEODATA.Buf,@SBmpOutInfo.bmiHeader,SOutBuffer);
if (ResultTest=ICERR_OK) then
begin
showmessage('ok');
SetDIBitsToDevice(form1.canvas.Handle,0,0,320,240,0,0,0,
SBmpOutInfo^.bmiHeader.biHeight ,SOutBuffer,SBmpOutInfo^,DIB_RGB_COLORS);
end;
// ICDecompressEnd(ScapVar.hic);
end;
function InitCaptureParams : boolean;
begin
result := False;
//初始化CapVar
zeromemory(@CapVar,sizeof(TCOMPVARS));
CapVar.cbSize:=sizeof(CapVar);
//必须指定cbSize为TCOMPVARS结构大小
CapVar.dwFlags:=ICMF_COMPVARS_VALID;
CapVar.cbState:=0;
//fccHandler代表压缩编码类型,我们使用的是DIVX的编码器
CapVar.fccHandler:=mmioFOURCC('d','i','v','x');
CapVar.fccType:=ICTYPE_VIDEO;
//正式连接编码器
CapVar.hic:=ICOpen(ICTYPE_VIDEO, CapVar.fccHandler, ICMODE_COMPRESS);
if (CapVar.hic>0) then
begin
OutFormatSize:=ICCompressGetFormatSize(CapVar.hic,@BmpInInfo.bmiHeader);
getmem(BmpOutInfo,OutFormatSize);
//我们可以通过初始化时得到的BmpInInfo来获取压缩传出图像头BmpOutInfo
ICCompressGetFormat(CapVar.hic,@BmpInInfo.bmiHeader,@BmpOutInfo^.bmiHeader);
OutBufferSize:=ICCompressGetSize(CapVar.hic,@BmpInInfo.bmiHeader,@BmpOutInfo^.bmiHeader);
ICSeqCompressFrameStart(@CapVar, @BmpInInfo);
SCapVar.hic := ICOpen(CapVar.fccType,CapVar.fccHandler,ICMODE_DECOMPRESS);
result := True;
end
else
begin
Showmessage('请先安装视频压缩编码器');
Exit;
end
end;
function FrameCallBack(hWnd: HWND;
lpVHdr: PVIDEOHDR): DWORD;
stdcall;
var
bKeyFrame : BOOL ;
videoBuf : Pointer;
OutActSize : dword;
begin
OutActSize := BmpInInfo.bmiHeader.biSizeImage;
videoBuf := ICSeqCompressFrame(@CapVar,0,lpVHdr.lpData,@bKeyFrame,@OutActSize);
if (OutActSize <= sizeof(videodata.Buf) ) then
begin
zeromemory(@VideoData ,sizeof(TVIDEO_DATA));
//记录是否为关键帧
VideoData.bKeyFrame:=bKeyFrame;
copymemory(@VideoData.Buf, videoBuf, OutActSize);
VideoData.SampleNum:=SampleNum;
//我们可以记录下帧数, 可以做扩展用
VideoData.BufSize:=OutActSize;
//记录数据大小, 传输时用
//form1.Memo1.Lines.Add( 'Compressed size:'+inttostr(OutActSize));
mydraw;
//在这里, 你可以用你喜欢的网络方式传输视频数据,
//cc1.SendBuffer(VideoData,sizeof(TVIDEO_DATA)-SendBufferSize+Outactsize);
inc(SampleNum);
end;
result := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
CapWnd := capCreateCaptureWindow('预览窗口',WS_VISIBLE or WS_CHILD,0,0,panel1.Width,panel1.Height,panel1.Handle,1);
if CapWnd = 0 then
exit;
capDriverConnect(CapWnd,0);
//连接摄像头设备
capDlgVideoFormat(CapWnd);
//显示视频设置对话框,进行配置视频的大小、颜色位数等。
capGetVideoFormat(CapWnd,@BmpInInfo,sizeof(TBITMAPINFO));
//取得视频图像数据头,后面压缩时需要用到
capPreviewRate(CapWnd, 25);
//设置预览视频的频率,33代表第秒30帧。
capPreview(CapWnd, TRUE);
capSetCallbackOnFrame(CapWnd,FrameCallBack);
InitCaptureParams;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
capDriverDisconnect(CapWnd);
if (CapVar.hic > 0) then
begin
ICSeqCompressFrameEnd(@CapVar);
ICCompressorFree(@CapVar);
ICClose(CapVar.hic);
end;
if SCapVar.hic>0 then
ICClose(SCapVar.hic);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
capDriverDisconnect(CapWnd);
if (CapVar.hic > 0) then
begin
ICSeqCompressFrameEnd(@CapVar);
ICCompressorFree(@CapVar);
ICClose(CapVar.hic);
end;
if ScapVar.hic>0 then
IcClose(Scapvar.hic);
end;
procedure TForm1.Button3Click(Sender: TObject);
var VD:TVideo_Data;
begin
VD.SampleNum:=5;
try
IdUDPClient1.SendBuffer(VD,sizeof(VD));
except
end;
end;
end.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls,VFW, IdBaseComponent, IdComponent, IdUDPBase,
IdUDPClient;
const VBS=8179;//videoBufsize
type
TForm1 = class(TForm)
Button2: TButton;
Button1: TButton;
Panel1: TPanel;
IdUDPClient1: TIdUDPClient;
Button3: TButton;
IdUDPClient2: TIdUDPClient;
Memo1: TMemo;
Memo2: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TVIDEO_DATA=record
bKeyFrame:bool;
SampleNum:Word;
BufSizeWord;
buf:array[0..VBS] of byte;
end;
var
Form1: TForm1;
CapWnd:THandle;
CapVar:TCompVars;
OutFormatSize,OutBufferSize,SampleNumWord;
BmpInInfo:TBitmapInfo;
BmpOutInfoBitmapInfo;
VideoData:TVIDEO_DATA;
SCapVar:TCOMPVARS;
SOutFormatSize,SOutBufferSizeWord;
SOutBufferointer;
SBmpInInfo:TBitmapInfo;
SBmpOutInfoBitmapInfo;
ResultTestWord;
implementation
{$R *.dfm}
procedure mydraw;//解压并显示
var SVideodata:TVideo_Data;
begin
//把BmpOutInfo当作SBmpInInfo来取得解压输出的图像头BmpOutInfo
copymemory(@SVideoData,@VideoData,sizeof(videoData));
// copymemory(@sBmpInInfo,BmpOutInfo,sizeof(BmpOutInfo));
SBmpInInfo:=BmpOutInfo^;
SOutFormatSize:=ICDecompressGetFormatSize(SCapVar.hic,@SBmpInInfo.bmiHeader);
if not assigned(SBmpOutInfo) then
GetMem(SBmpOutInfo,SOutFormatSize);
zeromemory(SBmpOutInfo,SOutFormatSize);
ICDecompressGetFormat(SCapVar.hic, @SBmpInInfo.bmiHeader, @SBmpOutInfo^.bmiHeader);
SOutBufferSize:=SBmpOutInfo^.bmiHeader.biSizeImage;
if not assigned(SOutBuffer) then
getmem(SOutBuffer,SOutBufferSize);
zeromemory(SOutBuffer,SOutBufferSize);
ICDecompressbegin
(SCapVar.hic,@SBmpInInfo.bmiHeader, @SBmpOutInfo^.bmiHeader);
if VIDEODATA.bKeyFrame then
ResultTest:=ICDecompress(SCapVar.hic,0,@SBmpInInfo,@SVIDEODATA.Buf,
@SBmpOutInfo.bmiHeader,SOutBuffer)
else
ResultTest:=ICDecompress(SCapVar.hic,ICDECOMPRESS_NOTKEYFRAME,@SBmpInInfo,
@SVIDEODATA.Buf,@SBmpOutInfo.bmiHeader,SOutBuffer);
if (ResultTest=ICERR_OK) then
begin
showmessage('ok');
SetDIBitsToDevice(form1.canvas.Handle,0,0,320,240,0,0,0,
SBmpOutInfo^.bmiHeader.biHeight ,SOutBuffer,SBmpOutInfo^,DIB_RGB_COLORS);
end;
// ICDecompressEnd(ScapVar.hic);
end;
function InitCaptureParams : boolean;
begin
result := False;
//初始化CapVar
zeromemory(@CapVar,sizeof(TCOMPVARS));
CapVar.cbSize:=sizeof(CapVar);
//必须指定cbSize为TCOMPVARS结构大小
CapVar.dwFlags:=ICMF_COMPVARS_VALID;
CapVar.cbState:=0;
//fccHandler代表压缩编码类型,我们使用的是DIVX的编码器
CapVar.fccHandler:=mmioFOURCC('d','i','v','x');
CapVar.fccType:=ICTYPE_VIDEO;
//正式连接编码器
CapVar.hic:=ICOpen(ICTYPE_VIDEO, CapVar.fccHandler, ICMODE_COMPRESS);
if (CapVar.hic>0) then
begin
OutFormatSize:=ICCompressGetFormatSize(CapVar.hic,@BmpInInfo.bmiHeader);
getmem(BmpOutInfo,OutFormatSize);
//我们可以通过初始化时得到的BmpInInfo来获取压缩传出图像头BmpOutInfo
ICCompressGetFormat(CapVar.hic,@BmpInInfo.bmiHeader,@BmpOutInfo^.bmiHeader);
OutBufferSize:=ICCompressGetSize(CapVar.hic,@BmpInInfo.bmiHeader,@BmpOutInfo^.bmiHeader);
ICSeqCompressFrameStart(@CapVar, @BmpInInfo);
SCapVar.hic := ICOpen(CapVar.fccType,CapVar.fccHandler,ICMODE_DECOMPRESS);
result := True;
end
else
begin
Showmessage('请先安装视频压缩编码器');
Exit;
end
end;
function FrameCallBack(hWnd: HWND;
lpVHdr: PVIDEOHDR): DWORD;
stdcall;
var
bKeyFrame : BOOL ;
videoBuf : Pointer;
OutActSize : dword;
begin
OutActSize := BmpInInfo.bmiHeader.biSizeImage;
videoBuf := ICSeqCompressFrame(@CapVar,0,lpVHdr.lpData,@bKeyFrame,@OutActSize);
if (OutActSize <= sizeof(videodata.Buf) ) then
begin
zeromemory(@VideoData ,sizeof(TVIDEO_DATA));
//记录是否为关键帧
VideoData.bKeyFrame:=bKeyFrame;
copymemory(@VideoData.Buf, videoBuf, OutActSize);
VideoData.SampleNum:=SampleNum;
//我们可以记录下帧数, 可以做扩展用
VideoData.BufSize:=OutActSize;
//记录数据大小, 传输时用
//form1.Memo1.Lines.Add( 'Compressed size:'+inttostr(OutActSize));
mydraw;
//在这里, 你可以用你喜欢的网络方式传输视频数据,
//cc1.SendBuffer(VideoData,sizeof(TVIDEO_DATA)-SendBufferSize+Outactsize);
inc(SampleNum);
end;
result := 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
CapWnd := capCreateCaptureWindow('预览窗口',WS_VISIBLE or WS_CHILD,0,0,panel1.Width,panel1.Height,panel1.Handle,1);
if CapWnd = 0 then
exit;
capDriverConnect(CapWnd,0);
//连接摄像头设备
capDlgVideoFormat(CapWnd);
//显示视频设置对话框,进行配置视频的大小、颜色位数等。
capGetVideoFormat(CapWnd,@BmpInInfo,sizeof(TBITMAPINFO));
//取得视频图像数据头,后面压缩时需要用到
capPreviewRate(CapWnd, 25);
//设置预览视频的频率,33代表第秒30帧。
capPreview(CapWnd, TRUE);
capSetCallbackOnFrame(CapWnd,FrameCallBack);
InitCaptureParams;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
capDriverDisconnect(CapWnd);
if (CapVar.hic > 0) then
begin
ICSeqCompressFrameEnd(@CapVar);
ICCompressorFree(@CapVar);
ICClose(CapVar.hic);
end;
if SCapVar.hic>0 then
ICClose(SCapVar.hic);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
capDriverDisconnect(CapWnd);
if (CapVar.hic > 0) then
begin
ICSeqCompressFrameEnd(@CapVar);
ICCompressorFree(@CapVar);
ICClose(CapVar.hic);
end;
if ScapVar.hic>0 then
IcClose(Scapvar.hic);
end;
procedure TForm1.Button3Click(Sender: TObject);
var VD:TVideo_Data;
begin
VD.SampleNum:=5;
try
IdUDPClient1.SendBuffer(VD,sizeof(VD));
except
end;
end;
end.