请问视频采集,使用ControlStream来控制,却没有采集到视频是怎么回事?

sunnylht 2008-08-21 04:31:10
用DirectShow做了一个双目的视频采集程序,就是采集一定时间的视频,但是一点击开始采
集按钮,那么就看到保存的采集文件是0KB,但是只要一关闭,那么这个视频文件就立刻
消失了,没有被保存下来。

我是用ControlStream()函数控制采集视频的时间长短的。

后来我用想是不是视频只是临时存放,然后用 hr = pBuilder->CopyCaptureFile
(wachSrcFile, wachDstFile,TRUE,NULL);把视频拷出来,但是也不行。因为视频的采集好
像就没有启动一样,一直是0KB。

之前我用的hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video, m_pBF, NULL, m_pMux);
来采集视频,都可以把文件保存起来的。
可是为了控制采集的时间,换了个ControlStream,却不能保存视频数据了,用法应该没有
问题。
感觉好像只有预览启动了,而采集没启动一样,我看了下预设的文件的采集容量总是0KB。

请问可有人知道这是什么原因?谢谢


程序及相关说明如下:

1、打开视频并采集视频的函数为:

HRESULT CCaptureVideo::CaptureVideo(int iDeviceID, HWND hWnd, LPCOLESTR
lpwstrFile)
{
HRESULT hr;
//初始化
hr = InitCaptureGraphBuilder();

if (FAILED(hr))
{
AfxMessageBox("Failed to get video interfaces!");
return hr;
}

// Bind Device Filter. We know the device because the id was passed in
if(!BindFilter(iDeviceID, &m_pBF))
return S_FALSE;

// 添加Filter到过滤器图标管理器中
hr = m_pGB->AddFilter(m_pBF, L"Capture Filter");

hr = m_pCapture->SetOutputFileName(&MEDIASUBTYPE_Avi, lpwstrFile,
&m_pMux,/*NULL*/&pSink);

if( FAILED( hr ) )
{
AfxMessageBox("Could not create/hookup mux and writer!");
return hr;
}

// 配置视频
hr = ConfigVideo();

if( FAILED( hr ) )
{
AfxMessageBox("Could not config video!");
return hr;
}

// Control the video capture stream.
REFERENCE_TIME rtStart = 10000000, rtStop = 40000000; //REFERENCE_TIME
100ns

//REFERENCE_TIME rtMax = MAXLONGLONG;

const WORD wStartCookie = 1, wStopCookie = 2; // Arbitrary values.



hr = m_pCapture->ControlStream(&PIN_CATEGORY_CAPTURE, // Pin
category.
&MEDIATYPE_Video, // Media type.
m_pBF, // Capture filter.
&rtStart, &rtStop, // Start and stop
times.
wStartCookie, wStopCookie // Values for
the start and stop events.
);


if( FAILED( hr ) )
{
AfxMessageBox("Could not render capture pin!");
return hr;
}

hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
m_pBF, NULL, NULL);


if( FAILED( hr ) )
{
AfxMessageBox("Could not render preview pin!");
return hr;
}


//设置视频捕捉窗口
m_hWnd = hWnd ;
SetupVideoWindow();



return 0;
}


2、InitCaptureGraphBuilder函数如下:

HRESULT CCaptureVideo::InitCaptureGraphBuilder()
{
HRESULT hr;

// 创建IGraphBuilder接口
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&m_pGB);

// 创建ICaptureGraphBuilder2接口
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC,
IID_ICaptureGraphBuilder2, (void **)
&m_pCapture);

if (FAILED(hr))
return hr;

m_pCapture->SetFiltergraph(m_pGB);

// 获取控制
hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
if (FAILED(hr))
return hr;

// 获取视频窗口
hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVW);
if (FAILED(hr))
return hr;


return hr;
}


3、BindFilter函数:

bool CCaptureVideo::BindFilter(int deviceId, IBaseFilter **pFilter)
{
if (deviceId < 0)
return false;

// enumerate all video capture devices
CComPtr <ICreateDevEnum> pCreateDevEnum;

HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void** )
&pCreateDevEnum);

if (hr != NOERROR)
{
return false;
}

CComPtr <IEnumMoniker> pEm;

hr = pCreateDevEnum->CreateClassEnumerator
(CLSID_VideoInputDeviceCategory, &pEm, 0);

if (hr != NOERROR)
{
return false;
}

pEm->Reset();

ULONG cFetched;
IMoniker *pM;
int index = 0;

while(hr = pEm -> Next(1, &pM, &cFetched), hr == S_OK, index <=
deviceId)
{
IPropertyBag *pBag;

hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)
&pBag);

if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);

if (hr == NOERROR)
{
if (index == deviceId)
{
pM->BindToObject(0, 0,
IID_IBaseFilter, (void**)pFilter);

return true; //
}

SysFreeString(var.bstrVal);

}

pBag->Release();
}

pM->Release();

// 增加计数
index++;

}

//return true;
return false;
}
...全文
403 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hust_9 2010-10-11
  • 打赏
  • 举报
回复
4楼的兄弟有QQ号么,我的277355665,我现在可以抓到一帧图像,就是不能先须的存储AVI视频,不知道该用directshow的哪几个filter来做这个事情
Sephoenix 2009-11-10
  • 打赏
  • 举报
回复
去年的问题了啊。。。。

我用ControlStream来做的时候,返回S_OK,但是一点效果都没。。。。

但是用IFileSinkFilter::SetFileName这个函数来做,就是换一个文件来录像,原来的文件自然停止录了也能保存

不知道ControlStream为什么没效果?

另外,整条线路停止和播放也能控制录像停止和开始,但是这样总是不太好
zhangzhx3 2008-10-03
  • 打赏
  • 举报
回复
楼主,刚我试验了一下,可以解决了。

hr = p_builder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pcap, NULL,pmux);
hr = p_builder->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pcap,
&rtStart, &rtStop, wStartCookie, wStopCookie);

你按照这个顺序试试,我原来就是顺序反了,一直不行,现在顺序调转了一下,可以了。
zhangzhx3 2008-10-03
  • 打赏
  • 举报
回复
我跟你遇到相同的问题,帮顶。
sunnylht 2008-08-25
  • 打赏
  • 举报
回复
没人回答啊?要不我提高分,呵呵~~~
sunnylht 2008-08-23
  • 打赏
  • 举报
回复
这个没有人知道吗?有没有人遇到类似问题的呢?

4,445

社区成员

发帖
与我相关
我的任务
社区描述
图形图像/机器视觉
社区管理员
  • 机器视觉
  • 迪菲赫尔曼
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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