um
Гость
|
|
« Ответ #7 : 13-04-2004 22:27 » |
|
ловите... // FrameRenderer.h: interface for the CFrameRenderer class. // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_FRAMERENDERER_H__93D88322_AAAA_11D5_BD90_E5B9C216A273__INCLUDED_) #define AFX_FRAMERENDERER_H__93D88322_AAAA_11D5_BD90_E5B9C216A273__INCLUDED_
#include <strmif.h> #include <uuids.h>
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#define SAFE_RELEASE(p) if(p)|p->Release();p = NULL;}
const GUID IID_ISampleGrabber = {0x6B652FFF,0x11FE,0x4fce,{0x92,0xAD,0x02,0x66,0xB5,0xD7,0xC7,0x8F}}; const GUID CLSID_SampleGrabber = {0xC1F400A0,0x3F08,0x11D3,{0x9F,0x0B,0x00,0x60,0x08,0x03,0x9E,0x37}}; const GUID CLSID_NullRenderer = {0xC1F400A4,0x3F08,0x11d3,{0x9F,0x0B,0x00,0x60,0x08,0x03,0x9E,0x37}}; const GUID CLSID_AviDecompressor = {0xCF49D4E0,0x1115,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
DECLARE_INTERFACE(ISampleGrabberCB) : public IBaseFilter { };
DECLARE_INTERFACE(ISampleGrabber) : public IUnknown { STDMETHOD(SetOneShot(BOOL OneShot)) = 0; STDMETHOD(SetMediaType(const AM_MEDIA_TYPE *pType)) = 0; STDMETHOD(GetConnectedMediaType(AM_MEDIA_TYPE *pType)) = 0; STDMETHOD(SetBufferSamples(BOOL BufferThem)) = 0; STDMETHOD(GetCurrentBuffer(long *pBufferSize,long *pBuffer)) = 0; STDMETHOD(GetCurrentSample(IMediaSample **ppSample)) = 0; STDMETHOD(SetCallback(ISampleGrabberCB *pCallback,long WhichMethodToCallback)) = 0; };
class CSampleGrabber { public: bool SelectBestCompatibleFormat(IPin* ppin); bool ReconfigureGraph(IGraphBuilder* pgraph); void AddToGraph(IGraphBuilder *pgraph); void SetVideoFormat(GUID format = MEDIASUBTYPE_RGB24); CSampleGrabber(); virtual ~CSampleGrabber(); public: IBaseFilter* m_pNullRenderer; IBaseFilter* m_pAviDecompressor; ISampleGrabber *m_pGrabber; IBaseFilter *m_pFilter; IPin* m_pInputPin; IPin* m_pOutputPin; };
UINT ConfigureCamera_thread( LPVOID pParam );
class CFrameGrabber { friend UINT ConfigureCamera_thread( LPVOID pParam ); friend UINT ConfigureCamera_thread_new( LPVOID pParam ); public: void ConfigureCamera(); void *RecieveBitmap(); void QueryGraphInfo(IGraphBuilder* pgb); CString m_sfile; // имя AVI-файла, to be played void Stop(); bool Run(); bool ConstructCaptureGraph(CString capdev); CFrameGrabber(); virtual ~CFrameGrabber(); bool EnumDevices(CStringArray *psa) { return ScanDevices(psa,NULL,false) != NULL;} private: HANDLE mutex; void ListGraphFilters(); void CreateGraph(); void ResetGraph(); bool m_bCapturing; IBaseFilter* SelectDevice(CString sref) { return ScanDevices(NULL,&sref,true);} IBaseFilter* ScanDevices(CStringArray *psa,CString* prefs, bool bsearch = FALSE); IGraphBuilder* m_pGraph; ICaptureGraphBuilder *m_pBuilder; CSampleGrabber *m_pGrabber; IBaseFilter* m_camera; HANDLE m_flog; };
#endif // !defined(AFX_FRAMERENDERER_H__93D88322_AAAA_11D5_BD90_E5B9C216A273__INCLUDED_)
// FrameRenderer.cpp: implementation of the CFrameRenderer class. // //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "FrameRenderer.h"
#include <strmif.h> #include <control.h> #include <uuids.h> #include <amvideo.h>
#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif
LPCWSTR WSTR(char* s) { static WCHAR buf[128]; MultiByteToWideChar(CP_ACP, 0, s, -1,buf, 128); return buf; }
extern void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt); extern void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt);
////////////////////////////////////////////////////////////////////// // CFrameGrabber Class ////////////////////////////////////////////////////////////////////// CSampleGrabber::CSampleGrabber() { // создаем фильтр-граббер HRESULT hr = CoCreateInstance((REFCLSID)CLSID_SampleGrabber, NULL, CLSCTX_INPROC, (REFIID)IID_IBaseFilter,(void **)&m_pFilter); ASSERT(SUCCEEDED(hr)); // ищем интрефейс самого граббера hr = m_pFilter->QueryInterface(IID_ISampleGrabber,(void**)&m_pGrabber); ASSERT(SUCCEEDED(hr)); // смотрим пины IEnumPins *penum; ULONG cbReturned; m_pFilter->EnumPins(&penum); hr = penum->Next(1,&m_pInputPin,&cbReturned); hr = penum->Next(1,&m_pOutputPin,&cbReturned); penum->Release(); // создаем рендерер hr = CoCreateInstance((REFCLSID)CLSID_NullRenderer, NULL, CLSCTX_INPROC, (REFIID)IID_IBaseFilter,(void **)&m_pNullRenderer); ASSERT(SUCCEEDED(hr)); // создаем avi-декомпрессор (вдруг придется обрабатывать видеофайлы!) hr = CoCreateInstance((REFCLSID)CLSID_AviDecompressor, NULL, CLSCTX_INPROC, (REFIID)IID_IBaseFilter,(void **)&m_pAviDecompressor); ASSERT(SUCCEEDED(hr)); // устанавливаем всякие свойства hr = m_pGrabber->SetBufferSamples(true); }
CSampleGrabber::~CSampleGrabber() { SAFE_RELEASE(m_pFilter); SAFE_RELEASE(m_pGrabber); SAFE_RELEASE(m_pInputPin); SAFE_RELEASE(m_pOutputPin); SAFE_RELEASE(m_pNullRenderer); SAFE_RELEASE(m_pAviDecompressor); }
void CSampleGrabber::SetVideoFormat(GUID format) { AM_MEDIA_TYPE mt; memset(&mt,0,sizeof(mt)); mt.majortype = MEDIATYPE_Video; mt.formattype = FORMAT_VideoInfo; mt.subtype = format; HRESULT hr = m_pGrabber->SetMediaType(&mt); ASSERT(SUCCEEDED(hr)); }
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
CFrameGrabber::CFrameGrabber() { m_bCapturing = false; m_camera = NULL; mutex = CreateMutex(NULL,false,"framegrabber_mutex"); // создаем GraphBuilder CreateGraph(); }
CFrameGrabber::~CFrameGrabber() { WaitForSingleObject(mutex,INFINITE); CloseHandle(mutex); Stop(); ResetGraph(); SAFE_RELEASE(m_camera); }
IBaseFilter* CFrameGrabber::ScanDevices(CStringArray *psa,CString* refs, bool bsearch) { // !!! There's got to be a way to cache these from building the menu // Enumerate all the video devices. We want #gcap.iVideoDevice ICreateDevEnum *pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) return NULL;
IEnumMoniker *pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); pCreateDevEnum->Release(); if (hr != NOERROR) return NULL; pEm->Reset();
ULONG cFetched; IMoniker *pM; char achFriendlyName[120]; IBaseFilter *pVCap; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) { // this is the one we want. Get its name, and instantiate it. IPropertyBag *pBag; achFriendlyName[0] = 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, achFriendlyName, 80, NULL, NULL); SysFreeString(var.bstrVal); if (!bsearch) // если не поиск, то заполняем список psa->Add(achFriendlyName); else // иначе ищем такое же имя if (refs->CompareNoCase(achFriendlyName) == 0){ // если строки одинаковы (НАШЛИ!!!) pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&pVCap); pBag->Release(); pM->Release(); pEm->Release(); return pVCap; } } pBag->Release(); } pM->Release(); } pEm->Release(); return NULL; }
bool CFrameGrabber::Run() { if (m_bCapturing) return true; // уже выполняемся // run the graph IMediaControl *pMC = NULL; HRESULT hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC); if (FAILED(hr)) return false; hr = pMC->Run(); if (FAILED(hr)) { // stop parts that started pMC->Stop(); pMC->Release(); return false; } pMC->Release(); m_bCapturing = true; return true; }
void CFrameGrabber::Stop() { if (!m_bCapturing) return; IMediaControl *pMC = NULL; HRESULT hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC); if (SUCCEEDED(hr)) hr = pMC->Stop(); pMC->Release(); }
void CFrameGrabber::ResetGraph() { SAFE_RELEASE(m_pBuilder); SAFE_RELEASE(m_pGraph); delete m_pGrabber; }
void CFrameGrabber::CreateGraph() { // capture graph builder HRESULT hr = CoCreateInstance((REFCLSID)CLSID_CaptureGraphBuilder, NULL, CLSCTX_INPROC, (REFIID)IID_ICaptureGraphBuilder,(void **)&m_pBuilder); ASSERT(SUCCEEDED(hr)); // simple graph builder hr = CoCreateInstance((REFCLSID)CLSID_FilterGraph, NULL, CLSCTX_INPROC, (REFIID)IID_IGraphBuilder,(void **)&m_pGraph); ASSERT(SUCCEEDED(hr)); // sample grabber m_pGrabber = new CSampleGrabber; hr = m_pBuilder->SetFiltergraph(m_pGraph); ASSERT(SUCCEEDED(hr)); // добавляем фильтры в граф m_pGrabber->AddToGraph(m_pGraph); }
bool CFrameGrabber::ConstructCaptureGraph(CString capdev) { // нашли выбранное устройство SAFE_RELEASE(m_camera); m_camera = SelectDevice(capdev); HRESULT hr; if (m_camera)| // capture driver WCHAR ws[] = {'U','M','_','C','A','P','T','U','R','E',0}; hr = m_pGraph->AddFilter(m_camera,ws); QueryGraphInfo(m_pGraph); m_pGrabber->SetVideoFormat(); hr = m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, m_camera, m_pGrabber->m_pFilter, m_pGrabber->m_pNullRenderer); if (FAILED(hr)) return false; QueryGraphInfo(m_pGraph); hr = m_pGrabber->m_pGrabber->SetOneShot(false); if (FAILED(hr)) return false; // убираем синхронизацию IMediaFilter *pmf; hr = m_pGraph->QueryInterface(IID_IMediaFilter,(void**)&pmf); if (SUCCEEDED(hr)){ hr = pmf->SetSyncSource(NULL); pmf->Release(); } } return hr == S_OK; }
void CFrameGrabber::ListGraphFilters() { IEnumFilters *pEnum; m_pGraph->EnumFilters(&pEnum);
HRESULT hr; IBaseFilter *pf; FILTER_INFO fi; ULONG cFetched; char achFriendlyName[128]; while(hr = pEnum->Next(1, &pf, &cFetched), hr==S_OK) { // this is the one we want. Get its name, and instantiate it. pf->QueryFilterInfo(&fi); achFriendlyName[0] = 0; WideCharToMultiByte(CP_ACP, 0, fi.achName, -1, achFriendlyName, 80, NULL, NULL); pf->Release(); } pEnum->Release(); }
void CFrameGrabber::QueryGraphInfo(IGraphBuilder *pgb) { #ifdef _DEBUG IEnumFilters *pfenum; m_pGraph->EnumFilters(&pfenum); ULONG cbFetched; IBaseFilter *pf; FILTER_INFO fi; while(pfenum->Next(1,&pf,&cbFetched)==S_OK && cbFetched == 1){ pf->QueryFilterInfo(&fi); afxDump << "Filter [" << fi.achName << "] at address " << pf << "\n"; // name of filter IEnumPins *ppenum; pf->EnumPins(&ppenum); IPin* pp; PIN_INFO pi; while(ppenum->Next(1,&pp,&cbFetched)==S_OK && cbFetched == 1){ pp->QueryPinInfo(&pi); CString sdir = pi.dir == PINDIR_INPUT ? "IN" : "OUT"; afxDump << "\t " << sdir << " pin [" << pi.achName << "] at address "<< pp; // name of pin IPin *ptemp; HRESULT hr = pp->ConnectedTo(&ptemp); if (hr == S_OK){ afxDump << " is connected to pin at " << ptemp << "\n"; ptemp->Release(); } else afxDump << " is NOT connected!\n"; } pp->Release(); ppenum->Release(); pf->Release(); } pfenum->Release(); #endif }
void CSampleGrabber::AddToGraph(IGraphBuilder *pgraph) { pgraph->AddFilter(m_pFilter,WSTR("SampleGrabber")); pgraph->AddFilter(m_pNullRenderer,WSTR("NULL_Renderer")); SetVideoFormat(); }
bool CSampleGrabber::ReconfigureGraph(IGraphBuilder *pgraph) { IPin *pin; HRESULT hr = m_pInputPin->ConnectedTo(&pin); // если же мы не соединены, то ... // ... смотрим пины у рендерера IPin *pp; IEnumPins *penum; ULONG cbReturned; m_pNullRenderer->EnumPins(&penum); penum->Next(1,&pp,&cbReturned); // только один пин ULONG u = penum->Release(); hr = pp->ConnectedTo(&pin); // получаем пин, с которым соединен рендерер SelectBestCompatibleFormat(pin); hr = pgraph->Disconnect(pin); // удаляем соединение hr = pgraph->Disconnect(pp); // удаляем соединение u = pp->Release(); // соединяем заново hr = pgraph->ConnectDirect(pin,m_pInputPin,NULL); hr = pgraph->Render(m_pOutputPin); // соединяем с рендерером u = pin->Release(); return true; }
bool CSampleGrabber::SelectBestCompatibleFormat(IPin *ppin) { IEnumMediaTypes *penum; ppin->EnumMediaTypes(&penum); AM_MEDIA_TYPE *pmt; GUID fmt; ULONG cbReturned; BYTE check = 0xFF; // nothing is selected // ищем только RGB uncompressed formats while(penum->Next(1,&pmt,&cbReturned)==S_OK && cbReturned == 1){ if (IsEqualGUID(pmt->subtype,MEDIASUBTYPE_RGB24)){ check = 0; fmt = MEDIASUBTYPE_RGB24; } else if (IsEqualGUID(pmt->subtype,MEDIASUBTYPE_RGB32) && check>1){ check = 1; // we found it fmt = MEDIASUBTYPE_RGB32; } else if (IsEqualGUID(pmt->subtype,MEDIASUBTYPE_RGB565) && check>2){ check = 2; // we found it fmt = MEDIASUBTYPE_RGB565; } else if (IsEqualGUID(pmt->subtype,MEDIASUBTYPE_RGB555) && check>3){ check = 3; // we found it fmt = MEDIASUBTYPE_RGB555; } else if (IsEqualGUID(pmt->subtype,MEDIASUBTYPE_RGB8) && check>4){ check = 4; // we found it fmt = MEDIASUBTYPE_RGB8; } DeleteMediaType(pmt); } penum->Release(); if (check < 5){ SetVideoFormat(fmt); return true; } return false; }
void* CFrameGrabber::RecieveBitmap() { long cbBuffer = 0; HRESULT hr = m_pGrabber->m_pGrabber->GetCurrentBuffer(&cbBuffer, NULL); if (FAILED(hr)) return NULL; void *pBuffer = malloc(cbBuffer); hr = m_pGrabber->m_pGrabber->GetCurrentBuffer(&cbBuffer,(long*)pBuffer); return pBuffer; }
static bool in_thread = false;
UINT ConfigureCamera_thread( LPVOID pParam ) { in_thread = true; CFrameGrabber* pfg = (CFrameGrabber*)pParam; IBaseFilter* pcamera = pfg->m_camera; if (!pcamera) return 0; ISpecifyPropertyPages *pProp; HRESULT hr = pcamera->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp); if (SUCCEEDED(hr)) { // Get the filter's name and IUnknown pointer. FILTER_INFO FilterInfo; pcamera->QueryFilterInfo(&FilterInfo); IUnknown* pfilterUnk; pcamera->QueryInterface(IID_IUnknown, (void **)&pfilterUnk); // Show the page. CAUUID caGUID; pProp->GetPages(&caGUID); pProp->Release(); OleCreatePropertyFrame( NULL, // Parent window 0, 0, // (Reserved) FilterInfo.achName, // Caption for the dialog box 1, // Number of objects (just the filter) &pfilterUnk, // Array of object pointers. caGUID.cElems, // Number of property pages caGUID.pElems, // Array of property page CLSIDs 0, // Locale identifier 0, NULL // Reserved ); // Clean up. pfilterUnk->Release(); FilterInfo.pGraph->Release(); CoTaskMemFree(caGUID.pElems); } ReleaseMutex(pfg->mutex); in_thread = false; return 0; }
IUnknown* GetPropPages(IBaseFilter* filter,CAUUID* pcaGUID) { ISpecifyPropertyPages *pProp; HRESULT hr = filter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp); IUnknown* pfilterUnk=NULL; if (SUCCEEDED(hr)) { // Get the filter's name and IUnknown pointer. FILTER_INFO FilterInfo; filter->QueryFilterInfo(&FilterInfo); filter->QueryInterface(IID_IUnknown, (void **)&pfilterUnk); FilterInfo.pGraph->Release(); if (pfilterUnk){ pProp->GetPages(pcaGUID); pProp->Release(); } } return pfilterUnk; }
UINT ConfigureCamera_thread_new( LPVOID pParam ) { CFrameGrabber* pfg = (CFrameGrabber*)pParam; IBaseFilter* pcamera = pfg->m_camera; if (!pcamera) return 0; in_thread = true; IEnumFilters *pfenum; pfg->m_pGraph->EnumFilters(&pfenum); IUnknown* punk[100]; memset(punk,0,sizeof(IUnknown*)); GUID guids[100]; CAUUID caGUID = |0,guids"; DWORD cbFetched; long num=0; IBaseFilter* pf; while(pfenum->Next(1,&pf,&cbFetched)==S_OK && cbFetched == 1){ CAUUID tmpGUID; IUnknown* unk = GetPropPages(pf,&tmpGUID); pf->Release(); if (!unk) continue; num++; WCHAR wch[] = {'C','A','P',0}; DWORD dw = OleCreatePropertyFrame( NULL, // Parent window 0, 0, // (Reserved) wch, // Caption for the dialog box 1, // Number of objects (just the filter) &unk, // Array of object pointers. tmpGUID.cElems, // Number of property pages tmpGUID.pElems, // Array of property page CLSIDs 0, // Locale identifier 0, NULL // Reserved ); CoTaskMemFree(tmpGUID.pElems); unk->Release(); } pfenum->Release();
ReleaseMutex(pfg->mutex); in_thread = false; return 0; }
void CFrameGrabber::ConfigureCamera() { if (!in_thread) AfxBeginThread(&ConfigureCamera_thread_new,this); }
|
|
« Последнее редактирование: 23-11-2007 15:20 от Алексей1153++ »
|
Записан
|
|
|
|