一个视频聊天程序,我安装了对应的编码器,能成功压缩,能接收到数据但不能成功解压,请大家帮忙修改下
   相信需要改的地方不多,不要改变程序的整体模式,
   改完测试成功后请发至邮箱[email protected]程序在地址http://e.ys168.com/?slmax
改完后400分相送。地址在http://topic.csdn.net/u/20100909/20/d31df1ac-2321-42bd-8b62-8fb619403423.html

解决方案 »

  1.   

    這個分我收下了
    看了你的代碼,程序的關鍵在於視頻的壓縮和解壓縮部分,按照我的方式修改:
    以下為視頻解壓關鍵部分代碼:
    服務器端解壓視頻數據處理//下面的代碼是Delphi的處理方法:   //接著,一起來看看用戶端的圖像顯示過程:   //CapVar是COMPVARS物件 C++的定義為 COMPVARS CapVar;   //先用取得的CapVar來連接視訊轉碼器   //Capvar.fccHandler是使用用戶端一樣的解碼器   CapVar.hic := ICOpen(CapVar.fccType,CapVar.fccHandler,ICMODE_DECOMPRESS);   //成功後,用伺服器傳來的BmpOutInfo當作用戶端的BmpInInfo來取得解壓輸出的圖像頭BmpOutInfo   //獲得參數   OutFormatSize:=ICDecompressGetFormatSize(CapVar.hic,@BmpInInfo.bmiHeader);   //分配記憶體   GetMem(BmpOutInfo,OutFormatSize);   //初始化   zeromemory(BmpOutInfo,OutFormatSize);   //設置參數   ICDecompressGetFormat(CapVar.hic, @BmpInInfo.bmiHeader, @BmpOutInfo^.bmiHeader);   //設置參數   OutBufferSize:=BmpOutInfo^.bmiHeader.biSizeImage;   //分配記憶體   getmem(OutBuffer,OutBufferSize);   //初始化   zeromemory(OutBuffer,OutBufferSize);   //解壓縮開始   ICDecompressBegin(CapVar.hic,@BmpInInfo.bmiHeader, @BmpOutInfo^.bmiHeader);   //最後,當然是視頻資料的解壓過程   //如果是關鍵幀   if VIDEO_DATA.bKeyFrame then   Result:=ICDecompress(CapVar.hic,0,@BmpInInfo,@VIDEO_DATA.Buf,@BmpOutInfo.bmiHeader,OutBuffer)   //如果是普通幀   else   Result:=ICDecompress(CapVar.hic,ICDECOMPRESS_NOTKEYFRAME,@BmpInInfo,@VIDEO_DATA.Buf,@BmpOutInfo.bmiHeader,OutBuffer);   //如果解壓成功   if (Result=ICERR_OK) then   begin   //將圖像畫出來   SetDIBitsToDevice(Canvas.Handle,0,0,bmptmp.Width,bmptmp.Height,0,0,0,BmpOutInfo^.bmiHeader.biHeight ,OutBuffer,BmpOutInfo^,DIB_RGB_COLORS);   end;   //下面的代碼是Delphi的處理方法:  //接著,一起來看看用戶端的圖像顯示過程:   //CapVar是COMPVARS物件 C++的定義為 COMPVARS CapVar;  //先用取得的CapVar來連接視訊轉碼器   //Capvar.fccHandler是使用用戶端一樣的解碼器  CapVar.hic := ICOpen(CapVar.fccType,CapVar.fccHandler,ICMODE_DECOMPRESS);   //成功後,用伺服器傳來的BmpOutInfo當作用戶端的BmpInInfo來取得解壓輸出的圖像頭BmpOutInfo   //獲得參數  OutFormatSize:=ICDecompressGetFormatSize(CapVar.hic,@BmpInInfo.bmiHeader);   //分配記憶體  GetMem(BmpOutInfo,OutFormatSize);  //初始化   zeromemory(BmpOutInfo,OutFormatSize);   //設置參數  ICDecompressGetFormat(CapVar.hic, @BmpInInfo.bmiHeader, @BmpOutInfo^.bmiHeader);   //設置參數  OutBufferSize:=BmpOutInfo^.bmiHeader.biSizeImage;   //分配記憶體  getmem(OutBuffer,OutBufferSize);   //初始化  zeromemory(OutBuffer,OutBufferSize);   //解壓縮開始  ICDecompressBegin(CapVar.hic,@BmpInInfo.bmiHeader, @BmpOutInfo^.bmiHeader);   //最後,當然是視頻資料的解壓過程   //如果是關鍵幀  if VIDEO_DATA.bKeyFrame then   Result:=ICDecompress(CapVar.hic,0,@BmpInInfo,@VIDEO_DATA.Buf,@BmpOutInfo.bmiHeader,OutBuffer)   //如果是普通幀  else   Result:=ICDecompress(CapVar.hic,ICDECOMPRESS_NOTKEYFRAME,@BmpInInfo,@VIDEO_DATA.Buf,@BmpOutInfo.bmiHeader,OutBuffer);   //如果解壓成功  if (Result=ICERR_OK) then   begin   //將圖像畫出來  SetDIBitsToDevice(Canvas.Handle,0,0,bmptmp.Width,bmptmp.Height,0,0,0,BmpOutInfo^.bmiHeader.biHeight ,OutBuffer,BmpOutInfo^,DIB_RGB_COLORS);   end;
      

  2.   

    按照我这里的代码老是返回-2,是怎么回事unit Unit2;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer, ExtCtrls,VFW,IdSocketHandle;type
      TForm1 = class(TForm)
        Image1: TImage;
        VideoReceiver: TIdUDPServer;
        procedure FormShow(Sender: TObject);
        procedure VideoReceiverUDPRead(Sender: TObject; AData: TStream;
          ABinding: TIdSocketHandle);
      private
        { Private declarations }
      public
        { Public declarations }
        procedure InitDeCompressor;
        procedure FillBitmapStruc;    
      end;
    type  VideoData=record    buf:array[0..8079] of byte; //压缩后的视频数据    Num:integer;//帧数据过大时,分几个数据包发送,数据包在这一帧中的编号    IsLast:boolean;//是否是这一帧的最后一个数据包end;VarFCV: TCOMPVARS;//帧压缩结构FInInfo: TBitmapInfo;//解压时输入结构FOutInfo: TBitmapInfo;//解压时输出结构FoutActSize: DWORD;//压缩后帧数据的大小OutFormatSize,OutBufferSize:DWORD;Buf: array of Byte;// 未解压时帧数据myout:array[0..230399] of byte;// 解压后帧数据  Form1: TForm1;implementation{$R *.dfm}//填充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.InitDeCompressor;
    var
      sResult,a,b:DWORD;
    begin  FillChar(FCV, SizeOf(FCV), 0);  with FCV do  begin    dwFlags := ICDECOMPRESS_NOTKEYFRAME;    cbSize := SizeOf(FCV);    cbState := 0;    fccHandler := mmioFOURCC('x','v','i','d');   //选择压缩引擎,这里选择divx    fccType := ICTYPE_VIDEO;    hic := ICOpen(ICTYPE_VIDEO,fccHandler, ICMODE_DECOMPRESS);    lDataRate := 780;    lKey := 15;    lFrame := 0;    lKeyCount :=0;    lpbiIn :=nil;    lpbiOut :=nil;    lpBitsPrev :=nil;    lpState := nil;    lQ :=dword(ICQUALITY_DEFAULT);    if hic <> 0 then    begin      OutFormatSize:=ICCompressGetFormatSize(FCV.hic,@FInInfo.bmiHeader);      ShowMessage(IntToStr(OutFormatSize));      FillChar(FOutInfo, SizeOf(FOutInfo), 0);      a:=ICCompressGetFormat(hic, @FInInfo, @FOutInfo);      ShowMessage(IntToStr(a));      FInInfo.bmiHeader.biCompression:=BI_RGB;      FOutInfo.bmiHeader.biCompression:=fccHandler;      sResult:=ICDecompressBegin(FCV.hic,@FInInfo.bmiHeader, @FOutInfo.bmiHeader);      ShowMessage(IntToStr(sResult));
        end;  end;end;
    procedure TForm1.FormShow(Sender: TObject);
    begin
      FillBitmapStruc;  InitDeCompressor;  VideoReceiver.Active:=true;end;
    procedure TForm1.VideoReceiverUDPRead(Sender: TObject; AData: TStream;
      ABinding: TIdSocketHandle);
    var RetVal:integer;  MyVideo:VideoData;  i:integer;begin  RetVal:=-1;  AData.Position:=0;  //读取数据  AData.ReadBuffer(MyVideo,sizeof(MyVideo));  if MyVideo.Num=1 then  SetLength(buf,0);  SetLength(buf,(MyVideo.Num)*8080);  for i:=0 to 8079 do  begin    buf[(MyVideo.Num-1)*8080+i]:=MyVideo.buf[i];  end;  if MyVideo.IsLast  then  //当前帧最后一个数据包  begin  //解压数据    RetVal := ICDeCompress(FCV.hic,0,@FoutInfo.bmiHeader,@Buf,@FOutInfo.bmiHeader,@myout);    if  RetVal= ICERR_OK then    begin      //在Image1上画出一帧图像      StretchDIBits(Image1.Canvas.Handle,0,0,Image1.Width,Image1.Height,0,0,FOutInfo.bmiHeader.biWidth,FOutInfo.bmiHeader.biHeight,@myout,FOutInfo,0,SRCCOPY  );      Image1.Repaint;    end
        else
        begin
          ShowMessage(IntToStr(RetVal));
        end;  end;  end;
    end.
      

  3.   

    我有自己写这个视频传输的程序,用的也是divx,不过我没有用视频控件这是我写一个压缩和解码单元
    unit unVCMVideoProcess;interface
    uses
      Windows,SysUtils,vfw,unVideoProcess;type
       // 压缩
      TVCMEncode=class(TInterfacedObject,IVideoProcess)
      private
        CapVar: TCOMPVARS;
        pvdData :PVideoData;
      protected  public
        constructor Create(ch0, ch1, ch2, ch3: AnsiChar);
        destructor Destroy; override;
        //
        function InitProcess(pbiInfo:PBitmapInfo):Integer;stdcall;
        procedure EndProcess();stdcall;
        function DoProcess(Data :PByte;Len:DWORD; var ReturnData :PByte;var ReturnLen:DWORD
          ):Integer;stdcall;
       end;
    //解码
      TVCMDecode=class(TInterfacedObject,IVideoProcess)
      private
        pDeReturn:PByte;
        CapVar: TCOMPVARS;
        pbiInfoOut:PBitmapInfo;
      protected  public
        constructor Create(ch0, ch1, ch2, ch3: AnsiChar);
        destructor Destroy; override;
        //
        function InitProcess(pbiInfo:PBitmapInfo):Integer;stdcall;
        procedure EndProcess();stdcall;
        function DoProcess(Data :PByte;Len:DWORD; var ReturnData :PByte;var ReturnLen:DWORD
          ):Integer;stdcall;
       end;
    implementation
    { TVideoProcessCompress }constructor TVCMEncode.Create(ch0, ch1, ch2, ch3: AnsiChar);
    begin
      inherited Create;
      pvdData :=nil;  Zeromemory(@CapVar,sizeof(TCOMPVARS));
      //初始化CapVar  CapVar.cbSize:=sizeof(CapVar); //必须指定cbSize为TCOMPVARS结构大小
      CapVar.dwFlags:=ICMF_COMPVARS_VALID;
      CapVar.cbState:=0;
      //fccHandler代表压缩编码类型,我们使用的是DIVX的编码器
      CapVar.fccHandler:=mmioFOURCC(ch0,ch1,ch2,ch3);
      CapVar.fccType:=ICTYPE_VIDEO;
    end;destructor TVCMEncode.Destroy;
    begin
      EndProcess;
      
      if Assigned(pvdData) then
      begin
        FreeMemory(pvdData);
        pvdData:=nil;
      end;  inherited;end;function TVCMEncode.DoProcess(Data :PByte;Len:DWORD; var ReturnData :PByte;var ReturnLen:DWORD):Integer;
    var
      bKeyFrame : BOOL ;
      pBuf:PByte;
      dwDataLen:DWORD;begin
      Result:=0;
      ReturnData:=nil;  if CapVar.hic=0 then
      begin
        Result:=-1;
        Exit;
      end;
      pBuf := ICSeqCompressFrame(@CapVar,0,Data,@bKeyFrame,@dwDataLen);
      if not Assigned(pBuf) then
      begin
        Result:=-2;
        Exit;
      end;
      ReturnLen:= dwDataLen+Sizeof(TVideoData);
      if Assigned(pvdData) then
      begin
        FreeMemory(pvdData);
        pvdData:=nil;
      end;
      pvdData:=GetMemory(ReturnLen);
      pvdData.KeyFrame:=  Byte( bKeyFrame);  CopyMemory( @pvdData^.BitmapInfo,CapVar.lpbiOut,SizeOf(TBitmapInfo)  );
      pvdData^.DataLen:=dwDataLen;
      CopyMemory( @pvdData^.Data[0]  ,pBuf ,dwDataLen);
      ReturnData:=PByte(pvdData);
    end;
    procedure TVCMEncode.EndProcess;
    begin
      if (CapVar.hic > 0) then
      begin
         ICSeqCompressFrameEnd(@CapVar);
         ICCompressorFree(@CapVar);
         ICClose(CapVar.hic);
         CapVar.hic:=0;
      end;end;function TVCMEncode.InitProcess(pbiInfo: PBitmapInfo): Integer;
    begin
      Result :=0;
      //正式连接编码器
      CapVar.hic:=ICOpen(ICTYPE_VIDEO, CapVar.fccHandler, ICMODE_COMPRESS);
      if (CapVar.hic=0) then
      begin
        Result:=-1;
        Exit;
      end;//  dwOutFormatSize:=ICCompressGetFormatSize(CapVar.hic, pbiInfo);
    //  pbiInfoOut:=GetMemory(dwOutFormatSize);
    //  ICCompressGetFormat(CapVar.hic,pbiInfo,pbiInfoOut);
      ICSeqCompressFrameStart(@CapVar, pbiInfo);
     end;
    { TVideoProcessDeCompress }constructor TVCMDecode.Create(ch0, ch1, ch2, ch3: AnsiChar);
    begin
      inherited Create;
      Zeromemory(@CapVar,sizeof(TCOMPVARS));  //初始化CapVar
      pDeReturn:=nil;
      CapVar.cbSize:=sizeof(CapVar); //必须指定cbSize为TCOMPVARS结构大小
      CapVar.dwFlags:=ICMF_COMPVARS_VALID;
      CapVar.cbState:=0;
      //fccHandler代表压缩编码类型,我们使用的是DIVX的编码器
      CapVar.fccHandler:=mmioFOURCC(ch0,ch1,ch2,ch3);
      CapVar.fccType:=ICTYPE_VIDEO;
    end;destructor TVCMDecode.Destroy;
    begin
      EndProcess;
      if Assigned(pDeReturn) then
      begin
        FreeMemory(pDeReturn);
        pDeReturn:=nil;
      end;
      inherited;
    end;function TVCMDecode.DoProcess( Data :PByte;Len:DWORD; var ReturnData :PByte;var ReturnLen:DWORD):Integer;
    var
      dwFlag,dwResult:DWORD;
      pvdReceive:PVideoData;begin
      Result:=0;
      if CapVar.hic=0 then
      begin
        Result:=-1;
        Exit;
      end;  pvdReceive:=PVideoData(Data);
      if  pvdReceive^.KeyFrame = 0 then
        dwFlag:=ICDECOMPRESS_NOTKEYFRAME
      else
        dwFlag:=0;  ReturnLen:= pbiInfoOut^.bmiHeader.biSizeImage;  if Assigned(pDeReturn) then
      begin
        FreeMemory(pDeReturn);
        pDeReturn:=nil;
      end;
      pDeReturn:=GetMemory(ReturnLen);
      dwResult:=ICDecompress(CapVar.hic,dwFlag,@pvdReceive^.BitmapInfo.bmiHeader,
        @pvdReceive^.Data[0], @pbiInfoOut^.bmiHeader,pDeReturn);  ReturnData:=pDeReturn;
    //  ReturnLen:= SizeOf(TVideoData)+pbiInfoOut^.bmiHeader.biSizeImage;
    //  ReturnData:=GetMemory(ReturnLen);
    //  //ICERR_OK
    //  CopyMemory(@ReturnData^.BitmapInfo,pbiInfoOut,SizeOf(TBitmapInfo));
    //  ReturnData^.DataLen:= pbiInfoOut^.bmiHeader.biSizeImage;
    //  dwResult:=ICDecompress(CapVar.hic,dwFlag,@pvdReceive^.BitmapInfo.bmiHeader,
    //    @pvdReceive^.Data[0], @pbiInfoOut^.bmiHeader,@ReturnData^.Data[0] );end;procedure TVCMDecode.EndProcess;
    begin
      if (CapVar.hic > 0) then
      begin
         ICDeCompressEnd(CapVar.hic);
         ICClose(CapVar.hic);
         CapVar.hic:=0;
      end;  if Assigned(pbiInfoOut) then
      begin
        FreeMemory(pbiInfoOut);
        pbiInfoOut:=nil;
      end;
    end;function TVCMDecode.InitProcess(
      pbiInfo: PBitmapInfo): Integer;
    var
      dwOutFormatSize:DWORD;
    begin
      Result :=0;
      //正式连接编码器
      CapVar.hic:=ICOpen(ICTYPE_VIDEO, CapVar.fccHandler, ICMODE_DECOMPRESS);
      if (CapVar.hic=0) then
      begin
        Result:=-1;
        Exit;
      end;  dwOutFormatSize:=ICDecompressGetFormatSize(CapVar.hic, pbiInfo);
      pbiInfoOut:=GetMemory(dwOutFormatSize);
      ICDeCompressGetFormat(CapVar.hic,pbiInfo,pbiInfoOut);  if ICERR_OK<>ICDecompressBegin(CapVar.hic,pbiInfo,pbiInfoOut) then
      begin
        EndProcess;
      end;
     end;
    end.
    这是接口单元
    unit unVideoProcess;interfaceuses
      Windows;
    type
      PVideoData=^TVideoData;
      TVideoData=packed record
        KeyFrame:Byte;
        BitmapInfo:TBitmapInfo;
        DataLen:DWORD;
        Data:array [0..0] of Byte;
      end;  IVideoProcess=interface
        function InitProcess(pbiInfo:PBitmapInfo):Integer;stdcall;
        procedure EndProcess();stdcall;
        function DoProcess(Data :PByte;Len:DWORD; var ReturnData :PByte;var ReturnLen:DWORD
          ):Integer;stdcall;
      end;implementationend.
      

  4.   

    視頻會議系統做過嗎?如果沒,只是知道;那麼請你提供一個油箱吧,我發一個基於視頻會議的測試demo給你參考看看...
      

  5.   

    [email protected]我只是需要视频传输而且能够显示的那个功能就OK了
      

  6.   


    好,我正在從之前開發的視頻會議室系統中分離代碼;給您編寫一個視頻傳輸並顯示的demo...
    PS,預計晚上將測試demo發給您!
      

  7.   

    基於視頻傳輸的demo程序已發送到[email protected],請查收!PS:(此DEMO程序是我使用DSPACK組件給公司開發的視頻會議系統中分享出了視頻傳輸代碼)目前只發給你了EXE可執行程序,先看一下效果;如有任何問題,請與我聯繫
      

  8.   

    用了你的程序,只有PClient.exe有两个图像,而PServer.exe没有图像。
      

  9.   

    我這裡用的是中文繁體操作系統,測試使用一切正常;而且基於視頻會議管理系統一直使用,(兩岸三地)即從台灣-->香港-->東莞均無問題;兩邊視頻圖像均顯示正常且流暢