请问视频采集,使用ControlStream来控制,却没有采集到视频是怎么回事?
用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;
}