unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls,VFW, IdBaseComponent, IdComponent, IdUDPBase,
  IdUDPServer, IdUDPClient,IdSocketHandle, IdAntiFreezeBase, IdAntiFreeze;type
   TVIDEO_DATA = packed record
    bKeyFrame : bool;
    nSampleNum : DWORD;
    nUsedSize : DWORD;
    Buf : Array[0..4084-1] of byte;
  end;
  
  TForm1 = class(TForm)
    PnV1: TPanel;
    PnV2: TPanel;
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    IdUDPClient1: TIdUDPClient;
    IdUDPServer1: TIdUDPServer;
    IdAntiFreeze1: TIdAntiFreeze;
    Button3: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
 
    
  private
    { Private declarations }
      
  public
    { Public declarations }   
    dc:HDC;
    hdd:HDRAWDIB;
    BmpInfo,BmpInfo1:BITMAPINFO;
    hWndc:Thandle;    DataPoint:^byte;
    DataPoint1:^byte;   OutFormatSize:dword;
   BmpOutInfo:^BITMAPINFO;
   CapVar:TCOMPVARS;
   OutBufferSize:DWORD;   
  
   function InitCaptureParams : boolean;
    procedure ShowDib();
  
  end;var
  Form1: TForm1;
   function FrameCallBack(hWnd:HWND;lpVHdr:PVIDEOHDR):DWORD;stdcall;
 implementation{$R *.dfm}{ TForm1 }function Tform1.InitCaptureParams : boolean;
 // var
  //  ICINFO: info;
begin
      result := False;
      zeromemory(@CapVar,sizeof(TCOMPVARS));
      CapVar.cbSize:=sizeof(CapVar); //必须指定cbSize为TCOMPVARS结构大小
      CapVar.dwFlags:=ICMF_COMPVARS_VALID;
      CapVar.cbState:=0;
      CapVar.fccHandler:=859189837;
      CapVar.fccType:=ICTYPE_VIDEO;
      CapVar.hic:=ICOpen(ICTYPE_VIDEO, CapVar.fccHandler, ICMODE_COMPRESS);      if (CapVar.hic>0) then
      begin
         OutFormatSize:=ICCompressGetFormatSize(CapVar.hic,@BmpInfo);      //   form1.Caption:=inttostr(OutFormatSize);         getmem(BmpOutInfo,OutFormatSize);
         ICCompressGetFormat(CapVar.hic,@BmpInfo.bmiHeader,@BmpOutInfo^.bmiHeader);         ICSendMessage(CapVar.hic,$60c9,$f7329ace,$acdeaea2); //非此不可         OutBufferSize:=ICCompressGetSize(CapVar.hic,@BmpInfo.bmiHeader,@BmpOutInfo^.bmiHeader);         ICSeqCompressFrameStart(@CapVar,@BmpInfo);                 result := True;      //   form1.Caption:=inttostr(OutBufferSize);      end
      else
      begin
        Showmessage('请先安装视频压缩编码器');
        Exit;
      end
end;function FrameCallBack(hWnd:HWND;lpVHdr:PVIDEOHDR):DWORD;stdcall;
 var
       bKeyFrame : BOOL ;
       Buf : PBYTE;
       VideoData : TVIDEO_DATA;
       OutActSize : dword;
    //   SampleNum:DWORD;
      begin
    OutActSize := form1.BmpInfo.bmiHeader.biSizeImage;
    Buf := ICSeqCompressFrame(@form1.CapVar,0,lpVHdr.lpData,@bKeyFrame,@OutActSize);
 //   form1.caption:=inttostr(OutActSize);
 
     if (OutActSize <= sizeof(videodata.Buf)) then
       begin
         zeromemory(@VideoData ,sizeof(TVIDEO_DATA));
         
         //记录是否为关键帧
         VideoData.bKeyFrame:=bKeyFrame;         copymemory(@VideoData.Buf, Buf, OutActSize);       //  VideoData.nSampleNum:=SampleNum; //我们可以记录下帧数, 可以做扩展用
      //   VideoData.nUsedSize:=OutActSize;  //记录数据大小, 传输时用   form1.IdUDPClient1.SendBuffer(VideoData,sizeof(VideoData)); //           这是发送视频数据
      
      end;
    result := 0;   end;procedure TForm1.Button1Click(Sender: TObject);
var
 // nn:integer;
  dwSize:DWORD;
begin
   hWndC:=capCreateCaptureWindowA('Capdfture Window',WS_CHILD or WS_VISIBLE,0,0,PnV1.Width,PnV1.Height,PnV1.Handle,0);
  if hWndC = 0 then exit;
 {
  capDriverConnect(hWndC,0);   //连接摄像头设备
  capDlgVideoFormat(hWndC);  //显示视频设置对话框,进行配置视频的大小、颜色位数等。
  capGetVideoFormat(hWndC,@BmpInfo,sizeof(BITMAPINFO));  //取得视频图像数据头,后面压缩时需要用到
  capPreviewRate(hWndC,33);  //设置预览视频的频率,33代表第秒30帧。
  capPreview(hWndC, TRUE);
  capSetCallbackOnFrame(hWndC,FrameCallBack);
 }
       SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0,0);
      SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
      SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
      SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
      SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
      SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 80, 0);
      SendMessage(hWndC, WM_CAP_SET_CALLBACK_FRAME,0,LongInt(@FrameCallBack));      SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
      SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);      dwSize:=capGetVideoFormatSize(hWndC);
      capGetVideoFormat(hWndC, Addr(BmpInfo), dwSize);
      InitCaptureParams;
end;procedure TForm1.ShowDib();
begin
//  DrawDibDraw(hdd,dc,0,0,PnV2.Width,PnV2.Height,@BmpOutInfo.bmiHeader,form1.,0,0,-1,-1,0);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
  capDriverDisconnect(hWndC);
end;procedure TForm1.Button3Click(Sender: TObject);
begin
  // form1.Decom(hWnd:HWND;lpVHdr:PVIDEOHDR);
end;end.

解决方案 »

  1.   

    >>>只剩下最后如何接收数据、解压、显示晕这也叫只剩下?CSDN论坛浏览器:http://CoolSlob.ys168.com/
      

  2.   

    建议你用TCP实现视频传输,以前我们用UDP发现视频流丢包很严重
      

  3.   

    @DaiSoft() 
    视频无所谓了,只要KEYFRAME关键桢到达目标即可;如果是audio则采用tcp,否则声音很难听
    @qxh0724 (623827)  
    LZ的代码貌似我以前发给你的那段,你压缩了,就可以解压,再给你发段解压的,呵呵.
    //初始化     
    //determin the ouput format
          self.m_OutFormatSize := VFW.ICDecompressGetFormatSize(self.m_CV.hic,
            @self.m_InInfo.bmiHeader);
          GetMem(m_pOutInfo, m_OutFormatSize);
          zeromemory(m_pOutInfo, m_OutFormatSize);
          VFW.ICDecompressGetFormat(self.m_CV.hic, @self.m_InInfo,
            @self.m_pOutInfo^.bmiHeader);
          WriteLn(format('out format:%d', [self.m_pOutInfo.bmiHeader.biHeight]));
          self.m_OutBufSize := self.m_pOutInfo.bmiHeader.biSizeImage;
          GetMem(m_pOutBuf, m_OutBufSize);
          ZeroMemory(m_pOutBuf, m_OutBufSize);      ICSendMessage(m_CV.hic, $60C9, $F7329ACE, $ACDEAEA2);
          m_cv.dwFlags := ICMF_COMPVARS_VALID;      VFW.ICDecompressBegin(self.m_CV.hic, @self.m_InInfo,
            @self.m_pOutInfo^.bmiHeader);//获取数据解压
      Socket.ReceiveBuf(VideoData, SizeOf(TVIDEO_DATA));
      Inc(m_RecvLength, VideoData.nUsedSize);    if (VideoData.nUsedSize > 0) and (VideoData.nUsedSize < 4084) then
        Ret := VFW.ICDecompress(m_CV.hic, 0, @m_InInfo.bmiHeader, @VideoData.Buf,
          @m_pOutInfo.bmiHeader, m_pOutBuf);
    //绘制
      dc := GetDc(p.Handle);
      h := VFW.DrawDibOpen();  Self.m_cv.lQ := 100;
      VFW.DrawDibDraw(h, dc, 0, 0, m_pOutInfo.bmiHeader.biWidth,
        m_pOutInfo.bmiHeader.biHeight, @m_pOutInfo^.bmiHeader, Buf, 0, 0,
          m_pOutInfo.bmiHeader.biWidth,
        m_pOutInfo.bmiHeader.biHeight, DDF_NOTKEYFRAME);
      DrawDibClose(h);
      ReleaseDC(p.Handle, dc);关键是要把Bmpinfo和 m_CV.hic 传递过来,具体应该好好阅读VFW的API,不过这个已经过时了,WIN2K以上平台应该使用DSHOW来做.
      

  4.   

    http://www.libing.net.cn/read.php/1010.htm
    http://www.libing.net.cn/read.php/1012.htm我叶在做
    参考一下 对你肯定有帮助