下载:DirectShow获取视频和音频数据
近段时间由于工作上的需要,大概看了下DirectShow,写了个小的demo,方便理解。以后在深入的学习下DirectShow。贴出代码。
对音频所做的处理如下图:
1. common.h文件
#ifndef __COMMON_H__ #define __COMMON_H__ #include <DShow.h> #include "qedit.h" #include <strsafe.h> #include <assert.h> #pragma comment(lib,"Strmiids.lib") //define release maco #define ReleaseInterface(x) \ if ( NULL != x ) \ { \ x->Release( ); \ x = NULL; \ } // Application-defined message to notify app of filter graph events #define WM_GRAPHNOTIFY WM_APP+100 void Msg(HWND hwnd,TCHAR *szFormat, ...); bool Bstr_Compare(BSTR bstrFilter,BSTR bstrDevice); #endif// __COMMON_H__
实现:
#include "common.h" void Msg(HWND hwnd,TCHAR *szFormat, ...) { TCHAR szBuffer[1024]; const size_t NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]); const int LASTCHAR = NUMCHARS - 1; va_list pArgs; va_start(pArgs, szFormat); (void)StringCchVPrintf(szBuffer, NUMCHARS - 1, szFormat, pArgs); va_end(pArgs); szBuffer[LASTCHAR] = TEXT('\0'); MessageBox(hwnd, szBuffer, TEXT("Message"), MB_OK | MB_ICONERROR); } bool Bstr_Compare(BSTR bstrFilter,BSTR bstrDevice) { bool flag = true; int strlenFilter = SysStringLen(bstrFilter); int strlenDevice = SysStringLen(bstrDevice); char* chrFilter = (char*)malloc(strlenFilter+1); char* chrDevice = (char*)malloc(strlenDevice+1); int j = 0; if (strlenFilter!=strlenDevice) flag = false; else { for(; j < strlenFilter;j++) { chrFilter[j] = (char)bstrFilter[j]; chrDevice[j] = (char)bstrDevice[j]; } chrFilter[strlenFilter] = '\0'; chrDevice[strlenDevice] = '\0'; for(j=0; j < strlenFilter;j++) { if(chrFilter[j] != chrDevice[j]) flag = false; } if(flag == true && j == strlenFilter-1) flag = true; } return flag; }
2.SampleGrabberCallback.h文件,由于截取视频图片,回调函数的实现
#ifndef __SAMPLEGRABBERCALLBACK_H__ #define __SAMPLEGRABBERCALLBACK_H__ #include "common.h" class SampleGrabberCallback : public ISampleGrabberCB { public: ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void** ppvObject); HRESULT STDMETHODCALLTYPE SampleCB(double Time, IMediaSample *pSample); HRESULT STDMETHODCALLTYPE BufferCB(double Time, BYTE *pBuffer, long BufferLen); SampleGrabberCallback(); BOOL SaveBitmap(BYTE * pBuffer, long lBufferSize ); //保存bitmap图片 public: BOOL m_bGetPicture; // is get a picture long m_lWidth; //存储图片的宽度 long m_lHeight; //存储图片的长度 int m_iBitCount; //the number of bits per pixel (bpp) TCHAR m_chTempPath[MAX_PATH]; TCHAR m_chSwapStr[MAX_PATH]; TCHAR m_chDirName[MAX_PATH]; }; #endif //__SAMPLEGRABBERCALLBACK_H__
#include "SampleGrabberCallback.h" SampleGrabberCallback::SampleGrabberCallback() { m_bGetPicture = FALSE; //Get template path GetTempPath(MAX_PATH,m_chTempPath); StringCchCat(m_chTempPath,MAX_PATH,TEXT("NTKOCapturePic")); CreateDirectory(m_chTempPath,NULL); } ULONG STDMETHODCALLTYPE SampleGrabberCallback::AddRef() { return 1; } ULONG STDMETHODCALLTYPE SampleGrabberCallback::Release() { return 2; } HRESULT STDMETHODCALLTYPE SampleGrabberCallback::QueryInterface(REFIID riid,void** ppvObject) { if (NULL == ppvObject) return E_POINTER; if (riid == __uuidof(IUnknown)) { *ppvObject = static_cast<IUnknown*>(this); return S_OK; } if (riid == IID_ISampleGrabberCB) { *ppvObject = static_cast<ISampleGrabberCB*>(this); return S_OK; } return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SampleGrabberCallback::SampleCB(double Time, IMediaSample *pSample) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SampleGrabberCallback::BufferCB(double Time, BYTE *pBuffer, long BufferLen) { if(FALSE == m_bGetPicture) //判断是否需要截图 return S_FALSE; if(!pBuffer) return E_POINTER; SaveBitmap(pBuffer,BufferLen); m_bGetPicture = FALSE; return S_OK; } BOOL SampleGrabberCallback::SaveBitmap(BYTE * pBuffer, long lBufferSize ) { SYSTEMTIME sysTime; GetLocalTime(&sysTime); StringCchCopy(m_chSwapStr,MAX_PATH,m_chTempPath); StringCchPrintf(m_chDirName,MAX_PATH,TEXT("\\%04i%02i%02i%02i%02i%02i%03ione.bmp"), sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour, sysTime.wMinute,sysTime.wSecond,sysTime.wMilliseconds); StringCchCat(m_chSwapStr,MAX_PATH,m_chDirName); //MessageBox(NULL,chTempPath,TEXT("Message"),MB_OK); //create picture file HANDLE hf = CreateFile(m_chSwapStr,GENERIC_WRITE,FILE_SHARE_WRITE,NULL, CREATE_ALWAYS,0,NULL); if(hf == INVALID_HANDLE_VALUE) { return E_FAIL; } BITMAPFILEHEADER bfh; //Set bitmap header ZeroMemory(&bfh,sizeof(bfh)); bfh.bfType = 'MB'; bfh.bfSize = sizeof(bfh) + lBufferSize + sizeof(BITMAPFILEHEADER); bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPFILEHEADER); // Write the file header. DWORD dwWritten = 0; WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL ); // Write the file Format BITMAPINFOHEADER bih; ZeroMemory(&bih,sizeof(bih)); bih.biSize = sizeof( bih ); bih.biWidth = m_lWidth; bih.biHeight = m_lHeight; bih.biPlanes = 1; bih.biBitCount = m_iBitCount; //Specifies the number of bits per pixel (bpp) WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL ); //Write the file Data WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL ); CloseHandle( hf ); return 0; }
#ifndef __CAPTUREVIDEO_H__ #define __CAPTUREVIDEO_H__ #include "SampleGrabberCallback.h" class CaptureVideo { public: CaptureVideo(); ~CaptureVideo(); HRESULT InitializeEnv(); //initialize environment HRESULT EnumAllDevices(HWND hCombox); //Enumeration all devices void CloseInterface(); //close all interface HRESULT OpenDevice(int deviceID, LONG nLeft, LONG nTop, LONG nWide, LONG nHeight); HRESULT BindFilter(int deviceID, IBaseFilter **pBaseFilter); HRESULT SetupVideoWindow(LONG nLeft, LONG nTop, LONG nWidth, LONG nHeight); void ResizeVideoWindow(LONG nLeft, LONG nTop, LONG nWidth, LONG nHeight); void GrabOneFrame(BOOL bGrab); // use ISampleGrabberCallbackCB get a picture HRESULT HandleGraphCapturePicture(void); //capture picture use GetCurrentBuffer private: IGraphBuilder *m_pGraphBuilder; ICaptureGraphBuilder2 *m_pCaptureGB; IMediaControl *m_pMediaControl; IBaseFilter *m_pDevFilter; ISampleGrabber *m_pSampGrabber; IMediaEventEx *m_pMediaEvent; public: int m_nCaptureDeviceNumber; //Device Count //vector<string> m_vecCapDeviceName; //the Device name TCHAR m_pCapDeviceName[10][MAX_PATH]; //the Device name HWND m_App; BOOL m_bGetOneShot; BOOL m_bConnect; IVideoWindow *m_pVideoWindow; }; #endif //__CAPTUREVIDEO_H__
#include "CaptureVideo.h" SampleGrabberCallback g_sampleGrabberCB; //CallBack CaptureVideo::CaptureVideo() { //COM Library Initialize if (FAILED(CoInitialize(NULL))) { Msg(m_App,TEXT("CoInitialize Failed!\r\n")); return; } //initialize member variable m_nCaptureDeviceNumber = 0; m_pDevFilter = NULL; m_pCaptureGB = NULL; m_pGraphBuilder = NULL; m_pMediaControl = NULL; m_pMediaEvent = NULL; m_pSampGrabber = NULL; m_pVideoWindow = NULL; m_App = NULL; m_bGetOneShot = FALSE; m_bConnect = FALSE; InitializeEnv(); } CaptureVideo::~CaptureVideo() { CloseInterface(); CoUninitialize(); } HRESULT CaptureVideo::EnumAllDevices(HWND hCombox) { if (!hCombox) return S_FALSE; ICreateDevEnum *pDevEnum; IEnumMoniker *pEnumMon; IMoniker *pMoniker; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,(LPVOID*)&pDevEnum); if (SUCCEEDED(hr)) { hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumMon, 0); if (hr == S_FALSE) { hr = VFW_E_NOT_FOUND; return hr; } pEnumMon->Reset(); ULONG cFetched; while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK) { IPropertyBag *pProBag; hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag); if (SUCCEEDED(hr)) { VARIANT varTemp; varTemp.vt = VT_BSTR; hr = pProBag->Read(L"FriendlyName",&varTemp,NULL); if (SUCCEEDED(hr)) { //int nStrSize = WideCharToMultiByte(CP_ACP,0,varTemp.bstrVal,-1,0,0,NULL,FALSE); //char *strName = new char[nStrSize]; //WideCharToMultiByte(CP_ACP,0,varTemp.bstrVal,-1,strName,nStrSize,NULL,FALSE); //m_vecCapDeviceName.push_back(string(strName)); //push the device name to vector StringCchCopy(m_pCapDeviceName[m_nCaptureDeviceNumber],MAX_PATH,varTemp.bstrVal); m_nCaptureDeviceNumber++; //Device number add 1 ::SendMessage(hCombox, CB_ADDSTRING, 0,(LPARAM)varTemp.bstrVal); SysFreeString(varTemp.bstrVal); } pProBag->Release(); } pMoniker->Release(); } pEnumMon->Release(); } return hr; } HRESULT CaptureVideo::InitializeEnv() { HRESULT hr; //Create the filter graph hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER, IID_IGraphBuilder,(LPVOID*)&m_pGraphBuilder); if(FAILED(hr)) return hr; //Create the capture graph builder hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,(LPVOID*)&m_pCaptureGB); if(FAILED(hr)) return hr; //Obtain interfaces for media control and Video Window hr = m_pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID*)&m_pMediaControl); if(FAILED(hr)) return hr; hr = m_pGraphBuilder->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVideoWindow); if(FAILED(hr)) return hr; hr = m_pGraphBuilder->QueryInterface(IID_IMediaEventEx,(LPVOID*)&m_pMediaEvent); if(FAILED(hr)) return hr; hr = m_pMediaEvent->SetNotifyWindow((OAHWND)m_App,WM_GRAPHNOTIFY,0); if(FAILED(hr)) return hr; m_pCaptureGB->SetFiltergraph(m_pGraphBuilder); if(FAILED(hr)) return hr; return hr; } void CaptureVideo::CloseInterface() { m_bGetOneShot = FALSE; if (m_pMediaControl) m_pMediaControl->Stop(); if(m_pVideoWindow) { m_pVideoWindow->get_Visible(FALSE); m_pVideoWindow->put_Owner(NULL); } if(m_pMediaEvent) m_pMediaEvent->SetNotifyWindow(NULL,WM_GRAPHNOTIFY,0); //release interface ReleaseInterface(m_pDevFilter); ReleaseInterface(m_pCaptureGB); ReleaseInterface(m_pGraphBuilder); ReleaseInterface(m_pMediaControl); ReleaseInterface(m_pMediaEvent); ReleaseInterface(m_pSampGrabber); ReleaseInterface(m_pVideoWindow); } HRESULT CaptureVideo::BindFilter(int deviceID, IBaseFilter **pBaseFilter) { ICreateDevEnum *pDevEnum; IEnumMoniker *pEnumMon; IMoniker *pMoniker; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,(LPVOID*)&pDevEnum); if (SUCCEEDED(hr)) { hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumMon, 0); if (hr == S_FALSE) { hr = VFW_E_NOT_FOUND; return hr; } pEnumMon->Reset(); ULONG cFetched; int index = 0; while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK, index<= deviceID) { IPropertyBag *pProBag; hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag); if (SUCCEEDED(hr)) { if (index == deviceID) { pMoniker->BindToObject(0,0,IID_IBaseFilter,(LPVOID*)pBaseFilter); } } pMoniker->Release(); index++; } pEnumMon->Release(); } return hr; } HRESULT CaptureVideo::SetupVideoWindow(LONG nLeft, LONG nTop, LONG nWidth, LONG nHeight) { HRESULT hr; hr = m_pVideoWindow->put_Owner((OAHWND)m_App); if (FAILED(hr)) return hr; hr = m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN); if(FAILED(hr)) return hr; ResizeVideoWindow(nLeft,nTop,nWidth,nHeight); hr = m_pVideoWindow->put_Visible(OATRUE); if(FAILED(hr)) return hr; return hr; } void CaptureVideo::ResizeVideoWindow(LONG nLeft, LONG nTop, LONG nWidth, LONG nHeight) { if(m_pVideoWindow) { m_pVideoWindow->SetWindowPosition(nLeft,nTop,nWidth,nHeight); } } HRESULT CaptureVideo::OpenDevice(int deviceID, LONG nLeft, LONG nTop, LONG nWide, LONG nHeight) { HRESULT hr; IBaseFilter *pSampleGrabberFilter; if (m_bConnect) { CloseInterface(); InitializeEnv(); } hr = CoCreateInstance(CLSID_SampleGrabber,NULL,CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID*)&pSampleGrabberFilter); if(FAILED(hr)) return hr; //bind device filter hr = BindFilter(deviceID,&m_pDevFilter); if (FAILED(hr)) return hr; hr = m_pGraphBuilder->AddFilter(m_pDevFilter,L"Video Filter"); if (FAILED(hr)) return hr; hr = m_pGraphBuilder->AddFilter(pSampleGrabberFilter,L"Sample Grabber"); if (FAILED(hr)) return hr; hr = pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber,(LPVOID*)&m_pSampGrabber); if(FAILED(hr)) return hr; //set media type AM_MEDIA_TYPE mediaType; ZeroMemory(&mediaType,sizeof(AM_MEDIA_TYPE)); //Find the current bit depth HDC hdc=GetDC(NULL); int iBitDepth=GetDeviceCaps(hdc, BITSPIXEL); g_sampleGrabberCB.m_iBitCount = iBitDepth; ReleaseDC(NULL,hdc); //Set the media type mediaType.majortype = MEDIATYPE_Video; switch(iBitDepth) { case 8: mediaType.subtype=MEDIASUBTYPE_RGB8; break; case 16: mediaType.subtype=MEDIASUBTYPE_RGB555; break; case 24: mediaType.subtype=MEDIASUBTYPE_RGB24; break; case 32: mediaType.subtype=MEDIASUBTYPE_RGB32; break; default: return E_FAIL; } mediaType.formattype = FORMAT_VideoInfo; hr = m_pSampGrabber->SetMediaType(&mediaType); hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video, m_pDevFilter,pSampleGrabberFilter,NULL); if(FAILED(hr)) return hr; hr = m_pSampGrabber->GetConnectedMediaType(&mediaType); if(FAILED(hr)) return hr; VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mediaType.pbFormat; g_sampleGrabberCB.m_lWidth = vih->bmiHeader.biWidth; g_sampleGrabberCB.m_lHeight = vih->bmiHeader.biHeight; // Configure the Sample Grabber hr = m_pSampGrabber->SetOneShot(FALSE); if (FAILED(hr)) return hr; hr = m_pSampGrabber->SetBufferSamples(TRUE); if (FAILED(hr)) return hr; // 1 = Use the BufferCB callback method. hr = m_pSampGrabber->SetCallback(&g_sampleGrabberCB,1); //set capture video Window SetupVideoWindow(nLeft,nTop,nWide,nHeight); hr = m_pMediaControl->Run(); if(FAILED(hr)) return hr; if (mediaType.cbFormat != 0) { CoTaskMemFree((PVOID)mediaType.pbFormat); mediaType.cbFormat = 0; mediaType.pbFormat = NULL; } if (mediaType.pUnk != NULL) { mediaType.pUnk->Release(); mediaType.pUnk = NULL; } m_bConnect = TRUE; return hr; } void CaptureVideo::GrabOneFrame(BOOL bGrab) { m_bGetOneShot = bGrab; g_sampleGrabberCB.m_bGetPicture = bGrab; } HRESULT CaptureVideo::HandleGraphCapturePicture(void) { ////////////////////////////////////////////////////////////////////////// HRESULT hr; long evCode = 0; long lBufferSize = 0; BYTE *p; hr = m_pMediaEvent->WaitForCompletion(INFINITE, &evCode); // if (SUCCEEDED(hr)) { switch(evCode) { case EC_COMPLETE: m_pSampGrabber->GetCurrentBuffer(&lBufferSize, NULL); p = new BYTE[lBufferSize]; m_pSampGrabber->GetCurrentBuffer(&lBufferSize, (LONG*)p);// get Current buffer g_sampleGrabberCB.SaveBitmap(p,lBufferSize); //save bitmap break; default: break; } } ////////////////////////////////////////////////////////////////////////// return hr; }
#ifndef __CAPTUREAUDIO_H__ #define __CAPTUREAUDIO_H__ #include "common.h" class CaptureAudio { public: CaptureAudio(); ~CaptureAudio(); HRESULT InitializeEnv(); //initialize environment HRESULT EnumAllDevices(HWND hCombox); //Enumeration all devices void CloseInterface(); //close all interface HRESULT OpenDevice(BSTR bstrDeviceName); HRESULT BindDeviceFilter(BSTR deviceName,GUID DEVICE_CLSID,IBaseFilter **pBaseFilter); HRESULT DeviceConnect(IBaseFilter* pInputDevice,IBaseFilter* pOutputDevice, BSTR bstrInputPin, BSTR bstrOutputDevice); private: IGraphBuilder *m_pGraphBuilder; ICaptureGraphBuilder2 *m_pCaptureGB; IBaseFilter *m_pDevFilter; IMediaControl *m_pMediaContrl; public: int m_nCaptureDeviceNumber; //Device Count //vector<string> m_vecCapDeviceName; //the Device name TCHAR m_pCapDeviceName[10][MAX_PATH]; //the Device name TCHAR m_pRendererDeviceName[10][MAX_PATH]; // Render Device name HWND m_App; }; #endif //__CAPTUREAUDIO_H__
#include "CaptureAudio.h" CaptureAudio::CaptureAudio() { //COM Library Initialize if (FAILED(CoInitialize(NULL))) { Msg(m_App,TEXT("CoInitialize Failed!\r\n")); return; } //initialize member variable m_nCaptureDeviceNumber = 0; m_pDevFilter = NULL; m_pCaptureGB = NULL; m_pGraphBuilder = NULL; m_pMediaContrl = NULL; m_App = NULL; InitializeEnv(); } CaptureAudio::~CaptureAudio() { CloseInterface(); CoUninitialize(); } HRESULT CaptureAudio::EnumAllDevices(HWND hCombox) { if (!hCombox) return S_FALSE; ICreateDevEnum *pDevEnum; IEnumMoniker *pEnumMon; IMoniker *pMoniker; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,(LPVOID*)&pDevEnum); if (SUCCEEDED(hr)) { // get all Audio input Device Friendly Name hr = pDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory,&pEnumMon, 0); if (hr == S_FALSE) { hr = VFW_E_NOT_FOUND; return hr; } pEnumMon->Reset(); ULONG cFetched; while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK) { IPropertyBag *pProBag; hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag); if (SUCCEEDED(hr)) { VARIANT varTemp; varTemp.vt = VT_BSTR; hr = pProBag->Read(L"FriendlyName",&varTemp,NULL); if (SUCCEEDED(hr)) { //int nStrSize = WideCharToMultiByte(CP_ACP,0,varTemp.bstrVal,-1,0,0,NULL,FALSE); //char *strName = new char[nStrSize]; //WideCharToMultiByte(CP_ACP,0,varTemp.bstrVal,-1,strName,nStrSize,NULL,FALSE); //m_vecCapDeviceName.push_back(string(strName)); //push the device name to vector StringCchCopy(m_pCapDeviceName[m_nCaptureDeviceNumber],MAX_PATH,varTemp.bstrVal); m_nCaptureDeviceNumber++; //Device number add 1 ::SendMessage(hCombox, CB_ADDSTRING, 0,(LPARAM)varTemp.bstrVal); SysFreeString(varTemp.bstrVal); } pProBag->Release(); } pMoniker->Release(); } pEnumMon->Release(); //get All Audio Renderer Device Friendly Name hr = pDevEnum->CreateClassEnumerator(CLSID_AudioRendererCategory,&pEnumMon, 0); if (hr == S_FALSE) { hr = VFW_E_NOT_FOUND; return hr; } pEnumMon->Reset(); int index = 0; while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK) { IPropertyBag *pProBag; hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag); if (SUCCEEDED(hr)) { VARIANT varTemp; varTemp.vt = VT_BSTR; hr = pProBag->Read(L"FriendlyName",&varTemp,NULL); if (SUCCEEDED(hr)) { StringCchCopy(m_pRendererDeviceName[index],MAX_PATH,varTemp.bstrVal); index++; //Device number add 1 SysFreeString(varTemp.bstrVal); } pProBag->Release(); } pMoniker->Release(); } pEnumMon->Release(); } return hr; } HRESULT CaptureAudio::InitializeEnv() { HRESULT hr; //Create the filter graph hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER, IID_IGraphBuilder,(LPVOID*)&m_pGraphBuilder); if(FAILED(hr)) return hr; //Create the capture graph builder hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,(LPVOID*)&m_pCaptureGB); if(FAILED(hr)) return hr; hr = m_pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID*)&m_pMediaContrl); if(FAILED(hr)) return hr; m_pCaptureGB->SetFiltergraph(m_pGraphBuilder); if(FAILED(hr)) return hr; return hr; } void CaptureAudio::CloseInterface() { if (m_pMediaContrl) m_pMediaContrl->Stop(); //release interface ReleaseInterface(m_pDevFilter); ReleaseInterface(m_pCaptureGB); ReleaseInterface(m_pGraphBuilder); ReleaseInterface(m_pMediaContrl); } HRESULT CaptureAudio::OpenDevice(BSTR bstrDeviceName) { HRESULT hr; IBaseFilter *pWaveDest = NULL, *pWriter = NULL, *pOutputDev = NULL; IFileSinkFilter *pSink= NULL; BSTR bstrTempDeviceName; BSTR bstrOutPin,bstrInPin; IBaseFilter *pPinTeeFilter = NULL; hr = BindDeviceFilter(bstrDeviceName,CLSID_AudioInputDeviceCategory, &m_pDevFilter); if (FAILED(hr)) return hr; // Add the audio capture filter to the filter graph. hr = m_pGraphBuilder->AddFilter(m_pDevFilter, L"Capture"); if (FAILED(hr)) return hr; /************************************************************************/ /* Audio Prieview */ /************************************************************************/ bstrTempDeviceName = SysAllocString(L"Infinite Pin Tee Filter"); hr = BindDeviceFilter(bstrTempDeviceName,CLSID_LegacyAmFilterCategory,&pPinTeeFilter); if (FAILED(hr)) return hr; hr = m_pGraphBuilder->AddFilter(pPinTeeFilter,bstrTempDeviceName); bstrInPin = SysAllocString(L"Capture"); bstrOutPin = SysAllocString(L"Input"); hr = DeviceConnect(m_pDevFilter,pPinTeeFilter,bstrInPin,bstrOutPin); if(FAILED(hr)) return hr; ////////////////////////////////////////////////////////////////////////// // output the Rendered Device SysReAllocString(&bstrTempDeviceName,m_pRendererDeviceName[0]); //Rendered Device Name; hr = BindDeviceFilter(bstrTempDeviceName,CLSID_AudioRendererCategory,&pOutputDev); if(FAILED(hr)) return hr; hr = m_pGraphBuilder->AddFilter(pOutputDev,bstrTempDeviceName); if(FAILED(hr)) return hr; SysReAllocString(&bstrInPin,L"Output1"); SysReAllocString(&bstrOutPin,L"Audio Input pin (rendered)"); hr = DeviceConnect(pPinTeeFilter,pOutputDev,bstrInPin,bstrOutPin); if(FAILED(hr)) return hr; ////////////////////////////////////////////////////////////////////////// //Add AudioRecorder WAV Dest SysReAllocString(&bstrTempDeviceName,TEXT("AudioRecorder WAV Dest")); hr = BindDeviceFilter(bstrTempDeviceName,CLSID_LegacyAmFilterCategory, &pWaveDest); if (FAILED(hr)) return hr; hr = m_pGraphBuilder->AddFilter(pWaveDest,bstrTempDeviceName); if (FAILED(hr)) return hr; //Connect the AudioRecorder WAV Dest SysReAllocString(&bstrInPin,L"Output2"); SysReAllocString(&bstrOutPin,L"In"); hr = DeviceConnect(pPinTeeFilter,pWaveDest,bstrInPin,bstrOutPin); if (FAILED(hr)) return hr; // output Filter Wirter SysReAllocString(&bstrTempDeviceName,L"File writer"); hr = BindDeviceFilter(bstrTempDeviceName,CLSID_LegacyAmFilterCategory,&pWriter); if (FAILED(hr)) return hr; IFileSinkFilter *pFileSink= NULL; SysReAllocString(&bstrTempDeviceName,L"test.wav"); hr = pWriter->QueryInterface(IID_IFileSinkFilter, (void**)&pFileSink); if(FAILED(hr)) return hr; hr = pFileSink->SetFileName((LPCOLESTR)bstrTempDeviceName,NULL); if(FAILED(hr)) return hr; hr = m_pGraphBuilder->AddFilter(pWriter,bstrTempDeviceName); if(FAILED(hr)) return hr; SysReAllocString(&bstrInPin,L"Out"); SysReAllocString(&bstrOutPin,L"in"); hr = DeviceConnect(pWaveDest,pWriter,bstrInPin,bstrOutPin); if(FAILED(hr)) return hr; SysFreeString(bstrInPin); SysFreeString(bstrOutPin); SysFreeString(bstrTempDeviceName); hr = m_pMediaContrl->Run(); if(FAILED(hr)) return hr; return hr; } HRESULT CaptureAudio::DeviceConnect(IBaseFilter* pInputDevice,IBaseFilter* pOutputDevice, BSTR bstrInputPin, BSTR bstrOutputDevice) { HRESULT hr; IEnumPins *pInputPins = NULL, *pOutputPins = NULL; IPin *pIn = NULL, *pOut = NULL; hr = pInputDevice->EnumPins(&pInputPins); if (SUCCEEDED(hr)) { hr = pInputDevice->FindPin(bstrInputPin,&pIn); if(FAILED(hr)) return hr; }else return hr; hr = pOutputDevice->EnumPins(&pOutputPins); if (SUCCEEDED(hr)) { hr = pOutputDevice->FindPin(bstrOutputDevice,&pOut); if(FAILED(hr)) return hr; } hr = pIn->Connect(pOut, NULL); if (FAILED(hr)) return hr; return hr; } HRESULT CaptureAudio::BindDeviceFilter(BSTR deviceName,GUID DEVICE_CLSID,IBaseFilter **pBaseFilter) { ICreateDevEnum *pDevEnum; IEnumMoniker *pEnumMon; IMoniker *pMoniker; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,(LPVOID*)&pDevEnum); if (SUCCEEDED(hr)) { hr = pDevEnum->CreateClassEnumerator(DEVICE_CLSID,&pEnumMon, 0); if (hr == S_FALSE) { hr = VFW_E_NOT_FOUND; return hr; } pEnumMon->Reset(); ULONG cFetched; while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK) { IPropertyBag *pProBag; hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag); if (SUCCEEDED(hr)) { VARIANT varTemp; varTemp.vt = VT_BSTR; hr = pProBag->Read(L"FriendlyName",&varTemp,NULL); if (SUCCEEDED(hr)) { if (Bstr_Compare(varTemp.bstrVal,deviceName) == true) { hr = pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter,(LPVOID*)pBaseFilter); if (SUCCEEDED(hr)) return hr; } SysFreeString(varTemp.bstrVal); } pProBag->Release(); } pMoniker->Release(); } pEnumMon->Release(); } return hr; }
#include "CaptureVideo.h" #include "CaptureAudio.h" #include "resource.h" #define ID_COMBOBOX 10000 #define ID_COMBOBOX2 10001 #define ID_TIMER 10002 CaptureVideo g_CaptureVideo; CaptureAudio g_CaptureAudio; HWND hwndCombo1; HWND hwndCombo2; BSTR bstrDeviceName; HICON g_hIconLarge; HICON g_hIconSmall; int g_nTimerCount = 0; BOOL CALLBACK WndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); VOID CALLBACK TimerGetPicture(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTimer); VOID SetWindowPosCenter(HWND hDlg); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { g_hIconLarge = static_cast<HICON>(LoadImage(hInstance, TEXT("IDI_ICON1"), IMAGE_ICON, //set large ico GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CXICON), 0)); g_hIconSmall = static_cast<HICON>(LoadImage(hInstance, TEXT("IDI_ICON1"), IMAGE_ICON, //set small ico GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CXSMICON), 0)); MSG msg; HWND hDlg = CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,WndProc); ShowWindow(hDlg,iCmdShow); UpdateWindow(hDlg); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } CoUninitialize(); // Exit DestroyIcon(g_hIconLarge); DestroyIcon(g_hIconSmall); return msg.wParam; } BOOL CALLBACK WndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { int nGetComboxCount = 0; int iGetCurSel = 0; DWORD dwBaseUnits; switch(message) { case WM_INITDIALOG: { SendMessage(hDlg,WM_SETICON,FALSE,reinterpret_cast<LPARAM>(g_hIconSmall)); SendMessage(hDlg,WM_SETICON,TRUE,reinterpret_cast<LPARAM>(g_hIconLarge)); ////////////////////////////////////////////////////////////////////////// SetWindowPosCenter(hDlg); //set Dialog at window center ////////////////////////////////////////////////////////////////////////// g_CaptureVideo.m_App = hDlg; g_CaptureAudio.m_App = hDlg; dwBaseUnits = GetDialogBaseUnits(); hwndCombo1 = CreateWindow(TEXT("COMBOBOX"), TEXT(""), CBS_DROPDOWN | WS_CHILD | WS_VISIBLE, (6 * LOWORD(dwBaseUnits)) / 4, (2 * HIWORD(dwBaseUnits)) / 8, (100 * LOWORD(dwBaseUnits)) / 4, (50 * HIWORD(dwBaseUnits)) / 8, hDlg, (HMENU)ID_COMBOBOX, NULL, NULL); hwndCombo2 = CreateWindow(TEXT("COMBOBOX"), TEXT(""), CBS_DROPDOWN | WS_CHILD | WS_VISIBLE, (110 * LOWORD(dwBaseUnits)) / 4, (2 * HIWORD(dwBaseUnits)) / 8, (100 * LOWORD(dwBaseUnits)) / 4, (50 * HIWORD(dwBaseUnits)) / 8, hDlg, (HMENU)ID_COMBOBOX2, NULL, NULL); //Video g_CaptureVideo.EnumAllDevices(hwndCombo1); //Enum All Camera nGetComboxCount = ComboBox_GetCount(hwndCombo1); if (nGetComboxCount == 0) ComboBox_Enable(hwndCombo1,FALSE); else ComboBox_SetCurSel(hwndCombo1,0); if(g_CaptureVideo.m_nCaptureDeviceNumber == 0) { Msg(hDlg,TEXT("没有摄像头设备")); EnableWindow(GetDlgItem(hDlg,IDC_PREVIWE),FALSE); } EnableWindow(GetDlgItem(hDlg,IDONESHOT),FALSE); // Audio g_CaptureAudio.EnumAllDevices(hwndCombo2); nGetComboxCount = ComboBox_GetCount(hwndCombo2); if (nGetComboxCount == 0) ComboBox_Enable(hwndCombo2,FALSE); else ComboBox_SetCurSel(hwndCombo2,0); if(g_CaptureAudio.m_nCaptureDeviceNumber == 0) { Msg(hDlg,TEXT("没有音频设备")); EnableWindow(GetDlgItem(hDlg,IDC_PREVIWE),FALSE); } } return TRUE; case WM_DESTROY: { g_CaptureVideo.CloseInterface(); PostQuitMessage(0); } break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: { PostQuitMessage(0); } break; case IDONESHOT: { //g_CaptureVideo.GrabOneFrame(TRUE); SetTimer(hDlg,ID_TIMER,150,TimerGetPicture); } break; case IDC_PREVIWE: { //Video iGetCurSel = ComboBox_GetCurSel(hwndCombo1); g_CaptureVideo.OpenDevice(iGetCurSel,20,30,430,400); EnableWindow(GetDlgItem(hDlg,IDONESHOT),TRUE); //Audio iGetCurSel = ComboBox_GetCurSel(hwndCombo2); bstrDeviceName = SysAllocString(g_CaptureAudio.m_pCapDeviceName[iGetCurSel]); g_CaptureAudio.OpenDevice(bstrDeviceName); } break; default: break; } case WM_MOVE: g_CaptureVideo.m_pVideoWindow->NotifyOwnerMessage((OAHWND)hDlg, message, wParam, lParam); break; } return (FALSE); } VOID CALLBACK TimerGetPicture(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTimer) { if(g_nTimerCount < 25) { g_CaptureVideo.GrabOneFrame(TRUE); g_nTimerCount++; }else { KillTimer(hDlg,ID_TIMER); g_nTimerCount = 0; } } VOID SetWindowPosCenter(HWND hDlg) { int cxWindow,cyWindow; //window Screen width and height RECT hDlgRect; //Dialog Rect int cxDialog,cyDialog; //Dialog Screen width and height int cxSetPos,cySetPos; GetWindowRect(hDlg,&hDlgRect); // cxDialog = hDlgRect.right - hDlgRect.left; cyDialog = hDlgRect.bottom - hDlgRect.top; // cxWindow = GetSystemMetrics(SM_CXSCREEN); cyWindow = GetSystemMetrics(SM_CYSCREEN); // cxSetPos = (cxWindow-cxDialog)/2; cySetPos = (cyWindow-cyDialog)/2; SetWindowPos(hDlg,NULL,cxSetPos,cySetPos,0,0,SWP_NOSIZE); }