求教VFW只能捕获第一帧数据,后面的数据通过capSetCallbackOnVideoStream函数无法获得

huzhangyou 2007-03-16 07:46:04
部分代码如下:
LRESULT CALLBACK VideoCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr)
{

frm_View->ms->Clear();
frm_View->ms->Write(lpVHdr->lpData,lpVHdr->dwBufferLength);
frm_View->cs->Enter();
frm_View->pMemorySVec.push_back(frm_View->ms);
frm_View->cs->Leave();
frm_View->VST->Resume();
return (LRESULT)TRUE;
}
回调函数是启动VST线程,发送数据走

VFW的启动函数如下:

ghWndCap=capCreateCaptureWindow((LPSTR)"Capture Window",WS_CHILD|WS_VISIBLE,0,0,800,600,(HWND)Panel1->Handle,(int)0);
capPreviewRate(ghWndCap, 15); capSetCallbackOnVideoStream(ghWndCap, (FARPROC)VideoCallbackProc);

capDriverConnect(ghWndCap,0); capDriverGetCaps(ghWndCap,&gCapDriverCaps,sizeof(CAPDRIVERCAPS));

capPreview(ghWndCap, TRUE); //启动Preview模式
if(gCapDriverCaps.fHasOverlay) //检查驱动器是否有叠加能力
capOverlay(ghWndCap,TRUE); //启动Overlay模式
capCaptureSequenceNoFile(ghWndCap);
capPreview(ghWndCap, TRUE);
capPreviewScale(ghWndCap,false);


按照说法:
每获得一帧图象,应该是调用一次回调函数
可是我的Log报告显示只调用了一次回调函数!


大家看看有没有什么方法!

非常谢谢您的回复!
最好不要推荐我放弃现在的方案,使用DS或者DSPack
谢谢!
...全文
573 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
huzhangyou 2007-03-19
  • 打赏
  • 举报
回复
恩 谢谢 我已经搞定了
~~~~
constantine 2007-03-19
  • 打赏
  • 举报
回复
2年没搞忘的差不多了,
我以前写的跟你区别比较大。
我是采集数据到buffer,然后直接调用函数压缩buf里面的数据,然后发送。
所以压缩跟vfw采集一点关系都没有。
huzhangyou 2007-03-18
  • 打赏
  • 举报
回复
这段时间人好少啊
还是需要自己研究啊
大家感兴趣的可以看
http://www.libing.net.cn/read.php/1015.htm
huzhangyou 2007-03-18
  • 打赏
  • 举报
回复
分片已经好了
现在剩下的问题是压缩了:
为什么不成功:

bool __fastcall Tfrm_View::InitialCompressData()
{

int i_Return;
ZeroMemory(&cp,sizeof(cp));
cp.cbSize = sizeof(cp);
cp.dwFlags = ICMF_COMPVARS_VALID;
cp.cbState = 0;
cp.fccHandler = mmioFOURCC('x','v','i','d');
cp.fccType = ICTYPE_VIDEO;
cp.hic = ICOpen(cp.fccType,cp.fccHandler,ICMODE_COMPRESS);
if(cp.hic > 0){
//
i_OutFormatSize = ICCompressGetFormatSize(cp.hic,&bih.bmiHeader);
ICSeqCompressFrameStart(&cp, &bih);
i_Return = true;

}else{
i_Return = false;
MessageBox(NULL,"没有安装相应的解码器!","提示",MB_OK);
}
return i_Return;

}




LRESULT CALLBACK VideoCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr)
{

int b_KeyFrame;
long ul_OutSize;
ul_OutSize = frm_View->bih.bmiHeader.biSizeImage;
void *buf = new char[MAXSIZE];
buf = ICSeqCompressFrame(&frm_View->cp,0,lpVHdr->lpData,&b_KeyFrame,&ul_OutSize);

}

告诉我读写了xvidvfw.dll的非法内存!!!
郁闷哈!
huzhangyou 2007-03-17
  • 打赏
  • 举报
回复
to constantine(飘遥的安吉儿):
感谢光临

恩 我现在也分片发送
MTU开始我的确没有认识到
现在大概明白了
剩下的工作就是调用xvid了

直接调用四个函数的话不太方便
可以考虑使用DentistryDoctor(不在无聊中无奈,就在沉默中变态)的方法
使用ICLocate
我也大概明白了
只要注册了xvid
就能有一个guid
然后使用ICLocate就能定位编码器
压缩就可以了

constantine 2007-03-17
  • 打赏
  • 举报
回复
建议看看vediocap控件代码.
装了xvid,也好像要找到她的dll,然后使用她的函数吧
我以前用的是直接使用她提供的4个函数就行了,捕捉到数据,压缩后就发出去

传送不管你用TCP还是UDP都要考虑MTU的,不是只有udp要考虑.不然路由端都要帮你拆包会影响效率的,最后自定义的包接近MTU,这样做视频比较好.太小也不好.
huzhangyou 2007-03-16
  • 打赏
  • 举报
回复
还是不行
只能捕获第一帧的数据
后面的就没有了!
huzhangyou 2007-03-16
  • 打赏
  • 举报
回复
大概是不是这个意思:
安装xvid的vfw以后
使用ICLocate能够自动定位到xvid她的压缩函数执行压缩?
十分感谢!
huzhangyou 2007-03-16
  • 打赏
  • 举报
回复
回复:
udp如果大,就拆开


谢谢

压缩能请教一下吗?
xvid压缩!
我也编译了vfw的xvid库
应该如何使用还是没有明白!
感谢!
DentistryDoctor 2007-03-16
  • 打赏
  • 举报
回复
ZeroMemory(&m_cv, sizeof m_cv);
m_cv.cbSize = sizeof m_cv;
m_cv.dwFlags = ICMF_COMPVARS_VALID;
m_cv.fccType = ICTYPE_VIDEO;
m_cv.fccHandler = encodeParam->fccCodec;
m_cv.lKey = encodeParam->keyFramerate;
m_cv.lDataRate = encodeParam->bitrate; //Data rate, in kilobytes per second.
m_cv.lQ = encodeParam->quality; //1 to 10,000 or specify ICQUALITY_DEFAULT

m_cv.hic = ICLocate(m_cv.fccType, m_cv.fccHandler, m_pSrcFmt, NULL, ICMODE_COMPRESS);
if (m_cv.hic)
{
DWORD dwSize = ICCompressGetFormatSize(m_cv.hic, m_pSrcFmt);
m_pDestFmt = (BITMAPINFOHEADER*) m_bufDestFmt.GetBuf(dwSize);
ICCompressGetFormat(m_cv.hic, m_pSrcFmt, m_pDestFmt);
ICSeqCompressFrameStart(&m_cv, (BITMAPINFO*) m_pSrcFmt);
}
huzhangyou 2007-03-16
  • 打赏
  • 举报
回复
想继续请教一下
1:我下载了xvid并编译了代码,生成了lib以及dll
但是怎么也找不到入口如何进行压缩
直接使用xvid_enforce好像不行!

看到一段baidu的delphi代码:
zeromemory(@m_CV, sizeOf(TCOMPVARS));
m_CV.dwFlags := VFW.ICMF_COMPVARS_VALID;
m_CV.cbSize := sizeof(m_CV);
m_CV.cbState := 0;
m_CV.fccHandler := 859189837; // .H263 压缩 ,换别的请写VFW.mmioFOURCC('d', 'i', 'v', 'x');

还是不得其解!
还忘赐教一下如何使用xvid压缩!

2:还有传输的时候
使用的是UDP
因为udp包有最大的限制
请问应该如何处理!
如果超出大小的话!


再次感谢偶像级别人物的光临!
huzhangyou 2007-03-16
  • 打赏
  • 举报
回复
郁闷 刚才白写了
huzhangyou 2007-03-16
  • 打赏
  • 举报
回复
非常感谢偶像!
huzhangyou 2007-03-16
  • 打赏
  • 举报
回复
我测试一下
十分感谢偶像!DentistryDoctor(不在无聊中无奈,就在沉默中变态)
DentistryDoctor 2007-03-16
  • 打赏
  • 举报
回复
m_hVid = capCreateCaptureWindow(sName,WS_CHILD|WS_VISIBLE,rectDisp.left,rectDisp.top,rectDisp.Width(),rectDisp.Height(),m_hMainDlg, nWindowID);
CHECK_BOOL(capDriverConnect(m_hVid,id));
m_nFramerate = nFrameRate;

CAPDRIVERCAPS caps;
capDriverGetCaps(m_hVid, &caps, sizeof caps);
capPreviewRate(m_hVid, 40);
capPreviewScale(m_hVid, TRUE);
capOverlay(m_hVid, !g_bOverlayDisplay);

DWORD dwCompression = m_pFmt->biCompression;
capSetVideoFormat(m_hVid, m_pFmt, m_dwFmtSize);
m_dwFmtSize = capGetVideoFormatSize(m_hVid);
m_pFmt = (BITMAPINFOHEADER*) m_bufFmtSrc.GetBuf(m_dwFmtSize);
capGetVideoFormat(m_hVid, m_pFmt, m_dwFmtSize);
if (BI_RGB != m_pFmt->biCompression && BI_BITFIELDS != m_pFmt->biCompression)
m_pFmt->biCompression = dwCompression;
capCaptureGetSetup(m_hVid, &m_param, sizeof m_param);
m_param.dwRequestMicroSecPerFrame = 10000000L/nFrameRate;
m_param.fYield = TRUE;
m_param.fCaptureAudio = FALSE;
m_param.fLimitEnabled = FALSE;
m_param.vKeyAbort = 0;
m_param.fAbortLeftMouse = FALSE;
m_param.fAbortRightMouse = FALSE;
capCaptureSetSetup(m_hVid, &m_param, sizeof m_param);
AddToList();
capSetCallbackOnStatus(m_hVid, OnCapStatusCallback);
capSetCallbackOnVideoStream(m_hVid, OnCapVideoStreamCallback);
huzhangyou 2007-03-16
  • 打赏
  • 举报
回复
等看到如何解答以后
我就在下面公布地址
不算过分吧???

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧