[DirectShow有关问题]Windows Mobile平台,CameraCapture的Preview的有关问题
[DirectShow问题]Windows Mobile平台,CameraCapture的Preview的问题
背景:WM平台Camera程序开发:Windows Mobile SDK 6.0 Professional 包中的CameraCapture例子程序,这个例子程序是SDK的,我将它修改成MFC对话框工程。但是该程序没有预览功能,所以我要在它的基础上加上预览,主要修改了CGraphManager类的CreateCaptureGraphInternal函数和RunCaptureGraphInternal函数,然后自己加个自定义函数PreviewCaptureGraph用来预览。PreviewCaptureGraph函数是在主对话框类中调用间接调用的,不是像例子程序中那样什么都放到工作线程中(因为我发现放到线程中,函数会卡在pMediaControl->Run()处,所有我就自定义了PreviewCaptureGraph函数,改写了原来的RunCaptureGraphInternal()函数)
问题:现在可以预览,但是预览的效果如下所示:
PreviewCaptureGraph()函数中的CHK(pVideoWindow->SetWindowPosition(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top));这句调用没有作用,函数调用本身并没有失败,而且发现前面两个参数有效,即left和top有效,可以改变预览的left和top坐标位置。希望那个预览的窗口可以填充满那个CStatic控件区域(黑色边框那个)。
对DirectShow不了解,希望有做过或者开发过的兄弟指点一下~
背景:WM平台Camera程序开发:Windows Mobile SDK 6.0 Professional 包中的CameraCapture例子程序,这个例子程序是SDK的,我将它修改成MFC对话框工程。但是该程序没有预览功能,所以我要在它的基础上加上预览,主要修改了CGraphManager类的CreateCaptureGraphInternal函数和RunCaptureGraphInternal函数,然后自己加个自定义函数PreviewCaptureGraph用来预览。PreviewCaptureGraph函数是在主对话框类中调用间接调用的,不是像例子程序中那样什么都放到工作线程中(因为我发现放到线程中,函数会卡在pMediaControl->Run()处,所有我就自定义了PreviewCaptureGraph函数,改写了原来的RunCaptureGraphInternal()函数)
问题:现在可以预览,但是预览的效果如下所示:
PreviewCaptureGraph()函数中的CHK(pVideoWindow->SetWindowPosition(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top));这句调用没有作用,函数调用本身并没有失败,而且发现前面两个参数有效,即left和top有效,可以改变预览的left和top坐标位置。希望那个预览的窗口可以填充满那个CStatic控件区域(黑色边框那个)。
对DirectShow不了解,希望有做过或者开发过的兄弟指点一下~
- C/C++ code
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; }