#define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #include "SCENE.h" extern TCHAR CurrWebCam[256]; int GetWebCamByName(char *compressorsName, IBaseFilter **FilterPtr); int CAMERA_SpecifyedW = 320; #pragma optimize("",off) #define MYDRV "YouUp" #define NB_UNFRENDLY_CAMS 2 static char *unfrendlyCams[NB_UNFRENDLY_CAMS] = { MYDRV, "CamCam" }; //#define Draw_Histogram #define CAM_ERROR 1 #define CAM_UNFRENDLY 2 #define CAM_IN_USE 3 #define CAM_USED 4 //#pragma optimize("",off) struct DeviceInfo { DeviceInfo():next(NULL), deviceId(-1) { } ~DeviceInfo() { if (next) delete next; } char friendlyName[2048]; int deviceId; DeviceInfo* next; }; class C2SampleGrabberCB : public ISampleGrabberCB { public: u32 ImageCounter; 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 ( this ); return NOERROR; } return E_NOINTERFACE; } STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ){ImageCounter ++;return 0;} STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ){ImageCounter ++;return 0;} }; class ARFrameGrabber { public: HRESULT hrinit ; VIDEOINFOHEADER Vih; char str[2048]; long hardwareFlipAvailable; long hardwareFlipSet; C2SampleGrabberCB CB; ARFrameGrabber(); virtual ~ARFrameGrabber(); int Init(int deviceId); void BindFilter(int deviceId, IBaseFilter **pFilter); int GrabFrame(); BOOL SetVideoControl(long mask, bool remove = 0); long GetBufferSize() {return bufferSize;} long* GetBuffer() {return pBuffer;} void DisplayProperties(); protected: CComPtr pGrabberInput; CComPtr pGrabberOutput; CComPtr pCameraOutput; CComPtr pNullInputPin; CComPtr pGraph; CComPtr pDeviceFilter; CComPtr pSampleGrabberFilter; CComPtr pNullFilter; CComPtr pMediaControl; CComPtr pSampleGrabber; CComPtr pMediaEvent; private: void ReportError(char *msg); long bufferSize; long *pBuffer; }; ARFrameGrabber::ARFrameGrabber():pBuffer(NULL), bufferSize(0) { // memset(this,0,sizeof(*this)); } ARFrameGrabber::~ARFrameGrabber() { if (pGrabberInput) pGrabberInput.Release(); if (pGrabberOutput) pGrabberOutput.Release(); if (pCameraOutput) pCameraOutput.Release(); if (pNullInputPin) pNullInputPin.Release(); if (pMediaControl) pMediaControl->Stop(); if (pMediaControl) pMediaControl.Release(); if (pMediaEvent) pMediaEvent.Release(); if (pSampleGrabber) pSampleGrabber.Release(); if (pSampleGrabberFilter) pSampleGrabberFilter.Release(); if (pNullFilter) pNullFilter.Release(); if (pDeviceFilter) pDeviceFilter.Release(); if (pGraph) pGraph.Release(); if (pBuffer) CC_free(pBuffer); pBuffer = NULL; bufferSize = 0; } void FAIL_TEST(HRESULT hr) { if (hr != S_OK) hr = hr; } int ARFrameGrabber::Init(int deviceId) { HRESULT hr = S_OK; hrinit = S_OK; // Bind Device Filter. We know the device because the id was passed in str[0] = 0; BindFilter(deviceId, &pDeviceFilter); char SaveStr9; SaveStr9 = str[9]; str[9] = 0; for (int uf=0; uf < NB_UNFRENDLY_CAMS; uf++) { if (strnicmp(unfrendlyCams[uf],str, strlen(unfrendlyCams[uf])) == 0) { hrinit = E_FAIL ; return CAM_UNFRENDLY; } } str[9] = SaveStr9; if (!pDeviceFilter) { hrinit = E_FAIL ; return CAM_ERROR; } // 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"); //hr = pGraph->AddSourceFilter(L"X:\\Bins\\je suis ton pere.avi", L"Source", &pDeviceFilter); if (S_OK != pGraph->AddFilter(pDeviceFilter, NULL)) { pDeviceFilter.Release(); pGraph.Release(); hrinit = E_FAIL ; return CAM_ERROR; } /* CComPtr videoProp; pDeviceFilter->QueryInterface(IID_IAMVideoProcAmp, (void **)&vidProp); if (vidProp) { long Min, Max, SteppingDelta, Default, CapsFlag; hr = vidProp->GetRange(VideoProcAmp_Brightness, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_Contrast, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_Hue, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_Saturation, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_Sharpness, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_Gamma, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_ColorEnable, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_WhiteBalance, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_BacklightCompensation, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); hr = vidProp->GetRange(VideoProcAmp_Gain, &Min, &Max, &SteppingDelta, &Default, &CapsFlag); flags = 2; vidProp->Get(VideoProcAmp_Gain, &value, &flags); flags = 0; } */ CComPtr pEnum; if (S_OK != pDeviceFilter->EnumPins(&pEnum)) { pDeviceFilter.Release(); pGraph.Release(); hrinit = E_FAIL ; return CAM_ERROR; } if (S_OK != pEnum->Reset()) { pDeviceFilter.Release(); pGraph.Release(); pEnum.Release(); hrinit = E_FAIL ; return CAM_ERROR; } if (S_OK != pEnum->Next(1, &pCameraOutput, NULL)) { pDeviceFilter.Release(); pGraph.Release(); hrinit = E_FAIL ; return CAM_ERROR; } // get flip available hardwareFlipAvailable = 0; hardwareFlipSet = 0; pEnum.Release(); pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); FAIL_TEST(pEnum->Next(1, &pGrabberInput, NULL)); pEnum.Release(); pSampleGrabberFilter->EnumPins(&pEnum); pEnum->Reset(); pEnum->Skip(1); FAIL_TEST(pEnum->Next(1, &pGrabberOutput, NULL)); pEnum.Release(); pNullFilter->EnumPins(&pEnum); FAIL_TEST(pEnum->Reset()); FAIL_TEST(pEnum->Next(1, &pNullInputPin, NULL)); pEnum.Release(); DisplayProperties(); FAIL_TEST(pGraph->Connect(pCameraOutput, pGrabberInput)); FAIL_TEST(pGraph->Connect(pGrabberOutput, pNullInputPin)); if (deviceId == 2) deviceId = deviceId; if (FAILED(hr)) { switch(hr) { case VFW_S_NOPREVIEWPIN : break; case E_FAIL : break; case E_INVALIDARG : break; case E_POINTER : break; } hrinit = hr ; return CAM_ERROR; } FAIL_TEST(pSampleGrabber->SetBufferSamples(TRUE)); FAIL_TEST(pSampleGrabber->SetOneShot(TRUE)); // AM_MEDIA_TYPE mt; hrinit = pSampleGrabber->GetConnectedMediaType(&mt); if (!FAILED(hrinit)) { memcpy(&Vih,mt.pbFormat,sizeof(VIDEOINFOHEADER)); hrinit = pMediaControl->Run(); long evCode; if (hrinit == S_FALSE) hrinit = S_OK; if (deviceId == 2) deviceId = deviceId; pSampleGrabber->SetCallback(&CB,1); } else { return CAM_USED; } pMediaControl->Run(); /* setting test //IKsPropertySet *m_pKSProp; CComPtr m_pKSProp; hr = pDeviceFilter->QueryInterface(IID_IKsPropertySet, (void**)&m_pKSProp); if (hr == S_OK) { DWORD dwSupported = 0; hr = m_pKSProp->QuerySupported(PROPSETID_VIDCAP_VIDEOPROCAMP, KSPROPERTY_VIDEOPROCAMP_GAIN, &dwSupported); if(SUCCEEDED(hr) && dwSupported&KSPROPERTY_SUPPORT_SET) { KSPROPERTY_VIDEOPROCAMP_S ModeCaps; memset(&ModeCaps,0,sizeof(KSPROPERTY_TUNER_MODE_CAPS_S)); DWORD cbBytes=0; //ModeCaps.Property = KSPROPERTY_SUPPORT_SET; ModeCaps.Value = 1; ModeCaps.Flags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL; #define INSTANCEDATA_OF_PROPERTY_PTR(x) ((PKSPROPERTY((x))) + 1) #define INSTANCEDATA_OF_PROPERTY_SIZE(x) (sizeof((x)) - sizeof(KSPROPERTY)) hr = m_pKSProp->Set(PROPSETID_VIDCAP_VIDEOPROCAMP,KSPROPERTY_VIDEOPROCAMP_COLORENABLE, INSTANCEDATA_OF_PROPERTY_PTR(&ModeCaps), INSTANCEDATA_OF_PROPERTY_SIZE(ModeCaps), &ModeCaps, sizeof(ModeCaps)); } }//*/ long evCode; pMediaEvent->WaitForCompletion(2000, &evCode); return 0; } #ifdef DRAW_FPS u32 RRRRRR = 0; #endif int ARFrameGrabber::GrabFrame() { long evCode; long size = 0; pMediaControl->Run(); pMediaEvent->WaitForCompletion(INFINITE, &evCode); //if (!CB.ImageCounter) return 0; #ifdef DRAW_FPS RRRRRR = 0; if (CB.ImageCounter > 1 ) RRRRRR = CB.ImageCounter; #endif /* u32 MAXWAIT = 100; while ((!CB.ImageCounter) && MAXWAIT) {Sleep(1);MAXWAIT--;}; */ if (!CB.ImageCounter ) return 0; pSampleGrabber->GetCurrentBuffer(&size, NULL); CB.ImageCounter = 0; // if buffer is not the same size as before, create a new one if (size && (size != bufferSize)) { if (pBuffer) CC_free(pBuffer); bufferSize = size; pBuffer = (long *)CC_malloc(bufferSize*sizeof(long)); } pSampleGrabber->GetCurrentBuffer(&size, pBuffer); return 1; } void ARFrameGrabber::BindFilter(int deviceId, IBaseFilter **pFilter) { if (deviceId < 0) return; *pFilter = NULL; // enumerate all video capture devices CComPtr pCreateDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (hr != NOERROR) { // ErrMsg("Error Creating Device Enumerator"); return; } CComPtr 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) { WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL); if (index == deviceId) { FILTER_STATE State; hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter); } SysFreeString(var.bstrVal); } pBag->Release(); } index++; } } BOOL ARFrameGrabber::SetVideoControl(long mask, bool remove) { HRESULT hr; return false; // .... if ( hardwareFlipAvailable != 0 && !(hardwareFlipAvailable & mask)) return false; if ((!remove && ( hardwareFlipSet & mask)) || ( remove && !(hardwareFlipSet & mask))) return true; CComPtr videoControl; CComPtr pEnum; CComPtr oPin; if (S_OK == pDeviceFilter->QueryInterface(IID_IAMVideoControl, (void **)&videoControl) && S_OK == pDeviceFilter->EnumPins(&pEnum) && S_OK == pEnum->Reset() && S_OK == pEnum->Next(1, &oPin, NULL)) { if (hardwareFlipAvailable == 0) { videoControl->GetCaps(oPin, &hardwareFlipAvailable); hardwareFlipAvailable |= 0x80; } if (hardwareFlipAvailable & mask) { long mode = 0; hr = videoControl->GetMode(oPin, &mode); if (remove) { mode &= ~mask; hardwareFlipSet &= ~mask; } else { mode |= mask; hardwareFlipSet |= mask; } hr = videoControl->SetMode(oPin, mode & hardwareFlipAvailable); hr = videoControl->GetMode(oPin, &mode); return true; } else { hardwareFlipAvailable ^= mask; return false; } } else { if (hardwareFlipAvailable == 0) hardwareFlipAvailable |= 0x80; } return false; } void 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; } } void MyDeleteMediaType(AM_MEDIA_TYPE *pmt) { if (pmt != NULL) { MyFreeMediaType(*pmt); // See FreeMediaType for the implementation. CoTaskMemFree(pmt); } } void ARFrameGrabber::DisplayProperties() { CComPtr pPages; HRESULT hr; IAMStreamConfig *pConfig; AM_MEDIA_TYPE *pt_Media; VIDEOINFOHEADER *pt_Vid; // try doing ersolution change automatically hr = pCameraOutput->QueryInterface(IID_IAMStreamConfig,(void**) &pConfig); if (hr == S_OK) { hr = pConfig->GetFormat( &pt_Media ); pt_Vid = (VIDEOINFOHEADER *) pt_Media->pbFormat; if (CAMERA_SpecifyedW == 160) { pt_Vid->bmiHeader.biWidth = 160; pt_Vid->bmiHeader.biHeight = 120;//*/ } else if (CAMERA_SpecifyedW == 352) { pt_Vid->bmiHeader.biWidth = 352; pt_Vid->bmiHeader.biHeight = 288;//*/ } else if (CAMERA_SpecifyedW == 640) { pt_Vid->bmiHeader.biWidth = 640; pt_Vid->bmiHeader.biHeight = 480;//*/ } else if (CAMERA_SpecifyedW == 800) { pt_Vid->bmiHeader.biWidth = 800; pt_Vid->bmiHeader.biHeight = 600;//*/ } else if (CAMERA_SpecifyedW == 1024) { pt_Vid->bmiHeader.biWidth = 1024; pt_Vid->bmiHeader.biHeight = 768;//*/ } else { pt_Vid->bmiHeader.biWidth = 320; pt_Vid->bmiHeader.biHeight = 240; } pt_Vid->bmiHeader.biBitCount = 24; pt_Media->lSampleSize = pt_Vid->bmiHeader.biSizeImage = (pt_Vid->bmiHeader.biWidth * pt_Vid->bmiHeader.biHeight * pt_Vid->bmiHeader.biBitCount)>>3; /*pt_Vid->bmiHeader.biWidth = 352; pt_Vid->bmiHeader.biHeight = 288;//*/ /*pt_Vid->bmiHeader.biWidth = 640; pt_Vid->bmiHeader.biHeight = 480;//*/ hr = pConfig->SetFormat( pt_Media ); pConfig->Release(); bufferSize = pt_Vid->bmiHeader.biWidth * pt_Vid->bmiHeader.biHeight; if (pBuffer) CC_free(pBuffer); if (bufferSize) { pBuffer = (long *)CC_malloc(bufferSize* sizeof(long)); } else pBuffer = NULL; MyDeleteMediaType( pt_Media ); if (hr == S_OK ) return; } // automatic resolution change does'nt work, display property page 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::ReportError(char *msg) { MessageBox(NULL, msg, "ARFrameGrabber Error", MB_ICONSTOP); } class WEBCAM:public INPUT_IO { public: ARFrameGrabber *grabber; WORLD*pScene; u32 DeviceID; u32 LastTime; u32 AvergageDT_x16; u32 frameTime ; u32 Locker ; u32 UnplugCount ; u32 UnplugWait; u32 camOK; int INIT (class WORLD*); int FRAME (void); int END (void); IOTYPE GetType() {return IOtype_CAM;}; void *GetData(int dataIdx); }; int WEBCAM::INIT(WORLD*pSc) { CoInitialize( NULL); int defaultCam = 0; LastTime = timeGetTime(); AvergageDT_x16 = 0; grabber = new ARFrameGrabber(); Image.SX = Image.SY = 0; if (*CurrWebCam) { defaultCam = GetWebCamByName(CurrWebCam, NULL); if (defaultCam == -1) defaultCam = 0; } if (grabber->Init(defaultCam) == CAM_USED) { UnplugWait = 63; } else if (grabber->hrinit != S_OK) { delete grabber; grabber = new ARFrameGrabber(); Image.SX = Image.SY = 0; grabber->Init(1); if (grabber->hrinit != S_OK) { delete grabber; grabber = new ARFrameGrabber(); Image.SX = Image.SY = 0; grabber->Init(2); if (grabber->hrinit != S_OK) { delete grabber; grabber = new ARFrameGrabber(); Image.SX = Image.SY = 0; grabber->Init(3); if (grabber->hrinit != S_OK) { delete grabber; grabber = new ARFrameGrabber(); Image.SX = Image.SY = 0; grabber->Init(0); if (grabber->hrinit != S_OK) { delete grabber; grabber = NULL; return 0; } } } } } if (grabber->hrinit != S_OK) { delete grabber; grabber = NULL; return 0; } if (grabber->Vih.bmiHeader.biWidth > 640) { delete grabber; grabber = NULL; return 0; } grabber->CB.ImageCounter = 1; grabber->GrabFrame(); //memset(&Image, 0, sizeof(MAP)); if (grabber->Vih.bmiHeader.biWidth * grabber->Vih.bmiHeader.biHeight) Image.SetSize(grabber->Vih.bmiHeader.biWidth, grabber->Vih.bmiHeader.biHeight); pScene = pSc; return 1; } u32 webcamInitTime = 0; int WEBCAM::FRAME(void) { int i, j; if (pScene->bManualBoot & 2) Locker = 8; /* if (Locker) { Locker--; return 1; }*/ if (!grabber) { MAP SaveImage; SaveImage = Image; SaveImage.staticBase = 1; if (UnplugCount > 3) { UnplugCount++; if ((UnplugCount & UnplugWait) != 0) return 1; if (!INIT(pScene)) { Image = SaveImage; Image.staticBase = 0; grabber = NULL; camOK = 0; memset(Image.GetBase(),rand()&7,Image.PITCH * Image.SY * 4); DRawTEXT_Soft_B_Centered((u8*)"Camera do not respond!!\nPlease restart or re-plug",(u32*)Image.GetBase(),Image.SX, Image.SY, 0xffff0000 + (rand()&7) + ((rand()&7)<<8)); return 1; } else { SaveImage.Delete(); if (ulAssociatedTextureIndex != -1) pScene->DI->DestroyTexture(ulAssociatedTextureIndex); ulAssociatedTextureIndex = pScene->DI->CreateTexture(&Image,ulColorMode); UnplugCount = 0; UnplugWait = 15; frameTime = timeGetTime(); } } } START_RASTER(WebCam); if (grabber && grabber->GrabFrame()) { camOK++; UnplugCount = 0; u32 curTime = timeGetTime(); if (!frameTime) webcamInitTime = curTime; else webcamInitTime = curTime - ((curTime - frameTime)>>1); frameTime = curTime; AvergageDT_x16 -= AvergageDT_x16>>4; AvergageDT_x16 += (curTime - LastTime)<<4; LastTime = curTime; int *dstPtr = Image.GetBase(); int *srcPtr = (int *)grabber->GetBuffer(); for (int y=0; yWebCamXInvert) { if (!grabber->SetVideoControl(VideoControlFlag_FlipVertical)) { s32 *ImageB,*ImageE; ImageB = Image.GetBase(); ImageE = Image.GetBase() + Image.PITCH * Image.SY; while (ImageB < ImageE) { s32 *RB,*RE; RB = ImageB; RE = ImageB + Image.SX - 1; while (RB < RE) { s32 Swap; Swap = *RB; *RB = *RE; *RE = Swap; RB++; RE--; } ImageB+=Image.PITCH; } } } else { grabber->SetVideoControl(VideoControlFlag_FlipVertical, 1); } if (pScene && pScene->WebCamYInvert) { if (!grabber->SetVideoControl(VideoControlFlag_FlipHorizontal)) { s32 *ImageB = Image.GetBase(); int PITCH = Image.PITCH; int tmp; int SX = Image.SX; int SY = Image.SY; for(int px=0; pxSetVideoControl(VideoControlFlag_FlipHorizontal, 1); } { s32 *ImageB,*ImageE; ImageB = Image.GetBase(); ImageE = Image.GetBase() + Image.PITCH * Image.SY; while (ImageB < ImageE) { *(ImageB++) |= 0xff000000 ; *(ImageB++) |= 0xff000000 ; *(ImageB++) |= 0xff000000 ; *(ImageB++) |= 0xff000000 ; } } #ifdef Draw_Histogram s32 Histo[2048],*pX; pX = Image.GetBase() + Image.PITCH * Image.SY/2; for (s32 XCounter = 0 ; XCounter < Image.SX ; XCounter ++ , pX++) Histo [XCounter]=(*pX &0xff) + ((*pX>>8) &0xff) + ((*pX>>16) &0xff); DrawLine_Clip(&Image, 0,Image.SY>>1 , Image.SX ,Image.SY>>1 , 0xff0000); for (s32 XCounter = 0 ; XCounter < Image.SX - 1; XCounter ++ ) DrawLine_Clip(&Image, XCounter,(Histo [XCounter] >>2) , XCounter+1,(Histo [XCounter+1] >>2) , 0xff00); #endif #ifdef DRAW_FPS char FrameRate[1024]; if (RRRRRR) { sprintf(FrameRate,"%d : %d",(s32)(256000.0f / (double)(AvergageDT_x16)),RRRRRR); DRawTEXT_Soft_B((u8*)FrameRate,(u32*)Image.BASE,20,20, Image.PITCH , Image.SY, 0xffff0000); } else { sprintf(FrameRate,"%d",(s32)(256000.0f / (double)(AvergageDT_x16))); DRawTEXT_Soft_B((u8*)FrameRate,(u32*)Image.BASE,20,20, Image.PITCH , Image.SY, 0xff00ff00); } #endif STOP_RASTER(WebCam); START_RASTER(Shots) void FindHotSpot(MAP *pSrc,float Focale); FindHotSpot(&Image,MediaFocale == 0.0 ? 2.2 : MediaFocale); STOP_RASTER(Shots);//*/ return 1; } else { static DWORD waitTime = 500; if (timeGetTime() - frameTime > waitTime) { if (UnplugCount == 3) { if (grabber) delete grabber; grabber = NULL; camOK = 0; Image.SetSize(Image.SX, Image.SY); memset(Image.GetBase(),0,Image.PITCH * Image.SY * 4); DRawTEXT_Soft_B_Centered((u8*)"Camera do not respond!!\nPlease restart or re-plug",(u32*)Image.GetBase(),Image.SX, Image.SY, 0xffff0000); STOP_RASTER(WebCam); UnplugCount ++; waitTime = waitTime + 500; return 1; } else UnplugCount ++; } else UnplugCount = 0; } STOP_RASTER(WebCam); return 0; } int WEBCAM::END(void) { if (grabber) delete grabber; Image.Delete(); return 0; } void *WEBCAM::GetData(int dataIdx) { switch (dataIdx) { case 3: return (void *)(camOK > 1); // one frame waiting } return NULL; } INPUT_IO *WEBCAM_CREATE(WORLD *pScene,char *MediaName) { INPUT_IO *Ret; u32 FFF = GetFileNameExtend((char *)MediaName) - 'CAM0'; Ret = (INPUT_IO *)new(WEBCAM); strcpy((char*)Ret->MediaName,MediaName); ((WEBCAM *)Ret)->DeviceID = FFF; Ret->dTotalTime = 0; Ret->dAvgFramePerSecond = 30.0; /* PHILIPPE : LOADING OPTIMIZE -> Create an unplugged camera */ if (0) { ((WEBCAM *)Ret)->grabber = NULL; ((WEBCAM *)Ret)->Image.SetSize(320, 240, 1); DRawTEXT_Soft_B_Centered((u8*)"Init Camera...",(u32*)((WEBCAM *)Ret)->Image.GetBase(),((WEBCAM *)Ret)->Image.SX, ((WEBCAM *)Ret)->Image.SY, 0xffff0000); ((WEBCAM *)Ret)->pScene = pScene; ((WEBCAM *)Ret)->UnplugCount = 0; ((WEBCAM *)Ret)->UnplugWait = 15; ((WEBCAM *)Ret)->camOK = 0; ((WEBCAM *)Ret)->frameTime = timeGetTime() - 200; ((WEBCAM *)Ret)->Locker = 0; } else /* PHILIPPE : LOADING OPTIMIZE -> instead of this */ Ret->INIT(pScene); if (Ret->Image.SX == 0) { char String[1024]; delete Ret; sprintf(String,"No Camera\n%s\nPlease Restart\nwith camera device",MediaName); return ERROR_CREATE(String); } return Ret; } /*************************************************************************/ int GetWebCamNames(char compressors[][256], int *nbCompressors, int maxCompressors) { HRESULT hr; ICreateDevEnum *pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); if (FAILED(hr)) return hr; // Obtain a class enumerator for the video compressor category. IEnumMoniker *pEnumCat = NULL; hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0); *nbCompressors = 0; if (hr == S_OK) { // Enumerate the monikers. IMoniker *pMoniker = NULL; ULONG cFetched; while(*nbCompressors < maxCompressors && pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) { IPropertyBag *pPropBag; hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); if (SUCCEEDED(hr)) { // To retrieve the filter's friendly name, do the following: VARIANT varName; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, 0); if (SUCCEEDED(hr)) { int net_len =WideCharToMultiByte(CP_ACP, 0,varName.bstrVal, -1, NULL, 0, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, -1, compressors[(*nbCompressors)++], net_len+1, NULL, NULL); for (int uf=0; uf < NB_UNFRENDLY_CAMS; uf++) { if (!strnicmp(compressors[*nbCompressors-1], unfrendlyCams[uf], strlen(unfrendlyCams[uf]))) { (*nbCompressors)--; break; } } } VariantClear(&varName); pPropBag->Release(); } pMoniker->Release(); } pEnumCat->Release(); } pSysDevEnum->Release(); return *nbCompressors; } int GetWebCamByName(char *compressorsName) { return GetWebCamByName(compressorsName, NULL); } int GetWebCamByName(char *compressorsName, IBaseFilter **FilterPtr) { HRESULT hr; char filterName[256]; int resIndex = -1; ICreateDevEnum *pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); if (FAILED(hr)) return false; // Obtain a class enumerator for the video compressor category. IEnumMoniker *pEnumCat = NULL; hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0); int currIndex = -1; if (hr == S_OK) { // Enumerate the monikers. IMoniker *pMoniker = NULL; ULONG cFetched; while(resIndex != 1 && pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) { IPropertyBag *pPropBag; hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); if (SUCCEEDED(hr)) { // To retrieve the filter's friendly name, do the following: VARIANT varName; VariantInit(&varName); hr = pPropBag->Read(L"FriendlyName", &varName, 0); if (SUCCEEDED(hr)) { currIndex++; int net_len =WideCharToMultiByte(CP_ACP, 0,varName.bstrVal, -1, NULL, 0, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, varName.bstrVal, -1, filterName, net_len+1, NULL, NULL); if (!strcmp(filterName, compressorsName)) { if (FilterPtr != NULL) hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)FilterPtr); resIndex = currIndex; } } VariantClear(&varName); pPropBag->Release(); } pMoniker->Release(); } pEnumCat->Release(); } pSysDevEnum->Release(); return resIndex; } void PropertyPageCall(void *params) { IBaseFilter *filter = (IBaseFilter *)params; HRESULT hr = E_FAIL; CComPtr pPages; hr = filter->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages); CAUUID caGUID; pPages->GetPages(&caGUID); OleCreatePropertyFrame( NULL, 0, 0, L"Property Sheet", 1, (IUnknown **)&(filter), caGUID.cElems, caGUID.pElems, 0, 0, NULL); CoTaskMemFree(caGUID.pElems); pPages.Release(); } BOOL GetWebCamFilterPropertyByName(char *name, bool openPage) { HRESULT hr = E_FAIL; if (!*name) return hr; IBaseFilter *filter; if (GetWebCamByName(name, &filter) != -1) { CComPtr pPages; hr = filter->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages); if (SUCCEEDED(hr)) { pPages.Release(); if (openPage) _beginthread(PropertyPageCall, 0, filter); } } return hr == S_OK; }