我写了个视频采集和压缩的程序,但是在压缩那块有问题,麻烦高手帮忙看下代码,谢谢了。
变量如下 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方法初始化/////////////////////////////////////////////////////////////////////////////////////////////////
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;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
回调方法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;
}
录制按钮方法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的错误消息,麻烦各位了,谢谢了

解决方案 »

  1.   

    哈哈 一般 
    我也在用vfw搞个小东西 我也很多问题找不到解决....
      

  2.   

    可以交流下么,你实现压缩功能了么,不然它生成的avi 1帧就是1M多,那也太大了
      

  3.   

    继续添加问题,压缩的我自己解决了,现在我想实现一个这样的效果,我让VFW预览窗口在一个mediaplayer上,然后录制完后我想要mediaplayer回放,但是现在问题出来了,预览窗口结束后它不会显示mediaplayer控件,就是一块黑的在mediaplayer控件上面,覆盖了它,这个应该怎么解决呀,谢谢了
      

  4.   



    ::ShowWindow(m_hWndVideo,SW_HIDE);
      

  5.   

    您好啊!我现在也用这个写点东西。同样是压缩问题没解决啊?请问你现在还有那个源代码吗?能提供一份不?邮箱:[email protected]   万分感谢!