完整的DirectShow捕获音视频的demo(源码)
来源:互联网 发布:数据库设计三大原则 编辑:程序博客网 时间:2024/04/30 14:36
转至:http://blog.csdn.net/wangqiulin123456/article/details/8675915
近段时间由于工作上的需要,大概看了下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;
- }
3.CaptureVideo.h 捕获视频,预览和截图文件
- #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;
- }
4.CaptureAudio.h 预览音频和保存捕获到的音频到文件
- #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;
- }
5.测试:Main.cpp
- #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);
- }
- 完整的DirectShow捕获音视频的demo(源码)
- 完整的DirectShow捕获音视频的demo(源码)
- directshow实现视频捕获(源码)vs2005
- 基于Directshow的USB视频捕获Delphi篇(一)
- 基于Directshow的USB视频捕获Delphi篇(二)
- DirectShow基于DirectShow视频及图片捕获软件的开发
- directshow 自带的视频捕获的例子
- DirectShow中怎样修改捕获视频的格式
- DirectShow中怎样修改捕获视频的格式
- 基于DirectShow视频及图片捕获软件的开发
- DirectShow 视频捕获(9) 生成新的采样
- DirectShow视频捕获
- DirectShow视频捕获
- DirectShow 视频捕获(1)
- DirectShow 视频捕获(2)
- DirectShow 视频捕获(3)
- directshow的视频采集
- Directshow的视频捕捉
- make -j选项的意义
- java map list xml转化操作类
- 第四周 项目一 三角形类
- .NET 推荐书籍
- 三角形类
- 完整的DirectShow捕获音视频的demo(源码)
- stm32 编程用到的文档
- 1145. 校门外的树
- 软件项目管理中的10个误区
- 2013c++ 第四周任务-三角类(vs2008)
- java的抽象类和抽象方法
- readlines的中文与英语的差别
- div中如何使图片垂直居中
- grep和正则表达式结合使用的一些例子