|
|
使用directShow播放摄像头的基类 |
|
|
作者:未知 来源:月光软件站 加入时间:2005-5-13 月光软件站 |
// Camera.h: interface for the CCamera class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_CAMERA_H__B5ACFC9D_D275_4114_940F_213B07C494B0__INCLUDED_) #define AFX_CAMERA_H__B5ACFC9D_D275_4114_940F_213B07C494B0__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include "Dshow.h" #include "amstream.h" #include "Qedit.h"
class CCamera { public: CCamera(); virtual ~CCamera(); int m_iTotal;
private: DWORD m_dwRegister; IMoniker* m_gVideoMoniker[3]; // This will access the actual devices IBaseFilter* m_pSrc[3]; IGraphBuilder* m_pGraph[3]; ICaptureGraphBuilder2* m_pCapture[3]; IVideoWindow* m_pVW[3]; IMediaControl* m_pMc[3]; IBaseFilter* m_pF[3]; ISampleGrabber* m_pGrab[3]; IBaseFilter* m_pNull[3]; HWND m_hCapWnd[3];
public: BOOL CCameraInit(); BOOL CCameraBindFilter(); // BOOL CCameraFormat(); // BOOL CCameraPreviewWindow(); // BOOL GetPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin); HRESULT GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin); BOOL ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pFirst, IBaseFilter* pSecond); HRESULT AddToRot(IUnknown* pUnkGraph, DWORD* pdwRegister); void RemoveFromRot(DWORD pdwRegister); BOOL CCameraGetImage(int i); // BOOL CCameraSizeImage(CBmpProc* aBmpProc, CRect aRect, CString sFilePath, int nCamera);
BOOL CreteMultileveDir(CString strFilePath); void MyFreeMediaType(AM_MEDIA_TYPE& mt); WCHAR* ToWChar(char* str); };
#endif // !defined(AFX_CAMERA_H__B5ACFC9D_D275_4114_940F_213B07C494B0__INCLUDED_)
// Camera.cpp: implementation of the CCamera class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "CameraClientOne.h" #include "Camera.h" #include <vfw.h>
#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
CCamera::CCamera() { m_iTotal = 0; for(int i=0; i<1; i++) { m_gVideoMoniker[i] = NULL; m_hCapWnd[i] = NULL; m_pCapture[i] = NULL; m_pF[i] = NULL; m_pGrab[i] = NULL; m_pMc[i] = NULL; m_pSrc[i] = NULL; m_pVW[i] = NULL; m_pNull[i] = NULL; // m_bpBmp[i] = (CBmpProc *)new(CBmpProc); } }
CCamera::~CCamera() { m_iTotal = 0; for(int i=0; i<m_iTotal; i++) { if(m_gVideoMoniker[i]) { m_gVideoMoniker[i]->Release(); m_gVideoMoniker[i] = NULL; } if(m_hCapWnd[i]) { m_hCapWnd[i] = NULL; } if(m_pCapture[i]) { m_pCapture[i]->Release(); m_pCapture[i] = NULL; } if(m_pF[i]) { m_pF[i]->Release(); m_pF[i] = NULL; } if(m_pGrab[i]) { m_pGrab[i]->Release(); m_pGrab[i] = NULL; } if(m_pMc[i]) { m_pMc[i]->Release(); m_pMc[i] = NULL; } if(m_pSrc[i]) { m_pSrc[i]->Release(); m_pSrc[i] = NULL; } if(m_pVW[i]) { m_pVW[i]->Release(); m_pVW[i] = NULL; } if(m_pNull[i]) { m_pNull[i]->Release(); m_pNull[i] = NULL; } // if(&m_bpBmp[i]) // { // delete (CBmpProc *)m_bpBmp; // } } // Disconnect the connect of GraphEdit and Filter Graph #ifdef _DEBUG RemoveFromRot(m_dwRegister); #endif }
// return the total of camera BOOL CCamera::CCameraInit() { HRESULT hr; CoInitialize(NULL); ICreateDevEnum* pDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void **)&pDevEnum); if(FAILED(hr)) { return false; } IEnumMoniker* pClassEnum = NULL; hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0); if(FAILED(hr)) { return false; } pDevEnum->Release(); if(pClassEnum == NULL) { return false; } pClassEnum->Reset(); // Init pClassEnum. IMoniker* pMoniker = NULL; ULONG cFetched; while (pClassEnum->Next(1, &pMoniker, &cFetched), hr == S_OK) // Get camera device. { m_gVideoMoniker[m_iTotal] = pMoniker; m_iTotal++; if(m_iTotal == 1) break; } pClassEnum->Release(); return true; }
// 将其他函数整合到该函数中,目的初始化时显示效果,完成一个Camera初始化 // 即可在Preview中显示。因此不会让用户感觉到太慢。 BOOL CCamera::CCameraBindFilter() { HRESULT hr; // 保存枚举到的视频设备的总数。 int iTempTotal = m_iTotal; // 因为枚举到的视频设备不一定都可以使用,比如正在使用 // 所以m_iTotal初始化为0,在下面的代码中从新赋值, // 即使m_iTotal保存可用的视频设备的总数。 m_iTotal = 0; // 开始按顺序初始化每一个枚举到的视频设备。 for(int i=0; i<iTempTotal; i++){ // 给视频设备榜定source filter. hr = m_gVideoMoniker[i]->BindToObject(0, 0, IID_IBaseFilter, (void **)&m_pSrc[i]); if(FAILED(hr)) { return false; } // 榜定后m_gVideoMoniker指针不再使用。 m_gVideoMoniker[i]->Release(); m_gVideoMoniker[i] = NULL; // 创造用于管理Filters 的IGraphBuilder。 hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGraph[i]); if(FAILED(hr)) { return false; }
// Display the Filter Graph of this program in GraphEdit when debug. #ifdef _DEBUG AddToRot(m_pGraph[i], &m_dwRegister); #endif hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **)&m_pCapture[i]); if(FAILED(hr)) { return false; }
hr = m_pGraph[i]->QueryInterface(IID_IMediaControl, (LPVOID *)&m_pMc[i]); if(FAILED(hr)) { return false; }
hr = m_pGraph[i]->QueryInterface(IID_IVideoWindow, (LPVOID *)&m_pVW[i]); if(FAILED(hr)) { return false; }
hr = m_pCapture[i]->SetFiltergraph(m_pGraph[i]); if(FAILED(hr)) { return false; } // Create Sample Grabber. hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID *)&m_pF[i]); if(FAILED(hr)) { return false; }
hr = m_pF[i]->QueryInterface(IID_ISampleGrabber, (void **)&m_pGrab[i]); if(FAILED(hr)) { return false; }
//Setting image type for image capture filter. AM_MEDIA_TYPE amt; memset(&amt, 0, sizeof(AM_MEDIA_TYPE)); amt.majortype = MEDIATYPE_Video; amt.subtype = MEDIASUBTYPE_RGB555; // RGB, 16 bit per pixel. Palettized. hr = m_pGrab[i]->SetMediaType(&amt); MyFreeMediaType(amt); hr = m_pGraph[i]->AddFilter(m_pF[i], L"Image Capture"); if(FAILED(hr)) { return false; }
hr = m_pGraph[i]->AddFilter(m_pSrc[i], L"Video Capture"); if(FAILED(hr)) { return false; }
hr = m_pCapture[i]->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, m_pSrc[i], NULL, NULL); if(FAILED(hr)) { continue; }
CString sTempTotal; sTempTotal.Format("%d", i+1); // AfxGetMainWnd()->GetDlgItem(IDC_STATIC1)->SetWindowText( // _T("Link camera " + sTempTotal + " ......")); hr = m_pCapture[i]->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pSrc[i], NULL, m_pF[i]); if(FAILED(hr)) { continue; }
/* // Setting source capture filter for the format of image // and the AvgTimePerFrame. IAMStreamConfig* pConfig = NULL; hr = m_pCapture[i]->FindInterface( &PIN_CATEGORY_CAPTURE, 0, // Any media type. m_pSrc[i], // Pointer to the capture filter. IID_IAMStreamConfig, (void **)&pConfig); if(SUCCEEDED(hr)) { AM_MEDIA_TYPE pmtConfig; hr = m_pGrab[i]->GetConnectedMediaType(&pmtConfig); if(SUCCEEDED(hr)) { //pmtConfig.majortype = MEDIATYPE_Video; //pmtConfig.subtype = MEDIASUBTYPE_RGB555; /* // Find the current bit depth. HDC hdc = GetDC(NULL); int iBitDepth = GetDeviceCaps(hdc, BITSPIXEL); ReleaseDC(NULL, hdc); // Set the media type. switch(iBitDepth) { case 8: pmtConfig.subtype = MEDIASUBTYPE_RGB8; break; case 16: pmtConfig.subtype = MEDIASUBTYPE_RGB555; break; case 24: pmtConfig.subtype = MEDIASUBTYPE_RGB24; break; case 32: pmtConfig.subtype = MEDIASUBTYPE_RGB32; break; default: pmtConfig.subtype = MEDIASUBTYPE_RGB555; } */ /* VIDEOINFOHEADER* pviImageCapture = (VIDEOINFOHEADER *)pmtConfig.pbFormat; pviImageCapture->bmiHeader.biBitCount = 16; pviImageCapture->bmiHeader.biWidth = 320; pviImageCapture->bmiHeader.biHeight = 240; pviImageCapture->AvgTimePerFrame = 333333; hr = pConfig->SetFormat(&pmtConfig); //hr = m_pGrab[i]->GetConnectedMediaType(&pmtConfig); //pviImageCapture = (VIDEOINFOHEADER *)pmtConfig.pbFormat; MyFreeMediaType(pmtConfig); } } */
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast<void **>(&m_pNull[i])); if(FAILED(hr)) { return false; }
hr = m_pGraph[i]->AddFilter(m_pNull[i], L"Null Renderer"); if(FAILED(hr)) { return false; }
hr = ConnectFilters(m_pGraph[i], m_pF[i], m_pNull[i]); if(FAILED(hr)) { return false; } m_pF[i]->Release(); m_pF[i] = NULL; m_pSrc[i]->Release(); m_pSrc[i] = NULL; m_pNull[i]->Release(); m_pNull[i] = NULL; CRect rect; CWnd* pWnd; if(i == 0) pWnd = AfxGetMainWnd()->GetDlgItem(IDC_VIDEO0); // else if(i == 1) // pWnd = AfxGetMainWnd()->GetDlgItem(IDC_VIDEO1); // else if(i == 2) // pWnd = AfxGetMainWnd()->GetDlgItem(IDC_VIDEO2); pWnd->GetWindowRect(&rect); m_hCapWnd[i] = capCreateCaptureWindow( (LPSTR)"Camera Capture Window", WS_CHILD|WS_VISIBLE|WS_EX_CLIENTEDGE| WS_EX_DLGMODALFRAME, 0, 0, rect.Width(), rect.Width(), pWnd->GetSafeHwnd(), 0 ); m_pVW[i]->put_Owner((OAHWND)m_hCapWnd[i]); m_pVW[i]->put_WindowStyle(WS_CHILD|WS_VISIBLE|WS_EX_CLIENTEDGE|WS_EX_DLGMODALFRAME); m_pVW[i]->put_Height(rect.Height()); m_pVW[i]->put_Width(rect.Width()); m_pVW[i]->SetWindowPosition(0, 0, rect.Width(), rect.Height()); IMediaEventEx *pEvent = NULL; hr = m_pGraph[i]->QueryInterface(IID_IMediaEventEx, (LPVOID *)&pEvent); if(FAILED(hr)) { return false; }
hr = m_pGrab[i]->SetOneShot(FALSE); if(FAILED(hr)) { return false; }
hr = m_pGrab[i]->SetBufferSamples(TRUE); if(FAILED(hr)) { return false; }
// pEvent->WaitForCompletion(INFINITE, (long *)EC_COMPLETE ); hr = m_pMc[i]->Run(); if(FAILED(hr)) { return false; }
m_pMc[i]->Release(); m_pMc[i] = NULL; m_pVW[i]->Release(); m_pVW[i] = NULL; m_iTotal++; } return true; }
HRESULT CCamera::GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin) { *ppPin = 0; IEnumPins* pEnum = 0; IPin* pPin = 0; HRESULT hr = pFilter->EnumPins(&pEnum); if(FAILED(hr)) return E_FAIL; pEnum->Reset(); while(pEnum->Next(1, &pPin, 0) == S_OK){ PIN_DIRECTION ThisPinDir; pPin->QueryDirection(&ThisPinDir); if (ThisPinDir == PinDir){ IPin* pTmp = 0; hr = pPin->ConnectedTo(&pTmp); if(SUCCEEDED(hr)){ pTmp->Release(); } else{ pEnum->Release(); *ppPin = pPin; return S_OK; } } pPin->Release(); } pEnum->Release(); return E_FAIL; }
BOOL CCamera::ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pFirst, IBaseFilter* pSecond) { IPin* pOut = NULL; IPin* pIn = NULL; HRESULT hr; hr = GetUnconnectedPin(pFirst, PINDIR_OUTPUT, &pOut); if(FAILED(hr)) return false; hr = GetUnconnectedPin(pSecond, PINDIR_INPUT, &pIn); if(FAILED(hr)) { pOut->Release(); return false; } hr = pGraph->Connect(pOut, pIn); pIn->Release(); pOut->Release(); return true; }
BOOL CCamera::CCameraGetImage(int i) { int iTemp = i; long lBitmapSize = 0; HRESULT hr; hr = m_pGrab[iTemp]->GetCurrentBuffer(&lBitmapSize, NULL); if(FAILED(hr)) { return false; } char* pBuffer = new char[lBitmapSize]; if(pBuffer == NULL) { // new operator failed. return false; } hr = m_pGrab[iTemp]->GetCurrentBuffer(&lBitmapSize, reinterpret_cast<long *>(pBuffer)); if(FAILED(hr)) { delete [] pBuffer; return false; } AM_MEDIA_TYPE mt; hr = m_pGrab[iTemp]->GetConnectedMediaType(&mt); if(FAILED(hr)) { delete [] pBuffer; return false; } VIDEOINFOHEADER *pVih; if ((mt.formattype == FORMAT_VideoInfo) && (mt.cbFormat >= sizeof(VIDEOINFOHEADER)) && (mt.pbFormat != NULL)) { pVih = reinterpret_cast<VIDEOINFOHEADER*>(mt.pbFormat); } else { // Wrong format. Free the format block and return an error. //AfxMessageBox("Wrong format."); MyFreeMediaType(mt); delete [] pBuffer; //return VFW_E_INVALIDMEDIATYPE; // Something went wrong return false; } // Now pVih->bmiHeader is the BITMAPINFOHEADER for the frame. CBitmap cBmp; HBITMAP hBmp; HWND hWnd = ::GetDesktopWindow(); ASSERT(hWnd); HDC hDC = ::GetDC(hWnd); if(hDC == NULL) { //AfxMessageBox("GetDC failed."); return false; } int iCurDevBitPix = GetDeviceCaps(hDC,BITSPIXEL); int iCurDevPlanes = GetDeviceCaps(hDC,PLANES); if(cBmp.CreateBitmap(pVih->bmiHeader.biWidth, pVih->bmiHeader.biHeight, iCurDevPlanes, iCurDevBitPix, NULL) == 0) { ::ReleaseDC(hWnd, hDC); delete [] pBuffer; //AfxMessageBox("CreateBitmap failed."); return false; } hBmp = (HBITMAP)cBmp.Detach(); if(hBmp == NULL) { //AfxMessageBox("(HBITMAP)cBmp.Detach failed."); delete [] pBuffer; ::ReleaseDC(hWnd, hDC); return false; } if(SetDIBits(hDC, hBmp, 0, pVih->bmiHeader.biHeight, pBuffer, (BITMAPINFO *)&pVih->bmiHeader, DIB_RGB_COLORS ) == 0) { ::DeleteObject(hBmp); ::ReleaseDC(hWnd, hDC); delete [] pBuffer; //AfxMessageBox("SetDIBits failed."); return false; }
::ReleaseDC(hWnd, hDC); delete [] pBuffer; pBuffer = NULL;
if(hBmp == NULL) { ::DeleteObject(hBmp); //AfxMessageBox("hBmp is NULL."); return false; } //CBmpProc* aBmpProc = (CBmpProc *)new(CBmpProc); // if(m_bpBmp[iTemp]->LoadFromHbmp(hBmp) == FALSE) // { // //AfxMessageBox("LoadFromHbmp failed!"); // ::DeleteObject(hBmp); // cBmp.DeleteObject(); // return false; // }
//m_bpBmp[iTemp] = aBmpProc; //delete (CBmpProc *)aBmpProc; ::DeleteObject(hBmp); return true; }
HRESULT CCamera::AddToRot(IUnknown* pUnkGraph, DWORD* pdwRegister) { IMoniker* pMoniker; IRunningObjectTable* pROT; if(FAILED(GetRunningObjectTable(0, &pROT))){ return E_FAIL; } WCHAR wsz[256]; wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); if(SUCCEEDED(hr)){ hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker, pdwRegister); pMoniker->Release(); } pROT->Release(); return hr; }
void CCamera::RemoveFromRot(DWORD pdwRegister) { IRunningObjectTable* pROT; if(SUCCEEDED(GetRunningObjectTable(0, &pROT))){ pROT->Revoke(pdwRegister); pROT->Release(); } }
void CCamera::MyFreeMediaType(AM_MEDIA_TYPE& mt) { if (mt.cbFormat != 0) { CoTaskMemFree((PVOID)mt.pbFormat); mt.cbFormat = 0; mt.pbFormat = NULL; } if (mt.pUnk != NULL) { // Unecessary because pUnk should not be used, but safest. mt.pUnk->Release(); mt.pUnk = NULL; } }
BOOL CCamera::CreteMultileveDir(CString strFilePath) { CString strTempPath = strFilePath; if (strTempPath.GetAt(strTempPath.GetLength() - 1) != '\\' ) { strTempPath += '\\'; } int nCountTemp = 0; CString strPath = ""; while (1) { int nCount = strTempPath.Find("\\"); if( nCount != -1 ){ strPath += strTempPath.Mid(nCountTemp, nCount + 2 - nCountTemp); ::CreateDirectory(strPath, NULL); nCountTemp = nCount + 2; strTempPath.SetAt(nCount, '|'); strTempPath.SetAt(nCount+1, '|'); } else break; } return true; } /* void CCamera::CCameraTypeImage(CString aBmpPath, CString aFilePath, CString aImageType) { CLSID clImageClsid; Image* igImageStore; CString sBmpPath = aBmpPath; CString sFilePath = aFilePath; CString sImageType = aImageType; igImageStore = Image::FromFile(ToWChar(sBmpPath.GetBuffer(255))); sBmpPath.ReleaseBuffer(); if(sImageType == "jpg"){ GetImageCLSID(L"image/jpeg", &clImageClsid); } else if (sImageType == "gif") { GetImageCLSID(L"image/gif", &clImageClsid); } else if (sImageType == "png") { GetImageCLSID(L"image/png", &clImageClsid); } sFilePath = sFilePath + sImageType + "\\0." + sImageType; igImageStore->Save(ToWChar(sFilePath.GetBuffer(255)), &clImageClsid); } */ WCHAR* CCamera::ToWChar(char* str) { static WCHAR buffer[1024]; wcsset(buffer, 0); MultiByteToWideChar(CP_ACP, 0, str, strlen(str), buffer, 1024); return buffer; } /* BOOL CCamera::GetImageCLSID(const WCHAR* format, CLSID* pCLSID) { UINT num = 0; UINT size = 0; ImageCodeInfo* pImageCodecInfo = NULL; GetImageEncodersSize(&num, &size); if (size == 0) { return false; } pImageCodecInfo = (ImageCodecInfo *)(malloc(size)); if(pImageCodecInfo == NULL) return false; GetImageEncoders(num, size, pImageCodecInfo); // Find for the support of format for image in the windows. for(UINT i=0; i<num; ++i){ // MimeType: Depiction for the program image. if (wcscmp(pImageCodecInfo[i].MimeType, format) == 0) { *pCLSID = pImageCodecInfo[i].Clsid; free(pImageCodecInfo); return true; } } free(pImageCodecInfo); return false; } */ /* UINT CCamera::SendFile(LPVOID lparam, int aImage, int aCamera) { CString* sFileName = (CString *)lparam; CFile cfImageFile; FILEINFO fiFileInfo; int x = cfImageFile.Open(*sFileName, CFile::modeRead); if (x == 0) { return -1; } fiFileInfo.iFileLength = cfImageFile.GetLength(); strcpy(fiFileInfo.cFileName, cfImageFile.GetFileName()); strcpy(fiFileInfo.UserID, gl_sUserID); fiFileInfo.iCamera = aCamera; fiFileInfo.iImage = aImage; } */
调用 // TODO: Add extra initialization here if(m_Camera.CCameraInit() == false) { //AfxMessageBox(_T("No found camera!")); // GetDlgItem(IDC_STATIC1)->SetWindowText( // _T("Camera愝旛傪尒偮偗傑偣傫丅")); return false; } //GetDlgItem(IDC_STATIC1)->SetWindowText(_T("Link camera......")); if(m_Camera.CCameraBindFilter() == false) { // GetDlgItem(IDC_STATIC1)->SetWindowText( // _T("Camera愝旛傪尒偮偗傑偣傫丅")); // //AfxMessageBox(_T("No found camera!")); return false; }

|
|
相关文章:相关软件: |
|