struct _capstuff {
IVideoWindow* pVidWin;
IGraphBuilder *pGraph;
IMediaControl *pMediaControl;
IMediaEventEx* pEvent;
IBasicVideo* pBV;
ICaptureGraphBuilder2* pBuilder;
CComPtr<ISampleGrabber> m_pGrabber;
IBaseFilter * pSrc;
IBaseFilter * pCompressFileter;
BOOL fPreview;
BOOL fCapture;
BOOL fAVI;
BOOL BindCaptureDevice;
BOOL BindCompressDevice;
IPin * pCapOut;
IPin * pGrabIn;
IPin * pGrabOut;
DWORD g_dwGraphRegister;
} gcap;
//初始化 ICaptureGraphBuilder2接口
BOOL CAviDlg::MakeBuilder()
{
if(gcap.pBuilder)
return TRUE;
HRESULT hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder2,
NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder2,
(void **)&gcap.pBuilder);
if (hr!=NOERROR)
{
AfxMessageBox("创建ICaptureGraphBuilder2失败 at MakeBuilder");
return FALSE;
}
// Associate the graph with the builder.
hr=gcap.pBuilder->SetFiltergraph(gcap.pGraph);
if (hr!=NOERROR)
{
AfxMessageBox("连接IGraphBuild - ICaptureGraphBuilder2失败 at MakeBuilder");
return FALSE;
}
return TRUE;
// return (hr == NOERROR) ? TRUE : FALSE;
}
//创建 IGaraphBuilder 接口
BOOL CAviDlg::MakeGraph()
{
if(gcap.pGraph)
return TRUE;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **)&gcap.pGraph);
return (hr == NOERROR) ? TRUE : FALSE;
}
void CAviDlg::EnumVideoInput(CComboBox *cb)
{
cb->ResetContent();
//列举 视频采集卡设备 并先中第一个视频采集设备
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker* pMoniker = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
(void**)&pSysDevEnum);
hr = pSysDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory, &pEnum, 0);
BOOL start=TRUE;
while (S_OK == pEnum->Next(1, &pMoniker, NULL))
{
IPropertyBag *pPropBag = NULL;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
VARIANT var;
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
if (SUCCEEDED(hr))
{
// LRESULT iSel = AddString(GetDlgItem(hDlg,
// IDC_CODEC_LIST), var.bstrVal);
CString str=var.bstrVal;
cb->AddString(str);
if(start)
{
MakeGraph();
MakeBuilder();
if(gcap.pSrc)
{
gcap.pSrc->Release();
gcap.pSrc=NULL;
}
hr=pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&gcap.pSrc);
if(SUCCEEDED(hr))
{
cb->SelectString(0,str);
start=FALSE;
gcap.pGraph->AddFilter(gcap.pSrc, L"Video Capture");
gcap.BindCaptureDevice=TRUE;
}
}
}
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
}
if (start)
AfxMessageBox("没有找到视频采集设备");
// SendDlgItemMessage(IDC_CODEC_LIST,LB_SETCURSEL, 0, 0);
pSysDevEnum->Release();
pEnum->Release();
}
BOOL CAviDlg::PreviewAndSaveVideo(HWND hWnd, HWND CtrlHwnd, CString szCaption, CRect rect)
{
HRESULT hr;
ClearUp();
if(!MakeGraph())
{
AfxMessageBox("创建IGraphBuilder失败 at PreviewAndSaveVideo");
return FALSE;
}
if(!MakeBuilder())
{
return FALSE;
}
EnumVideoInput((CComboBox*)GetDlgItem(IDC_INPUT_DEVICE));
if(!gcap.BindCaptureDevice)
{
AfxMessageBox("没有绑定视频采集设备 at PreviewAndSaveVideo");
return FALSE;
}
//存为视频文件
IBaseFilter *ppf = NULL;
IFileSinkFilter *pSink = NULL;
hr=gcap.pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, L"e:\\Example.avi", &ppf, &pSink);
if(FAILED(hr))
{
AfxMessageBox("创建视频文件失败 at PreviewAndSaveVideo");
return FALSE;
}
//创建回放、Render
hr=gcap.pBuilder->RenderStream(
&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video,
gcap.pSrc,
NULL, // No compression filter.
NULL // Default renderer.
);
if(FAILED(hr))
{
AfxMessageBox("创建视频回放Render失败 at PreviewAndSaveVideo");
return FALSE;
}
//创建视频保存到文件 Render
hr=gcap.pBuilder->RenderStream(
&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video,
gcap.pSrc,
NULL, // No compression filter.
ppf // Default renderer.
);
if(FAILED(hr))
{
AfxMessageBox("创建视频文件Render失败 at PreviewAndSaveVideo");
return FALSE;
}
/*
//set Capture Properties
IAMDroppedFrames *pDropped = NULL;
pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pSrc, IID_IAMDroppedFrames, (void **)&pDropped);
//控制视频播放
// IMediaControl *pControl;
REFERENCE_TIME rtStart = 0,
rtStop = MAX_TIME;
pBuilder->ControlStream(
&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video,
pSrc, // Source filter
&rtStart, // Start time
&rtStop, // Stop time
0, // Start cookie
0 // Stop cookie
);*/
hr=gcap.pGraph->QueryInterface(IID_IMediaControl, (void **)&gcap.pMediaControl);
if(FAILED(hr))
{
AfxMessageBox("创建IMediaControl失败 at PreviewAndSaveVideo");
return FALSE;
}
hr=gcap.pGraph->QueryInterface(IID_IVideoWindow, (void **)&gcap.pVidWin);
if(FAILED(hr))
{
AfxMessageBox("创建视频IVideoWindow失败 at PreviewAndSaveVideo");
return FALSE;
}
hr=gcap.pGraph->QueryInterface(IID_IBasicVideo,(void **)&gcap.pBV);
if(FAILED(hr))
{
AfxMessageBox("创建视频IBasicVideo失败 at PreviewAndSaveVideo");
return FALSE;
}
hr=gcap.pGraph->QueryInterface(IID_IMediaEventEx, (void **)&gcap.pEvent);
if(hr!=NOERROR)
{
AfxMessageBox("创建IMediaEventEx失败 at Play AVI");
return FALSE;
}
if(CtrlHwnd)
{
hr=gcap.pVidWin->put_Owner((OAHWND)CtrlHwnd);
gcap.pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
hr=gcap.pEvent->SetNotifyWindow((OAHWND)CtrlHwnd, WM_GRAPHNOTIFY, 0);
}
else
{
gcap.pVidWin->put_Caption(szCaption.AllocSysString());
}
gcap.pMediaControl->Run();
if( FAILED( hr ) )
{
AfxMessageBox("无法运行 Graph at Capture");
return FALSE;// hr;
}
gcap.fAVI=TRUE;
if( hWnd )
gcap.pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
if ((rect.Width()<=0) || (rect.Height()<=0))
{
long width,height;
gcap.pBV->GetVideoSize(&width,&height);
gcap.pVidWin->SetWindowPosition(0,0,width,height);
}
else
{
gcap.pVidWin->SetWindowPosition(rect.left,rect.top,rect.right,rect.bottom);
}
gcap.pVidWin->put_Visible(OATRUE);
return TRUE;
}
IVideoWindow* pVidWin;
IGraphBuilder *pGraph;
IMediaControl *pMediaControl;
IMediaEventEx* pEvent;
IBasicVideo* pBV;
ICaptureGraphBuilder2* pBuilder;
CComPtr<ISampleGrabber> m_pGrabber;
IBaseFilter * pSrc;
IBaseFilter * pCompressFileter;
BOOL fPreview;
BOOL fCapture;
BOOL fAVI;
BOOL BindCaptureDevice;
BOOL BindCompressDevice;
IPin * pCapOut;
IPin * pGrabIn;
IPin * pGrabOut;
DWORD g_dwGraphRegister;
} gcap;
//初始化 ICaptureGraphBuilder2接口
BOOL CAviDlg::MakeBuilder()
{
if(gcap.pBuilder)
return TRUE;
HRESULT hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder2,
NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder2,
(void **)&gcap.pBuilder);
if (hr!=NOERROR)
{
AfxMessageBox("创建ICaptureGraphBuilder2失败 at MakeBuilder");
return FALSE;
}
// Associate the graph with the builder.
hr=gcap.pBuilder->SetFiltergraph(gcap.pGraph);
if (hr!=NOERROR)
{
AfxMessageBox("连接IGraphBuild - ICaptureGraphBuilder2失败 at MakeBuilder");
return FALSE;
}
return TRUE;
// return (hr == NOERROR) ? TRUE : FALSE;
}
//创建 IGaraphBuilder 接口
BOOL CAviDlg::MakeGraph()
{
if(gcap.pGraph)
return TRUE;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
IID_IGraphBuilder, (void **)&gcap.pGraph);
return (hr == NOERROR) ? TRUE : FALSE;
}
void CAviDlg::EnumVideoInput(CComboBox *cb)
{
cb->ResetContent();
//列举 视频采集卡设备 并先中第一个视频采集设备
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker* pMoniker = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
(void**)&pSysDevEnum);
hr = pSysDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory, &pEnum, 0);
BOOL start=TRUE;
while (S_OK == pEnum->Next(1, &pMoniker, NULL))
{
IPropertyBag *pPropBag = NULL;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
VARIANT var;
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
if (SUCCEEDED(hr))
{
// LRESULT iSel = AddString(GetDlgItem(hDlg,
// IDC_CODEC_LIST), var.bstrVal);
CString str=var.bstrVal;
cb->AddString(str);
if(start)
{
MakeGraph();
MakeBuilder();
if(gcap.pSrc)
{
gcap.pSrc->Release();
gcap.pSrc=NULL;
}
hr=pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&gcap.pSrc);
if(SUCCEEDED(hr))
{
cb->SelectString(0,str);
start=FALSE;
gcap.pGraph->AddFilter(gcap.pSrc, L"Video Capture");
gcap.BindCaptureDevice=TRUE;
}
}
}
VariantClear(&var);
pPropBag->Release();
pMoniker->Release();
}
if (start)
AfxMessageBox("没有找到视频采集设备");
// SendDlgItemMessage(IDC_CODEC_LIST,LB_SETCURSEL, 0, 0);
pSysDevEnum->Release();
pEnum->Release();
}
BOOL CAviDlg::PreviewAndSaveVideo(HWND hWnd, HWND CtrlHwnd, CString szCaption, CRect rect)
{
HRESULT hr;
ClearUp();
if(!MakeGraph())
{
AfxMessageBox("创建IGraphBuilder失败 at PreviewAndSaveVideo");
return FALSE;
}
if(!MakeBuilder())
{
return FALSE;
}
EnumVideoInput((CComboBox*)GetDlgItem(IDC_INPUT_DEVICE));
if(!gcap.BindCaptureDevice)
{
AfxMessageBox("没有绑定视频采集设备 at PreviewAndSaveVideo");
return FALSE;
}
//存为视频文件
IBaseFilter *ppf = NULL;
IFileSinkFilter *pSink = NULL;
hr=gcap.pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, L"e:\\Example.avi", &ppf, &pSink);
if(FAILED(hr))
{
AfxMessageBox("创建视频文件失败 at PreviewAndSaveVideo");
return FALSE;
}
//创建回放、Render
hr=gcap.pBuilder->RenderStream(
&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video,
gcap.pSrc,
NULL, // No compression filter.
NULL // Default renderer.
);
if(FAILED(hr))
{
AfxMessageBox("创建视频回放Render失败 at PreviewAndSaveVideo");
return FALSE;
}
//创建视频保存到文件 Render
hr=gcap.pBuilder->RenderStream(
&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video,
gcap.pSrc,
NULL, // No compression filter.
ppf // Default renderer.
);
if(FAILED(hr))
{
AfxMessageBox("创建视频文件Render失败 at PreviewAndSaveVideo");
return FALSE;
}
/*
//set Capture Properties
IAMDroppedFrames *pDropped = NULL;
pBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pSrc, IID_IAMDroppedFrames, (void **)&pDropped);
//控制视频播放
// IMediaControl *pControl;
REFERENCE_TIME rtStart = 0,
rtStop = MAX_TIME;
pBuilder->ControlStream(
&PIN_CATEGORY_CAPTURE,
&MEDIATYPE_Video,
pSrc, // Source filter
&rtStart, // Start time
&rtStop, // Stop time
0, // Start cookie
0 // Stop cookie
);*/
hr=gcap.pGraph->QueryInterface(IID_IMediaControl, (void **)&gcap.pMediaControl);
if(FAILED(hr))
{
AfxMessageBox("创建IMediaControl失败 at PreviewAndSaveVideo");
return FALSE;
}
hr=gcap.pGraph->QueryInterface(IID_IVideoWindow, (void **)&gcap.pVidWin);
if(FAILED(hr))
{
AfxMessageBox("创建视频IVideoWindow失败 at PreviewAndSaveVideo");
return FALSE;
}
hr=gcap.pGraph->QueryInterface(IID_IBasicVideo,(void **)&gcap.pBV);
if(FAILED(hr))
{
AfxMessageBox("创建视频IBasicVideo失败 at PreviewAndSaveVideo");
return FALSE;
}
hr=gcap.pGraph->QueryInterface(IID_IMediaEventEx, (void **)&gcap.pEvent);
if(hr!=NOERROR)
{
AfxMessageBox("创建IMediaEventEx失败 at Play AVI");
return FALSE;
}
if(CtrlHwnd)
{
hr=gcap.pVidWin->put_Owner((OAHWND)CtrlHwnd);
gcap.pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
hr=gcap.pEvent->SetNotifyWindow((OAHWND)CtrlHwnd, WM_GRAPHNOTIFY, 0);
}
else
{
gcap.pVidWin->put_Caption(szCaption.AllocSysString());
}
gcap.pMediaControl->Run();
if( FAILED( hr ) )
{
AfxMessageBox("无法运行 Graph at Capture");
return FALSE;// hr;
}
gcap.fAVI=TRUE;
if( hWnd )
gcap.pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
if ((rect.Width()<=0) || (rect.Height()<=0))
{
long width,height;
gcap.pBV->GetVideoSize(&width,&height);
gcap.pVidWin->SetWindowPosition(0,0,width,height);
}
else
{
gcap.pVidWin->SetWindowPosition(rect.left,rect.top,rect.right,rect.bottom);
}
gcap.pVidWin->put_Visible(OATRUE);
return TRUE;
}