日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Windows下获取视频设备的一种改进实现

發布時間:2023/11/27 生活经验 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows下获取视频设备的一种改进实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之前在https://blog.csdn.net/fengbingchun/article/details/102806822中介紹過在Windows下獲取視頻設備列表的方法。其實那種實現方法是有缺陷的,當PC機上連接多個視頻設備,并且其中有設備處于啟動運行狀態時,再調用相關接口獲取視頻設備可能會崩潰,因為為了獲取視頻設備列表,它會先以索引0遍歷獲取視頻設備名,然后會執行啟動此設備操作。如果此設備已經被其它應用程序啟動過,則此時就會崩潰。

其實如果僅僅為了獲取視頻設備列表,沒有必要執行啟動設備的操作。以下是測試代碼,無需啟動任何設備即可獲取到所有的視頻設備列表。

此測試代碼調用的是系統C接口,你也可以調整為調用系統的C++接口實現。

#define CINTERFACE
#define COBJMACROS
#include <strmif.h>
#include <Setupapi.h>
#include <uuids.h>
#include <devguid.h>
#include <memory>
#include <algorithm>namespace {std::unique_ptr<char[]> dup_wchar_to_utf8(wchar_t *w, int& len)
{len = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);std::unique_ptr<char[]> s(new char[len]);WideCharToMultiByte(CP_UTF8, 0, w, -1, s.get(), len, 0, 0);return s;
}} // namespaceint test_get_windows_camera_list()
{CoInitialize(nullptr);ICreateDevEnum *devenum = nullptr;int r = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&devenum));if (r != S_OK) {fprintf(stdout, "fail to CoCreateInstance: %d\n", r);return -1;}IEnumMoniker *classenum = nullptr;r = ICreateDevEnum_CreateClassEnumerator(devenum, CLSID_VideoInputDeviceCategory, (IEnumMoniker **)&classenum, 0);if (r != S_OK) {fprintf(stdout, "fail to ICreateDevEnum_CreateClassEnumerator: %d\n", r);return -1;}IMoniker *m = nullptr;typedef struct devices_info {int index;std::string name;} devices_info;std::vector<devices_info> lists;int device_counter = 0;while (IEnumMoniker_Next(classenum, 1, &m, nullptr) == S_OK) {IPropertyBag *bag = nullptr;VARIANT var;r = IMoniker_BindToStorage(m, 0, 0, IID_IPropertyBag, (void **)&bag);if (r != S_OK) {fprintf(stdout, "fail to IMoniker_BindToStorage: %d\n", r);return -1;}var.vt = VT_BSTR;r = IPropertyBag_Read(bag, L"FriendlyName", &var, nullptr);if (r != S_OK) {fprintf(stdout, "fail to IPropertyBag_Read: %d\n", r);return -1;}int length;auto friendly_name = dup_wchar_to_utf8(var.bstrVal, length);lists.push_back({ device_counter++, friendly_name.get() });if (bag)IPropertyBag_Release(bag);IMoniker_Release(m);}IEnumMoniker_Release(classenum);CoUninitialize();fprintf(stdout, "device lists:\n");std::for_each(lists.cbegin(), lists.cend(), [](const devices_info& info) {fprintf(stdout, "  index: %d, name: %s\n", info.index, info.name.c_str());});return 0;
}

執行結果如下:設備索引與設備名并不是固定不變的,再次拔下設備再插上,此時獲得的設備索引和設備名可能與之前不同。

GitHub:https://github.com//fengbingchun/OpenCV_Test

總結

以上是生活随笔為你收集整理的Windows下获取视频设备的一种改进实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。