Skip to content

Commit 68cc5fa

Browse files
author
Frank Cheng
committed
Handling KsEvent, KSCAMERAPROFILE_FaceAuth_Mode for different streaming behavior on camera DMFT.
1 parent e1bec22 commit 68cc5fa

File tree

5 files changed

+208
-15
lines changed

5 files changed

+208
-15
lines changed

avstream/avscamera/DMFT/AvsCameraDMFT.cpp

Lines changed: 171 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
#ifdef MF_WPP
77
#include "AvsCameraDMFT.tmh" //--REF_ANALYZER_DONT_REMOVE--
88
#endif
9+
10+
// TODO: required to avoid bug OS bug 36971659 in extended property handling that introduces a 16 bytes cookie
11+
typedef struct
12+
{
13+
//byte cookieBuffer[16];
14+
KSCAMERA_EXTENDEDPROP_HEADER header;
15+
} KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED, * PKSCAMERA_EXTENDEDPROP_HEADER_BUFFERED;
16+
917
//
1018
// This DeviceMFT is a stripped down implementation of the device MFT Sample present in the sample Repo
1119
// The original DMFT is present at https://github.com/microsoft/Windows-driver-samples/tree/main/avstream/sampledevicemft
@@ -29,6 +37,7 @@ CMultipinMft::CMultipinMft()
2937
DMFTCHECKHR_GOTO(pAttributes->SetUINT32( MF_SA_D3D_AWARE, TRUE ), done);
3038
DMFTCHECKHR_GOTO(pAttributes->SetString( MFT_ENUM_HARDWARE_URL_Attribute, L"SampleMultiPinMft" ),done);
3139
m_spAttributes = pAttributes;
40+
m_selectedProfileId = { KSCAMERAPROFILE_Legacy, 0, 0 };
3241
done:
3342
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
3443
}
@@ -638,6 +647,10 @@ IFACEMETHODIMP CMultipinMft::ProcessInput(
638647
goto done;
639648
}
640649

650+
if (m_selectedProfileId.Type == KSCAMERAPROFILE_FaceAuth_Mode)
651+
{
652+
// DMFT might switch to different behavior when profile, KSCAMERAPROFILE_FaceAuth_Mode is selected.
653+
}
641654
DMFTCHECKHR_GOTO(spInPin->SendSample( pSample ), done );
642655
done:
643656
DMFTRACE( DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr );
@@ -990,13 +1003,23 @@ IFACEMETHODIMP CMultipinMft::KsProperty(
9901003
--*/
9911004
{
9921005
HRESULT hr = S_OK;
1006+
1007+
/// PDMFT only cares about ExtendedCameraControls, all others
1008+
/// are just blindly forwarded to the upstream DMFTs.
1009+
if (!IsEqualCLSID(pProperty->Set, KSPROPERTYSETID_ExtendedCameraControl))
1010+
{
1011+
DMFTCHECKHR_GOTO(m_spIkscontrol->KsProperty(pProperty, ulPropertyLength, pvPropertyData,
1012+
ulDataLength, pulBytesReturned), done);
1013+
goto done;
1014+
}
9931015

994-
DMFTCHECKHR_GOTO(m_spIkscontrol->KsProperty(pProperty,
995-
ulPropertyLength,
996-
pvPropertyData,
997-
ulDataLength,
998-
pulBytesReturned),done);
1016+
if (pProperty->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE)
1017+
{
1018+
DMFTCHECKHR_GOTO(ProfilePropertyHandler(pProperty, ulPropertyLength, pvPropertyData, ulDataLength, pulBytesReturned), done);
1019+
goto done;
1020+
}
9991021
done:
1022+
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
10001023
return hr;
10011024
}
10021025

@@ -1040,15 +1063,53 @@ IFACEMETHODIMP CMultipinMft::KsEvent(
10401063
--*/
10411064
{
10421065

1043-
HRESULT hr = S_OK;
1044-
// Handle the events here if you want, This sample passes the events to the driver
1045-
DMFTCHECKHR_GOTO(m_spIkscontrol->KsEvent(pEvent,
1046-
ulEventLength,
1047-
pEventData,
1048-
ulDataLength,
1049-
pBytesReturned), done);
1050-
done:
1051-
return hr;
1066+
//HRESULT hr = S_OK;
1067+
// handle the event if it is to set profile
1068+
if (pEvent != nullptr
1069+
&& ulEventLength >= sizeof(KSEVENT)
1070+
&& pEvent->Set == KSEVENTSETID_ExtendedCameraControl
1071+
&& pEventData != nullptr
1072+
&& ulDataLength >= sizeof(KSEVENTDATA)
1073+
&& (pEvent->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE))
1074+
{
1075+
1076+
m_hSelectedProfileKSEvent.reset();
1077+
RETURN_IF_WIN32_BOOL_FALSE(DuplicateHandle(
1078+
GetCurrentProcess(),
1079+
((KSEVENTDATA*)(pEventData))->EventHandle.Event,
1080+
GetCurrentProcess(),
1081+
&m_hSelectedProfileKSEvent,
1082+
0,
1083+
FALSE,
1084+
DUPLICATE_SAME_ACCESS));
1085+
1086+
if (m_isProfileDDISupportedInBaseDriver.value_or(true))
1087+
{
1088+
RETURN_IF_FAILED(m_hSelectedProfileKSEventSentToDriver.create());
1089+
KSEVENTDATA driverEventData = {};
1090+
driverEventData.NotificationType = KSEVENTF_EVENT_HANDLE;
1091+
driverEventData.EventHandle.Event = m_hSelectedProfileKSEventSentToDriver.get();
1092+
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "Handling profile set KsEvent, created profile KsEvent handle for driver: %p", m_hSelectedProfileKSEventSentToDriver.get());
1093+
1094+
// defer to source device
1095+
auto hr = m_spIkscontrol->KsEvent(pEvent, ulEventLength, (void*)(&driverEventData), ulDataLength, pBytesReturned);
1096+
if (FAILED(hr))
1097+
{
1098+
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "Failed to send profile KsEvent handle to driver: %p | hr=0x%08x", m_hSelectedProfileKSEventSentToDriver.get(), hr);
1099+
m_hSelectedProfileKSEventSentToDriver.reset();
1100+
m_isProfileDDISupportedInBaseDriver = false;
1101+
}
1102+
}
1103+
}
1104+
else {
1105+
// Pass the events to the driver
1106+
RETURN_IF_FAILED(m_spIkscontrol->KsEvent(pEvent,
1107+
ulEventLength,
1108+
pEventData,
1109+
ulDataLength,
1110+
pBytesReturned));
1111+
}
1112+
return S_OK;
10521113
}
10531114

10541115
//
@@ -1293,6 +1354,102 @@ IFACEMETHODIMP CMultipinMft::Shutdown(
12931354
return ShutdownEventGenerator();
12941355
}
12951356

1357+
/*++
1358+
Description:
1359+
Implements the KsProperty KSPROPERTY_CAMERACONTROL_EXTENDED_PROFILE handler.
1360+
--*/
1361+
1362+
HRESULT CMultipinMft::ProfilePropertyHandler(
1363+
_In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
1364+
_In_ ULONG ulPropertyLength,
1365+
_In_ LPVOID pPropertyData,
1366+
_In_ ULONG ulDataLength,
1367+
_Inout_ PULONG pulBytesReturned) try
1368+
{
1369+
1370+
UNREFERENCED_PARAMETER(ulPropertyLength);
1371+
HRESULT hr = S_OK;
1372+
1373+
if (pProperty->Flags & KSPROPERTY_TYPE_SET)
1374+
{
1375+
DMFTCHECKNULL_GOTO(pulBytesReturned, done, E_POINTER);
1376+
*pulBytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED) + sizeof(KSCAMERA_EXTENDEDPROP_PROFILE);
1377+
if (ulDataLength < *pulBytesReturned)
1378+
{
1379+
return HRESULT_FROM_WIN32(ERROR_MORE_DATA);
1380+
}
1381+
if (pPropertyData)
1382+
{
1383+
1384+
PBYTE pPayload = (PBYTE)pPropertyData;
1385+
PKSCAMERA_EXTENDEDPROP_HEADER pExtendedHeader = &((PKSCAMERA_EXTENDEDPROP_HEADER_BUFFERED)pPayload)->header;
1386+
KSCAMERA_EXTENDEDPROP_PROFILE* pProfile = (PKSCAMERA_EXTENDEDPROP_PROFILE)(pExtendedHeader + 1);
1387+
1388+
m_selectedProfileId.Type = pProfile->ProfileId;
1389+
m_selectedProfileId.Index = pProfile->Index;
1390+
m_selectedProfileId.Unused = pProfile->Reserved;
1391+
1392+
if (m_selectedProfileId.Type == GUID_NULL)
1393+
{
1394+
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_WARNING, "The caller incorrectly sets GUID_NULL, default back to legacy.");
1395+
m_selectedProfileId = { KSCAMERAPROFILE_Legacy, 0, 0 };
1396+
}
1397+
1398+
// signal we are done
1399+
if (m_hSelectedProfileKSEvent.get() != nullptr)
1400+
{
1401+
if (m_hSelectedProfileKSEventSentToDriver != nullptr)
1402+
{
1403+
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "Waiting for driver profile KsEvent handle: %p", m_hSelectedProfileKSEventSentToDriver.get());
1404+
if (!m_hSelectedProfileKSEventSentToDriver.wait(kMAX_WAIT_TIME_DRIVER_PROFILE_KSEVENT))
1405+
{
1406+
1407+
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_ERROR,
1408+
"Waiting for driver profile KsEvent handle: %p timed out after %i ms, failing",
1409+
m_hSelectedProfileKSEventSentToDriver.get(),
1410+
kMAX_WAIT_TIME_DRIVER_PROFILE_KSEVENT);
1411+
m_hSelectedProfileKSEvent.SetEvent();
1412+
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_TIMEOUT));
1413+
}
1414+
m_hSelectedProfileKSEventSentToDriver.reset();
1415+
}
1416+
m_hSelectedProfileKSEvent.SetEvent();
1417+
m_hSelectedProfileKSEvent.reset();
1418+
}
1419+
}
1420+
}
1421+
else if (pProperty->Flags & KSPROPERTY_TYPE_GET)
1422+
{
1423+
DMFTCHECKNULL_GOTO(pulBytesReturned, done, E_POINTER);
1424+
*pulBytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED) + sizeof(KSCAMERA_EXTENDEDPROP_PROFILE);
1425+
if (ulDataLength < *pulBytesReturned)
1426+
{
1427+
return HRESULT_FROM_WIN32(ERROR_MORE_DATA);
1428+
}
1429+
if (pPropertyData)
1430+
{
1431+
if (!m_isProfileDDISupportedInBaseDriver.has_value())
1432+
{
1433+
hr = m_spIkscontrol->KsProperty(pProperty, ulPropertyLength, pPropertyData, ulDataLength, pulBytesReturned);
1434+
m_isProfileDDISupportedInBaseDriver = SUCCEEDED(hr);
1435+
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "Profile DDI GET support on base driver: %d, hr=0x%08x", m_isProfileDDISupportedInBaseDriver.value(), hr);
1436+
*pulBytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED) + sizeof(KSCAMERA_EXTENDEDPROP_PROFILE);
1437+
}
1438+
}
1439+
}
1440+
// --GETPAYLOAD--
1441+
else if (pProperty->Flags & KSPROPERTY_TYPE_GETPAYLOADSIZE)
1442+
{
1443+
RETURN_HR_IF_NULL(E_POINTER, pulBytesReturned);
1444+
*pulBytesReturned = sizeof(KSCAMERA_EXTENDEDPROP_HEADER_BUFFERED) + sizeof(PKSCAMERA_EXTENDEDPROP_PROFILE);
1445+
}
1446+
1447+
done:
1448+
DMFTRACE(DMFT_GENERAL, TRACE_LEVEL_INFORMATION, "%!FUNC! exiting %x = %!HRESULT!", hr, hr);
1449+
return hr;
1450+
} CATCH_RETURN()
1451+
1452+
12961453
//
12971454
// Static method to create an instance of the MFT.
12981455
//

avstream/avscamera/DMFT/AvsCameraDMFT.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
#include "mftpeventgenerator.h"
88
#include "basepin.h"
99

10+
#include <wil/com.h>
11+
#include <wil/resource.h>
12+
#include <optional>
13+
1014
//
1115
// The Below GUID is needed to transfer photoconfirmation sample successfully in the pipeline
1216
// It is used to propagate the mediatype of the sample to the pipeline which will consume the sample
@@ -19,6 +23,8 @@ DEFINE_GUID(MFSourceReader_SampleAttribute_MediaType_priv,
1923

2024
interface IDirect3DDeviceManager9;
2125

26+
constexpr int kMAX_WAIT_TIME_DRIVER_PROFILE_KSEVENT = 3000;// ms, amount of time to wait for the profile DDI KsEvent sent to the driver
27+
2228
//
2329
// Forward declarations
2430
//
@@ -275,9 +281,18 @@ class CMultipinMft :
275281
_In_opt_ IMFMediaType *pMediaType,
276282
_In_ DeviceStreamState newState
277283
);
284+
278285
HRESULT BridgeInputPinOutputPin(
279286
_In_ CInPin* pInPin,
280287
_In_ COutPin* pOutPin);
288+
289+
HRESULT ProfilePropertyHandler(
290+
_In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
291+
_In_ ULONG ulPropertyLength,
292+
_Inout_updates_to_(ulDataLength, *pulBytesReturned) LPVOID pPropertyData,
293+
_In_ ULONG ulDataLength,
294+
_Inout_ PULONG pulBytesReturned);
295+
281296
//
282297
//Inline functions
283298
//
@@ -320,8 +335,14 @@ class CMultipinMft :
320335
UINT32 m_punValue;
321336
ComPtr<IKsControl> m_spIkscontrol;
322337
ComPtr<IMFAttributes> m_spAttributes;
338+
323339
map<int, int> m_outputPinMap; // How output pins are connected to input pins i-><0..outpins>
324340
PWCHAR m_SymbolicLink;
341+
wil::unique_event_nothrow m_hSelectedProfileKSEvent;
342+
wil::unique_event_nothrow m_hSelectedProfileKSEventSentToDriver;
343+
std::optional<bool> m_isProfileDDISupportedInBaseDriver;
344+
SENSORPROFILEID m_selectedProfileId;
345+
325346
};
326347

327348

avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@
162162
<ClCompile>
163163
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
164164
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories);..\..\common;..\common</AdditionalIncludeDirectories>
165+
<LanguageStandard>stdcpp17</LanguageStandard>
165166
</ClCompile>
166167
<Midl>
167168
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
@@ -178,6 +179,7 @@
178179
<ClCompile>
179180
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
180181
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories);..\..\common;..\common</AdditionalIncludeDirectories>
182+
<LanguageStandard>stdcpp17</LanguageStandard>
181183
</ClCompile>
182184
<Midl>
183185
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
@@ -194,6 +196,7 @@
194196
<ClCompile>
195197
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
196198
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories);..\..\common;..\common</AdditionalIncludeDirectories>
199+
<LanguageStandard>stdcpp17</LanguageStandard>
197200
</ClCompile>
198201
<Midl>
199202
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
@@ -210,6 +213,7 @@
210213
<ClCompile>
211214
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
212215
<AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories);..\..\common;..\common</AdditionalIncludeDirectories>
216+
<LanguageStandard>stdcpp17</LanguageStandard>
213217
</ClCompile>
214218
<Midl>
215219
<PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;MF_WPP;SECURITY_WIN32;MFT_UNIQUE_METHOD_NAMES;MF_DEVICEMFT_ALLOW_MFT0_LOAD</PreprocessorDefinitions>
@@ -237,6 +241,7 @@
237241
<ItemGroup>
238242
<None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
239243
<None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
244+
<None Include="packages.config" />
240245
<None Include="Source.def" />
241246
</ItemGroup>
242247
<ItemGroup>
@@ -247,4 +252,11 @@
247252
<ClInclude Include="stdafx.h" />
248253
</ItemGroup>
249254
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
255+
<Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
256+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
257+
<PropertyGroup>
258+
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
259+
</PropertyGroup>
260+
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.250325.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
261+
</Target>
250262
</Project>

avstream/avscamera/DMFT/AvsCameraDMFT.vcxproj.Filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,7 @@
5454
<Filter>Header Files</Filter>
5555
</ClInclude>
5656
</ItemGroup>
57+
<ItemGroup>
58+
<None Include="packages.config" />
59+
</ItemGroup>
5760
</Project>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3-
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.210204.1" targetFramework="native" />
3+
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.250325.1" targetFramework="native" />
44
</packages>

0 commit comments

Comments
 (0)