📄 graphmanager.cpp
字号:
handle = FindFirstDevice( DeviceSearchByGuid, &guidCamera, &di );
if(( handle == NULL ) || ( di.hDevice == NULL ))
{
ERR( HRESULT_FROM_WIN32( GetLastError() ));
}
StringCchCopy( pwzName, MAX_PATH, di.szLegacyName );
Cleanup:
FindClose( handle );
return hr;
}
HRESULT
CGraphManager::CreateCaptureGraphInternal()
{
HRESULT hr = S_OK;
CComVariant varCamName;
CPropertyBag PropBag;
OAEVENT oaEvent;
WCHAR wzDeviceName[ MAX_PATH + 1 ];
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 ));
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 ));
//
// 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_fGraphBuilt = TRUE;
NotifyMessage( MESSAGE_ERROR, L"Builing the graph failed" );
Cleanup:
if( FAILED( hr ))
{
NotifyMessage( MESSAGE_ERROR, L"Builing 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(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt == FALSE ))
{
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"Runing the capture graph failed" );
}
return hr;
}
HRESULT
CGraphManager::StartCaptureVideoInternal()
{
HRESULT hr = S_OK;
LONGLONG dwStart = 0, dwEnd = 0;
WORD wStartCookie = 1, wEndCookie = 2;
CComPtr<IGraphBuilder> pGraphBuilder;
// Make sure that the capture graph builder is present
if(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt == FALSE ))
{
ERR( E_FAIL );
}
// Let's retrieve the event signaled by the filtergraph
CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pGraphBuilder ));
// To start the video capture, call ICaptureGraphBuilder2::ControlStream.
dwStart=0;
dwEnd=MAXLONGLONG;
CHK( m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, NULL, &dwStart, &dwEnd, wStartCookie, wEndCookie ));
CHK( NotifyMessage( MESSAGE_INFO, L"Capturing...." ));
Cleanup:
if( FAILED( hr ))
{
NotifyMessage( MESSAGE_ERROR, L"Starting the video recording failed" );
}
return hr;
}
HRESULT
CGraphManager::StopCaptureVideoInternal()
{
HRESULT hr = S_OK;
LONGLONG dwStart = 0, dwEnd = 0;
WORD wStartCookie = 1, wEndCookie = 2;
CComPtr<IGraphBuilder> pFilterGraph;
CComPtr<IMediaSeeking> pMediaSeeking;
CHK( m_pCaptureGraphBuilder->GetFiltergraph( &pFilterGraph ));
CHK( pFilterGraph->QueryInterface( &pMediaSeeking ));
// Stop the capture of the graph
dwStart = 0;
CHK( pMediaSeeking->GetCurrentPosition( &dwEnd ));
CHK( m_pCaptureGraphBuilder->ControlStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, NULL, &dwStart, &dwEnd, wStartCookie, wEndCookie ));
// The filtergraph will fire a EC_CONTROLSTREAM_STOPPED event once the capture of the video is completed
// The event will be caugth in the main loop and processed in the ProcessDshowEvents function
CHK( NotifyMessage( MESSAGE_INFO, L"Encoding file ..." ));
Cleanup:
if( FAILED( hr ))
{
NotifyMessage( MESSAGE_ERROR, L"Stopping the video recording failed" );
}
return hr;
}
HRESULT
CGraphManager::CaptureStillImageInternal()
{
HRESULT hr = S_OK;
CComPtr<IFileSinkFilter> pFileSink;
CComPtr<IUnknown> pUnkCaptureFilter;
CComPtr<IPin> pStillPin;
CComPtr<IAMVideoControl> pVideoControl;
if(( m_pCaptureGraphBuilder == NULL ) || ( m_fGraphBuilt == FALSE ))
{
ERR( E_FAIL );
}
CHK( m_pImageSinkFilter.QueryInterface( &pFileSink ));
CHK( pFileSink->SetFileName( L"\\test.jpg", NULL ));
CHK( m_pVideoCaptureFilter.QueryInterface( &pUnkCaptureFilter ));
CHK( m_pCaptureGraphBuilder->FindPin( pUnkCaptureFilter, PINDIR_OUTPUT, &PIN_CATEGORY_STILL, &MEDIATYPE_Video, FALSE, 0, &pStillPin ));
CHK( m_pVideoCaptureFilter.QueryInterface( &pVideoControl ));
CHK( pVideoControl->SetMode( pStillPin, VideoControlFlag_Trigger ));
Cleanup:
if( FAILED( hr ))
{
NotifyMessage( MESSAGE_ERROR, L"Capturing a still image failed" );
}
return hr;
}
HRESULT
CGraphManager::NotifyMessage( DSHOW_MESSAGE message, WCHAR *wzText )
{
HRESULT hr = S_OK;
Message *pMessage;
WCHAR *wzString;
if(( wzText == NULL ) || ( *wzText == NULL ))
{
ERR( E_POINTER );
}
if( m_hwnd == NULL )
{
return S_FALSE;
}
pMessage = (Message*) LocalAlloc( LMEM_ZEROINIT, sizeof( Message ));
if( pMessage == NULL )
{
ERR( E_OUTOFMEMORY );
}
wzString = (WCHAR*) LocalAlloc( LMEM_ZEROINIT, ( wcslen( wzText ) + 1 ) * sizeof( WCHAR ));
if( wzString == NULL )
{
ERR( E_OUTOFMEMORY );
}
StringCchCopy( wzString, wcslen( wzText ) + 1, wzText );
pMessage->wzMessage = wzString;
pMessage->dwMessage = message;
PostMessage( m_hwnd, WM_USER, 0, (LPARAM) pMessage );
Cleanup:
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -