123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- #include "stdafx.h"
- #include "CameraImpl.h"
- #include "Dshow.h"
- #include "smartptr.h"
- static int Bin2Str(unsigned char *x, int xlen, char *str, int str_size)
- {
- static const char *hex2char = "0123456789ABCDEF";
- int i, k = 0;
- if (str_size <= xlen * 2)
- return -1;
- for (i = 0; i < xlen; ++i) {
- int h = x[i] >> 4;
- int l = x[i] & 0xf;
- str[k++] = hex2char[h];
- str[k++] = hex2char[l];
- }
- str[k] = 0;
- return k;
- }
- int GetCameraInfors(CAMERA_BUCKET& vtCameraList)
- {
- LOG_FUNCTION();
- DestoryCamereBuckets(vtCameraList);
- SmartPtr<ICreateDevEnum> pDevEnum = NULL;
- int deviceCounter = 0;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
- reinterpret_cast<void**>(&pDevEnum));
- if (SUCCEEDED(hr)) {
- // Create an enumerator for the video capture category.
- IEnumMoniker *pEnum = NULL;
- hr = pDevEnum->CreateClassEnumerator(
- CLSID_VideoInputDeviceCategory,
- &pEnum, 0);
- if (hr == S_OK) {
- //if (!silent)printf("SETUP: Looking For Capture Devices\n");
- IMoniker *pMoniker = NULL;
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
- if (FAILED(hr)) {
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- continue; // Skip this one, maybe the next one will work.
- }
- PCAMERA_INFOR_ITEM item = new CAMERA_INFOR_ITEM();
- if(item != NULL) {
- item->Cleanup();
- // Find the description or friendly name.
-
- VARIANT varName;
- VariantInit(&varName);
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if (SUCCEEDED(hr)) {
- int maxLen = sizeof(item->szDevName) - 2;
- int nLen = WrapW2A(varName, &(item->szDevName[0]), maxLen);
- }
- VariantClear(&varName);
-
- VARIANT varCLSID;
- VariantInit(&varCLSID);
- hr = pPropBag->Read(L"CLSID", &varCLSID, 0);
- if (SUCCEEDED(hr)) {
- int maxLen = sizeof(item->szCLSID) - 2;
- int nLen = WrapW2A(varCLSID, &(item->szCLSID[0]), maxLen);
- }
- VariantClear(&varCLSID);
- VARIANT varDevPath;
- VariantInit(&varDevPath);
- hr = pPropBag->Read(L"DevicePath", &varDevPath, 0);
- if (SUCCEEDED(hr)) {
- int maxLen = sizeof(item->szDevPath) - 2;
- int nLen = WrapW2A(varDevPath, &(item->szDevPath[0]), maxLen);
- }
- VariantClear(&varDevPath);
- VARIANT varWaveID;
- VariantInit(&varWaveID);
- hr = pPropBag->Read(L"WaveInID", &varWaveID, 0);
- if (SUCCEEDED(hr)) {
- item->uWaveInID = varWaveID.lVal;
- }
- VariantClear(&varWaveID);
- vtCameraList.push_back(item);
- }
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- deviceCounter++;
- }
- SAFE_RELEASE_IDEV(pMoniker);
- }
- SAFE_RELEASE_IDEV(pEnum);
- }
- else {
- DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CoCreateInstance failed, hr=%d(0x%x)", hr, hr);
- }
- return deviceCounter;
- }
- int GetCameraCount()
- {
- ICreateDevEnum *pDevEnum = NULL;
- int deviceCounter = 0;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
- reinterpret_cast<void**>(&pDevEnum));
- if (SUCCEEDED(hr)) {
- IEnumMoniker *pEnum = NULL;
- hr = pDevEnum->CreateClassEnumerator(
- CLSID_VideoInputDeviceCategory,
- &pEnum, 0);
- if(hr == S_OK){
- IMoniker *pMoniker = NULL;
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK){
- IPropertyBag *pPropBag;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
- (void**)(&pPropBag));
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- if (FAILED(hr)){
- continue; // Skip this one, maybe the next one will work.
- }
- deviceCounter++;
- }
- }
- SAFE_RELEASE_IDEV(pEnum);
- }
- SAFE_RELEASE_IDEV(pDevEnum);
- return deviceCounter;
- }
- //usually consumes 300ms
- int IsDeviceBusy(const char* lpcszDeviceName)
- {
- LOG_FUNCTION();
- return 0;
- int nRet = -2;
- ICreateDevEnum *pDevEnum = NULL;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
- CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pDevEnum);
- IEnumMoniker *pEnum = NULL;
- hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
-
- if (SUCCEEDED(hr)) {
- // Create an enumerator for the video capture category.
- IMoniker *pMoniker = NULL;
- nRet = -1;
- while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
- IPropertyBag *pPropBag = NULL;
- hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
- if(SUCCEEDED(hr)) {
- VARIANT varName;
- varName.vt = VT_BSTR;
- hr = pPropBag->Read(L"FriendlyName", &varName, 0);
- if (SUCCEEDED(hr)) {
- int count = 0;
- char tmp[256] = {0};
- WrapW2A(varName, tmp, 255);
- SysFreeString(varName.bstrVal);
- if(!strcmp(lpcszDeviceName, tmp)) {
- //Deal the specific device
- nRet = 0;
- LPBC* pbc = NULL;
- CreateBindCtx(0, pbc);
- SmartPtr<IBaseFilter> pCap = NULL;
- hr = pMoniker->BindToObject((IBindCtx*)pbc, 0, IID_IBaseFilter,(void **)&pCap);
- IGraphBuilder *m_pGB = NULL;
- hr = CoCreateInstance(CLSID_FilterGraph, NULL,
- CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);
- if (FAILED(hr)) {
- nRet = -2;
- SAFE_RELEASE_IDEV(m_pGB);
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- goto PEnd;
- }
- m_pGB->AddFilter(pCap, NULL);
- ICaptureGraphBuilder2 *m_pCapGB = NULL;
- hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
- CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&m_pCapGB);
- if (FAILED(hr)) {
- nRet = -2;
- SAFE_RELEASE_IDEV(m_pCapGB);
- SAFE_RELEASE_IDEV(m_pGB);
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- goto PEnd;
- }
- m_pCapGB->SetFiltergraph(m_pGB);
- IAMCrossbar *pXBar1 = NULL;
- hr = m_pCapGB->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pCap,
- IID_IAMCrossbar,(void **)&pXBar1);
- if (SUCCEEDED(hr)) {
- long OutputPinCount;
- long InputPinCount;
- long PinIndexRelated;
- long PhysicalType;
- long inPort = 0;
- long outPort = 0;
- pXBar1->get_PinCounts(&OutputPinCount,&InputPinCount);
- int videoBusy = 1;
- for (int i=0; i<InputPinCount; i++) {
- pXBar1->get_CrossbarPinInfo(TRUE, i, &PinIndexRelated, &PhysicalType);
- if(PhysConn_Video_Composite == PhysicalType) {
- inPort = i;
- break;
- }
- }
- for (int j=0; j<OutputPinCount; j++) {
- pXBar1->get_CrossbarPinInfo(FALSE, j, &PinIndexRelated, &PhysicalType);
- if(PhysConn_Video_Composite == PhysicalType) {
- outPort = j;
- break;
- }
-
- }
- for (int i=0; i<InputPinCount; i++) {
- for (int j=0; j<OutputPinCount; j++) {
- hr = pXBar1->CanRoute(j, i);
- if(S_OK == hr) {
- pXBar1->Route(j,i);
- IMediaControl *m_pMC = NULL;
- IVideoWindow *m_pVW = NULL;
- IBaseFilter *P_VCamTrans = NULL;
- m_pGB->AddFilter(pCap, L"Capture Filter");
- hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
- hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);
- hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);
- hr = m_pVW->put_Owner((OAHWND)NULL);
- hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);
- hr = m_pVW->put_Visible(OAFALSE);
- hr = m_pVW->put_AutoShow(OAFALSE);
- HRESULT innhr = m_pMC->StopWhenReady();
- if (SUCCEEDED(innhr)){
- videoBusy = 0;
- } else {
- LogWarn(Severity_Low, Error_DevCommFailed, DETECT_CAMERA_BUSY_ONE,
- CSimpleStringA::Format("%s stop failed: 0x%08X", lpcszDeviceName, innhr));
- }
- SAFE_RELEASE_IDEV(m_pVW);
- SAFE_RELEASE_IDEV(m_pMC);
- SAFE_RELEASE_IDEV(P_VCamTrans);
- }
- else {
- DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CanRoute failed: 0x%08X", hr);
- }
- }
- }
- if (videoBusy == 1)
- {
- nRet = 1; //视频设备占用
- }
- SAFE_RELEASE_IDEV(pXBar1);
- }
- else //pXBar1
- {
- IMediaControl *m_pMC = NULL;
- IVideoWindow *m_pVW = NULL;
- IBaseFilter *P_VCamTrans = NULL;
- m_pGB->AddFilter(pCap, L"Capture Filter");
- m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
- hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);
- hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);
- hr = m_pVW->put_Owner((OAHWND)NULL);
- hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);
- hr = m_pVW->put_Visible(OAFALSE);
- hr = m_pVW->put_AutoShow(OAFALSE);
- HRESULT innhr = m_pMC->StopWhenReady();
- if (FAILED(innhr))
- {
- LogWarn(Severity_Low, Error_DevCommFailed, DETECT_CAMERA_BUSY_TWO,
- CSimpleStringA::Format("%s stop failed: 0x%08X", lpcszDeviceName, innhr));
- nRet = 1; //视频设备占用
- }
- SAFE_RELEASE_IDEV(m_pVW);
- SAFE_RELEASE_IDEV(m_pMC);
- SAFE_RELEASE_IDEV(P_VCamTrans);
- }
- SAFE_RELEASE_IDEV(pXBar1);
- SAFE_RELEASE_IDEV(m_pCapGB);
- SAFE_RELEASE_IDEV(m_pGB);
- break;
- }
- }
- VariantClear(&varName);
- }
- SAFE_RELEASE_IDEV(pPropBag);
- SAFE_RELEASE_IDEV(pMoniker);
- }
- SAFE_RELEASE_IDEV(pMoniker);
- }
- PEnd:
- SAFE_RELEASE_IDEV(pEnum);
- SAFE_RELEASE_IDEV(pDevEnum);
-
- if(nRet != 1) {
- nRet = 0;
- }
- return nRet;
- }
- int UpdateCameraInfors(CAMERA_BUCKET& vtCameraList)
- {
- LOG_FUNCTION();
- int old_count = vtCameraList.size();
- if(old_count > 0) {
- DestoryCamereBuckets(vtCameraList);
- }
- GetCameraInfors(vtCameraList);
- return old_count;
- }
- int ExclusiveCameraBuckes(const CAMERA_BUCKET& lhs, const CAMERA_BUCKET& rhs, CAMERA_BUCKET& diff)
- {
- int count = 0;
- const size_t l_size = lhs.size();
- const size_t r_size = rhs.size();
- if(!diff.empty()) {
- DestoryCamereBuckets(diff);
- }
- //Is it necessary to sort before doing comparation job ?
- if(l_size > r_size) {
- for(CAMERA_BUCKET_CITER citer=lhs.cbegin(); citer!=lhs.cend(); ++citer) {
- auto aim = std::find_if(rhs.cbegin(), rhs.cend(), [citer](PCAMERA_INFOR_ITEM const item){
- return !strcmp(item->szDevPath, (*citer)->szDevPath);
- });
- if(aim == rhs.cend()) {
- PCAMERA_INFOR_ITEM item = new CAMERA_INFOR_ITEM();
- if(item != NULL) {
- item->Copy((*citer));
- diff.push_back(item);
- count++;
- }
- }
- }
- } else if(l_size < r_size) {
- for(CAMERA_BUCKET_CITER citer=rhs.cbegin(); citer!=rhs.cend(); ++citer) {
- auto aim = std::find_if(lhs.cbegin(), lhs.cend(), [citer](PCAMERA_INFOR_ITEM const item){
- return !strcmp(item->szDevPath, (*citer)->szDevPath);
- });
- if(aim == lhs.cend()) {
- PCAMERA_INFOR_ITEM item = new CAMERA_INFOR_ITEM();
- if(item != NULL) {
- item->Copy((*citer));
- diff.push_back(item);
- count++;
- }
- }
- }
- }
- return count;
- }
- void DisplayCameraInfos(const CAMERA_BUCKET& vtCameraList)
- {
- for(CAMERA_BUCKET_CITER it=vtCameraList.cbegin(); it!=vtCameraList.cend(); ++it) {
- if(*it) {
- (*it)->Display();
- }else {
- LOG_ASSERT(!"Empty elememt occurs !!");
- }
- }
- }
|