您的位置:首页 > 其它

CCapture directshow 视频捕获类

2016-11-27 16:20 405 查看
本文来自:http://blog.csdn.NET/xgx198831/article/details/7284618

// Capture.h for class CCapture

#include <dshow.h>

#include <qedit.h>

#include <atlbase.h>

#if !defined(CAPTURE_H_________)

#define CAPTURE_H_________

// image size: 160*120 176*144 320*240 640*480 1024*1806

#define IMG_WIDTH 320

#define IMG_HEIGHT 240

typedef void (*capCallBackFunc)(LPVOID lParam);

enum DeviceType{DTypeVideo, DTypeAudio};

class CSampleGrabberCB; // 用于不会帧数据保存图片的接口

class CCapture

{

friend class CSampleGrabberCB;

public:

// 设置回调函数 用于处理获取的图片帧数据

CDialog *m_dlgParent;

capCallBackFunc calFunc;

void SetCallBKFun(capCallBackFunc f);

/////////////////////////////////

CCapture();

virtual ~CCapture();

int EnumDevice(HWND hCmbList, DeviceType deviceType); // 设备枚举

// void SaveGraph(TCHAR *wFileName); // 保存滤波器链表

void SetCameraFormat(HWND hwndParent); // 设置摄像头的视频格式

void SetCameraFilter(HWND hwndParent); // 设置摄像头的图像参数

HRESULT CaptureVideo(CString inFileName); // 捕获保存视频

HRESULT CaptureImage(CString inFileName); // 抓取保存图片

HRESULT CaptureImage(); // 抓取图片并显示

HRESULT Preview(int iDevVideoID, HWND hVideo, int iDevAudioID = 0, HWND hAudio = NULL); // 采集预览视频

HRESULT InitCaptureGraphBuilder(); // 创建滤波器管理器,查询其各种控制接口

void StopCapture(); // 停止捕获

void FreeMediaType(AM_MEDIA_TYPE &mt); // 释放对象内存

void SetOnShot(BOOL bFlag); // 设置是否捕获帧数据

void SetParent(CDialog *pdlg);

protected:

bool BindFilter(int iDeviceID, IBaseFilter **pOutFilter, DeviceType deviceType); // 把指定的设备滤波器捆绑到链表中

void ResizeVideoWindow(); // 更改视频显示窗口

HRESULT SetupVideoWindow(); // 设置视频显示窗口的特性

static UINT ThreadFunDrawText(LPVOID lParam);

private:

HWND m_hWnd; // 视频显示窗口的句柄

IBaseFilter *m_pVideoCap; // 视频捕获滤波器

IBaseFilter *m_pAudioCap; // 音频捕获滤波器

CComPtr<ISampleGrabber> m_pGrabber; // 抓取图片滤波器

IBaseFilter *m_pMux; // 写文件滤波器

ICaptureGraphBuilder2 *m_pCapGB; // 增强型捕获滤波器链表管理

IGraphBuilder *m_pGB; // 滤波链表管理器

IVideoWindow *m_pVW; // 视频显示窗口接口

IMediaControl *m_pMC; // 媒体控制接口

static bool m_bRecording; // 录制视频标志

IBaseFilter *m_pXviDCodec; //mpeg4 滤波器

};

#endif

[cpp] view
plain copy

/// Capture.cpp for class CCapture implement

//

///

////////////////////////////////////////

#include "StdAfx.h"

#include "Capture.h"

#include <atlconv.h>

#include "VideoChatDlg.h"

#include "yuv2bmp.h"

#ifndef srelease

#define srelease(x) if (NULL != x)\

{\

x->Release();\

x = NULL;\

}

#endif

#ifndef MAX_PATH

#define MAX_PATH 1024

#endif

BOOL bOneShot = FALSE; // 全局变量

capCallBackFunc fun;

class CSampleGrabberCB : public ISampleGrabberCB

{

public:

long lWidth;

long lHeight;

CCapture *pCap;

TCHAR m_szFileName[MAX_PATH]; // 位图文件名称

CSampleGrabberCB(){

strcpy(m_szFileName, ".\\sample.bmp");

}

STDMETHODIMP_(ULONG) AddRef() { return 2; }

STDMETHODIMP_(ULONG) Release() { return 1; }

STDMETHODIMP QueryInterface(REFIID riid, void ** ppv){

if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ){

*ppv = (void *) static_cast<ISampleGrabberCB*> ( this );

return NOERROR;

}

return E_NOINTERFACE;

}

STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ){

return 0;

}

STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ){

if( !bOneShot )

return 0;

if (!pBuffer)

{

AfxMessageBox(_T("Save Bmp File Failure!"));

return E_POINTER;

}

if (pBuffer != NULL && pCap)

{

// BYTE *rgb = new BYTE[lWidth*lHeight*3];

// YUV422_C_RGB(pBuffer,rgb, (int)lHeight, (int)lWidth);

// outBmpBuf(pBuffer, pCap); // 将一帧图像数据传给显示函数

// ((CVideoNetDlg *)pCap->m_dlgParent)->SendVideo(pBuffer, (int)lBufferSize);

}

// SaveBitmap(pBuffer, lBufferSize); // 保存成位图文件

// bOneShot = FALSE; // 停止捕获图像

// AfxMessageBox(_T("Get bmp data success."));

return 0;

}

void outBmpBuf(BYTE *buf, CCapture* cap)

{

cap->calFunc(buf);

}

// 创建位图文件

BOOL SaveBitmap(BYTE *pBuffer, long lBufferLen)

{

HANDLE hf = CreateFile(m_szFileName, GENERIC_WRITE,

FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL);

if (hf == INVALID_HANDLE_VALUE) return 0;

// 写文件头

BITMAPFILEHEADER fileheader;

ZeroMemory(&fileheader, sizeof(BITMAPFILEHEADER));

fileheader.bfType = 'MB';

fileheader.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+lBufferLen;

fileheader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);

DWORD dwWritter = 0;

WriteFile(hf, &fileheader, sizeof(BITMAPFILEHEADER), &dwWritter, NULL);

// 写文图格式

BITMAPINFOHEADER infoHeader;

ZeroMemory(&infoHeader, sizeof(BITMAPINFOHEADER));

infoHeader.biSize = sizeof(BITMAPINFOHEADER);

infoHeader.biSizeImage = lBufferLen;

infoHeader.biWidth = lWidth;

infoHeader.biHeight = lHeight;

infoHeader.biBitCount = 24;

WriteFile(hf, &infoHeader, sizeof(BITMAPINFOHEADER), &dwWritter, NULL);

// 写位图数据

WriteFile(hf, pBuffer, lBufferLen, &dwWritter, NULL);

CloseHandle(hf);

MessageBox(NULL, _T("Save bmp file succeed!"), _T("warn"), MB_OK|MB_ICONINFORMATION);

return 0;

}

};

/////////////////////////////////////////////

/// for class CCapture's Function

///

////////////////////////////////////////////////

CSampleGrabberCB samCB;

CCapture::CCapture()

{

CoInitialize(NULL); // 初始化COM库

m_hWnd = NULL;

m_pVideoCap = NULL;

m_pAudioCap = NULL;

m_pCapGB = NULL;

m_pGB = NULL;

m_pMC = NULL;

m_pMux = NULL;

m_pVW = NULL;

m_pGrabber = NULL;

m_dlgParent = NULL;

}

bool CCapture::m_bRecording = false;

CCapture::~CCapture()

{

if (m_pMC) m_pMC->Stop();

if (m_pVW)

{

m_pVW->put_Owner(NULL);

m_pVW->put_Visible(OAFALSE);

}

m_hWnd = NULL;

srelease(m_pVideoCap);

srelease(m_pGB);

srelease(m_pCapGB);

srelease(m_pMC);

srelease(m_pVW);

m_bRecording = false;

CoUninitialize(); // 释放COM库

}

int CCapture::EnumDevice( HWND hCmbList, DeviceType deviceType )

{

if (hCmbList == NULL) return -1;

int id = 0;

/////枚举捕获设备

ICreateDevEnum *pCreateDevEnum;

HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,

NULL,

CLSCTX_INPROC_SERVER,

IID_ICreateDevEnum,

(LPVOID *)&pCreateDevEnum);

if ( hr != NOERROR) return -1;

//////// 获取视频类的枚举器

IEnumMoniker *pEm; //枚举监控器接口

if (deviceType == DTypeVideo)

hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);

// 如果获取音频类的枚举器 用下面的代码

else

hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEm, 0);

// if (hr != NOERROR) return -1;

if (!pEm || FAILED(hr)) return -1;

////////////////////////

pEm->Reset(); // 类型枚举器复位

ULONG cFetched;

IMoniker *pM; // 监控器接口指针

while(hr = pEm->Next(1, &pM, &cFetched), hr == S_OK)

{

IPropertyBag *pBag; // 属性页接口指针

hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);

// 获取设备属性页

if (SUCCEEDED(hr))

{

VARIANT var;

var.vt = VT_BSTR; // 保存的是二进制数据

// 获取firendlyName 形式的信息

hr = pBag->Read(L"FriendlyName", &var, NULL);

if (hr == NOERROR) // 获取成功

{

id++;

char szDeviceName[256] = {0};

WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, szDeviceName,80, NULL, NULL); // 字符串编码转换UNICODE TO ANSI

::SendMessage(hCmbList, CB_ADDSTRING, 0, (LPARAM)szDeviceName);//添加到组合列表框

SysFreeString(var.bstrVal); //释放资源,特别要注意

}

pBag->Release();

}

pM->Release();

}

return 0;

}

void CCapture::ResizeVideoWindow()

{

if (m_pVW)

{

// 让图像充满整个指定窗口

CRect rc;

::GetClientRect(m_hWnd, &rc);

m_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);

}

}

HRESULT CCapture::SetupVideoWindow()

{

HRESULT hr;

//m_hWnd为类CCapture的成员变量,在使用该函数前须初始化

hr = m_pVW->put_Visible(OAFALSE); // 视频窗口不可见

hr = m_pVW->put_Owner((OAHWND)m_hWnd); // 设置视频窗口

if (FAILED(hr)) return hr;

hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN); //设置窗口类型

if (FAILED(hr)) return hr;

ResizeVideoWindow(); // 更改窗口大小

hr = m_pVW->put_Visible(OATRUE); // 显示视频窗口

return hr;

}

HRESULT CCapture::InitCaptureGraphBuilder()

{

HRESULT hr;

//创建IGraphBuilder接口(滤波器链表管理器) m_pGB

hr = CoCreateInstance(CLSID_FilterGraph, NULL,

CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);

if (FAILED(hr)) return hr;

//创建ICaptureGraphBuilder2接口(增强型捕获滤波器链表管理器)m_pCapGB

hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,

CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&m_pCapGB);

if (FAILED(hr)) return hr;

// 创建抓取图片滤波器

if (m_pGrabber){

m_pGrabber.Release();

m_pGrabber = NULL;

}

hr = CoCreateInstance(CLSID_SampleGrabber, NULL,CLSCTX_INPROC_SERVER, IID_ISampleGrabber, (void **)&m_pGrabber);

// hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );

if (FAILED(hr)) return hr;

// 初始化滤波器链表管理器IGraphBuilder

m_pCapGB->SetFiltergraph(m_pGB);

// 查询媒体控制接口

hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);

if (FAILED(hr)) return hr;

// 查询视频窗口接口

hr = m_pGB->QueryInterface(IID_IVideoWindow, (LPVOID *)&m_pVW);

if (FAILED(hr)) return hr;

/////

return hr;

}

HRESULT CCapture::Preview( int iDevVideoID, HWND hVideo, int iDevAudioID /*= 0*/, HWND hAudio /*= NULL*/ )

{

HRESULT hr;

if (m_pMC)

m_pMC->Stop();

m_bRecording = false;

// 初始化视频捕获滤波器链表管理器

hr = InitCaptureGraphBuilder();

if (FAILED(hr)) return hr;

// 把指定的视频采集设备与滤波器捆绑

if (BindFilter(iDevVideoID, &m_pVideoCap, DTypeVideo))

{

// 把滤波器添加到滤波器链表中

hr = m_pGB->AddFilter(m_pVideoCap, L"Video Capture Filter");

if (FAILED(hr)) return hr;

}

else return FALSE;

if (BindFilter(iDevAudioID, &m_pAudioCap, DTypeAudio))

{

hr = m_pGB->AddFilter(m_pAudioCap, L"Audio Capture Filter");

if (FAILED(hr))

{

MessageBox(NULL, _T("绑定音频设备失败!"), _T("系统提示"), MB_OK|MB_ICONINFORMATION);

// return hr;

}

}

else

{

MessageBox(NULL, _T("绑定音频设备失败!"), _T("系统提示"), MB_OK|MB_ICONINFORMATION);

// return FALSE;

}

// 如果我们想抓取24位的RGB图片,如下设置媒体图片类型

CComQIPtr<IBaseFilter, &IID_IBaseFilter> pGrabBase(m_pGrabber);

AM_MEDIA_TYPE mediaType;

VIDEOINFOHEADER vih;

IAMStreamConfig* pConfig = NULL;

m_pCapGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCap, IID_IAMStreamConfig, (void**)&pConfig);

// 设置视频格式

ZeroMemory(&mediaType, sizeof(AM_MEDIA_TYPE));

vih.bmiHeader.biWidth = IMG_WIDTH;

vih.bmiHeader.biHeight = IMG_HEIGHT;

vih.bmiHeader.biSizeImage = IMG_HEIGHT*IMG_WIDTH*3;

mediaType.pbFormat = (BYTE *)(&vih);

mediaType.cbFormat = sizeof(VIDEOINFOHEADER);

mediaType.subtype = MEDIASUBTYPE_YUY2;

mediaType.majortype = MEDIATYPE_Video;

mediaType.formattype = FORMAT_VideoInfo;

hr = pConfig->SetFormat(&mediaType);

hr = m_pGrabber->SetMediaType(&mediaType);

if( FAILED( hr ) ){

AfxMessageBox("Fail to set media type!");

return hr;

}

hr = m_pGB->AddFilter(pGrabBase, L"SampleGrabber");

if (FAILED(hr)) return hr;

// 渲染媒体, 把链表中滤波器链接起来

hr = m_pCapGB->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, m_pAudioCap, NULL, NULL);

hr = m_pCapGB->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pVideoCap, pGrabBase, NULL);

if (FAILED(hr))

hr = m_pCapGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCap, pGrabBase, NULL);

if( FAILED( hr ) ){

AfxMessageBox(_T("Can’t build the graph"));

return hr;

}

////////// 设置图片捕获数据

hr = m_pGrabber->GetConnectedMediaType( &mediaType );

if ( FAILED( hr) ){

AfxMessageBox(_T("Failt to read the connected media type"));

return hr;

}

VIDEOINFOHEADER * pVih = (VIDEOINFOHEADER*)mediaType.pbFormat;

samCB.lWidth = pVih->bmiHeader.biWidth;

samCB.lHeight = pVih->bmiHeader.biHeight;

samCB.pCap = (CCapture *)this;

FreeMediaType(mediaType);

hr = m_pGrabber->SetBufferSamples( TRUE ); // 如果此处为false 第一次抓取图片时失败(不用回调方式)

hr = m_pGrabber->SetOneShot( FALSE );

hr = m_pGrabber->SetCallback( &samCB, 1 );

SetOnShot(TRUE);// ture 时开始捕获视频帧数据

// 设置视频显示窗口

m_hWnd = hVideo;

SetupVideoWindow(); // 设置显示窗口

hr = m_pMC->Run(); // 开始采集、预览视频,并在指定窗口显示

if (FAILED(hr))

{

MessageBox(NULL, _T("请检查该设备是否被占用!"), _T("系统提示"), MB_OK|MB_ICONINFORMATION);

return hr;

}

return S_OK;

}

#if 1 // avi video format

HRESULT CCapture::CaptureVideo( CString inFileName ) // 录制视频

{

HRESULT hr = 0;

DWORD dwId;

HANDLE hThread;

m_bRecording = false;

m_pMC->Stop(); // 先停止视频采集

// 设置文件名,注意第二个参数类型

hr = m_pCapGB->SetOutputFileName(&MEDIASUBTYPE_Avi, inFileName.AllocSysString(), &m_pMux, NULL);

//渲染媒体 连接捕获器和AVI Muxer过滤器

hr = m_pCapGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoCap, NULL, m_pMux);

hr = m_pCapGB->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, m_pAudioCap, NULL, m_pMux);

//设置音频流为主流

IConfigAviMux *pConfigMux;

m_pMux->QueryInterface(IID_IConfigAviMux, (void **)&pConfigMux);

hr = pConfigMux->SetMasterStream(1); // 0 为视频 1为音频

pConfigMux->Release();

m_pMux->Release();

m_bRecording = true;

hThread = CreateThread(NULL, 0,

(LPTHREAD_START_ROUTINE)ThreadFunDrawText,

(LPVOID)m_hWnd,

0, &dwId);

m_pMC->Run(); // 恢复视频采集,同时写入文件

return hr;

}

#else // mpeg4 format video

HRESULT CCapture::CaptureVideo(CString inFileName)

{

HRESULT hr=0;

m_pMC->Stop();

m_pGB->AddFilter(m_pXviDCodec,L"99 Xvid MPEG-4 Codec");

m_pXviDCodec->Release();

hr = m_pCapGB->SetOutputFileName(&MEDIASUBTYPE_Avi, inFileName.AllocSysString(), &m_pMux, NULL );

hr = ConnectFilters(m_pGB,m_pSmartTee_1,m_pXviDCodec, 0); //0,连接capture引脚

hr = ConnectFilters(m_pGB,m_pXviDCodec,m_pMux, 2); //2,默认自然连接

m_pMux->Release();

m_pMC->Run();

return hr;

}

#endif

///////////////////////////////

HRESULT CCapture::CaptureImage() // 抓取并显示图像

{ // 采用CB接口回调函数存储图片

bOneShot = TRUE;

return 0;

}

HRESULT CCapture::CaptureImage( CString inFileName ) // 抓取图像

{

HRESULT hr;

AM_MEDIA_TYPE mediaType;

hr = m_pGrabber->GetConnectedMediaType(&mediaType);

if (FAILED(hr)) return hr;

VIDEOINFOHEADER *pVih;

if (mediaType.formattype == FORMAT_VideoInfo &&

(mediaType.cbFormat >= sizeof(VIDEOINFOHEADER)) &&

mediaType.pbFormat != NULL)

{

pVih = (VIDEOINFOHEADER *)mediaType.pbFormat;

}

else

return VFW_E_INVALIDMEDIATYPE;

// hr = m_pGrabber->SetOneShot(TRUE);

if (SUCCEEDED(m_pGrabber->SetBufferSamples(TRUE)) ) // 设置为缓冲形式)

{

long cbBuffer = 0;

hr = m_pGrabber->GetCurrentBuffer(&cbBuffer, NULL);

BYTE *pBuffer = new BYTE[cbBuffer];

if (!pBuffer) return -1;

// 获取一帧媒体的数据

hr = m_pGrabber->GetCurrentBuffer(&cbBuffer, (long *)pBuffer);

if (FAILED(hr)) return hr;

// if (pBuffer != NULL)

// {

// calFunc(pBuffer); // 将一帧图像数据传给显示函数

// }

///-------------------------测试所得数据是rgb格式还是yuv格式--------

long n1,n2;

int datalen = IMG_WIDTH*IMG_HEIGHT*3;

BYTE *rgb = new BYTE[datalen];

YUV422_C_RGB(pBuffer,rgb, IMG_HEIGHT, IMG_WIDTH);

n1 = strlen((char *)pBuffer);

n2 = strlen((char *)rgb);

// ((CVideoNetDlg *)(m_dlgParent))->SendVideo((BYTE *)pBuffer, (int)cbBuffer);

///------------------------------------------------------------------

///////////////////////////////////////////////////////////////

// Create a file to hold the bitmap

HANDLE hf = CreateFile(inFileName, GENERIC_WRITE, FILE_SHARE_READ,

NULL, CREATE_ALWAYS, NULL, NULL );

if( hf == INVALID_HANDLE_VALUE ){

MessageBox(NULL, _T("Create bmp file failure!"), _T(""), MB_OK|MB_ICONINFORMATION);

return 0;

}

// Write out the file header

//

// 信息头

BITMAPFILEHEADER bfh;

memset( &bfh, 0, sizeof( bfh ) );

bfh.bfType = 'MB';

bfh.bfSize = sizeof( bfh ) + cbBuffer + sizeof( BITMAPINFOHEADER );

bfh.bfOffBits = sizeof( BITMAPINFOHEADER ) + sizeof( BITMAPFILEHEADER );

DWORD Written = 0;

WriteFile( hf, &bfh, sizeof( bfh ), &Written, NULL );

// Write the bitmap format

//文件头

BITMAPINFOHEADER bih;

memset( &bih, 0, sizeof( bih ) );

bih.biSize = sizeof( bih );

bih.biWidth = pVih->bmiHeader.biWidth;

bih.biHeight = pVih->bmiHeader.biHeight;

bih.biPlanes = 1;

bih.biBitCount = 24;

Written = 0;

WriteFile( hf, &bih, sizeof( bih ), &Written, NULL );

// Write the bitmap bits

//

Written = 0;

WriteFile( hf, rgb, datalen, &Written, NULL );

CloseHandle( hf );

delete pBuffer;

MessageBox(NULL, _T("Save photo succeeded!"), _T("抓取图片提示"), MB_OK|MB_ICONINFORMATION);

}

m_pGrabber->SetOneShot(FALSE);

m_pGrabber->SetBufferSamples(FALSE);

FreeMediaType(mediaType);

return 0;

}

bool CCapture::BindFilter( int iDeviceID, IBaseFilter **pOutFilter, DeviceType deviceType )

{

if (iDeviceID < 0) return false;

// 枚举所有的视频设备

ICreateDevEnum *pCreateDevEnum;

//生成设备枚举器pCreateDevEnum

HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,

NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pCreateDevEnum);

if (hr != NOERROR) return false;

IEnumMoniker *pEM;

// 创建视频输入设备类枚举器

if (deviceType == DTypeVideo)

hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEM, 0);

// 音频设备枚举器

else

hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEM, 0);

if (hr != NOERROR) return false;

pEM->Reset(); // 复位该设备

ULONG cFetched;

IMoniker *pM;

int indexDev = 0;

// 获取设备

while(hr = pEM->Next(1, &pM, &cFetched), hr == S_OK, indexDev <= iDeviceID)

{

IPropertyBag *pBag;

// 获取该设备属性集

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)

{

// 采集设备与捕获滤波器捆绑

if (indexDev == iDeviceID) pM->BindToObject(0, 0, IID_IBaseFilter, (void **)pOutFilter);

SysFreeString(var.bstrVal);

}

pBag->Release();

}

pM->Release();

indexDev++;

}

return true;

}

void CCapture::SetCameraFormat( HWND hwndParent ) // 设置视频格式

{

HRESULT hr;

IAMStreamConfig *pSC; // 流配置接口

ISpecifyPropertyPages *pSpec; //属性页接口

m_pMC->Stop(); // 只有停止后才能进行引脚属性的设置

m_bRecording = false;

// 首先查询捕获CAPTURE、视频Video接口

hr = m_pCapGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,

m_pVideoCap, IID_IAMStreamConfig, (void **)&pSC);

CAUUID cauuid; // 所有属性页结构体

hr = pSC->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpec);

if (hr == S_OK)

{

// 显示属性页窗口

hr = pSpec->GetPages(&cauuid); // 获取所有属性页

hr = OleCreatePropertyFrame(hwndParent, 30, 30, NULL, 1,

(IUnknown **)&pSC, cauuid.cElems, (GUID *)cauuid.pElems, 0, 0, NULL);

// 释放内存资源

CoTaskMemFree(cauuid.pElems);

pSpec->Release();

pSC->Release();

}

// 恢复运行

m_pMC->Run();

}

void CCapture::SetCameraFilter( HWND hwndParent ) // 设置图像各参数设置

{

HRESULT hr = 0;

ISpecifyPropertyPages *pSpec;

hr = m_pVideoCap->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pSpec);

if (SUCCEEDED(hr))

{

// 获取滤波器名称和IUnknown 接口指针

FILTER_INFO FilterInfo;

hr = m_pVideoCap->QueryFilterInfo(&FilterInfo);

IUnknown *pFilterUnk;

m_pVideoCap->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);

// 显示该页

CAUUID caGUID;

pSpec->GetPages(&caGUID);

OleCreatePropertyFrame(hwndParent,

0, 0,

FilterInfo.achName,

1,

&pFilterUnk,

caGUID.cElems,

caGUID.pElems,

0,

0, NULL);

// 释放内存资源

CoTaskMemFree(caGUID.pElems);

pFilterUnk->Release();

FilterInfo.pGraph->Release();

pSpec->Release();

}

}

void CCapture::StopCapture()

{

m_pMC->Stop();

}

UINT CCapture::ThreadFunDrawText( LPVOID lParam )

{

HWND hwnd = (HWND)lParam;

if (hwnd == NULL) return -1;

HDC hdc = GetDC(hwnd);

CRect rcDraw, rcTime;

CTime time, time0;

CTimeSpan timespan;

CString strTime;

CBrush br;

time0 = CTime::GetCurrentTime();

br.CreateSolidBrush(RGB(255,0,0));

GetClientRect(hwnd, &rcDraw);

rcTime = rcDraw;

rcTime.bottom = rcTime.top + 30;

rcDraw.top = rcDraw.bottom - 30;

SelectObject(hdc, &br);

SetTextColor(hdc, 0x0000ff);

SetBkMode(hdc, TRANSPARENT);

while(m_bRecording)

{

time = CTime::GetCurrentTime();

timespan = time - time0;

strTime = time.Format(_T(" %Y-%m-%d 星期%w %H:%M:%S"));

DrawText(hdc, strTime, strTime.GetLength(), &rcTime, DT_VCENTER|DT_LEFT|DT_SINGLELINE);

strTime = timespan.Format(_T("%H:%M:%S "));

strTime = _T("●录制 ") + strTime;

DrawText(hdc, strTime, strTime.GetLength(), &rcDraw, DT_VCENTER|DT_RIGHT|DT_SINGLELINE);

}

return 0;

}

void CCapture::FreeMediaType(AM_MEDIA_TYPE &mt)

{

if (mt.cbFormat != 0)

{

CoTaskMemFree((PVOID)mt.pbFormat);

mt.cbFormat = 0;

mt.pbFormat = NULL;

}

if (mt.pUnk != NULL)

{

mt.pUnk->Release();

mt.pUnk = NULL;

}

}

void CCapture::SetOnShot( BOOL bFlag )

{

bOneShot = bFlag;

}

void CCapture::SetCallBKFun( capCallBackFunc f )

{

this->calFunc = f;

samCB.pCap = static_cast<CCapture *>(this);

}

void CCapture::SetParent( CDialog *pdlg )

{

m_dlgParent = pdlg;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息