http://leave001.blog.163.com/blog/static/162691293201232103611325/
最近因项目需要,研究了一下MS的camera框架。主要资料来源有:
a. MSDN:
b. 微软出版的一本书《Programming Microsoft DirectShow for Digital Video and Television》,电子书下载地址:
http://www.infoxa.com/asp/book_file/xxnr_book_3459.htm
c. 微软提供的wince camera测试程序,路径
PRIVATE\TEST\MULTIMEDIA\DIRECTX\DSHOW\CAMERA
1. 若干概念
Filter: Directshow中视频处理单元,分为Source Filter, Transform Filter, Renderer Filter
Pin: Filter的连接点。依靠Pin间的连接,若干Filter可以连接为一个Graph
Filter Graph: 由Filter组成的功能单元。视频数据依次经过各Filter进行处理。
DMO: DirectX Media Object。DMOWrapperFilter包含windows视频格式编码器。
2. Camera Framework框架
![Windows CE camera framework - leave - leave](http://img8.ph.126.net/fVH3zbx81oUr_XmjzUr0mA==/2745225447876459638.gif)
3. 列出camera设备
driverenumerator.cpp中CDriverEnumerator::Init中,根据传入的guid,创建MessageQueue,读取设备名,存放在字符串数组中。
hNotification = RequestDeviceNotifications(DriverGuid, hMsgQueue, TRUE);
dwWaitResult = WaitForSingleObject ( hMsgQueue, nMsgQueueTimout) ;
ReadMsgQueue( hMsgQueue, ddDeviceInformation, nMaxMessageSize, &dwBytesRead, nMsgQueueTimout, &dwFlags )
传入的guid为DEVCLASS_CAMERA_GUID,正如MSDN中所讲:
http://msdn.microsoft.com/en-us/library/ms940046.aspx
4. 创建Filter Graph
MS提供了ICaptureGraphBuilder2类,用来辅助创建IGraphBuilder。创建好两个对象后,用pBuild->SetFiltergraph(pGraph)来初始化Graph builder
CComPtr<ICaptureGraphBuilder2> m_pCaptureGraphBuilder;
CComPtr<IGraphBuilder> m_pGraph;
CoCreateComponents():
CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**) &m_pGraph );
hr = CoCreateInstance( CLSID_CaptureGraphBuilder, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**) &m_pCaptureGraphBuilder );
RenderGraph()
hr = m_pCaptureGraphBuilder->SetFiltergraph( m_pGraph );
CCaptureFramework类的Init函数中,先调用CoCreateComponents(),然后是RenderGraph()
MSDN参考:
http://msdn.microsoft.com/en-us/library/ms940047.aspx
5. 连接Filter
在RenderGraph中对三个Filter进行连接:
hr = m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pVideoCapture, m_pColorConverter, m_pVideoRenderer );
另外,对于录制和拍照的Filter的连接也是在该函数中处理的。
三个Filter都是在CoCreateComponents中通过CoCreateInstance创建:
CoCreateInstance( CLSID_VideoCapture, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**) &m_pVideoCapture );
MSDN参考:
http://msdn.microsoft.com/en-us/library/ms940045.aspx
6. 预览窗口
在RenderGraph中,put_Owner设置了视频窗口:
hr = m_pVideoWindow->put_Owner((OAHWND) m_hwndOwner);
m_hwndOwner为传入的Window句柄。m_pVideoWindow为AddInterfaces()中使用QueryInterface获取的Interface:
hr = m_pVideoRenderer.QueryInterface( &m_pVideoWindow );
7. 录制文件格式
hr = m_pCaptureGraphBuilder->SetOutputFileName( &m_clsidMux, VIDEO_CAPTURE_STATICFILE_NAME, &m_pMuxFilter, &m_pVideoFileSink );
返回m_pMuxFilter和m_pVideoFileSink。m_clsidMux为CLSID_ASFWriter,代表ASF格式。VIDEO_CAPTURE_STATICFILE_NAME为录制文件名。
m_pMuxFilter被连接到Filter Graph:
m_pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCapture, m_pVideoDMOWrapperFilter, m_pMuxFilter);