一个视频聊天程序,我安装了对应的编码器,能成功压缩,能接收到数据但不能成功解压,请大家帮忙修改下
相信需要改的地方不多,不要改变程序的整体模式,
改完测试成功后请发至邮箱[email protected]程序在地址http://e.ys168.com/?slmax
改完后400分相送。前面还有一贴。
相信需要改的地方不多,不要改变程序的整体模式,
改完测试成功后请发至邮箱[email protected]程序在地址http://e.ys168.com/?slmax
改完后400分相送。前面还有一贴。
解决方案 »
- 真邪门,单单不能捕获ALT键
- 如何将DBGRID数据导入到记事本中去,格式就像事件查看器导出的那种
- 请问窗口上的的各种初始化设置应该在OnActivate事件、OnCreate事件还是OnShow事件中???
- 向mengirl 道歉!
- 兄弟们,为什么?
- 在delphi中根据ComboBox1显示的数据库中楼盘名称的内容,取数据库select楼盘编号,并显示到edit中,这个代码怎么写?
- 感谢[email protected],来接分!!
- adoquery查詢不到產生錯誤怎么辦?
- 怎么改变Treeview一个节点的Text上某些文本的字体啊?
- 数据库入库
- 如何实现支持多语言、多环境的Delphi程序
- Delphi2010 引用IdStrings Debug时的crash
看了你的代碼,程序的關鍵在於視頻的壓縮和解壓縮部分,按照我的方式修改:
以下為視頻壓縮關鍵部分代碼: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的最後一個參數是壓縮後資料的大小.
先定義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);
下面的函數完成一個安裝壓縮器: // 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);