Segmentasi latar belakang mode fokus dangkal dan tatapan mata menatap sampel driver mode
Ini adalah contoh implementasi segmentasi latar belakang mode fokus dangkal dan mode tatapan mata mata, dua bidang bit baru yang diperkenalkan dalam Windows 11, versi 22H2.
Kontrol ini biasanya diimplementasikan di C++, sebagai bagian dari ekstensi mode pengguna dari driver kamera Avstream di MFT Perangkat.
Catatan
Sampel aplikasi WinRT_ExtendedControlAndMetadataSample C# UWP di GitHub mempratinjau kamera dan berinteraksi dengan kontrol yang diperluas.
SampleMFT.h
Class CSampleMFT //Snipped from SampleDeviceMFT Implementation
{
...
Private:
...
VOID SetBackgroundSegmentationShallowFocus(BOOLEAN enabled)
{
m_backgroundSegmentationShallowFocusEnabled = enabled;
}
BOOLEAN GetBackgroundSegmentationShallowFocus()
{
return m_backgroundSegmentationShallowFocusEnabled;
}
constexpr ULONGLONG SupportedBackgroundSegmentation()
{
return KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_BLUR |
KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_MASK |
KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_SHALLOWFOCUS;
}
VOID SetEyeGazeCorrectionMode(DWORD flags)
{
m_eyeGazeCorrectionMode = flags;
}
DWORD GetEyeGazeCorrectionMode()
{
return m_eyeGazeCorrectionMode;
}
BOOLEAN m_backgroundSegmentationShallowFocusEnabled;
DWORD m_eyeGazeCorrectionMode;
};
SampleMFT.cpp
// KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_SHALLOWFOCUS
HRESULT CSampleMft::BackgroundSegmentationHandler(
_In_ PKSPROPERTY property,
_In_ LPVOID data,
_In_ ULONG outputBufferLength,
_Inout_ PULONG bytesReturned)
{
*bytesReturned = 0;
if (property->Flags & KSPROPERTY_TYPE_SET)
{
if (outputBufferLength == 0)
{
*bytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE);
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
}
else if (outputBufferLength < sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE))
{
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
}
else if (data && outputBufferLength >= sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE))
{
PBYTE payload = (PBYTE)data;
PKSCAMERA_EXTENDEDPROP_HEADER extendedHeader = (PKSCAMERA_EXTENDEDPROP_HEADER)payload;
// The extended value is unused for SET with this control, only flags are expected
PKSCAMERA_EXTENDEDPROP_VALUE extendedValue = (PKSCAMERA_EXTENDEDPROP_VALUE)(payload + sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
if (extendedHeader->Flags & ~SupportedBackgroundSegmentation())
{
RETURN_HR(E_INVALIDARG);
}
bool shallowFocus = WI_IsFlagSet((extendedHeader->Flags, KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_SHALLOWFOCUS);
bool blur = WI_IsFlagSet((extendedHeader->Flags, KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_BLUR);
bool mask = WI_IsFlagSet((extendedHeader->Flags, KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_MASK);
// If you ask for shallow focus, you must also ask for blur.
if (shallowFocus && !blur)
{
RETURN_HR(E_INVALIDARG);
}
SetBackgroundSegmentationShallowFocus(shallowFocus);
SetBackgroundSegmentationBlur(blur);
SetBackgroundSegmentationMask(mask);
}
else
{
RETURN_IF_FAILED(E_INVALIDARG);
}
}
else if (property->Flags & KSPROPERTY_TYPE_GET)
{
if (outputBufferLength == 0)
{
*bytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(m_configCaps);
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
}
else if (outputBufferLength < sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(m_configCaps))
{
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
}
else if (data && outputBufferLength >= sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(m_configCaps))
{
PBYTE payload = (PBYTE)data;
PKSCAMERA_EXTENDEDPROP_HEADER extendedHeader = (PKSCAMERA_EXTENDEDPROP_HEADER)(payload);
extendedHeader->Capability = KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_MASK |
KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_BLUR |
KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_SHALLOWFOCUS |
KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_OFF;
if (GetBackgroundSegmentationMask())
{
extendedHeader->Flags |= KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_MASK;
}
if (GetBackgroundSegmentationBlur())
{
extendedHeader->Flags |= KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_BLUR;
}
else if (GetBackgroundSegmentationShallowFocus())
{
extendedHeader->Flags |= KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_BLUR | KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_SHALLOWFOCUS;
}
else
{
extendedHeader->Flags = KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_OFF;
}
extendedHeader->Result = 0;
extendedHeader->Size = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(m_configCaps);
extendedHeader->Version = 1;
PKSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_CONFIGCAPS configCap = (PKSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_CONFIGCAPS)( payload + sizeof(KSCAMERA_EXTENDEDPROP_HEADER)));
memcpy(configCap, m_configCaps, sizeof(m_configCaps));
*bytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(m_configCaps);
}
}
return S_OK;
}
// KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_STARE
HRESULT CSampleMft::EyeGazeCorrectionHandler(
_In_ PKSPROPERTY property,
_In_ LPVOID data,
_In_ ULONG outputBufferLength,
_Inout_ PULONG bytesReturned
)
{
HRESULT hr = S_OK;
*bytesReturned = 0;
if (property->Flags & KSPROPERTY_TYPE_SET)
{
if (outputBufferLength == 0)
{
*bytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE);
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
}
else if (outputBufferLength < sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE))
{
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
}
else if (data && outputBufferLength >= sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE))
{
PBYTE payload = (PBYTE)data;
PKSCAMERA_EXTENDEDPROP_HEADER extendedHeader = (PKSCAMERA_EXTENDEDPROP_HEADER)payload;
//
// Use the extended value to make changes to the property.. refer documentation
// PKSCAMERA_EXTENDEDPROP_VALUE extendedValue = (PKSCAMERA_EXTENDEDPROP_VALUE)(payload + sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
//
if ( (extendedHeader->Flags == KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_ON) ||
(extendedHeader->Flags == (KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_ON | KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_STAREMODE)) ||
(extendedHeader->Flags == KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_OFF) )
{
SetEyeGazeCorrectionMode (extendedHeader->Flags);
}
else
{
RETURN_HR(E_INVALIDARG);
}
*bytesReturned = sizeof(PKSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE);
}
else
{
RETURN_IF_FAILED(E_INVALIDARG);
}
}
else if (property->Flags & KSPROPERTY_TYPE_GET)
{
if (outputBufferLength == 0)
{
*bytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE);
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
}
else if (outputBufferLength < sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE))
{
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_MORE_DATA));
}
else if (data && outputBufferLength >= sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE))
{
PBYTE payload = (PBYTE)data;
PKSCAMERA_EXTENDEDPROP_HEADER extendedHeader = (PKSCAMERA_EXTENDEDPROP_HEADER)(payload);
//
// Use the extended value to make changes to the property.. refer documentation
// PKSCAMERA_EXTENDEDPROP_VALUE extendedValue = (PKSCAMERA_EXTENDEDPROP_VALUE)(payload +sizeof(KSCAMERA_EXTENDEDPROP_HEADER));
//
extendedHeader->Capability = KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_OFF |
KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_ON |
KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_STAREMODE;
extendedHeader->Flags = GetEyeGazeCorrectionMode();
extendedHeader->Result = 0;
extendedHeader->Size = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE);
extendedHeader->Version = 1;
*bytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER) + sizeof(KSCAMERA_EXTENDEDPROP_VALUE);
}
}
return S_OK;
}
Lihat juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk