#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <atlbase.h>
#include <windows.h>
#include <fstream>
#include <iostream>
using namespace std;
#include<iostream>
#include <atlconv.h>
#include <atlstr.h>
void vhd_printf(CString cTemp)
{
wcout << (LPCTSTR)cTemp << endl;
}
void vhd_printf2file(CString cTemp)
{
wcout << (LPCTSTR)cTemp << endl;
}
#include <DShow.h>
//#include <streams.h>
#include <qedit.h> // ISampleGrabberCB
#include <comdef.h>
#pragma comment(lib,"Strmiids.lib")
#pragma comment(lib,"Quartz.lib")
#define CHECK_HR(s) do {if (FAILED(s)) { printf("fail line:%d",__LINE__); return 1;} } while(0)
#define SAFE_RELEASE(p) do { if ((p)) { (p)->Release(); (p) = NULL; } } while(0)
HRESULT GetPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin)
{
CComPtr< IEnumPins > pEnum;
*ppPin = NULL;
HRESULT hr = pFilter->EnumPins(&pEnum);
if(FAILED(hr))
return hr;
ULONG ulFound;
IPin *pPin;
hr = E_FAIL;
while(S_OK == pEnum->Next(1, &pPin, &ulFound))
{
PIN_DIRECTION pindir = (PIN_DIRECTION)3;
pPin->QueryDirection(&pindir);
if(pindir == dirrequired)
{
if(iNum == 0)
{
*ppPin = pPin; // Return the pin's interface
hr = S_OK; // Found requested pin, so clear error
break;
}
iNum--;
}
pPin->Release();
}
return hr;
}
IPin * GetInPin( IBaseFilter * pFilter, int nPin )
{
CComPtr<IPin> pComPin=0;
GetPin(pFilter, PINDIR_INPUT, nPin, &pComPin);
return pComPin;
}
IPin * GetOutPin( IBaseFilter * pFilter, int nPin )
{
CComPtr<IPin> pComPin=0;
GetPin(pFilter, PINDIR_OUTPUT, nPin, &pComPin);
return pComPin;
}
int count=0;
char *buf;
class CSampleGrabberCB:public ISampleGrabberCB
{
public:
// These will get set by the main thread below. We need to
// know this in order to write out the bmp
long Width;
long Height;
// Fake out any COM ref counting
//
STDMETHODIMP_(ULONG) AddRef() { return 2; }
STDMETHODIMP_(ULONG) Release() { return 1; }
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
{
//CheckPointer(ppv,E_POINTER);
if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown )
{
*ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
return NOERROR;
}
return E_NOINTERFACE;
}
STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize )
{
//Callback method that receives a pointer to the sample buffer.
printf("+");
count++;
if(count==2*30)
{
ofstream outfile("out.yuv", ios::binary|ios::_Noreplace);
outfile.write((char *)pBuffer,lBufferSize);
printf("saved");
}
return 0;
}
STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
{
//Callback method that receives a pointer to the media sample.
printf("-");
return 0;
}
};
typedef struct VHD_USB_Device_T
{
char friendlyName[128];
IMoniker *pM;
VHD_USB_Device_T * pNext;
}VHD_USB_Device_T;
typedef struct ImgDeviceInfo
{
int count;
VHD_USB_Device_T * pCamera;
}CAMERA_LIST_T;
typedef struct AudioDeviceInfo
{
int count;
VHD_USB_Device_T * pCamera;
}AUDIO_LIST_T;
CAMERA_LIST_T m_cameraList;
AUDIO_LIST_T m_AudioList;
CAMERA_LIST_T *GetCameraList()
{
if (NULL != m_cameraList.pCamera || m_cameraList.count > 0)
{
return &m_cameraList;
}
if (NULL == m_cameraList.pCamera)
{
m_cameraList.count = 0;
// enumerate all video capture devices
CComPtr<ICreateDevEnum> pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
if (hr != NOERROR)
{
return &m_cameraList;
}
pEm->Reset();
VHD_USB_Device_T *pCameraList = m_cameraList.pCamera;
VHD_USB_Device_T *pCameraInfo = NULL;
ULONG cFetched;
IMoniker *pM = NULL;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
pCameraInfo = new VHD_USB_Device_T;
memset(pCameraInfo, 0x00, sizeof(VHD_USB_Device_T));
pCameraInfo->pM=pM;
printf("get %p",pM);
IPropertyBag *pBag=0;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL); //还有其他属性,像描述信息等等...
if(hr == NOERROR)
{
//获取设备名称
WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,pCameraInfo->friendlyName, sizeof(pCameraInfo->friendlyName) ,"",NULL);
SysFreeString(var.bstrVal);
}
pBag->Release();
m_cameraList.count++;
{
pCameraList = m_cameraList.pCamera;
if (NULL == m_cameraList.pCamera)
{
m_cameraList.pCamera = pCameraInfo;
}
else
{
while (NULL != pCameraList->pNext)
{
pCameraList = pCameraList->pNext;
}
pCameraList->pNext = pCameraInfo;
}
}
}
//pM->Release();//这里release之后就没办法在后面调用了,最好是传id进来直接BindToObject,获得filter
}
pCreateDevEnum = NULL;
pEm = NULL;
}
return &m_cameraList;
}
AUDIO_LIST_T *GetAudioList()
{
if (NULL != m_AudioList.pCamera || m_AudioList.count > 0)
{
return &m_AudioList;
}
if (NULL == m_AudioList.pCamera)
{
m_AudioList.count = 0;
// enumerate all video capture devices
CComPtr<ICreateDevEnum> pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEm, 0);
if (hr != NOERROR)
{
return &m_AudioList;
}
pEm->Reset();
VHD_USB_Device_T *pCameraList = m_AudioList.pCamera;
VHD_USB_Device_T *pCameraInfo = NULL;
ULONG cFetched;
IMoniker *pM = NULL;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
{
pCameraInfo = new VHD_USB_Device_T;
memset(pCameraInfo, 0x00, sizeof(VHD_USB_Device_T));
IPropertyBag *pBag=0;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL); //还有其他属性,像描述信息等等...
if(hr == NOERROR)
{
//获取设备名称
WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,pCameraInfo->friendlyName, sizeof(pCameraInfo->friendlyName) ,"",NULL);
SysFreeString(var.bstrVal);
}
pBag->Release();
m_AudioList.count++;
{
pCameraList = m_AudioList.pCamera;
if (NULL == m_AudioList.pCamera) m_AudioList.pCamera = pCameraInfo;
else
{
while (NULL != pCameraList->pNext)
{
pCameraList = pCameraList->pNext;
}
pCameraList->pNext = pCameraInfo;
}
}
}
//pM->Release();//这里release之后就没办法在后面调用了,最好是传id进来直接BindToObject,获得filter
}
pCreateDevEnum = NULL;
pEm = NULL;
}
return &m_AudioList;
}
#if 0 //windows 自带的hello world
int _tmain(int argc, _TCHAR* argv[])
{
printf("hello world");
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
// 初始化COM 库
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
return 0;
}
// 建立过滤器图表管理器
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr))
{
printf("ERROR - Could not create the Filter Graph Manager.");
return 0;
}
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
// 建立过滤器图表
hr = pGraph->RenderFile(L"Example.avi", NULL);
if (SUCCEEDED(hr))
{
// 播放
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// 等待播放结束
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
}
}
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
system("pause");
return 0;
}
#endif
int _tmain(int argc, _TCHAR* argv[])
{
int i=0;
HRESULT hr;
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *m_pBuild;//捕获图表管理器
CoInitialize(NULL);
CAMERA_LIST_T *p_g_camera=GetCameraList();
VHD_USB_Device_T * pCamera=p_g_camera->pCamera;
vhd_printf(pCamera->friendlyName);
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&pGraph);
CHECK_HR(hr);
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&m_pBuild);
CHECK_HR(hr);
hr = m_pBuild->SetFiltergraph(pGraph);//给捕获图表管理器指定一个可用的图表管理器来进行使用
CHECK_HR(hr);
#if 0
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pClsEnum = NULL;
IMoniker *pMoniker = NULL;
//创建设备枚举COM对象
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void **)&pDevEnum);
CHECK_HR(5);
//创建视频采集设备枚举COM对象
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClsEnum, 0);
CHECK_HR(6);
i=0;
while (i <= 0)
{
hr = pClsEnum->Next(1, &pMoniker, NULL);
++i;
}
CHECK_HR(hr);
SAFE_RELEASE(pClsEnum);
SAFE_RELEASE(pDevEnum);
#else
IMoniker *pMoniker=pCamera->pM;
#endif
IBaseFilter *m_pSrc;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void **)&m_pSrc);//就是这句获得Filter
CHECK_HR(8);
SAFE_RELEASE(pMoniker);
//将设备添加到filter管理器graph
hr = pGraph->AddFilter(m_pSrc, L"Video Capture");
CHECK_HR(hr);
//IMediaControl接口,用来控制流媒体在Filter Graph中的流动,例如流媒体的启动和停止
IMediaControl *m_pMediaControl;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
CHECK_HR(hr);
// This semi-COM object will receive sample callbacks for us
//
CComPtr< ISampleGrabber > pGrabber;
pGrabber.CoCreateInstance( CLSID_SampleGrabber );
CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase( pGrabber );
hr = pGraph->AddFilter( pGrabberBase, L"Grabber" );
#if 0
//手动绑定
CComPtr< IPin > pSourcePin;
CComPtr< IPin > pGrabPin;
pSourcePin = GetOutPin( m_pSrc, 0 );
pGrabPin = GetInPin( pGrabberBase, 0 );
hr = pGraph->Connect( pSourcePin, pGrabPin );
#else
//智能绑定
hr = m_pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pSrc, pGrabberBase, NULL);
#endif
// Don't buffer the samples as they pass through
hr = pGrabber->SetBufferSamples( TRUE );
hr = pGrabber->SetOneShot( FALSE );
CSampleGrabberCB CB;
CB.Width = 640;
CB.Height = 480;
hr = pGrabber->SetCallback( &CB, 1 );
#if 0
// activate the threads
CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
hr = pControl->Run( );
// wait for the graph to settle
CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
long EvCode = 0;
hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
#else
hr = m_pMediaControl->Run();
system("pause");
hr = m_pMediaControl->Stop();
#endif
CoUninitialize();
system("pause");
}
dshow的Hellowrold以及获取camera数据
于 2021-05-23 20:02:26 首次发布
关键词由CSDN通过智能技术生成