VFW压缩AVI问题
我写了个视频采集和压缩的程序,但是在压缩那块有问题,麻烦高手帮忙看下代码,谢谢了。
变量如下
- C/C++ code
HIC hic; HWND m_hCapWnd; // 预示窗口 BOOL m_bInit; // 捕捉器初始化 CAPDRIVERCAPS m_CapDrvCap; // CAPDRIVERCAPS 结构,定义驱动器性能 CAPSTATUS m_CapStatus;// CAPSTATUS 结构,定义捕捉窗口当前状态 CAPTUREPARMS m_Parms;// CAPTURE PARMS 结构,定义捕捉参数 BITMAPINFO bmiFormat; //采集格式设置 DWORD VideoFormatSize; LPBITMAPINFO lpbinfo; //视频格式 ICCOMPRESSFRAMES VideoFrameInfo; //视频压缩信息结构 LPWSABUF pSourceDatabuf; COMPVARS cv; //视频压缩结构
OnInitDialog方法初始化
- C/C++ code
///////////////////////////////////////////////////////////////////////////////////////////////// m_bInit = FALSE; CWnd* pWnd = GetDlgItem(IDC_OCX1); CRect rect; pWnd->GetWindowRect(&rect); m_hCapWnd=capCreateCaptureWindow((LPTSTR)TEXT("视频捕捉测试程序"),WS_CHILD|WS_VISIBLE|WS_EX_CLIENTEDGE|WS_EX_DLGMODALFRAME,0,0,rect.Width(),rect.Width(),pWnd->GetSafeHwnd(),0); // 设置预示窗口 ASSERT(m_hCapWnd); if(capDriverConnect(m_hCapWnd,0)) { m_bInit = TRUE; capDriverGetCaps(m_hCapWnd,sizeof(CAPDRIVERCAPS),&m_CapDrvCap); if(m_CapDrvCap.fCaptureInitialized) { capGetStatus(m_hCapWnd,&m_CapStatus,sizeof(m_CapStatus)); capPreviewRate(m_hCapWnd,30); //设置预示帧数 capPreview(m_hCapWnd,TRUE); //设置预示方式 } else{// 初始化未成功 AfxMessageBox("视频捕捉卡初始化失败!"); AfxGetMainWnd()->PostMessage (WM_CLOSE); } } else{// 未能连接到驱动器 AfxMessageBox("与视频捕捉卡连接失败!"); AfxGetMainWnd()->PostMessage(WM_CLOSE); } ///////////////////////////////////////////////////////////////////////////////////////////////// /**初始化MPEG4压缩与解压缩器*/ int i; int fccType = 0; ICINFO info; CString strDriverName; for(i = 0;ICInfo(fccType,i,&info);i++) { hic = ICOpen(info.fccType,info.fccHandler,ICMODE_QUERY); ICGetInfo(hic,&info,sizeof(ICINFO)); strDriverName = CString(info.szDescription); ICClose(hic); if(strDriverName == "Microsoft MPEG-4 Video Codec V1") { cv.hic = ICOpen(info.fccType,info.fccHandler,ICMODE_FASTCOMPRESS); cv.dwFlags = ICMF_COMPVARS_VALID; cv.fccType = info.fccType; cv.fccHandler = info.fccHandler; cv.lDataRate = 6000; cv.lKey = 1; cv.lQ = 10000; break; } strDriverName = ""; }//////////////////////////////////////////////////////////////////// /***初始化视频压缩格式**/ cv.cbSize = sizeof(COMPVARS); VideoFormatSize = capGetVideoFormatSize(m_hCapWnd); lpbinfo = (LPBITMAPINFO)LocalAlloc(LPTR,VideoFormatSize); if(lpbinfo) { capGetVideoFormat(m_hCapWnd,lpbinfo,VideoFormatSize); } else return; VideoFormatSize = ICCompressGetFormatSize(cv.hic,lpbinfo); cv.lpbiOut = (LPBITMAPINFO)LocalAlloc(LPTR,VideoFormatSize); ICCompressGetFormat(cv.hic,lpbinfo,cv.lpbiOut); VideoFrameInfo.dwFlags = ICCOMPRESSFRAMES_PADDING; VideoFrameInfo.lpbiOutput = &(cv.lpbiOut->bmiHeader); VideoFrameInfo.lpbiInput = &(lpbinfo->bmiHeader); VideoFrameInfo.lStartFrame = 0; VideoFrameInfo.lQuality = ICGetDefaultQuality(cv.hic); VideoFrameInfo.lDataRate = 910; VideoFrameInfo.lKeyRate = 60; VideoFrameInfo.dwRate = 25*40; VideoFrameInfo.dwScale = 25; ICSendMessage(cv.hic,ICM_COMPRESS_FRAMES_INFO,(DWORD)(LPVOID)&VideoFrameInfo,sizeof(ICCOMPRESSFRAMES));///////////////////////////////////////////////////////////////////////////////////////////////// /***判断压缩支持**/ if(ICCompressQuery(cv.hic,lpbinfo,0)==ICERR_OK) { if(ICSeqCompressFrameStart(&cv,lpbinfo)==true) { capSetCallbackOnVideoStream(m_hCapWnd,&VideoCallBack); } } else { ICClose(cv.hic); cv.hic = NULL; AfxMessageBox(strDriverName+_T("系统视频压缩方式不支持"),MB_ICONINFORMATION|MB_OK); return; }/////////////////////////////////////////////////////////////////////////////////////////////////
回调方法
- C/C++ code
LRESULT CALLBACK VideoCallBack(HWND hwnd,LPVIDEOHDR lpd){ if(lpd->dwFlags&VHDR_DONE) { pSourceDatabuf->len = lpd->dwBufferLength; CopyMemory(pSourceDatabuf->buf,lpd->lpData,pSourceDatabuf->len); //开始视频压缩 void * pCompressData; BOOL lKey; long size; pCompressData = NULL; pCompressData = ICSeqCompressFrame(&cv,0,pSourceDatabuf->buf,&lKey,&size); if(pCompressData == NULL) return(LRESULT)FALSE; } return(LRESULT)FALSE;}录制按钮方法
- C/C++ code
BOOL CTHIRD::OnCapture() { CTime dntm; dntm=CTime::GetCurrentTime(); CString str=dntm.Format(("%Y-%m-%d %H-%M-%S")); CString path; path.Format("D:\\%s-%s\\%s.avi",id,Name,str);// capFileSetCaptureFile(m_hCapWnd,path.GetBuffer(255));////////////////////////////////////////////////////////////////////////// /***********采集设置与控制*****/ capGetVideoFormat(m_hCapWnd,&bmiFormat,sizeof(BITMAPINFO)); bmiFormat.bmiHeader.biBitCount = 24; bmiFormat.bmiHeader.biWidth = 352; bmiFormat.bmiHeader.biHeight = 288; bmiFormat.bmiHeader.biSizeImage = 0; capSetVideoFormat(m_hCapWnd,&bmiFormat,sizeof(BITMAPINFO));////////////////////////////////////////////////////////////////////////// capCaptureGetSetup(m_hCapWnd, &m_Parms,sizeof(m_Parms));// 得到设置参数 m_Parms.fYield = TRUE; m_Parms.fMakeUserHitOKToCapture = true; m_Parms.wPercentDropForError = 100; if(capCaptureSetSetup(m_hCapWnd, &m_Parms,sizeof(m_Parms))==TRUE) { BOOL suc=TRUE; suc=capCaptureSequence(m_hCapWnd); // 捕捉到文件 return suc; } capSetCallbackOnVideoStream(m_hCapWnd,&VideoCallBack); // capCaptureSequenceNoFile(m_hCapWnd); capFileSetCaptureFile(m_hCapWnd,path.GetBuffer(255)); pSourceDatabuf = new WSABUF; pSourceDatabuf->buf = new char[352*288*3];}基本功能就在这里,麻烦各位帮我看下,我如果去掉压缩的话可以正常采集到视频放在D盘,但是一加上压缩就会弹出个应用程序错误,什么什么内存不能written的错误消息,麻烦各位了,谢谢了
[解决办法]
- C/C++ code
::ShowWindow(m_hWndVideo,SW_HIDE);