ICSeqCompressFrame总是返回空值

slmax1 2010-09-08 12:30:59
声明如下:

type

VideoData=record

buf:array[0..8079] of byte; //压缩后的视频数据

Num:integer;//帧数据过大时,分几个数据包发送,数据包在这一帧中的编号

IsLast:boolean;//是否是这一帧的最后一个数据包

end;


Var

FCV: TCOMPVARS;//帧压缩结构

FInInfo: TBitmapInfo;//压缩时输入结构

FOutInfo: TBitmapInfo;//压缩时输出结构

FoutActSize: DWORD;//压缩后帧数据的大小

Buffer:^byte; //压缩后帧数据地址

Buf: array of Byte;// 压缩后帧数据

代码如下

procedure TForm1.VideoCap1VideoStream(sender: TObject; lpVhdr: PVIDEOHDR);
var

KeyFrame:boolean;

MyVideo:VideoData;

i:integer;

begin
FOutActSize:=0;

MyVideo.Num:=0;

//压缩帧数据

Buffer:= ICSeqCompressFrame(@FCV, 0, lpVHdr^.lpData, @KeyFrame, @FOutActSize);//buffer等于NIL

SetLength(buf,FOutActSize);

Move(Buffer^, Buf[0], FOutActSize);

//当帧数据太大时,分几个数据包发送

while FOutActSize>8080 do

begin

MyVideo.Num:=MyVideo.Num+1;

MyVideo.IsLast:=false;

for i:=0 to 8079 do

begin

MyVideo.buf[i]:= buf[(MyVideo.Num-1)*8080+i];

end;

FOutActSize:=FOutActSize-8080;

// 向客户端发送数据包

VideoSender.SendBuffer('127.0.0.1',1234,MyVideo,sizeof(MyVideo));

end;

{if FOutActSize<8080 then

begin

MyVideo.Num:=MyVideo.Num+1;

MyVideo.IsLast:=true; //当前帧最后一个数据包

for i:=0 to FOutActSize do

begin

MyVideo.buf[i]:= buf[(MyVideo.Num-1)*8080+i];

end; }

//向客户端发送数据包

VideoSender.SendBuffer('127.0.0.1',1234,MyVideo,sizeof(MyVideo));

//end;



application.ProcessMessages;

end;


我的视频明明是有图像的,为什么会是空值?
...全文
172 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
slmax1 2010-09-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 kye_jufei 的回复:]
這樣肯定不行...
你先使用ICCompressGetFormat去獲得壓縮格式所需要的空間大小,然後使用GlobalAlloc分配記憶體,最後使用ICCompressGetFormat去設置壓縮信息…
[/Quote]


我这里有另外两个函数还写出来

//填充BMP头结构

procedure TForm1.FillBitmapStruc;

begin

FillChar(FInInfo.bmiHeader, SizeOf(TBitmapInfoHeader), 0);

with FInInfo.bmiHeader do

begin

biBitCount := 24;

biCompression := BI_RGB;

biHeight := 240;

biPlanes := 1;

biSize := SizeOf(TBitmapInfoHeader);

biWidth := 320;

end;

end;

//初始化压缩引擎

procedure TForm1.InitCompressor;

begin

FillChar(FCV, SizeOf(FCV), 0);

with FCV do

begin

dwFlags := ICMF_COMPVARS_VALID;

cbSize := SizeOf(FCV);

fccHandler := mmioFOURCC('d','i','v','x'); //选择压缩引擎,这里选择divx

fccType := ICTYPE_VIDEO;

hic := ICOpen(ICTYPE_VIDEO,fccHandler, ICMODE_COMPRESS);

lDataRate := 780;

lKey := 15;

lQ :=dword(ICQUALITY_DEFAULT);

if hic <> 0 then

begin

FillChar(FOutInfo, SizeOf(FOutInfo), 0);

ICCompressGetFormat(hic, @FInInfo, @FOutInfo);

FInInfo.bmiHeader.biCompression:=BI_RGB;

FOutInfo.bmiHeader.biCompression:=fccHandler;

ICSeqCompressFrameStart(@FCV, @FInInfo);

end;

end;

end;

//FormOnShow事件

procedure TForm1.FormShow(Sender: TObject);

begin

FillBitmapStruc;

InitCompressor;

//设置VideoCap1的相关属性

VideoCap1.DriverIndex:=0;

VideoCap1.CapToFile:=false;

VideoCap1.DriverOpen:=true;

videocap1.VideoPreview:=true;

end;

kye_jufei 2010-09-08
  • 打赏
  • 举报
回复
please try :

DWORD dwCkID; 

  DWORD dwCompFlags;

  DWORD dwQuality;

  LONG lNumFrames, lFrameNum;

  // Assume dwNumFrames is initialized to the total number of frames.

  // Assume dwQuality holds the proper quality value (0-10000).

  // Assume lpbiOut, lpOut, lpbiIn, and lpIn are initialized properly.

  // If OK to start, compress each frame.

  if (ICCompressBegin(hIC, lpbiIn, lpbiOut) == ICERR_OK)

  {

  for ( lFrameNum = 0; lFrameNum < lNumFrames; lFrameNum++)

  {

  if (ICCompress(hIC, 0, lpbiOut, lpOut, lpbiIn, lpIn,

  &dwCkID, &dwCompFlags, lFrameNum,

  0, dwQuality, NULL, NULL) == ICERR_OK)

  {

  // Write compressed data to the AVI file.

  // Set lpIn to the next frame in the sequence.

  }

  else

  {

  // Handle compressor error.

  }

  }

  ICCompressEnd(hIC); // terminate compression

  }

  else

  {

  // Handle the error identifying the unsupported format.

  }

  DWORD dwCkID;

  DWORD dwCompFlags;

  DWORD dwQuality;

  LONG lNumFrames, lFrameNum;

  // Assume dwNumFrames is initialized to the total number of frames.

  // Assume dwQuality holds the proper quality value (0-10000).

  // Assume lpbiOut, lpOut, lpbiIn, and lpIn are initialized properly.

  // If OK to start, compress each frame.

  if (ICCompressBegin(hIC, lpbiIn, lpbiOut) == ICERR_OK)

  {

  for ( lFrameNum = 0; lFrameNum < lNumFrames; lFrameNum++)

  {

  if (ICCompress(hIC, 0, lpbiOut, lpOut, lpbiIn, lpIn,

  &dwCkID, &dwCompFlags, lFrameNum,

  0, dwQuality, NULL, NULL) == ICERR_OK)

  {

  // Write compressed data to the AVI file.

  // Set lpIn to the next frame in the sequence.

  }

  else

  {

  // Handle compressor error.

  }

  }

  ICCompressEnd(hIC); // terminate compression

  }

  else

  {

  // Handle the error identifying the unsupported format.

  }

  上面的壓縮只是一定方式的,壓縮視頻幀的時候應該使用ICSeqCompressFrame

  
  
LPVOID ICSeqCompressFrame( 

  PCOMPVARS pc,

  UINT uiFlags,

  LPVOID lpBits,

  BOOL * pfKey,

  LONG * plSize

  );

  LPVOID ICSeqCompressFrame(

  PCOMPVARS pc,

  UINT uiFlags,

  LPVOID lpBits,

  BOOL * pfKey,

  LONG * plSize

  );

  參數:

  pc:一個COMPVARS結構的指標,必須先初始化一些壓縮參數.

  uiFlags:必須為0

  lpBits:指向待壓縮資料的指標,資料不包含header以及format格式

  pfKey:返回是否該幀壓縮為關鍵幀.

  plSize:返回使用者壓縮資料的大小

  該函數使用一個COMPVARS結構提供壓縮器以及關鍵幀,速率,速率通過函數 ICSeqCompressorFrameStart 設置.

  當壓縮一系列視頻流的時候,要使用這個函數去代替ICCompress函數.

  你也可以通過使用函數ICCompressorChoose去讓使用者選擇結構.你也可以自己手動設置這個參數.

  使用ICSeqCompressFrameStart, ICSeqCompressFrame, and ICSeqCompressFrameEnd函數去壓縮一系列幀,每出現一幀資料使用ICSeqCompressFrame 一次.

  當完成了壓縮,使用ICCompressorFree去釋放COMPVARS的資源.

  2:設置COMPVARS對象的參數:

  1:cbSize

  2:dwFlags

  3:cbState

  4:fccHandler

  5:fccType

  6:hic

  1:使用ICOpen

  2:使用ICLocate

  3:使用ICCompressGetFormatSize獲得資料大小
4:分配記憶體

  5:ICCompressGetFormat 設置參數

  6:ICCompressGetSize設置參數

  7:ICSeqCompressFrameStart開始

  8:斷開連接的時候需要如下:

  引用

  1:ICSeqCompressFrameEnd

  2:ICCompressorFree

  3:ICClose

  9:然後在回呼函數裡面使用:

  ICSeqCompressFrame來壓縮.

  這裡要注意有一個參數是是否為關鍵幀.bKeyFrame!

  一定要將這個參數傳遞給伺服器端.

  ICSeqCompressFrame函數返回的BUF也要發送到伺服器端.這裡就算是開發完畢了!

  ICSeqCompressFrame的最後一個參數是壓縮後資料的大小.
kye_jufei 2010-09-08
  • 打赏
  • 举报
回复
這樣肯定不行...
你先使用ICCompressGetFormat去獲得壓縮格式所需要的空間大小,然後使用GlobalAlloc分配記憶體,最後使用ICCompressGetFormat去設置壓縮信息…
slmax1 2010-09-08
  • 打赏
  • 举报
回复
难道说我提的问题都那么难回答吗?

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧