16,548
社区成员




HRESULT CGraphManager::CreateCaptureGraphInternal()
{
HRESULT hr = S_OK;
CComVariant varCamName;
CPropertyBag PropBag;
OAEVENT oaEvent;
WCHAR wzDeviceName[MAX_PATH + 1] = {0};
CComPtr<IMediaEvent> pMediaEvent;
CComPtr<IGraphBuilder> pFilterGraph;
CComPtr<IBaseFilter> pVideoEncoder;
CComPtr<IBaseFilter> pASFMultiplexer;
CComPtr<IFileSinkFilter> pFileSinkFilter;
CComPtr<IPersistPropertyBag> pPropertyBag;
CComPtr<IDMOWrapperFilter> pWrapperFilter;
CComPtr<IBaseFilter> pImageSinkFilter;
//
// Create the capture graph builder and register the filtergraph manager.
//
CHK(m_pCaptureGraphBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder));
CHK(pFilterGraph.CoCreateInstance(CLSID_FilterGraph));
CHK(m_pCaptureGraphBuilder->SetFiltergraph(pFilterGraph));
//
// Create and initialize the video capture filter
//
CHK(m_pVideoCaptureFilter.CoCreateInstance(CLSID_VideoCapture));
CHK(m_pVideoCaptureFilter.QueryInterface(&pPropertyBag));
// We are loading the driver CAM1 in the video capture filter.
CHK(GetFirstCameraDriver(wzDeviceName, MAX_PATH));
varCamName = wzDeviceName;
if(varCamName.vt != VT_BSTR)
{
ERR(E_OUTOFMEMORY);
}
CHK(PropBag.Write(L"VCapName", &varCamName));
CHK(pPropertyBag->Load(&PropBag, NULL));
// Everything succeeded, the video capture filter is added to the filtergraph
CHK(pFilterGraph->AddFilter(m_pVideoCaptureFilter, L"Video Capture Filter Source" ));
//
// Third step: Create the video encoder DMO, load the WMV9 encoder, and
// add it to the graph
//
// Create the video encoder
CHK(pVideoEncoder.CoCreateInstance(CLSID_DMOWrapperFilter ));
CHK(pVideoEncoder.QueryInterface(&pWrapperFilter));
// Load the WMV9 DMO
CHK(pWrapperFilter->Init(CLSID_CWMV9EncMediaObject, DMOCATEGORY_VIDEO_ENCODER));
// Everything succeeded, let's add the encoder to the graph
CHK(pFilterGraph->AddFilter(pVideoEncoder, L"WMV9 DMO Encoder"));
//
// Create the ASF multiplexer and add it to the graph
//
CHK(m_pCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Asf, L"\\video1.asf", &pASFMultiplexer, &pFileSinkFilter));
// Create preview
CHK(m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, NULL));
//
// Connect the video capture filter, the encoder and the multiplexer together
//
CHK(m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCaptureFilter, pVideoEncoder, pASFMultiplexer));
//
// Create the still image filter, and connect it to the video capture filter
//
CHK(pImageSinkFilter.CoCreateInstance(CLSID_IMGSinkFilter));
CHK(pFilterGraph->AddFilter(pImageSinkFilter, L"Still image filter"));
CHK(m_pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_STILL, &MEDIATYPE_Video, m_pVideoCaptureFilter, NULL, pImageSinkFilter));
CHK(pImageSinkFilter.QueryInterface(&m_pImageSinkFilter));
//
// Prevent the data from flowing into the capture stream
//
CHK(m_pCaptureGraphBuilder->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCaptureFilter, 0, 0 ,0,0));
//
// Let's get the handle for DShow events. The main loop will listen to both notifications from
// the UI thread and for DShow notifications
//
CHK(pFilterGraph->QueryInterface(IID_IMediaEvent, (void**) &pMediaEvent));
CHK(pMediaEvent->GetEventHandle(&oaEvent));
m_handle[1] = (HANDLE) oaEvent;
m_bGraphBuilt = TRUE;
_CLEANUP:
if(FAILED(hr))
{
NotifyMessage(MESSAGE_ERROR, _T("Building the graph failed"));
}
return hr;
}
HRESULT CGraphManager::RunCaptureGraphInternal()
{
HRESULT hr = S_OK;
// CComPtr<IGraphBuilder> pGraphBuilder;
// CComPtr<IMediaControl> pMediaControl;
// Let's make sure that the graph has been initialized
if((NULL == m_pCaptureGraphBuilder) || (FALSE == m_bGraphBuilt))
{
ERR(E_FAIL);
}
// Retrieve the filtergraph off the capture graph builder
// CHK(m_pCaptureGraphBuilder->GetFiltergraph(&pGraphBuilder));
// Get the media control interface, and run the graph
// CHK(pGraphBuilder->QueryInterface(&pMediaControl));
// CHK(pMediaControl->Run());
CHK(NotifyMessage(MESSAGE_INFO, L"The Graph is Running ..."));
_CLEANUP:
if(FAILED(hr))
{
NotifyMessage(MESSAGE_ERROR, L"Running The Capture Graph Failed");
}
PostMessage(m_hWnd, MSG_EVENTNOTIFICATION, 0, 0); // 这里我发送一个自定义消息到主对话框,在主对话框类的消息响应函数中调用PreviewCaptureGraph()函数。
return hr;
}
HRESULT CGraphManager::PreviewCaptureGraph()
{
HRESULT hr = S_OK;
CComPtr<IGraphBuilder> pGraphBuilder;
CComPtr<IMediaControl> pMediaControl;
CComPtr<IVideoWindow> pVideoWindow;
// Let's make sure that the graph has been initialized
if((NULL == m_pCaptureGraphBuilder) || (FALSE == m_bGraphBuilt))
{
ERR(E_FAIL);
}
// Retrieve the filtergraph off the capture graph builder
CHK(m_pCaptureGraphBuilder->GetFiltergraph(&pGraphBuilder));
// Previewer
{
ASSERT(m_hWndPreviewer);
RECT rect = {0};
GetClientRect(m_hWndPreviewer, &rect);
CHK(pGraphBuilder->QueryInterface(&pVideoWindow));
CHK(pVideoWindow->put_Owner((OAHWND)m_hWndPreviewer));
CHK(pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN));
CHK(pVideoWindow->SetWindowPosition(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top));
// 这里无效,SetWindowPosition()中的最后两个参数宽度和高度似乎没起作用
CHK(pVideoWindow->put_Visible(OATRUE));
//CHK(pMediaControl->Run());
}
// Get the media control interface, and run the graph
CHK(pGraphBuilder->QueryInterface(&pMediaControl));
//CHK(pMediaControl->Stop());
CHK(pMediaControl->Run());
CHK(NotifyMessage(MESSAGE_INFO, L"The Graph is Running ..."));
_CLEANUP:
if(FAILED(hr))
{
NotifyMessage(MESSAGE_ERROR, L"Running The Capture Graph Failed");
}
return hr;
}