一个视频聊天程序,我安装了对应的编码器,能成功压缩,能接收到数据但不能成功解压,请大家帮忙修改下
   相信需要改的地方不多,不要改变程序的整体模式,
   改完测试成功后请发至邮箱[email protected]程序在地址http://e.ys168.com/?slmax
改完后400分相送。前面还有一贴。

解决方案 »

  1.   

    這個分我收下了
    看了你的代碼,程序的關鍵在於視頻的壓縮和解壓縮部分,按照我的方式修改:
    以下為視頻壓縮關鍵部分代碼: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的最後一個參數是壓縮後資料的大小.
      

  2.   

    補充說明:視頻資料壓縮步驟:
    先定義COMPVARS物件:  view plaincopy to clipboardprint?  typedef struct {   LONG cbSize;   DWORD dwFlags;   HIC hic;   DWORD fccType;   DWORD fccHandler;   LPBITMAPINFO lpbiIn;   LPBITMAPINFO lpbiOut;   LPVOID lpBitsOut;   LPVOID lpBitsPrev;   LONG lFrame;   LONG lKey;   LONG lDataRate;   LONG lQ;   LONG lKeyCount;   LPVOID lpState;   LONG cbState;   } COMPVARS;   typedef struct {   LONG cbSize;   DWORD dwFlags;   HIC hic;   DWORD fccType;   DWORD fccHandler;   LPBITMAPINFO lpbiIn;   LPBITMAPINFO lpbiOut;   LPVOID lpBitsOut;   LPVOID lpBitsPrev;   LONG lFrame;   LONG lKey;   LONG lDataRate;   LONG lQ;   LONG lKeyCount;   LPVOID lpState;   LONG cbState;   } COMPVARS;   cbSize:  必須設置該值為一個正確的值.  或者cbSize = sizeof(COMPVARS);  dwFlags:  ICMF_COMPVARS_VALID  如果你使用ICCompressorChoose 函數來初始化結構,請不要設置這個值.  hic:壓縮的控制碼,你可以使用ICOpen去獲得一個控制碼  fccType: ICTYPE_VIDEO   當然也可以設置為zero  fccHandler:四個字元的壓縮引擎  lpbiIn:保留  lpbiOut:BITMAPINFO結構的指標,包含了輸出圖像格式,也可以通過使用函數ICCompressorChoose設置輸出格式  lpBitsOut:保留  lpBitsPrev:保留  lFrame:保留  lKey:關鍵畫面播放速率 ICSeqCompressFrameStart 函數使用這個值來創建關鍵幀  lDataRate:資料速率,可以通過ICCompressorChoose設置  lQ:品質設置.可以使用ICQUALITY_DEFAULT 默認. ICSeqCompressFrameStart 函數使用這個值來產生資料品質  lKeyCount:保留  lpState:保留  cbState:保留  重要:  如果你要手動設置這個結構,你必須提供如下成員的值:  cbSize, hic, lpbiOut, lKey, and lQ.還有dwFlags為ICMF_COMPVARS_VALID.  對Video Compression Manager(VCM)要熟悉,你還需要瞭解如下幾個結構:  1:BITMAPINFO   2:BITMAPINFOHEADER  VCM工作在應用程式以壓縮解壓縮驅動之間. 當一個程式調用VCM時候,VCM翻譯成一個消息,消息通過ICSendMessage函數去選擇調用相應的壓縮解壓縮器.  VCM服務,一般來說,一個應用程式使用VCM去處理如下的工作:  1:定位,打開,安裝一個壓縮解壓縮器.  2:配置或者獲取壓縮解壓縮器的配置資訊.  3:使用一系列的函數去壓縮,解壓縮,顯示資料.  一般顯示資料是使用函數DrawDIB.  壓縮解壓縮基本資訊:  你可以使用ICLocate和ICOpen函數定位打開一個壓縮器.你可以使用ICLocate去找到一個特定類型的壓縮器並獲得她的控制碼為下一步的VCM函數做準備.你還可以使用ICOpen去打開一個壓縮器,你的程式使用ICOpen返回來的控制碼來完成更多VCM的功能.  用戶如何選擇一個壓縮器:  當壓縮資料時候,你的應用程式可以使用ICCompressorChoose 函數去打開一個對話方塊去選擇一個壓縮器,然後返回一個控制碼給COMPVARS 結構的hic成員.後面壓縮的時候就可以使用這個控制碼.  應用程式可以定位和打開一個已經安裝的壓縮解壓縮器,通過使用函數ICLocate和ICOpen函數,當一個應用程式完成使用壓縮解壓縮器以後,要使用ICClose來關閉.  單圖像壓縮:  可以使用ICImageCompress 函數來完成單幅圖片的壓縮.  下面來討論一下關鍵的問題:  流壓縮的問題  你的程式可以使用 ICSeqCompressFrame, ICSeqCompressFrameStart, and ICSeqCompressFrameEnd函數去壓縮一系列的幀.這些函數使用存儲在COMPVARS結構中的資料,應用程式可以使用ICCompressorChoose去讓用戶選擇一個壓縮器.  在應用程式開始壓縮一系列幀之前,必須使用ICSeqCompressFrameStart函數去分配必須的資源.資源配置以後,應用程式可以使用ICSeqCompressFrame去壓縮.畫面播放速率和關鍵幀參數以及其他的一系列參數都存儲在COMPVARS結構中,最後程式要使用ICCompressorFree 釋放資源.  下面的內容是圖像壓縮,暫時不翻譯,感興趣的可以去看MSDN.  如何將資料顯示出來:  可以使用ICDraw.ICDrawStart.ICDrawBegin.  下面的方法使用ICLocate找到一個壓縮器能夠壓縮8bits的圖像的:  view plaincopy to clipboardprint?  BITMAPINFOHEADER bih;   HIC hIC
    // Initialize the bitmap structure.   bih.biSize = sizeof(BITMAPINFOHEADER);   bih.biWidth = bih.biHeight = 0;   bih.biPlanes = 1;   bih.biCompression = BI_RGB; // standard RGB bitmap   bih.biBitcount = 8; // 8 bits-per-pixel format   bih.biSizeImage = 0;   bih.biXPelsPerMeter = bih.biYPelsPerMeter = 0;   bih.biClrUsed = bih.biClrImportant = 256;   hIC = ICLocate (ICTYPE_VIDEO, 0L, (LPBITMAPINFOHEADER) &bih,   NULL, ICMODE_COMPRESS); 
      

  3.   

    下面的例子定位一個壓縮器去壓縮一個8bitRGB 為 8bit RLE格式   BITMAPINFOHEADER bihIn, bihOut;   HIC hIC   // Initialize the bitmap structure.   biSize = bihOut.biSize = sizeof(BITMAPINFOHEADER);   bihIn.biWidth = bihIn.biHeight = bihOut.biWidth = bihOut.biHeight = 0;   bihIn.biPlanes = bihOut.biPlanes= 1;   bihIn.biCompression = BI_RGB; // standard RGB bitmap for input   bihOut.biCompression = BI_RLE8; // 8-bit RLE for output format   bihIn.biBitcount = bihOut.biBitCount = 8; // 8 bits-per-pixel format   bihIn.biSizeImage = bihOut.biSizeImage = 0;   bihIn.biXPelsPerMeter = bih.biYPelsPerMeter =   bihOut.biXPelsPerMeter = bihOut.biYPelsPerMeter = 0;   bihIn.biClrUsed = bih.biClrImportant =   bihOut.biClrUsed = bihOut.biClrImportant = 256;   hIC = ICLocate (ICTYPE_VIDEO, 0L,   (LPBITMAPINFOHEADER)&bihIn,   (LPBITMAPINFOHEADER)&bihOut, ICMODE_COMPRESS); 
      下面的函數完成一個安裝壓縮器:   // This function looks like a DriverProc entry point.   LRESULT MyCodecFunction(DWORD dwID, HDRVR hDriver,   UINT uiMessage, LPARAM lParam1, LPARAM lParam2);   // This function installs the MyCodecFunction as a compressor.   result = ICInstall ( ICTYPE_VIDEO, mmioFOURCC('s','a','m','p'),   (LPARAM)(FARPROC)&MyCodecFunction, NULL, ICINSTALL_FUNCTION);   BITMAPINFOHEADER bih;   HIC hIC   // Initialize the bitmap structure.   bih.biSize = sizeof(BITMAPINFOHEADER);   bih.biWidth = bih.biHeight = 0;   bih.biPlanes = 1;   bih.biCompression = BI_RGB; // standard RGB bitmap   bih.biBitcount = 8; // 8 bits-per-pixel format   bih.biSizeImage = 0;   bih.biXPelsPerMeter = bih.biYPelsPerMeter = 0;   bih.biClrUsed = bih.biClrImportant = 256;   hIC = ICLocate (ICTYPE_VIDEO, 0L, (LPBITMAPINFOHEADER) &bih,   NULL, ICMODE_COMPRESS); 
      下面的例子定位一個壓縮器去壓縮一個8bitRGB 為 8bit RLE格式  BITMAPINFOHEADER bihIn, bihOut;   HIC hIC   // Initialize the bitmap structure.   biSize = bihOut.biSize = sizeof(BITMAPINFOHEADER);   bihIn.biWidth = bihIn.biHeight = bihOut.biWidth = bihOut.biHeight = 0;   bihIn.biPlanes = bihOut.biPlanes= 1;   bihIn.biCompression = BI_RGB; // standard RGB bitmap for input   bihOut.biCompression = BI_RLE8; // 8-bit RLE for output format   bihIn.biBitcount = bihOut.biBitCount = 8; // 8 bits-per-pixel format   bihIn.biSizeImage = bihOut.biSizeImage = 0;   bihIn.biXPelsPerMeter = bih.biYPelsPerMeter =   bihOut.biXPelsPerMeter = bihOut.biYPelsPerMeter = 0;   bihIn.biClrUsed = bih.biClrImportant =   bihOut.biClrUsed = bihOut.biClrImportant = 256;   hIC = ICLocate (ICTYPE_VIDEO, 0L,   (LPBITMAPINFOHEADER)&bihIn,   (LPBITMAPINFOHEADER)&bihOut, ICMODE_COMPRESS);   下面的函數完成一個安裝壓縮器:  // This function looks like a DriverProc entry point.   LRESULT MyCodecFunction(DWORD dwID, HDRVR hDriver,   UINT uiMessage, LPARAM lParam1, LPARAM lParam2);   // This function installs the MyCodecFunction as a compressor.   result = ICInstall ( ICTYPE_VIDEO, mmioFOURCC('s','a','m','p'),   (LPARAM)(FARPROC)&MyCodecFunction, NULL, ICINSTALL_FUNCTION);   設置一個壓縮器的輸出格式:  view plaincopy to clipboardprint?  LPBITMAPINFOHEADER lpbiIn, lpbiOut;   // *lpbiIn must be initialized to the input format.   dwFormatSize = ICCompressGetFormatSize(hIC, lpbiIn);   h = GlobalAlloc(GHND, dwFormatSize);
    lpbiOut = (LPBITMAPINFOHEADER)GlobalLock(h);   ICCompressGetFormat(hIC, lpbiIn, lpbiOut);   LPBITMAPINFOHEADER lpbiIn, lpbiOut;   // *lpbiIn must be initialized to the input format.   dwFormatSize = ICCompressGetFormatSize(hIC, lpbiIn);   h = GlobalAlloc(GHND, dwFormatSize);   lpbiOut = (LPBITMAPINFOHEADER)GlobalLock(h);   ICCompressGetFormat(hIC, lpbiIn, lpbiOut); 
      

  4.   

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