dshow的Hellowrold以及获取camera数据

#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");


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值