ARToolKit | Mailing List Archive |
![]() |
From: | Gerhard Reitmayr <reitmayr@i ...............> | Received: | Jan 18, 2002 |
To | artoolkit <artoolkit@h ..................> | ||
Subject: | Some more mods to ARFrameGrabber :) | ||
This is a multi-part message in MIME format. --------------030709010201000802050902 Content-Type: Content-Transfer-Encoding: 8bit Hi, I added the ability to define a video image size during initialization. It simlpy sets the first media type it finds that fits the desired format. If none is found, it doesn't change the default format. In any case there are to member functions that let you query the size of the video image. maybe somebody finds this useful. please use the changes as you like. bye, Gerhard -- Gerhard Reitmayr mailto:reitmayr@i ............... tel:++ 43 1 58801 18856 Interactive Media Systems Group Vienna University of Technology --------------030709010201000802050902 Content-Type: text/plain; charset=windows-1252; name="ARFrameG.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ARFrameG.h" // ARFrameGrabber.h: interface for the ARFrameGrabber class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_) #define AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <dshow.h> //#include <streams.h> #include <atlbase.h> #include <qedit.h> class SmartString { public: SmartString():str(NULL) {} SmartString(char* pStr):str(NULL) { if (pStr) { int size = strlen(pStr); str = new char[size+1]; strcpy(str, pStr); } } SmartString(SmartString& sStr) { SetString(sStr.GetBuffer()); } ~SmartString() { if (str) delete[] str; } SmartString& operator =(char* pStr) { SetString(pStr); return *this; } SmartString& operator =(SmartString& sStr) { SetString(sStr.GetBuffer()); return *this; } char* GetBuffer() {return str;} protected: void SetString(char *pStr) { if (str) delete[] str; if (!pStr) { str = NULL; } else { int size = strlen(pStr); str = new char[size + 1]; strcpy(str, pStr); } } char* str; }; struct DeviceInfo { DeviceInfo():next(NULL), deviceId(-1) { } ~DeviceInfo() { if (next) delete next; } SmartString friendlyName; int deviceId; DeviceInfo* next; }; class ARFrameGrabber { public: ARFrameGrabber(); virtual ~ARFrameGrabber(); void Init(int deviceId, int = 0, int = 0); void BindFilter(int deviceId, IBaseFilter **pFilter); void GrabFrame(long* size, long** pBuffer); void GrabFrame(); void Grab32BitFrame(); long GetBufferSize() {return bufferSize;} long* GetBuffer() {return pBuffer;} void SetFlippedImageHorizontal(bool flag) {flipImageH = flag;} void SetFlippedImageVertical(bool flag) {flipImageV = flag;} void SetFlippedImage(bool flag) {flipImageV =flag; flipImageH = flag;} void DisplayProperties(); void EnumDevices(DeviceInfo *head); int GetWidth() { return width; } int GetHeight() { return height; } protected: CComPtr<IGraphBuilder> pGraph; CComPtr<IBaseFilter> pDeviceFilter; CComPtr<IMediaControl> pMediaControl; CComPtr<IBaseFilter> pSampleGrabberFilter; CComPtr<ISampleGrabber> pSampleGrabber; CComPtr<IPin> pGrabberInput; CComPtr<IPin> pGrabberOutput; CComPtr<IPin> pCameraOutput; CComPtr<IMediaEvent> pMediaEvent; CComPtr<IBaseFilter> pNullFilter; CComPtr<IPin> pNullInputPin; void FlipImage(long* pBuf); private: void ReportError(char *msg); int width; int height; bool flipImageH; bool flipImageV; long bufferSize; long *pBuffer; }; #endif // !defined(AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_) --------------030709010201000802050902 Content-Type: text/plain; charset=windows-1252; name="ARFrameG.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ARFrameG.cpp" // ARFrameGrabber.cpp: implementation of the ARFrameGrabber class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ARFrameGrabber.h" void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// ARFrameGrabber::ARFrameGrabber():pBuffer(NULL), bufferSize(0), flipImageV(false), flipImageH(false) { } ARFrameGrabber::~ARFrameGrabber() { pMediaControl->Stop(); } void ARFrameGrabber::Init(int deviceId, int width_, int height_) { HRESULT hr = S_OK; // Create the Filter Graph Manager. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph); hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID *)&pSampleGrabberFilter); hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMediaControl); hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pMediaEvent); hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID*) &pNullFilter); hr = pGraph->AddFilter(pNullFilter, L"NullRenderer"); hr = pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&pSampleGrabber); AM_MEDIA_TYPE mt; ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB32; mt.formattype = FORMAT_VideoInfo; hr = pSampleGrabber->SetMediaType(&mt); pGraph->AddFilter(pSampleGrabberFilter, L"Grabber"); // Bind Device Filter. We know the device because the id was passed in BindFilter(deviceId, &pDeviceFilter); pGraph->AddFilter(pDeviceFilter, NULL); CComPtr<IEnumPins> pEnum; pDeviceFilter->EnumPins(&pEnum); hr = pEnum->Reset(); hr = pEnum->Next(1, &pCameraOutput, NULL); pEnum = NULL; pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); hr = pEnum->Next(1, &pGrabberInput, NULL); pEnum = NULL; pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); pEnum->Skip(1); hr = pEnum->Next(1, &pGrabberOutput, NULL); pEnum = NULL; pNullFilter->EnumPins(&pEnum); pEnum->Reset(); hr = pEnum->Next(1, &pNullInputPin, NULL); // Set the grabbing size // First we iterate through the available media types and // store the first one that fits the requested size. // If we have found one, we set it. // In any case we query the size of the current media type // to have this information for clients of this class. // Gerhard Reitmayr <reitmayr@i ...............> CComPtr<IAMStreamConfig> pConfig; IEnumMediaTypes *pMedia; AM_MEDIA_TYPE *pmt = NULL, *pfnt = NULL; hr = pCameraOutput->EnumMediaTypes( &pMedia ); if(SUCCEEDED(hr)) { while(pMedia->Next(1, &pmt, 0) == S_OK) { if( pmt->formattype == FORMAT_VideoInfo ) { VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pmt->pbFormat; // printf("Size %i %i\n", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight ); if( vih->bmiHeader.biWidth == width_ && vih->bmiHeader.biHeight == height_ ) { pfnt = pmt; // printf("found mediatype with %i %i\n", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight ); break; } DeleteMediaType( pmt ); //delete pmt; } } pMedia->Release(); } hr = pCameraOutput->QueryInterface( IID_IAMStreamConfig, (void **) &pConfig ); if(SUCCEEDED(hr)) { if( pfnt != NULL ) { pConfig->SetFormat( pfnt ); DeleteMediaType( pfnt ); //delete pfnt; } hr = pConfig->GetFormat( &pfnt ); if(SUCCEEDED(hr)) { width = ((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biWidth; height = ((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biHeight; } } hr = pGraph->Connect(pCameraOutput, pGrabberInput); hr = pGraph->Connect(pGrabberOutput, pNullInputPin); // hr = pGraph->Render(pGrabberOutput); if (FAILED(hr)) { switch(hr) { case VFW_S_NOPREVIEWPIN : break; case E_FAIL : break; case E_INVALIDARG : break; case E_POINTER : break; } } pSampleGrabber->SetBufferSamples(TRUE); pSampleGrabber->SetOneShot(TRUE); } void ARFrameGrabber::GrabFrame(long* size, long** pBuffer) { if (!size) return; // don't want to leak mem, pBuffer must be NULL if (!pBuffer || *pBuffer) return; long evCode; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(size, NULL); if (*size) { *pBuffer = new long[*size]; } pSampleGrabber->GetCurrentBuffer(size, *pBuffer); } void ARFrameGrabber::GrabFrame() { long evCode; long size = 0; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(&size, NULL); // if buffer is not the same size as before, create a new one if (size != bufferSize) { if (pBuffer) delete[] pBuffer; bufferSize = size; pBuffer = new long[bufferSize]; } pSampleGrabber->GetCurrentBuffer(&size, pBuffer); if (flipImageV | flipImageH) FlipImage(pBuffer); } void ARFrameGrabber::FlipImage(long* pBuf) { DWORD *ptr = (DWORD*)pBuf; int pixelCount = bufferSize/4; if (!pBuf) return; // Added code for more image manipulations // Gerhard Reitmayr <reitmayr@i ............... if( flipImageV ) { if( flipImageH ) { // both flips set -> rotation about 180 degree for (int index = 0; index < pixelCount/2; index++) { ptr[index] = ptr[index] ^ ptr[pixelCount - index - 1]; ptr[pixelCount - index - 1] = ptr[index] ^ ptr[pixelCount - index - 1]; ptr[index] = ptr[index] ^ ptr[pixelCount - index - 1]; } } else { // only vertical flip for( int line = 0; line < height/2; line++ ) for( int pixel = 0; pixel < width; pixel ++ ) { ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; ptr[pixelCount - line*width - (width - pixel )] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; } } } else { if( flipImageH ) { // only horizontal flip for( int line = 0; line < height; line++ ) for( int pixel = 0; pixel < width/2; pixel ++ ) { ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; ptr[line*width + (width - pixel )] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; } } } } void ARFrameGrabber::Grab32BitFrame() { long evCode; long size = 0; long* pData; unsigned char* pTemp; unsigned char* ptr; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(&size, NULL); if (size != bufferSize) { if (pBuffer) delete[] pBuffer; bufferSize = size/3*4; // add space for padding pBuffer = new long[bufferSize]; } pData= (long*) new unsigned char[size]; pSampleGrabber->GetCurrentBuffer(&size, pData); ptr = ((unsigned char*)pBuffer) + bufferSize - 1; pTemp = (unsigned char*) pData; // do the padding for (int index = 0; index < size/3; index++) { unsigned char r = *(pTemp++); unsigned char g = *(pTemp++); unsigned char b = *(pTemp++); *(ptr--) = 0; *(ptr--) = b; *(ptr--) = g; *(ptr--) = r; } /* for (int index = 0; index < size; index++) { *ptr = ((unsigned char *)pTemp)[index]; ptr--; if (index % 3 == 2) { *ptr = 0; ptr--; } } */ delete[] pData; } void ARFrameGrabber::BindFilter(int deviceId, IBaseFilter **pFilter) { if (deviceId < 0) return; // enumerate all video capture devices CComPtr<ICreateDevEnum> pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr<IEnumMoniker> pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR) { // ErrMsg("Sorry, you have no video capture hardware"); return; } pEm->Reset(); ULONG cFetched; IMoniker *pM; int index = 0; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId) { 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 (index == deviceId) { pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter); } SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); index++; } } void ARFrameGrabber::DisplayProperties() { CComPtr<ISpecifyPropertyPages> pPages; HRESULT hr = pCameraOutput->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages); if (SUCCEEDED(hr)) { PIN_INFO PinInfo; pCameraOutput->QueryPinInfo(&PinInfo); CAUUID caGUID; pPages->GetPages(&caGUID); OleCreatePropertyFrame( NULL, 0, 0, L"Property Sheet", 1, (IUnknown **)&(pCameraOutput.p), caGUID.cElems, caGUID.pElems, 0, 0, NULL); CoTaskMemFree(caGUID.pElems); PinInfo.pFilter->Release(); } } void ARFrameGrabber::EnumDevices(DeviceInfo *head) { if (!head) return; DeviceInfo *ptr = head; int id = 0; // enumerate all video capture devices CComPtr<ICreateDevEnum> pCreateDevEnum; // ICreateDevEnum *pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr<IEnumMoniker> pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR) { // ErrMsg("Sorry, you have no video capture hardware"); return; } 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; hr = pBag->Read(L"FriendlyName", &var, NULL); if (hr == NOERROR) { char str[2048]; if (ptr->deviceId != -1) { ptr->next = new DeviceInfo(); ptr = ptr->next; } ptr->deviceId = id++; WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL); ptr->friendlyName = str; SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); } } void ARFrameGrabber::ReportError(char *msg) { MessageBox(NULL, msg, "ARFrameGrabber Error", MB_ICONSTOP); } // delete a media type, copied from the dshow base classes void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt) { // allow NULL pointers for coding simplicity if (pmt == NULL) { return; } if (pmt->cbFormat != 0) { CoTaskMemFree((PVOID)pmt->pbFormat); // Strictly unnecessary but tidier pmt->cbFormat = 0; pmt->pbFormat = NULL; } if (pmt->pUnk != NULL) { pmt->pUnk->Release(); pmt->pUnk = NULL; } CoTaskMemFree((PVOID)pmt); } --------------030709010201000802050902-- |
From: | Gerhard Reitmayr <reitmayr@i ...............> | Received: | Jan 18, 2002 |
To | artoolkit <artoolkit@h ..................> | ||
Subject: | Some more mods to ARFrameGrabber :) | ||
This is a multi-part message in MIME format. --------------000700090700010304040409 Content-Type: Content-Transfer-Encoding: 8bit Hi, I added the ability to define a video image size during initialization. It simlpy sets the first media type it finds that fits the desired format. If none is found, it doesn't change the default format. In any case there are to member functions that let you query the size of the video image. maybe somebody finds this useful. please use the changes as you like. bye, Gerhard -- Gerhard Reitmayr mailto:reitmayr@i ............... tel:++ 43 1 58801 18856 Interactive Media Systems Group Vienna University of Technology --------------000700090700010304040409 Content-Type: text/plain; charset=windows-1252; name="ARFrameG.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ARFrameG.h" // ARFrameGrabber.h: interface for the ARFrameGrabber class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_) #define AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <dshow.h> //#include <streams.h> #include <atlbase.h> #include <qedit.h> class SmartString { public: SmartString():str(NULL) {} SmartString(char* pStr):str(NULL) { if (pStr) { int size = strlen(pStr); str = new char[size+1]; strcpy(str, pStr); } } SmartString(SmartString& sStr) { SetString(sStr.GetBuffer()); } ~SmartString() { if (str) delete[] str; } SmartString& operator =(char* pStr) { SetString(pStr); return *this; } SmartString& operator =(SmartString& sStr) { SetString(sStr.GetBuffer()); return *this; } char* GetBuffer() {return str;} protected: void SetString(char *pStr) { if (str) delete[] str; if (!pStr) { str = NULL; } else { int size = strlen(pStr); str = new char[size + 1]; strcpy(str, pStr); } } char* str; }; struct DeviceInfo { DeviceInfo():next(NULL), deviceId(-1) { } ~DeviceInfo() { if (next) delete next; } SmartString friendlyName; int deviceId; DeviceInfo* next; }; class ARFrameGrabber { public: ARFrameGrabber(); virtual ~ARFrameGrabber(); void Init(int deviceId, int = 0, int = 0); void BindFilter(int deviceId, IBaseFilter **pFilter); void GrabFrame(long* size, long** pBuffer); void GrabFrame(); void Grab32BitFrame(); long GetBufferSize() {return bufferSize;} long* GetBuffer() {return pBuffer;} void SetFlippedImageHorizontal(bool flag) {flipImageH = flag;} void SetFlippedImageVertical(bool flag) {flipImageV = flag;} void SetFlippedImage(bool flag) {flipImageV =flag; flipImageH = flag;} void DisplayProperties(); void EnumDevices(DeviceInfo *head); int GetWidth() { return width; } int GetHeight() { return height; } protected: CComPtr<IGraphBuilder> pGraph; CComPtr<IBaseFilter> pDeviceFilter; CComPtr<IMediaControl> pMediaControl; CComPtr<IBaseFilter> pSampleGrabberFilter; CComPtr<ISampleGrabber> pSampleGrabber; CComPtr<IPin> pGrabberInput; CComPtr<IPin> pGrabberOutput; CComPtr<IPin> pCameraOutput; CComPtr<IMediaEvent> pMediaEvent; CComPtr<IBaseFilter> pNullFilter; CComPtr<IPin> pNullInputPin; void FlipImage(long* pBuf); private: void ReportError(char *msg); int width; int height; bool flipImageH; bool flipImageV; long bufferSize; long *pBuffer; }; #endif // !defined(AFX_ARFRAMEGRABBER_H__C5553937_4BAB_4FEF_B4A6_1693AB0C99E3__INCLUDED_) --------------000700090700010304040409 Content-Type: text/plain; charset=windows-1252; name="ARFrameG.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ARFrameG.cpp" // ARFrameGrabber.cpp: implementation of the ARFrameGrabber class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ARFrameGrabber.h" void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// ARFrameGrabber::ARFrameGrabber():pBuffer(NULL), bufferSize(0), flipImageV(false), flipImageH(false) { } ARFrameGrabber::~ARFrameGrabber() { pMediaControl->Stop(); } void ARFrameGrabber::Init(int deviceId, int width_, int height_) { HRESULT hr = S_OK; // Create the Filter Graph Manager. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph); hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID *)&pSampleGrabberFilter); hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMediaControl); hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pMediaEvent); hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID*) &pNullFilter); hr = pGraph->AddFilter(pNullFilter, L"NullRenderer"); hr = pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&pSampleGrabber); AM_MEDIA_TYPE mt; ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB32; mt.formattype = FORMAT_VideoInfo; hr = pSampleGrabber->SetMediaType(&mt); pGraph->AddFilter(pSampleGrabberFilter, L"Grabber"); // Bind Device Filter. We know the device because the id was passed in BindFilter(deviceId, &pDeviceFilter); pGraph->AddFilter(pDeviceFilter, NULL); CComPtr<IEnumPins> pEnum; pDeviceFilter->EnumPins(&pEnum); hr = pEnum->Reset(); hr = pEnum->Next(1, &pCameraOutput, NULL); pEnum = NULL; pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); hr = pEnum->Next(1, &pGrabberInput, NULL); pEnum = NULL; pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); pEnum->Skip(1); hr = pEnum->Next(1, &pGrabberOutput, NULL); pEnum = NULL; pNullFilter->EnumPins(&pEnum); pEnum->Reset(); hr = pEnum->Next(1, &pNullInputPin, NULL); // Set the grabbing size // First we iterate through the available media types and // store the first one that fits the requested size. // If we have found one, we set it. // In any case we query the size of the current media type // to have this information for clients of this class. // Gerhard Reitmayr <reitmayr@i ...............> CComPtr<IAMStreamConfig> pConfig; IEnumMediaTypes *pMedia; AM_MEDIA_TYPE *pmt = NULL, *pfnt = NULL; hr = pCameraOutput->EnumMediaTypes( &pMedia ); if(SUCCEEDED(hr)) { while(pMedia->Next(1, &pmt, 0) == S_OK) { if( pmt->formattype == FORMAT_VideoInfo ) { VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pmt->pbFormat; // printf("Size %i %i\n", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight ); if( vih->bmiHeader.biWidth == width_ && vih->bmiHeader.biHeight == height_ ) { pfnt = pmt; // printf("found mediatype with %i %i\n", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight ); break; } DeleteMediaType( pmt ); //delete pmt; } } pMedia->Release(); } hr = pCameraOutput->QueryInterface( IID_IAMStreamConfig, (void **) &pConfig ); if(SUCCEEDED(hr)) { if( pfnt != NULL ) { pConfig->SetFormat( pfnt ); DeleteMediaType( pfnt ); //delete pfnt; } hr = pConfig->GetFormat( &pfnt ); if(SUCCEEDED(hr)) { width = ((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biWidth; height = ((VIDEOINFOHEADER *)pmt->pbFormat)->bmiHeader.biHeight; } } hr = pGraph->Connect(pCameraOutput, pGrabberInput); hr = pGraph->Connect(pGrabberOutput, pNullInputPin); // hr = pGraph->Render(pGrabberOutput); if (FAILED(hr)) { switch(hr) { case VFW_S_NOPREVIEWPIN : break; case E_FAIL : break; case E_INVALIDARG : break; case E_POINTER : break; } } pSampleGrabber->SetBufferSamples(TRUE); pSampleGrabber->SetOneShot(TRUE); } void ARFrameGrabber::GrabFrame(long* size, long** pBuffer) { if (!size) return; // don't want to leak mem, pBuffer must be NULL if (!pBuffer || *pBuffer) return; long evCode; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(size, NULL); if (*size) { *pBuffer = new long[*size]; } pSampleGrabber->GetCurrentBuffer(size, *pBuffer); } void ARFrameGrabber::GrabFrame() { long evCode; long size = 0; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(&size, NULL); // if buffer is not the same size as before, create a new one if (size != bufferSize) { if (pBuffer) delete[] pBuffer; bufferSize = size; pBuffer = new long[bufferSize]; } pSampleGrabber->GetCurrentBuffer(&size, pBuffer); if (flipImageV | flipImageH) FlipImage(pBuffer); } void ARFrameGrabber::FlipImage(long* pBuf) { DWORD *ptr = (DWORD*)pBuf; int pixelCount = bufferSize/4; if (!pBuf) return; // Added code for more image manipulations // Gerhard Reitmayr <reitmayr@i ............... if( flipImageV ) { if( flipImageH ) { // both flips set -> rotation about 180 degree for (int index = 0; index < pixelCount/2; index++) { ptr[index] = ptr[index] ^ ptr[pixelCount - index - 1]; ptr[pixelCount - index - 1] = ptr[index] ^ ptr[pixelCount - index - 1]; ptr[index] = ptr[index] ^ ptr[pixelCount - index - 1]; } } else { // only vertical flip for( int line = 0; line < height/2; line++ ) for( int pixel = 0; pixel < width; pixel ++ ) { ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; ptr[pixelCount - line*width - (width - pixel )] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; } } } else { if( flipImageH ) { // only horizontal flip for( int line = 0; line < height; line++ ) for( int pixel = 0; pixel < width/2; pixel ++ ) { ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; ptr[line*width + (width - pixel )] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; } } } } void ARFrameGrabber::Grab32BitFrame() { long evCode; long size = 0; long* pData; unsigned char* pTemp; unsigned char* ptr; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(&size, NULL); if (size != bufferSize) { if (pBuffer) delete[] pBuffer; bufferSize = size/3*4; // add space for padding pBuffer = new long[bufferSize]; } pData= (long*) new unsigned char[size]; pSampleGrabber->GetCurrentBuffer(&size, pData); ptr = ((unsigned char*)pBuffer) + bufferSize - 1; pTemp = (unsigned char*) pData; // do the padding for (int index = 0; index < size/3; index++) { unsigned char r = *(pTemp++); unsigned char g = *(pTemp++); unsigned char b = *(pTemp++); *(ptr--) = 0; *(ptr--) = b; *(ptr--) = g; *(ptr--) = r; } /* for (int index = 0; index < size; index++) { *ptr = ((unsigned char *)pTemp)[index]; ptr--; if (index % 3 == 2) { *ptr = 0; ptr--; } } */ delete[] pData; } void ARFrameGrabber::BindFilter(int deviceId, IBaseFilter **pFilter) { if (deviceId < 0) return; // enumerate all video capture devices CComPtr<ICreateDevEnum> pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr<IEnumMoniker> pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR) { // ErrMsg("Sorry, you have no video capture hardware"); return; } pEm->Reset(); ULONG cFetched; IMoniker *pM; int index = 0; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId) { 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 (index == deviceId) { pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter); } SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); index++; } } void ARFrameGrabber::DisplayProperties() { CComPtr<ISpecifyPropertyPages> pPages; HRESULT hr = pCameraOutput->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages); if (SUCCEEDED(hr)) { PIN_INFO PinInfo; pCameraOutput->QueryPinInfo(&PinInfo); CAUUID caGUID; pPages->GetPages(&caGUID); OleCreatePropertyFrame( NULL, 0, 0, L"Property Sheet", 1, (IUnknown **)&(pCameraOutput.p), caGUID.cElems, caGUID.pElems, 0, 0, NULL); CoTaskMemFree(caGUID.pElems); PinInfo.pFilter->Release(); } } void ARFrameGrabber::EnumDevices(DeviceInfo *head) { if (!head) return; DeviceInfo *ptr = head; int id = 0; // enumerate all video capture devices CComPtr<ICreateDevEnum> pCreateDevEnum; // ICreateDevEnum *pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr<IEnumMoniker> pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR) { // ErrMsg("Sorry, you have no video capture hardware"); return; } 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; hr = pBag->Read(L"FriendlyName", &var, NULL); if (hr == NOERROR) { char str[2048]; if (ptr->deviceId != -1) { ptr->next = new DeviceInfo(); ptr = ptr->next; } ptr->deviceId = id++; WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL); ptr->friendlyName = str; SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); } } void ARFrameGrabber::ReportError(char *msg) { MessageBox(NULL, msg, "ARFrameGrabber Error", MB_ICONSTOP); } // delete a media type, copied from the dshow base classes void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt) { // allow NULL pointers for coding simplicity if (pmt == NULL) { return; } if (pmt->cbFormat != 0) { CoTaskMemFree((PVOID)pmt->pbFormat); // Strictly unnecessary but tidier pmt->cbFormat = 0; pmt->pbFormat = NULL; } if (pmt->pUnk != NULL) { pmt->pUnk->Release(); pmt->pUnk = NULL; } CoTaskMemFree((PVOID)pmt); } --------------000700090700010304040409-- |
From: | Gerhard Reitmayr <reitmayr@i ...............> | Received: | Jan 23, 2002 |
To | artoolkit <artoolkit@h ..................> | ||
Subject: | Re: Some more mods to ARFrameGrabber :) | ||
This is a multi-part message in MIME format. --------------030002000900000205080807 Content-Type: Content-Transfer-Encoding: 8bit Hi, there was a bug in the last version of ARFrameGrabber I sent out. Using the wrong pointer variable in one place could yield a null pointer access :(. This file fixes it. bye, Gerhard Gerhard Reitmayr wrote: > Hi, > > I added the ability to define a video image size during initialization. > It simlpy sets the first media type it finds that fits the desired > format. If none is found, it doesn't change the default format. In any > case there are to member functions that let you query the size of the > video image. > > maybe somebody finds this useful. please use the changes as you like. > > bye, > Gerhard > > -- Gerhard Reitmayr mailto:reitmayr@i ............... tel:++ 43 1 58801 18856 Interactive Media Systems Group Vienna University of Technology --------------030002000900000205080807 Content-Type: text/plain; charset=windows-1252; name="ARFrameG.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ARFrameG.cpp" // ARFrameGrabber.cpp: implementation of the ARFrameGrabber class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ARFrameGrabber.h" void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// ARFrameGrabber::ARFrameGrabber():pBuffer(NULL), bufferSize(0), flipImageV(false), flipImageH(false) { } ARFrameGrabber::~ARFrameGrabber() { pMediaControl->Stop(); } void ARFrameGrabber::Init(int deviceId, int width_, int height_) { HRESULT hr = S_OK; // Create the Filter Graph Manager. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph); hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID *)&pSampleGrabberFilter); hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMediaControl); hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pMediaEvent); hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID*) &pNullFilter); hr = pGraph->AddFilter(pNullFilter, L"NullRenderer"); hr = pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&pSampleGrabber); AM_MEDIA_TYPE mt; ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB32; mt.formattype = FORMAT_VideoInfo; hr = pSampleGrabber->SetMediaType(&mt); pGraph->AddFilter(pSampleGrabberFilter, L"Grabber"); // Bind Device Filter. We know the device because the id was passed in BindFilter(deviceId, &pDeviceFilter); pGraph->AddFilter(pDeviceFilter, NULL); CComPtr<IEnumPins> pEnum; pDeviceFilter->EnumPins(&pEnum); hr = pEnum->Reset(); hr = pEnum->Next(1, &pCameraOutput, NULL); pEnum = NULL; pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); hr = pEnum->Next(1, &pGrabberInput, NULL); pEnum = NULL; pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); pEnum->Skip(1); hr = pEnum->Next(1, &pGrabberOutput, NULL); pEnum = NULL; pNullFilter->EnumPins(&pEnum); pEnum->Reset(); hr = pEnum->Next(1, &pNullInputPin, NULL); // Set the grabbing size // First we iterate through the available media types and // store the first one that fits the requested size. // If we have found one, we set it. // In any case we query the size of the current media type // to have this information for clients of this class. // Gerhard Reitmayr <reitmayr@i ...............> CComPtr<IAMStreamConfig> pConfig; IEnumMediaTypes *pMedia; AM_MEDIA_TYPE *pmt = NULL, *pfnt = NULL; hr = pCameraOutput->EnumMediaTypes( &pMedia ); if(SUCCEEDED(hr)) { while(pMedia->Next(1, &pmt, 0) == S_OK) { if( pmt->formattype == FORMAT_VideoInfo ) { VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pmt->pbFormat; // printf("Size %i %i\n", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight ); if( vih->bmiHeader.biWidth == width_ && vih->bmiHeader.biHeight == height_ ) { pfnt = pmt; // printf("found mediatype with %i %i\n", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight ); break; } DeleteMediaType( pmt ); } } pMedia->Release(); } hr = pCameraOutput->QueryInterface( IID_IAMStreamConfig, (void **) &pConfig ); if(SUCCEEDED(hr)) { if( pfnt != NULL ) { pConfig->SetFormat( pfnt ); DeleteMediaType( pfnt ); } hr = pConfig->GetFormat( &pfnt ); if(SUCCEEDED(hr)) { width = ((VIDEOINFOHEADER *)pfnt->pbFormat)->bmiHeader.biWidth; height = ((VIDEOINFOHEADER *)pfnt->pbFormat)->bmiHeader.biHeight; DeleteMediaType( pfnt ); } } hr = pGraph->Connect(pCameraOutput, pGrabberInput); hr = pGraph->Connect(pGrabberOutput, pNullInputPin); // hr = pGraph->Render(pGrabberOutput); if (FAILED(hr)) { switch(hr) { case VFW_S_NOPREVIEWPIN : break; case E_FAIL : break; case E_INVALIDARG : break; case E_POINTER : break; } } pSampleGrabber->SetBufferSamples(TRUE); pSampleGrabber->SetOneShot(TRUE); } void ARFrameGrabber::GrabFrame(long* size, long** pBuffer) { if (!size) return; // don't want to leak mem, pBuffer must be NULL if (!pBuffer || *pBuffer) return; long evCode; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(size, NULL); if (*size) { *pBuffer = new long[*size]; } pSampleGrabber->GetCurrentBuffer(size, *pBuffer); } void ARFrameGrabber::GrabFrame() { long evCode; long size = 0; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(&size, NULL); // if buffer is not the same size as before, create a new one if (size != bufferSize) { if (pBuffer) delete[] pBuffer; bufferSize = size; pBuffer = new long[bufferSize]; } pSampleGrabber->GetCurrentBuffer(&size, pBuffer); if (flipImageV | flipImageH) FlipImage(pBuffer); } void ARFrameGrabber::FlipImage(long* pBuf) { DWORD *ptr = (DWORD*)pBuf; int pixelCount = bufferSize/4; if (!pBuf) return; // Added code for more image manipulations // Gerhard Reitmayr <reitmayr@i ............... if( flipImageV ) { if( flipImageH ) { // both flips set -> rotation about 180 degree for (int index = 0; index < pixelCount/2; index++) { ptr[index] = ptr[index] ^ ptr[pixelCount - index - 1]; ptr[pixelCount - index - 1] = ptr[index] ^ ptr[pixelCount - index - 1]; ptr[index] = ptr[index] ^ ptr[pixelCount - index - 1]; } } else { // only vertical flip for( int line = 0; line < height/2; line++ ) for( int pixel = 0; pixel < width; pixel ++ ) { ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; ptr[pixelCount - line*width - (width - pixel )] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; } } } else { if( flipImageH ) { // only horizontal flip for( int line = 0; line < height; line++ ) for( int pixel = 0; pixel < width/2; pixel ++ ) { ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; ptr[line*width + (width - pixel )] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; } } } } void ARFrameGrabber::Grab32BitFrame() { long evCode; long size = 0; long* pData; unsigned char* pTemp; unsigned char* ptr; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(&size, NULL); if (size != bufferSize) { if (pBuffer) delete[] pBuffer; bufferSize = size/3*4; // add space for padding pBuffer = new long[bufferSize]; } pData= (long*) new unsigned char[size]; pSampleGrabber->GetCurrentBuffer(&size, pData); ptr = ((unsigned char*)pBuffer) + bufferSize - 1; pTemp = (unsigned char*) pData; // do the padding for (int index = 0; index < size/3; index++) { unsigned char r = *(pTemp++); unsigned char g = *(pTemp++); unsigned char b = *(pTemp++); *(ptr--) = 0; *(ptr--) = b; *(ptr--) = g; *(ptr--) = r; } /* for (int index = 0; index < size; index++) { *ptr = ((unsigned char *)pTemp)[index]; ptr--; if (index % 3 == 2) { *ptr = 0; ptr--; } } */ delete[] pData; } void ARFrameGrabber::BindFilter(int deviceId, IBaseFilter **pFilter) { if (deviceId < 0) return; // enumerate all video capture devices CComPtr<ICreateDevEnum> pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr<IEnumMoniker> pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR) { // ErrMsg("Sorry, you have no video capture hardware"); return; } pEm->Reset(); ULONG cFetched; IMoniker *pM; int index = 0; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId) { 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 (index == deviceId) { pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter); } SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); index++; } } void ARFrameGrabber::DisplayProperties() { CComPtr<ISpecifyPropertyPages> pPages; HRESULT hr = pCameraOutput->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages); if (SUCCEEDED(hr)) { PIN_INFO PinInfo; pCameraOutput->QueryPinInfo(&PinInfo); CAUUID caGUID; pPages->GetPages(&caGUID); OleCreatePropertyFrame( NULL, 0, 0, L"Property Sheet", 1, (IUnknown **)&(pCameraOutput.p), caGUID.cElems, caGUID.pElems, 0, 0, NULL); CoTaskMemFree(caGUID.pElems); PinInfo.pFilter->Release(); } } void ARFrameGrabber::EnumDevices(DeviceInfo *head) { if (!head) return; DeviceInfo *ptr = head; int id = 0; // enumerate all video capture devices CComPtr<ICreateDevEnum> pCreateDevEnum; // ICreateDevEnum *pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr<IEnumMoniker> pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR) { // ErrMsg("Sorry, you have no video capture hardware"); return; } 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; hr = pBag->Read(L"FriendlyName", &var, NULL); if (hr == NOERROR) { char str[2048]; if (ptr->deviceId != -1) { ptr->next = new DeviceInfo(); ptr = ptr->next; } ptr->deviceId = id++; WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL); ptr->friendlyName = str; SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); } } void ARFrameGrabber::ReportError(char *msg) { MessageBox(NULL, msg, "ARFrameGrabber Error", MB_ICONSTOP); } // delete a media type, copied from the dshow base classes void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt) { // allow NULL pointers for coding simplicity if (pmt == NULL) { return; } if (pmt->cbFormat != 0) { CoTaskMemFree((PVOID)pmt->pbFormat); // Strictly unnecessary but tidier pmt->cbFormat = 0; pmt->pbFormat = NULL; } if (pmt->pUnk != NULL) { pmt->pUnk->Release(); pmt->pUnk = NULL; } CoTaskMemFree((PVOID)pmt); } --------------030002000900000205080807-- |
From: | Gerhard Reitmayr <reitmayr@i ...............> | Received: | Jan 23, 2002 |
To | artoolkit <artoolkit@h ..................> | ||
Subject: | Re: Some more mods to ARFrameGrabber :) | ||
This is a multi-part message in MIME format. --------------050106070301000300080408 Content-Type: Content-Transfer-Encoding: 8bit Hi, there was a bug in the last version of ARFrameGrabber I sent out. Using the wrong pointer variable in one place could yield a null pointer access :(. This file fixes it. bye, Gerhard Gerhard Reitmayr wrote: > Hi, > > I added the ability to define a video image size during initialization. > It simlpy sets the first media type it finds that fits the desired > format. If none is found, it doesn't change the default format. In any > case there are to member functions that let you query the size of the > video image. > > maybe somebody finds this useful. please use the changes as you like. > > bye, > Gerhard > > -- Gerhard Reitmayr mailto:reitmayr@i ............... tel:++ 43 1 58801 18856 Interactive Media Systems Group Vienna University of Technology --------------050106070301000300080408 Content-Type: text/plain; charset=windows-1252; name="ARFrameG.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ARFrameG.cpp" // ARFrameGrabber.cpp: implementation of the ARFrameGrabber class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ARFrameGrabber.h" void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// ARFrameGrabber::ARFrameGrabber():pBuffer(NULL), bufferSize(0), flipImageV(false), flipImageH(false) { } ARFrameGrabber::~ARFrameGrabber() { pMediaControl->Stop(); } void ARFrameGrabber::Init(int deviceId, int width_, int height_) { HRESULT hr = S_OK; // Create the Filter Graph Manager. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph); hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID *)&pSampleGrabberFilter); hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMediaControl); hr = pGraph->QueryInterface(IID_IMediaEvent, (void **) &pMediaEvent); hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID*) &pNullFilter); hr = pGraph->AddFilter(pNullFilter, L"NullRenderer"); hr = pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&pSampleGrabber); AM_MEDIA_TYPE mt; ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB32; mt.formattype = FORMAT_VideoInfo; hr = pSampleGrabber->SetMediaType(&mt); pGraph->AddFilter(pSampleGrabberFilter, L"Grabber"); // Bind Device Filter. We know the device because the id was passed in BindFilter(deviceId, &pDeviceFilter); pGraph->AddFilter(pDeviceFilter, NULL); CComPtr<IEnumPins> pEnum; pDeviceFilter->EnumPins(&pEnum); hr = pEnum->Reset(); hr = pEnum->Next(1, &pCameraOutput, NULL); pEnum = NULL; pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); hr = pEnum->Next(1, &pGrabberInput, NULL); pEnum = NULL; pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); pEnum->Skip(1); hr = pEnum->Next(1, &pGrabberOutput, NULL); pEnum = NULL; pNullFilter->EnumPins(&pEnum); pEnum->Reset(); hr = pEnum->Next(1, &pNullInputPin, NULL); // Set the grabbing size // First we iterate through the available media types and // store the first one that fits the requested size. // If we have found one, we set it. // In any case we query the size of the current media type // to have this information for clients of this class. // Gerhard Reitmayr <reitmayr@i ...............> CComPtr<IAMStreamConfig> pConfig; IEnumMediaTypes *pMedia; AM_MEDIA_TYPE *pmt = NULL, *pfnt = NULL; hr = pCameraOutput->EnumMediaTypes( &pMedia ); if(SUCCEEDED(hr)) { while(pMedia->Next(1, &pmt, 0) == S_OK) { if( pmt->formattype == FORMAT_VideoInfo ) { VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pmt->pbFormat; // printf("Size %i %i\n", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight ); if( vih->bmiHeader.biWidth == width_ && vih->bmiHeader.biHeight == height_ ) { pfnt = pmt; // printf("found mediatype with %i %i\n", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight ); break; } DeleteMediaType( pmt ); } } pMedia->Release(); } hr = pCameraOutput->QueryInterface( IID_IAMStreamConfig, (void **) &pConfig ); if(SUCCEEDED(hr)) { if( pfnt != NULL ) { pConfig->SetFormat( pfnt ); DeleteMediaType( pfnt ); } hr = pConfig->GetFormat( &pfnt ); if(SUCCEEDED(hr)) { width = ((VIDEOINFOHEADER *)pfnt->pbFormat)->bmiHeader.biWidth; height = ((VIDEOINFOHEADER *)pfnt->pbFormat)->bmiHeader.biHeight; DeleteMediaType( pfnt ); } } hr = pGraph->Connect(pCameraOutput, pGrabberInput); hr = pGraph->Connect(pGrabberOutput, pNullInputPin); // hr = pGraph->Render(pGrabberOutput); if (FAILED(hr)) { switch(hr) { case VFW_S_NOPREVIEWPIN : break; case E_FAIL : break; case E_INVALIDARG : break; case E_POINTER : break; } } pSampleGrabber->SetBufferSamples(TRUE); pSampleGrabber->SetOneShot(TRUE); } void ARFrameGrabber::GrabFrame(long* size, long** pBuffer) { if (!size) return; // don't want to leak mem, pBuffer must be NULL if (!pBuffer || *pBuffer) return; long evCode; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(size, NULL); if (*size) { *pBuffer = new long[*size]; } pSampleGrabber->GetCurrentBuffer(size, *pBuffer); } void ARFrameGrabber::GrabFrame() { long evCode; long size = 0; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(&size, NULL); // if buffer is not the same size as before, create a new one if (size != bufferSize) { if (pBuffer) delete[] pBuffer; bufferSize = size; pBuffer = new long[bufferSize]; } pSampleGrabber->GetCurrentBuffer(&size, pBuffer); if (flipImageV | flipImageH) FlipImage(pBuffer); } void ARFrameGrabber::FlipImage(long* pBuf) { DWORD *ptr = (DWORD*)pBuf; int pixelCount = bufferSize/4; if (!pBuf) return; // Added code for more image manipulations // Gerhard Reitmayr <reitmayr@i ............... if( flipImageV ) { if( flipImageH ) { // both flips set -> rotation about 180 degree for (int index = 0; index < pixelCount/2; index++) { ptr[index] = ptr[index] ^ ptr[pixelCount - index - 1]; ptr[pixelCount - index - 1] = ptr[index] ^ ptr[pixelCount - index - 1]; ptr[index] = ptr[index] ^ ptr[pixelCount - index - 1]; } } else { // only vertical flip for( int line = 0; line < height/2; line++ ) for( int pixel = 0; pixel < width; pixel ++ ) { ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; ptr[pixelCount - line*width - (width - pixel )] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[pixelCount - line*width - (width - pixel )]; } } } else { if( flipImageH ) { // only horizontal flip for( int line = 0; line < height; line++ ) for( int pixel = 0; pixel < width/2; pixel ++ ) { ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; ptr[line*width + (width - pixel )] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; ptr[line*width+pixel] = ptr[line*width+pixel] ^ ptr[line*width + (width - pixel )]; } } } } void ARFrameGrabber::Grab32BitFrame() { long evCode; long size = 0; long* pData; unsigned char* pTemp; unsigned char* ptr; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); pSampleGrabber->GetCurrentBuffer(&size, NULL); if (size != bufferSize) { if (pBuffer) delete[] pBuffer; bufferSize = size/3*4; // add space for padding pBuffer = new long[bufferSize]; } pData= (long*) new unsigned char[size]; pSampleGrabber->GetCurrentBuffer(&size, pData); ptr = ((unsigned char*)pBuffer) + bufferSize - 1; pTemp = (unsigned char*) pData; // do the padding for (int index = 0; index < size/3; index++) { unsigned char r = *(pTemp++); unsigned char g = *(pTemp++); unsigned char b = *(pTemp++); *(ptr--) = 0; *(ptr--) = b; *(ptr--) = g; *(ptr--) = r; } /* for (int index = 0; index < size; index++) { *ptr = ((unsigned char *)pTemp)[index]; ptr--; if (index % 3 == 2) { *ptr = 0; ptr--; } } */ delete[] pData; } void ARFrameGrabber::BindFilter(int deviceId, IBaseFilter **pFilter) { if (deviceId < 0) return; // enumerate all video capture devices CComPtr<ICreateDevEnum> pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr<IEnumMoniker> pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR) { // ErrMsg("Sorry, you have no video capture hardware"); return; } pEm->Reset(); ULONG cFetched; IMoniker *pM; int index = 0; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId) { 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 (index == deviceId) { pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter); } SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); index++; } } void ARFrameGrabber::DisplayProperties() { CComPtr<ISpecifyPropertyPages> pPages; HRESULT hr = pCameraOutput->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages); if (SUCCEEDED(hr)) { PIN_INFO PinInfo; pCameraOutput->QueryPinInfo(&PinInfo); CAUUID caGUID; pPages->GetPages(&caGUID); OleCreatePropertyFrame( NULL, 0, 0, L"Property Sheet", 1, (IUnknown **)&(pCameraOutput.p), caGUID.cElems, caGUID.pElems, 0, 0, NULL); CoTaskMemFree(caGUID.pElems); PinInfo.pFilter->Release(); } } void ARFrameGrabber::EnumDevices(DeviceInfo *head) { if (!head) return; DeviceInfo *ptr = head; int id = 0; // enumerate all video capture devices CComPtr<ICreateDevEnum> pCreateDevEnum; // ICreateDevEnum *pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr<IEnumMoniker> pEm; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); if (hr != NOERROR) { // ErrMsg("Sorry, you have no video capture hardware"); return; } 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; hr = pBag->Read(L"FriendlyName", &var, NULL); if (hr == NOERROR) { char str[2048]; if (ptr->deviceId != -1) { ptr->next = new DeviceInfo(); ptr = ptr->next; } ptr->deviceId = id++; WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL); ptr->friendlyName = str; SysFreeString(var.bstrVal); } pBag->Release(); } pM->Release(); } } void ARFrameGrabber::ReportError(char *msg) { MessageBox(NULL, msg, "ARFrameGrabber Error", MB_ICONSTOP); } // delete a media type, copied from the dshow base classes void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt) { // allow NULL pointers for coding simplicity if (pmt == NULL) { return; } if (pmt->cbFormat != 0) { CoTaskMemFree((PVOID)pmt->pbFormat); // Strictly unnecessary but tidier pmt->cbFormat = 0; pmt->pbFormat = NULL; } if (pmt->pUnk != NULL) { pmt->pUnk->Release(); pmt->pUnk = NULL; } CoTaskMemFree((PVOID)pmt); } --------------050106070301000300080408-- |