Divx 压缩与解压问题,高手请进!!!(100分)

  • 主题发起人 主题发起人 ysfy
  • 开始时间 开始时间
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;
BufSize:DWord;
buf:array[0..VBS] of byte;
end;

var
Form1: TForm1;
CapWnd:THandle;
CapVar:TCompVars;
OutFormatSize,OutBufferSize,SampleNum:DWord;
BmpInInfo:TBitmapInfo;
BmpOutInfo:PBitmapInfo;
VideoData:TVIDEO_DATA;
SCapVar:TCOMPVARS;
SOutFormatSize,SOutBufferSize:DWord;
SOutBuffer:Pointer;
SBmpInInfo:TBitmapInfo;
SBmpOutInfo:PBitmapInfo;
ResultTest:DWord;




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.
 
后退
顶部