-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to get IKsProperySet, 4k60 Pro Mk.2 #4
Comments
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;
} |
This is incredible thank you! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sorry if this is a dumb question but I'm trying to get your sample code to work with my 4k60 Pro Mk.2. I am frankly a total novice with both windows and C++ and I'm trying to figure out how to get this IKSPropertySet thing to pass into your function
EGAVDeviceProperties::EGAVDeviceProperties(IKsPropertySet* inKsPropertySet, DeviceType inDeviceType)
.Alternatively a full main style function would be nice. I basically am just trying to get a CLI program that sets the HDR tonemapping.
This is my device info according to
pnputil
The text was updated successfully, but these errors were encountered: