Comments (2)
Here's sample code that initializes COM, enumerates video input devices, finds a specific device (4K60 Pro MK.2), prints its details, manages its properties (checks for HDR status and toggles HDR tonemapping), and finally releases resources before exiting.
#include <iostream>
#include <windows.h>
#include <dshow.h>
#pragma comment(lib, "strmiids.lib")
#include "DriverInterface.h"
template <class T>
void SafeRelease(T** ppT) {
if (*ppT) {
(*ppT)->Release();
*ppT = NULL;
}
}
HRESULT InitializeCOM() {
return CoInitializeEx(NULL, COINIT_MULTITHREADED);
}
void UninitializeCOM() {
CoUninitialize();
}
HRESULT EnumerateDevices(REFGUID category, IEnumMoniker** ppEnum)
{
ICreateDevEnum* pDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));
if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);
if (hr == S_FALSE)
{
hr = VFW_E_NOT_FOUND;
}
pDevEnum->Release();
}
return hr;
}
HRESULT EnumerateVideoDevices(IEnumMoniker** ppEnum) {
return EnumerateDevices(CLSID_VideoInputDeviceCategory, ppEnum);
}
IMoniker* Find4K60ProMK2(IEnumMoniker* pEnum) {
IMoniker* pMoniker = NULL;
while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
IPropertyBag* pPropBag = NULL;
HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (SUCCEEDED(hr)) {
VARIANT varFriendlyName, varDevicePath;
VariantInit(&varFriendlyName);
VariantInit(&varDevicePath);
hr = pPropBag->Read(L"FriendlyName", &varFriendlyName, 0);
if (SUCCEEDED(hr)) {
const wchar_t* expectedName = L"Game Capture 4K60 Pro MK.2";
if (wcscmp(varFriendlyName.bstrVal, expectedName) == 0) {
hr = pPropBag->Read(L"DevicePath", &varDevicePath, 0);
if (SUCCEEDED(hr)) {
const wchar_t* expectedPathPrefix = L"\\\\?\\pci#ven_12ab&dev_0710";
if (wcsncmp(varDevicePath.bstrVal, expectedPathPrefix, wcslen(expectedPathPrefix)) == 0) {
VariantClear(&varFriendlyName);
VariantClear(&varDevicePath);
SafeRelease(&pPropBag);
return pMoniker;
}
}
}
}
VariantClear(&varFriendlyName);
VariantClear(&varDevicePath);
SafeRelease(&pPropBag);
}
SafeRelease(&pMoniker);
}
return NULL;
}
void PrintDeviceInfo(IMoniker* pMoniker) {
if (pMoniker == NULL) {
std::wcout << L"No moniker provided to PrintDeviceInfo." << std::endl;
return;
}
IPropertyBag* pPropBag = NULL;
HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (SUCCEEDED(hr)) {
VARIANT varFriendlyName, varDevicePath;
VariantInit(&varFriendlyName);
VariantInit(&varDevicePath);
hr = pPropBag->Read(L"FriendlyName", &varFriendlyName, 0);
if (SUCCEEDED(hr)) {
std::wcout << L"Friendly Name: " << varFriendlyName.bstrVal << std::endl;
}
else {
std::wcout << L"Could not read Friendly Name property." << std::endl;
}
hr = pPropBag->Read(L"DevicePath", &varDevicePath, 0);
if (SUCCEEDED(hr)) {
std::wcout << L"Device Path: " << varDevicePath.bstrVal << std::endl;
}
else {
std::wcout << L"Could not read Device Path property." << std::endl;
}
VariantClear(&varFriendlyName);
VariantClear(&varDevicePath);
SafeRelease(&pPropBag);
}
else {
std::wcout << L"Could not bind moniker to storage." << std::endl;
}
}
EGAVDeviceProperties* CreateDeviceProperties(IMoniker* pMoniker) {
IKsPropertySet* pKsPropertySet = nullptr;
HRESULT hr = pMoniker->BindToObject(0, 0, IID_PPV_ARGS(&pKsPropertySet));
if (SUCCEEDED(hr)) {
auto deviceProperties = new EGAVDeviceProperties(pKsPropertySet, EGAVDeviceProperties::DeviceType::GC4K60ProMK2);
pKsPropertySet->Release();
return deviceProperties;
}
else {
std::wcout << L"Failed to bind to IKsPropertySet interface." << std::endl;
return nullptr;
}
}
class DevicePropertiesManager {
private:
EGAVDeviceProperties* m_pDeviceProperties;
public:
DevicePropertiesManager(IMoniker* pMoniker) : m_pDeviceProperties(nullptr) {
if (pMoniker) {
m_pDeviceProperties = CreateDeviceProperties(pMoniker);
if (!m_pDeviceProperties) {
std::wcerr << L"Failed to create device properties." << std::endl;
}
}
}
~DevicePropertiesManager() {
delete m_pDeviceProperties;
}
DevicePropertiesManager(const DevicePropertiesManager&) = delete;
DevicePropertiesManager& operator=(const DevicePropertiesManager&) = delete;
bool IsVideoHDR() {
if (m_pDeviceProperties) {
bool isHDR = false;
HRESULT hr = m_pDeviceProperties->IsVideoHDR(isHDR);
if (SUCCEEDED(hr)) {
return isHDR;
}
std::wcerr << L"Failed to get HDR status." << std::endl;
}
return false;
}
void SetHDRTonemappingEnabled(bool enabled) {
if (m_pDeviceProperties) {
HRESULT hr = m_pDeviceProperties->SetHDRTonemapping(enabled);
if (FAILED(hr)) {
std::wcerr << L"Failed to set HDR tonemapping." << std::endl;
}
}
}
HRESULT GetHDMIHDRStatusPacket(uint8_t* outBuffer, int inBufferSize) {
if (m_pDeviceProperties) {
return m_pDeviceProperties->GetHDMIHDRStatusPacket(outBuffer, inBufferSize);
}
else {
std::wcerr << L"No device properties available to get HDMI HDR status packet." << std::endl;
return E_FAIL;
}
}
};
void MainProcess() {
IEnumMoniker* pEnum = nullptr;
HRESULT hr = EnumerateVideoDevices(&pEnum);
if (SUCCEEDED(hr)) {
IMoniker* pMoniker = Find4K60ProMK2(pEnum);
if (pMoniker != nullptr) {
PrintDeviceInfo(pMoniker);
DevicePropertiesManager device(pMoniker);
const int HDMI_PACKET_SIZE = 32;
uint8_t hdmiHDRStatusPacket[HDMI_PACKET_SIZE];
HRESULT res = device.GetHDMIHDRStatusPacket(hdmiHDRStatusPacket, HDMI_PACKET_SIZE);
std::cout << "GetHDMIHDRStatusPacket: ";
if (SUCCEEDED(res)) {
std::cout << "Successful" << std::endl;
bool isHDR = device.IsVideoHDR();
std::wcout << L"Is Video HDR? " << (isHDR ? L"Yes" : L"No") << std::endl;
if (isHDR) {
bool hdrToneMapping = false;
device.SetHDRTonemappingEnabled(hdrToneMapping);
std::wcout << L"HDR Tonemapping is now set to " << (hdrToneMapping ? L"enabled" : L"disabled") << std::endl;
}
}
else {
std::cout << "Error: Unknown (0x" << std::hex << res << ")" << std::endl;
}
pMoniker->Release();
}
else {
std::wcout << L"Device not found." << std::endl;
}
SafeRelease(&pEnum);
}
}
int main() {
HRESULT hr = InitializeCOM();
if (SUCCEEDED(hr)) {
MainProcess();
UninitializeCOM();
}
return 0;
}
from capture-device-support.
This is incredible thank you!
from capture-device-support.
Related Issues (4)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from capture-device-support.