Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Dit artikel bevat informatie over de implementatie van een aangepaste mediabron in de frameserverarchitectuur.
Opties voor AV Stream en Aangepaste mediabron
Wanneer u besluit hoe u ondersteuning voor videoopnamestreams kunt bieden in de frameserverarchitectuur, zijn er twee hoofdopties: AV Stream en Aangepaste mediabron.
Het AV Stream-model is het standaardmodel voor camerastuurprogramma's met behulp van een AV Stream-minipoortstuurprogramma (kernelmodusstuurprogramma). Normaal gesproken vallen AV Stream-stuurprogramma's in twee hoofdcategorieën: op MIPI gebaseerde stuurprogramma's en USB Video Class-stuurprogramma's.
Voor de optie Aangepaste mediabron is het stuurprogrammamodel mogelijk volledig aangepast (eigendom) of is het gebaseerd op een niet-traditionele camerabron (zoals bestand of netwerkbronnen).
AV Stream-stuurprogramma
Het belangrijkste voordeel van een AV Stream Driver-benadering is dat de PnP en Energiebeheer/Apparaatbeheer al worden verwerkt door het AV Stream-framework.
Het betekent echter ook dat de onderliggende bron een fysiek apparaat moet zijn met een kernelmodusstuurprogramma om te kunnen interfacen met de hardware. Voor UVC-apparaten wordt een Windows UVC 1.5-klassestuurprogramma geleverd, zodat apparaten gewoon hun firmware moeten implementeren.
Voor OP MIPI gebaseerde apparaten moet de leverancier een eigen AV Stream-minipoortstuurprogramma implementeren.
Aangepaste mediabron
Voor bronnen waarvan het apparaatstuurprogramma al beschikbaar is (maar geen AV Stream-minipoortstuurprogramma) of bronnen die gebruikmaken van niet-raditionele camera-opname, is een AV Stream-stuurprogramma mogelijk niet haalbaar. Een IP-camera die via het netwerk is verbonden, past bijvoorbeeld niet in een AV Stream Driver-model.
In dergelijke situaties is een aangepaste mediabron die gebruikmaakt van het frameservermodel een alternatief.
| Functies | Aangepaste mediabron | AV Stream-stuurprogramma |
|---|---|---|
| PnP en Energiebeheer | Moet worden geïmplementeerd door het bron- en/of stub-stuurprogramma | Geleverd door het AV Stream-framework |
| Invoegtoepassing voor gebruikersmodus | Niet beschikbaar. Custom Media Source bevat de oem/IHV-specifieke gebruikersmoduslogica. | DMFT, Platform DMFT en MFT0 voor verouderde implementatie |
| Sensorgroep | Ondersteund | Ondersteund |
| Cameraprofiel V2 | Ondersteund | Ondersteund |
| Cameraprofiel V1 | Niet ondersteund | Ondersteund |
Vereisten voor aangepaste mediabronnen
Met de introductie van de Windows Camera Frame Server -service (ook wel Frame Server genoemd) kan dit worden bereikt via een aangepaste mediabron. Hiervoor zijn twee hoofdonderdelen vereist:
Een stuurprogrammapakket met een stubbed stuurprogramma dat is ontworpen voor het registreren/inschakelen van een cameraapparaatinterface.
Een COM-DLL die als host fungeert voor de aangepaste mediabron.
De eerste vereiste is nodig voor twee doeleinden:
Een controleproces om ervoor te zorgen dat de aangepaste mediabron wordt geïnstalleerd via een vertrouwd proces (voor het stuurprogrammapakket is WHQL-certificering vereist).
Ondersteuning voor de standaard PnP-inventarisatie en detectie van de 'camera'.
Veiligheid
De aangepaste mediabron voor frameserver verschilt van de algemene aangepaste mediabron in termen van beveiliging op de volgende manier:
Frame Server Custom Media Source wordt uitgevoerd als lokale service (niet te verwarren met lokaal systeem; Lokale service is een account met beperkte bevoegdheden op Windows-computers).
Frame Server Custom Media Source wordt uitgevoerd in Sessie 0 (System Service-sessie) en kan niet communiceren met het bureaublad van de gebruiker.
Gezien deze beperkingen mogen aangepaste mediabronnen van Frame Server geen toegang proberen te krijgen tot beveiligde delen van het bestandssysteem of het register. Over het algemeen is leestoegang toegestaan, maar schrijftoegang niet.
Prestatie
Als onderdeel van het frameservermodel zijn er twee gevallen waarin aangepaste mediabronnen worden geïnstantieerd door de frameserver:
Tijdens het genereren/publiceren van sensorgroepen.
Tijdens de activering van de camera
De sensorgroep wordt meestal gegenereerd tijdens de installatie van het apparaat en/of de stroomcyclus. Aangezien dit het geval is, raden we ten zeerste aan dat Aangepaste Media Bronnen een aanzienlijke verwerking vermijden tijdens het aanmaken en dergelijke activiteiten uitstellen naar de IMFMediaSource::Start-functie. De generatie van de sensorgroep zal niet proberen de aangepaste mediabron te starten, maar slechts vragen stellen over de verschillende beschikbare streams/mediatypen en informatie over bron- en streamattributen.
Stub-stuurprogramma
Er zijn twee minimale vereisten voor het stuurprogrammapakket en het stub-stuurprogramma.
Het stub-stuurprogramma kan worden geschreven met behulp van het WDF (UMDF of KMDF) of het WDM-stuurprogrammamodel.
De vereisten voor stuurprogramma's zijn:
- Registreer de apparaatinterface 'camera' (de aangepaste mediabron) onder de categorie KSCATEGORY_VIDEO_CAMERA zodat deze kan worden geïnventariseerd.
Opmerking
Als u opsomming door verouderde DirectShow-toepassingen wilt toestaan, moet uw stuurprogramma zich ook registreren onder de KSCATEGORY_VIDEO en KSCATEGORY_CAPTURE.
- Voeg een registervermelding toe onder het knooppunt van de apparaatinterface (gebruik de AddReg-directive in de DDInstall.Interface sectie van uw driver INF) die de CoCreate-bare CLSID van uw aangepaste Media Source COM-object declareert. Deze moet worden toegevoegd met behulp van de volgende registerwaardenaam: CustomCaptureSourceClsid.
Hierdoor kan de 'camera'-bron door applicaties worden ontdekt. Wanneer deze wordt geactiveerd, informeert de Frame Server-service om de activeringsoproep te onderscheppen en deze om te leiden naar de aangepaste mediabron die met CoCreate is gemaakt.
Voorbeeld INF
In het volgende voorbeeld ziet u een typisch INF-bestand voor een stubstuurprogramma voor een aangepaste mediabron:
;/*++
;
;Module Name:
; SimpleMediaSourceDriver.INF
;
;Abstract:
; INF file for installing the Usermode SimpleMediaSourceDriver Driver
;
;Installation Notes:
; Using Devcon: Type "devcon install SimpleMediaSourceDriver.inf root\SimpleMediaSource" to install
;
;--*/
[Version]
Signature="$WINDOWS NT$"
Class=Sample
ClassGuid={5EF7C2A5-FF8F-4C1F-81A7-43D3CBADDC98}
Provider=%ProviderString%
DriverVer=01/28/2016,0.10.1234
CatalogFile=SimpleMediaSourceDriver.cat
PnpLockdown=1
[DestinationDirs]
DefaultDestDir = 13
UMDriverCopy=13 ; copy to DriverStore
CustomCaptureSourceCopy=13
; ================= Class section =====================
[ClassInstall32]
Addreg=SimpleMediaSourceClassReg
[SimpleMediaSourceClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-24
[SourceDisksNames]
1 = %DiskId1%,,,""
[SourceDisksFiles]
SimpleMediaSourceDriver.dll = 1,,
SimpleMediaSource.dll = 1,,
;*****************************************
; SimpleMFSource Install Section
;*****************************************
[Manufacturer]
%StdMfg%=Standard,NTamd64.10.0...25326
[Standard.NTamd64.10.0...25326]
%SimpleMediaSource.DeviceDesc%=SimpleMediaSourceWin11, root\SimpleMediaSource
;---------------- copy files
[SimpleMediaSourceWin11.NT]
Include=wudfrd.inf
Needs=WUDFRD.NT
CopyFiles=UMDriverCopy, CustomCaptureSourceCopy
AddReg = CustomCaptureSource.ComRegistration
[SimpleMediaSourceWin11.NT.Interfaces]
AddInterface = %KSCATEGORY_VIDEO_CAMERA%, %CustomCaptureSource.ReferenceString%, CustomCaptureSourceInterface
AddInterface = %KSCATEGORY_VIDEO%, %CustomCaptureSource.ReferenceString%, CustomCaptureSourceInterface
AddInterface = %KSCATEGORY_CAPTURE%, %CustomCaptureSource.ReferenceString%, CustomCaptureSourceInterface
[CustomCaptureSourceInterface]
AddReg = CustomCaptureSourceInterface.AddReg, CustomCaptureSource.ComRegistration
[CustomCaptureSourceInterface.AddReg]
HKR,,CLSID,,%ProxyVCap.CLSID%
HKR,,CustomCaptureSourceClsid,,%CustomCaptureSource.CLSID%
HKR,,FriendlyName,,%CustomCaptureSource.Desc%
[CustomCaptureSource.ComRegistration]
HKR,Classes\CLSID\%CustomCaptureSource.CLSID%,,,%CustomCaptureSource.Desc%
HKR,Classes\CLSID\%CustomCaptureSource.CLSID%\InprocServer32,,%REG_EXPAND_SZ%,%CustomCaptureSource.Location%
HKR,Classes\CLSID\%CustomCaptureSource.CLSID%\InprocServer32,ThreadingModel,,Both
[UMDriverCopy]
SimpleMediaSourceDriver.dll,,,0x00004000 ; COPYFLG_IN_USE_RENAME
[CustomCaptureSourceCopy]
SimpleMediaSource.dll,,,0x00004000 ; COPYFLG_IN_USE_RENAME
;-------------- Service installation
[SimpleMediaSourceWin11.NT.Services]
Include=wudfrd.inf
Needs=WUDFRD.NT.Services
;-------------- WDF specific section -------------
[SimpleMediaSourceWin11.NT.Wdf]
UmdfService=SimpleMediaSource, SimpleMediaSource_Install
UmdfServiceOrder=SimpleMediaSource
[SimpleMediaSource_Install]
UmdfLibraryVersion=$UMDFVERSION$
ServiceBinary=%13%\SimpleMediaSourceDriver.dll
[Strings]
ProviderString = "Microsoft Corporation"
StdMfg = "(Standard system devices)"
DiskId1 = "SimpleMediaSource Disk \#1"
SimpleMediaSource.DeviceDesc = "SimpleMediaSource Capture Source" ; what you will see under SimpleMediaSource dummy devices
ClassName = "SimpleMediaSource dummy devices" ; device type this driver will install as in device manager
WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector"
KSCATEGORY_VIDEO_CAMERA = "{E5323777-F976-4f5b-9B55-B94699C46E44}"
KSCATEGORY_CAPTURE="{65E8773D-8F56-11D0-A3B9-00A0C9223196}"
KSCATEGORY_VIDEO="{6994AD05-93EF-11D0-A3CC-00A0C9223196}"
ProxyVCap.CLSID="{17CCA71B-ECD7-11D0-B908-00A0C9223196}"
CustomCaptureSource.Desc = "SimpleMediaSource Source"
CustomCaptureSource.ReferenceString = "CustomCameraSource"
CustomCaptureSource.CLSID = "{9812588D-5CE9-4E4C-ABC1-049138D10DCE}"
CustomCaptureSource.Location = "%13%\SimpleMediaSource.dll"
CustomCaptureSource.Binary = "SimpleMediaSource.dll"
REG_EXPAND_SZ = 0x00020000
De bovenstaande aangepaste mediabron registreert zich onder KSCATEGORY_VIDEO, KSCATEGORY_CAPTURE en KSCATEGORY_VIDEO_CAMERA om ervoor te zorgen dat de camera detecteerbaar is door uwP- en niet-UWP-apps die zoeken naar een standaard RGB-camera.
Als de aangepaste mediabron ook niet-RGB-streams (IR, Diepte enzovoort) beschikbaar maakt, kan deze eventueel ook worden geregistreerd onder de KSCATEGORY_SENSOR_CAMERA.
Opmerking
De meeste USB-webcams maken YUY2- en MJPG-indelingen beschikbaar. Vanwege dit gedrag worden veel verouderde DirectShow-toepassingen geschreven met de veronderstelling dat YUY2/MJPG beschikbaar is. Om ervoor te zorgen dat deze toepassing compatibel is, wordt aanbevolen dat YUY2-mediatype beschikbaar wordt gesteld vanuit uw Aangepaste mediabron als verouderde app-compatibiliteit gewenst is.
Implementatie van Stub Driver
Naast de INF moet de stuurprogramma-stub ook de camera-apparaatinterfaces registreren en inschakelen. Dit gebeurt meestal tijdens de DRIVER_ADD_DEVICE bewerking.
Zie de DRIVER_ADD_DEVICE callback-functie voor stuurprogramma's op basis van WDM en de functie WdfDriverCreate voor UMDF-/KMDF-stuurprogramma's.
Hier volgt een codefragment van een UMDF-stuurprogramma-stub die deze bewerking afhandelt:
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
DriverEntry initializes the driver and is the first routine called by the
system after the driver is loaded. DriverEntry specifies the other entry
points in the function driver, such as EvtDevice and DriverUnload.
Parameters Description:
DriverObject - represents the instance of the function driver that is loaded
into memory. DriverEntry must initialize members of DriverObject before it
returns to the caller. DriverObject is allocated by the system before the
driver is loaded, and it is released by the system after the system unloads
the function driver from memory.
RegistryPath - represents the driver specific path in the Registry.
The function driver can use the path to store driver related data between
reboots. The path does not store hardware instance specific data.
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise.
--*/
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
WDF_DRIVER_CONFIG_INIT(&config,
EchoEvtDeviceAdd
);
status = WdfDriverCreate(DriverObject,
RegistryPath,
WDF_NO_OBJECT_ATTRIBUTES,
&config,
WDF_NO_HANDLE);
if (!NT_SUCCESS(status)) {
KdPrint(("Error: WdfDriverCreate failed 0x%x\n", status));
return status;
}
// ...
return status;
}
NTSTATUS
EchoEvtDeviceAdd(
IN WDFDRIVER Driver,
IN PWDFDEVICE_INIT DeviceInit
)
/*++
Routine Description:
EvtDeviceAdd is called by the framework in response to AddDevice
call from the PnP manager. We create and initialize a device object to
represent a new instance of the device.
Arguments:
Driver - Handle to a framework driver object created in DriverEntry
DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
Return Value:
NTSTATUS
--*/
{
NTSTATUS status;
UNREFERENCED_PARAMETER(Driver);
KdPrint(("Enter EchoEvtDeviceAdd\n"));
status = EchoDeviceCreate(DeviceInit);
return status;
}
NTSTATUS
EchoDeviceCreate(
PWDFDEVICE_INIT DeviceInit
/*++
Routine Description:
Worker routine called to create a device and its software resources.
Arguments:
DeviceInit - Pointer to an opaque init structure. Memory for this
structure will be freed by the framework when the WdfDeviceCreate
succeeds. Do not access the structure after that point.
Return Value:
NTSTATUS
--*/
{
WDF_OBJECT_ATTRIBUTES deviceAttributes;
PDEVICE_CONTEXT deviceContext;
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDFDEVICE device;
NTSTATUS status;
UNICODE_STRING szReference;
RtlInitUnicodeString(&szReference, L"CustomCameraSource");
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
//
// Register pnp/power callbacks so that we can start and stop the timer as the device
// gets started and stopped.
//
pnpPowerCallbacks.EvtDeviceSelfManagedIoInit = EchoEvtDeviceSelfManagedIoStart;
pnpPowerCallbacks.EvtDeviceSelfManagedIoSuspend = EchoEvtDeviceSelfManagedIoSuspend;
#pragma prefast(suppress: 28024, "Function used for both Init and Restart Callbacks")
pnpPowerCallbacks.EvtDeviceSelfManagedIoRestart = EchoEvtDeviceSelfManagedIoStart;
//
// Register the PnP and power callbacks. Power policy related callbacks will be registered
// later in SoftwareInit.
//
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
{
WDF_FILEOBJECT_CONFIG cameraFileObjectConfig;
WDF_OBJECT_ATTRIBUTES cameraFileObjectAttributes;
WDF_OBJECT_ATTRIBUTES_INIT(&cameraFileObjectAttributes);
cameraFileObjectAttributes.SynchronizationScope = WdfSynchronizationScopeNone;
WDF_FILEOBJECT_CONFIG_INIT(
&cameraFileObjectConfig,
EvtCameraDeviceFileCreate,
EvtCameraDeviceFileClose,
WDF_NO_EVENT_CALLBACK);
WdfDeviceInitSetFileObjectConfig(
DeviceInit,
&cameraFileObjectConfig,
&cameraFileObjectAttributes);
}
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
if (NT_SUCCESS(status)) {
//
// Get the device context and initialize it. WdfObjectGet_DEVICE_CONTEXT is an
// inline function generated by WDF_DECLARE_CONTEXT_TYPE macro in the
// device.h header file. This function will do the type checking and return
// the device context. If you pass a wrong object handle
// it will return NULL and assert if run under framework verifier mode.
//
deviceContext = WdfObjectGet_DEVICE_CONTEXT(device);
deviceContext->PrivateDeviceData = 0;
//
// Create a device interface so that application can find and talk
// to us.
//
status = WdfDeviceCreateDeviceInterface(
device,
&CAMERA_CATEGORY,
&szReference // ReferenceString
);
if (NT_SUCCESS(status)) {
//
// Create a device interface so that application can find and talk
// to us.
//
status = WdfDeviceCreateDeviceInterface(
device,
&CAPTURE_CATEGORY,
&szReference // ReferenceString
);
}
if (NT_SUCCESS(status)) {
//
// Create a device interface so that application can find and talk
// to us.
//
status = WdfDeviceCreateDeviceInterface(
device,
&VIDEO_CATEGORY,
&szReference // ReferenceString
);
}
if (NT_SUCCESS(status)) {
//
// Initialize the I/O Package and any Queues
//
status = EchoQueueInitialize(device);
}
}
return status;
}
PnP-bewerking
Net als bij elke andere fysieke camera is het raadzaam dat uw stubstuurprogramma ten minste de PnP-bewerkingen beheert voor het in- en uitschakelen van het apparaat wanneer de onderliggende bron wordt verwijderd/gekoppeld. Als uw aangepaste mediabron bijvoorbeeld gebruikmaakt van een netwerkbron (zoals een IP-camera), kunt u een apparaatverwijdering activeren wanneer die netwerkbron niet meer beschikbaar is.
Dit zorgt ervoor dat toepassingen de juiste meldingen ontvangen via de PnP-API's wanneer apparaten worden toegevoegd of verwijderd. En zorgt ervoor dat een bron die niet meer beschikbaar is, niet kan worden geïnventariseerd.
Zie de documentatie van de functie WdfDeviceSetDeviceState voor UMDF- en KMDF-stuurprogramma's.
Raadpleeg de documentatie van de functie IoSetDeviceInterfaceState voor de WMD-stuurprogramma's.
DLL voor aangepaste mediabronnen
De aangepaste mediabron is een standaard COM-server die de volgende interfaces moet implementeren:
Opmerking
IMFMediaSourceEx neemt over van IMFMediaSource en IMFMediaSource overgenomen van IMFMediaEventGenerator.
Elke ondersteunde stream in de aangepaste mediabron moet de volgende interfaces ondersteunen:
IMFMediaEventGenerator
IMFMediaStream2
Opmerking
IMFMediaStream2 neemt over van IMFMediaStream en IMFMediaStream neemt over van IMFMediaEventGenerator.
Raadpleeg de documentatie over het schrijven van een aangepaste mediabron voor het maken van een aangepaste mediabron. In de rest van deze sectie worden de verschillen uitgelegd die nodig zijn voor de ondersteuning van uw aangepaste mediabron binnen het Frame Server-framework.
IMFGetService
IMFGetService is een verplichte interface voor Frame Server Custom Media Source. IMFGetService kan MF_E_UNSUPPORTED_SERVICE retourneren als uw aangepaste mediabron geen andere service-interfaces beschikbaar hoeft te stellen.
In het volgende voorbeeld ziet u een IMFGetService-implementatie zonder ondersteuningsserviceinterfaces:
_Use_decl_annotations_
IFACEMETHODIMP
SimpleMediaSource::GetService(
_In_ REFGUID guidService,
_In_ REFIID riid,
_Out_ LPVOID * ppvObject
)
{
HRESULT hr = S_OK;
auto lock = _critSec.Lock();
RETURN_IF_FAILED (_CheckShutdownRequiresLock());
if (!ppvObject)
{
return E_POINTER;
}
*ppvObject = NULL;
// We have no supported service, just return
// MF_E_UNSUPPORTED_SERVICE for all calls.
return MF_E_UNSUPPORTED_SERVICE;
}
IMFMediaEventGenerator
Zoals hierboven wordt weergegeven, moeten zowel de bron als de afzonderlijke streams binnen de bron hun eigen IMFMediaEventGenerator-interface ondersteunen. De volledige MF-pijplijngegevens en controlestromen van de bron worden beheerd via de gebeurtenisgenerator door specifieke IMFMediaEvent te verzenden.
Voor de implementatie van IMFMediaEventGenerator moet de Custom Media Source de MFCreateEventQueue-API gebruiken om een IMFMediaEventQueue te maken en alle methoden voor IMFMediaEventGenerator naar het wachtrijobject te routeren:
IMFMediaEventGenerator heeft de volgende methoden:
// IMFMediaEventGenerator
IFACEMETHOD(BeginGetEvent)(_In_ IMFAsyncCallback *pCallback, _In_ IUnknown *punkState);
IFACEMETHOD(EndGetEvent)(_In_ IMFAsyncResult *pResult, _COM_Outptr_ IMFMediaEvent **ppEvent);
IFACEMETHOD(GetEvent)(DWORD dwFlags, _Out_ IMFMediaEvent **ppEvent);
IFACEMETHOD(QueueEvent)(MediaEventType met, REFGUID guidExtendedType, HRESULT hrStatus, _In_opt_ const PROPVARIANT *pvValue);
De volgende code toont de aanbevolen implementatie van de interface IMFMediaEventGenerator. De implementatie van de Custom Media Source toont de interface IMFMediaEventGenerator en de methoden voor die interface routeren de aanvragen naar het IMFMediaEventQueue-object dat is gemaakt tijdens het maken/initialiseren van mediabronnen.
In de onderstaande code is _spEventQueue object het IMFMediaEventQueue gemaakt met behulp van de functie MFCreateEventQueue :
// IMFMediaEventGenerator methods
IFACEMETHODIMP
SimpleMediaSource::BeginGetEvent(
_In_ IMFAsyncCallback *pCallback,
_In_ IUnknown *punkState
)
{
HRESULT hr = S_OK;
auto lock = _critSec.Lock();
RETURN_IF_FAILED (_CheckShutdownRequiresLock());
RETURN_IF_FAILED (_spEventQueue->BeginGetEvent(pCallback, punkState));
return hr;
}
IFACEMETHODIMP
SimpleMediaSource::EndGetEvent(
_In_ IMFAsyncResult *pResult,
_COM_Outptr_ IMFMediaEvent **ppEvent
)
{
HRESULT hr = S_OK;
auto lock = _critSec.Lock();
RETURN_IF_FAILED (_CheckShutdownRequiresLock());
RETURN_IF_FAILED (_spEventQueue->EndGetEvent(pResult, ppEvent));
return hr;
}
IFACEMETHODIMP
SimpleMediaSource::GetEvent(
DWORD dwFlags,
_COM_Outptr_ IMFMediaEvent **ppEvent
)
{
// NOTE:
// GetEvent can block indefinitely, so we do not hold the lock.
// This requires some juggling with the event queue pointer.
HRESULT hr = S_OK;
ComPtr<IMFMediaEventQueue> spQueue;
{
auto lock = _critSec.Lock();
RETURN_IF_FAILED (_CheckShutdownRequiresLock());
spQueue = _spEventQueue;
}
// Now get the event.
RETURN_IF_FAILED (spQueue->GetEvent(dwFlags, ppEvent));
return hr;
}
IFACEMETHODIMP
SimpleMediaSource::QueueEvent(
MediaEventType eventType,
REFGUID guidExtendedType,
HRESULT hrStatus,
_In_opt_ PROPVARIANT const *pvValue
)
{
HRESULT hr = S_OK;
auto lock = _critSec.Lock();
RETURN_IF_FAILED (_CheckShutdownRequiresLock());
RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(eventType, guidExtendedType, hrStatus, pvValue));
return hr;
}
Zoeken en pauzeren
Aangepaste mediabronnen die worden ondersteund via het Frame Server-framework bieden geen ondersteuning voor bewerkingen voor zoeken of onderbreken. Uw aangepaste mediabron hoeft geen ondersteuning te bieden voor deze bewerkingen en mag de gebeurtenis MFSourceSeeked of MEStreamSeeked niet posten.
IMFMediaSource::Pause moet MF_E_INVALID_STATE_TRANSITION retourneren (of MF_E_SHUTDOWN als de bron al was afgesloten).
IKsControl
IKsControl is de standaardbesturingselementinterface voor alle camera-gerelateerde besturingselementen. Als uw aangepaste mediabron camerabesturingselementen implementeert, bepaalt de IKsControl-interface hoe de pijplijn de I/O van het besturingselement routeert.
Zie voor meer informatie de volgende artikelen over de documentatie voor controlsets:
De bedieningselementen zijn optioneel en als ze niet worden ondersteund, is de aanbevolen foutcode die moet worden geretourneerd HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND).
De volgende code is een voorbeeld van een IKsControl-implementatie zonder ondersteunde besturingselementen:
// IKsControl methods
_Use_decl_annotations_
IFACEMETHODIMP
SimpleMediaSource::KsProperty(
_In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
_In_ ULONG ulPropertyLength,
_Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
_In_ ULONG ulDataLength,
_Out_ ULONG* pBytesReturned
)
{
// ERROR_SET_NOT_FOUND is the standard error code returned
// by the AV Stream driver framework when a miniport
// driver does not register a handler for a KS operation.
// We want to mimic the driver behavior here if we do not
// support controls.
return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
}
_Use_decl_annotations_
IFACEMETHODIMP SimpleMediaSource::KsMethod(
_In_reads_bytes_(ulMethodLength) PKSMETHOD pMethod,
_In_ ULONG ulMethodLength,
_Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pMethodData,
_In_ ULONG ulDataLength,
_Out_ ULONG* pBytesReturned
)
{
return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
}
_Use_decl_annotations_
IFACEMETHODIMP SimpleMediaSource::KsEvent(
_In_reads_bytes_opt_(ulEventLength) PKSEVENT pEvent,
_In_ ULONG ulEventLength,
_Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pEventData,
_In_ ULONG ulDataLength,
_Out_opt_ ULONG* pBytesReturned
)
{
return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND);
}
IMFMediaStream2
Zoals uitgelegd in het schrijven van een aangepaste mediabron, wordt de IMFMediaStream2-interface geleverd aan het framewerk van uw aangepaste mediabron via een MENewStream-media-gebeurtenis die is gepost in de bron gebeurteniswachtrij tijdens de voltooiing van de methode IMFMediaSource:::Start :
IFACEMETHODIMP
SimpleMediaSource::Start(
_In_ IMFPresentationDescriptor *pPresentationDescriptor,
_In_opt_ const GUID *pguidTimeFormat,
_In_ const PROPVARIANT *pvarStartPos
)
{
HRESULT hr = S_OK;
auto lock = _critSec.Lock();
DWORD count = 0;
PROPVARIANT startTime;
BOOL selected = false;
ComPtr<IMFStreamDescriptor> streamDesc;
DWORD streamIndex = 0;
if (pPresentationDescriptor == nullptr || pvarStartPos == nullptr)
{
return E_INVALIDARG;
}
else if (pguidTimeFormat != nullptr && *pguidTimeFormat != GUID_NULL)
{
return MF_E_UNSUPPORTED_TIME_FORMAT;
}
RETURN_IF_FAILED (_CheckShutdownRequiresLock());
if (_sourceState != SourceState::Stopped)
{
return MF_E_INVALID_STATE_TRANSITION;
}
_sourceState = SourceState::Started;
// This checks the passed in PresentationDescriptor matches the member of streams we
// have defined internally and that at least one stream is selected
RETURN_IF_FAILED (_ValidatePresentationDescriptor(pPresentationDescriptor));
RETURN_IF_FAILED (pPresentationDescriptor->GetStreamDescriptorCount(&count));
RETURN_IF_FAILED (InitPropVariantFromInt64(MFGetSystemTime(), &startTime));
// Send event that the source started. Include error code in case it failed.
RETURN_IF_FAILED (_spEventQueue->QueueEventParamVar(MESourceStarted,
GUID_NULL,
hr,
&startTime));
// We are hardcoding this to the first descriptor
// since this sample is a single stream sample. For
// multiple streams, we need to walk the list of streams
// and for each selected stream, send the MEUpdatedStream
// or MENewStream event along with the MEStreamStarted
// event.
RETURN_IF_FAILED (pPresentationDescriptor->GetStreamDescriptorByIndex(0,
&selected,
&streamDesc));
RETURN_IF_FAILED (streamDesc->GetStreamIdentifier(&streamIndex));
if (streamIndex >= NUM_STREAMS)
{
return MF_E_INVALIDSTREAMNUMBER;
}
if (selected)
{
ComPtr<IUnknown> spunkStream;
MediaEventType met = (_wasStreamPreviouslySelected ? MEUpdatedStream : MENewStream);
// Update our internal PresentationDescriptor
RETURN_IF_FAILED (_spPresentationDescriptor->SelectStream(streamIndex));
RETURN_IF_FAILED (_stream.Get()->SetStreamState(MF_STREAM_STATE_RUNNING));
RETURN_IF_FAILED (_stream.As(&spunkStream));
// Send the MEUpdatedStream/MENewStream to our source event
// queue.
RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(met,
GUID_NULL,
S_OK,
spunkStream.Get()));
// But for our stream started (MEStreamStarted), we post to our
// stream event queue.
RETURN_IF_FAILED (_stream.Get()->QueueEvent(MEStreamStarted,
GUID_NULL,
S_OK,
&startTime));
}
_wasStreamPreviouslySelected = selected;
return hr;
}
Dit moet worden gedaan voor elke stroom die is geselecteerd via de IMFPresentationDescriptor.
Voor aangepaste mediabronnen met videostream mogen meendOfStream - en MEEndOfPresentation-gebeurtenissen niet worden verzonden.
Stream-kenmerken
Voor alle aangepaste mediabronstreams moet de MF_DEVICESTREAM_STREAM_CATEGORY zijn ingesteld op PINNAME_VIDEO_CAPTURE. PINNAME_VIDEO_PREVIEW wordt niet ondersteund voor aangepaste mediabronnen.
Opmerking
Hoewel PINNAME_IMAGE wordt ondersteund, wordt het niet aanbevolen. Om een stream met PINNAME_IMAGE beschikbaar te stellen, moet de aangepaste mediabron alle besturingselementen voor de fototrigger ondersteunen. Zie de sectie Fotostroombesturingselementen hieronder voor meer informatie.
MF_DEVICESTREAM_STREAM_ID is een verplicht kenmerk voor alle streams. Dit moet een op 0 gebaseerde index zijn. De eerste stream heeft dus een id van 0, tweede stream een id van 1, enzovoort.
Hier volgt een lijst met aanbevolen kenmerken in de stream:
MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES
MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES is een UINT32-kenmerk dat een bitmaskerwaarde van het stroomtype is. Het kan worden ingesteld op een van de volgende (hoewel deze typen een bitmaskervlag zijn, wordt aanbevolen dat brontypen niet worden gemengd indien mogelijk):
| Typ | Vlag | Beschrijving |
|---|---|---|
| MFFrameSourceTypes_Color | 0x0001 | Standaard RGB-kleurenstroom |
| MFFrameSourceTypes_Infrared | 0x0002 | IR-stroom |
| MFFrameBronTypen_Diepte | 0x0004 | Diepte-stroom |
| MFFrameSourceTypes_Afbeelding | 0x0008 | Afbeeldingsstroom (niet-videosubtype, meestal JPEG) |
| MFFrameSourceTypes_Custom | 0x0080 | Aangepast stroomtype |
MF_DEVICESTREAM_FRAMESERVER_SHARED
MF_DEVICESTREAM_FRAMESERVER_SHARED is een UINT32-kenmerk dat kan worden ingesteld op 0 of 1. Als deze optie is ingesteld op 1, wordt de stroom gemarkeerd als 'deelbaar' door de frameserver. Hierdoor kunnen toepassingen de stream openen in een gedeelde modus, zelfs wanneer ze door een andere app worden gebruikt.
Als dit kenmerk niet is ingesteld, staat Frame Server toe dat de eerste niet-gemarkeerde stream wordt gedeeld (als de aangepaste mediabron slechts één stream heeft, wordt die stream gemarkeerd als gedeeld).
Als dit kenmerk is ingesteld op 0, blokkeert Frame Server de stroom van gedeelde apps. Als de aangepaste mediabron alle streams markeert met dit kenmerk ingesteld op 0, kan de bron niet worden geïnitialiseerd door een gedeelde toepassing.
Voorbeeldtoewijzing
Alle mediaframes moeten als een IMFSample worden geproduceerd. Aangepaste mediabronnen moeten de functie MFCreateSample gebruiken om een exemplaar van IMFSample toe te wijzen en de methode AddBuffer gebruiken om mediabuffers toe te voegen.
Elk IMFSample moet de steekproeftijd en de duur van de steekproef hebben ingesteld. Alle voorbeeldtijdstempels moeten zijn gebaseerd op QPC-tijd (QueryPerformanceCounter).
Aangeraden wordt om waar mogelijk de functie MFGetSystemTime te gebruiken bij aangepaste mediabronnen. Deze functie is een wrapper rond QueryPerformanceCounter en converteert de QPC-ticks naar eenheden van 100 nanoseconden.
Aangepaste mediabronnen kunnen een interne klok gebruiken, maar alle tijdstempels moeten worden gecorreleerd met 100 nanoseconden op basis van de huidige QPC.
Mediabuffer
Alle mediabuffers die aan het IMFSample zijn toegevoegd, moeten gebruikmaken van de standaardfuncties voor MF-buffertoewijzing. Aangepaste mediabronnen mogen hun eigen IMFMediaBuffer-interfaces niet implementeren of rechtstreeks proberen mediabuffer toe te wijzen (bijvoorbeeld new/malloc/VirtualAlloc, enzovoort, mogen niet worden gebruikt voor framegegevens).
Gebruik een van de volgende API's om mediaframes toe te wijzen:
MFCreateMemoryBuffer en MFCreateAlignedMemoryBuffer moeten worden gebruikt voor mediadata die niet zijn uitgelijnd volgens striding. Dit zijn meestal aangepaste subtypen of gecomprimeerde subtypen (zoals H264/HEVC/MJPG).
Voor bekende niet-gecomprimeerde mediatypen (zoals YUY2, NV12, enzovoort) met behulp van systeemgeheugen, is het raadzaam om MFCreate2DMediaBuffer te gebruiken.
Voor het gebruik van DX-oppervlakken (voor versnelde GPU-bewerkingen, zoals rendering en/of codering), moet MFCreateDXGISurfaceBuffer worden gebruikt.
MFCreateDXGISurfaceBuffer maakt het DX-oppervlak niet. Het oppervlak wordt gemaakt met behulp van de DXGI Manager die via de methode IMFMediaSourceEx::SetD3DManager wordt doorgegeven aan de mediabron.
Het IMFDXGIDeviceManager::OpenDeviceHandle biedt de ingang die is gekoppeld aan het geselecteerde D3D-apparaat. De ID3D11Device-interface kan vervolgens verkregen worden met behulp van de methode IMFDXGIDeviceManager::GetVideoService.
Ongeacht het type buffer dat wordt gebruikt, moet de IMFSample die is gemaakt aan de pijplijn worden verstrekt via de MEMediaSample gebeurtenis op de IMFMediaEventGenerator van de mediastroom.
Hoewel het mogelijk is om hetzelfde IMFMediaEventQueue te gebruiken voor zowel de aangepaste mediabron als de onderliggende verzameling van IMFMediaStream, moet dit ertoe leiden dat dit leidt tot serialisatie van de mediabrongebeurtenissen en stroomgebeurtenissen (waaronder de mediastroom). Voor bronnen met meerdere streams is dit niet wenselijk.
In het volgende codefragment ziet u een voorbeeld van de implementatie van de mediastream:
IFACEMETHODIMP
SimpleMediaStream::RequestSample(
_In_ IUnknown *pToken
)
{
HRESULT hr = S_OK;
auto lock = _critSec.Lock();
ComPtr<IMFSample> sample;
ComPtr<IMFMediaBuffer> outputBuffer;
LONG pitch = IMAGE_ROW_SIZE_BYTES;
BYTE *bufferStart = nullptr; // not used
DWORD bufferLength = 0;
BYTE *pbuf = nullptr;
ComPtr<IMF2DBuffer2> buffer2D;
RETURN_IF_FAILED (_CheckShutdownRequiresLock());
RETURN_IF_FAILED (MFCreateSample(&sample));
RETURN_IF_FAILED (MFCreate2DMediaBuffer(NUM_IMAGE_COLS,
NUM_IMAGE_ROWS,
D3DFMT_X8R8G8B8,
false,
&outputBuffer));
RETURN_IF_FAILED (outputBuffer.As(&buffer2D));
RETURN_IF_FAILED (buffer2D->Lock2DSize(MF2DBuffer_LockFlags_Write,
&pbuf,
&pitch,
&bufferStart,
&bufferLength));
RETURN_IF_FAILED (WriteSampleData(pbuf, pitch, bufferLength));
RETURN_IF_FAILED (buffer2D->Unlock2D());
RETURN_IF_FAILED (sample->AddBuffer(outputBuffer.Get()));
RETURN_IF_FAILED (sample->SetSampleTime(MFGetSystemTime()));
RETURN_IF_FAILED (sample->SetSampleDuration(333333));
if (pToken != nullptr)
{
RETURN_IF_FAILED (sample->SetUnknown(MFSampleExtension_Token, pToken));
}
RETURN_IF_FAILED (_spEventQueue->QueueEventParamUnk(MEMediaSample,
GUID_NULL,
S_OK,
sample.Get()));
return hr;
}
Aangepaste mediabronextensie om IMFActivate beschikbaar te maken (beschikbaar in Windows 10, versie 1809)
Naast de bovenstaande lijst met interfaces die moeten worden ondersteund voor een aangepaste mediabron, is een van de beperkingen die zijn opgelegd door de werking van Aangepaste mediabronnen in de frameserverarchitectuur, dat er slechts één exemplaar van het UMDF-stuurprogramma via de verwerkingsketen 'geactiveerd' kan zijn.
Als u bijvoorbeeld een fysiek apparaat hebt dat een UMDF-stub-stuurprogramma installeert naast het niet-AV Stream driverpakket en u meer dan een van deze fysieke apparaten aansluit op een computer, terwijl elk exemplaar van het UMDF-stuurprogramma een unieke symbolische koppelingsnaam krijgt, heeft het activeringspad voor de aangepaste mediabron geen middelen om de symbolische koppelingsnaam te communiceren die is gekoppeld aan de aangepaste mediabron tijdens de creatie.
Aangepaste Mediabron zoekt mogelijk naar het standaardkenmerk MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK in de kenmerkopslag van de Aangepaste Mediabron (de kenmerkopslag die is geretourneerd door de Aangepaste Mediabron via de methode IMFMediaSourceEx::GetSourceAttributes) wanneer IMFMediaSource::Start wordt aangeroepen.
Dit kan echter leiden tot een hogere opstartlatentie, omdat hierdoor de overname van HW-resources wordt uitgesteld tot de begintijd in plaats van de aanmaak-/initialisatietijd.
Daarom kunnen aangepaste mediabronnen in Windows 10 versie 1809 eventueel een IMFActivate-interface beschikbaar maken .
Opmerking
IMFActivate neemt over van IMFAttributes.
IMFActivate
Als de COM-server voor de Custom Media Source de IMFActivate-interface ondersteunt, wordt de informatie over de initialisatie van het apparaat aan de COM-server verstrekt via de IMFAttributes die zijn overgenomen door het IMFActivate. Dus wanneer het IMFActivate::ActivateObject wordt aangeroepen, bevat het kenmerkarchief van het IMFActivate de symbolische koppelingsnaam van het UMDF stub-stuurprogramma en eventuele andere configuratie-instellingen die door de pijplijn/toepassing worden geleverd op het moment van het maken/initialiseren van de bron.
De aangepaste mediabron moet deze methode aanroepen om de benodigde hardwareresources te verkrijgen.
Opmerking
Als het ophalen van hardwareresources langer duurt dan 200 milliseconden, wordt het aanbevolen hardwareresource asynchroon te verkrijgen. De activering van de aangepaste mediabron mag niet worden geblokkeerd bij het ophalen van hardwareresources. In plaats daarvan moet de bewerking IMFMediaSource::Start worden geserialiseerd op basis van de aanschaf van hardwareresources.
De twee andere methoden die worden weergegeven door IMFActivate, DetachObject en ShutdownObject, moeten E_NOTIMPL retourneren.
De aangepaste mediabron kan ervoor kiezen om de interface IMFActivate en IMFAttributes binnen hetzelfde COM-object als het IMFMediaSource te implementeren. Als dit wordt gedaan, is het aanbevolen dat de IMFMediaSourceEx::GetSourceAttributes dezelfde IMFAttributes-interface retourneert als die van IMFActivate.
Als de aangepaste mediabron het IMFActivate en IMFAttributes met hetzelfde object niet implementeert, moet de Custom Media Source alle kenmerken die zijn ingesteld op het kenmerkarchief IMFActivate kopiëren naar het bronkenmerkarchief van de aangepaste mediabron.
Gecodeerde camerastream
Een aangepaste mediabron kan gecomprimeerde mediatypen (HEVC- of H264 elementaire streams) beschikbaar maken en de besturingssysteempijplijn ondersteunt volledig de bron en configuratie van de coderingsparameters op de Custom Media Source (de coderingsparameters worden gecommuniceerd via de ICodecAPI, die wordt gerouteerd als een IKsControl::KsProperty-aanroep ):
// IKsControl methods
_Use_decl_annotations_
IFACEMETHODIMP
SimpleMediaSource::KsProperty(
_In_reads_bytes_(ulPropertyLength) PKSPROPERTY pProperty,
_In_ ULONG ulPropertyLength,
_Inout_updates_to_(ulDataLength, *pBytesReturned) LPVOID pPropertyData,
_In_ ULONG ulDataLength,
_Out_ ULONG* pBytesReturned
);
De KSPROPERTY-structuur die is doorgegeven aan de methode IKsControl::KsProperty heeft de volgende informatie:
KSPROPERTY.Set = Encoder Property GUID
KSPROPERTY.Id = 0
KSPROPERTY.Flags = (KSPROPERTY_TYPE_SET or KSPROPERTY_TYPE_GET)
Waarbij de GUID van de encodereigenschap de lijst met beschikbare eigenschappen is die zijn gedefinieerd in codec-API-eigenschappen.
De nettolading van de encodereigenschap wordt doorgegeven via het veld pPropertyData van de hierboven gedeclareerde KsProperty-methode .
Vereisten voor de opname-engine
Hoewel gecodeerde bronnen volledig worden ondersteund door Frame Server, legt de Client Side Capture Engine (IMFCaptureEngine) die wordt gebruikt door het object Windows.Media.Capture.MediaCapture extra vereisten op:
De stream moet of allemaal zijn gecodeerd (HEVC of H264) of allemaal ongecomprimeerd zijn (in deze context wordt MJPG als ongecomprimeerd beschouwd).
Er moet ten minste één niet-gecomprimeerde stroom beschikbaar zijn.
Opmerking
Deze vereisten komen bovenop de eisen voor aangepaste mediabronnen die in dit artikel worden beschreven. De vereisten voor de Capture Engine worden echter alleen afgedwongen wanneer de clienttoepassing de aangepaste mediabron gebruikt via de IMFCaptureEngine - of Windows.Media.Capture.MediaCapture-API .
Cameraprofielen (beschikbaar in Windows 10, versie 1803 en hoger)
Ondersteuning voor cameraprofielen is beschikbaar voor aangepaste mediabronnen. Het aanbevolen mechanisme is om het profiel te publiceren via het kenmerk MF_DEVICEMFT_SENSORPROFILE_COLLECTION van het bronkenmerk (IMFMediaSourceEx::GetSourceAttributes).
Het kenmerk MF_DEVICEMFT_SENSORPROFILE_COLLECTION is een IUnknown van de interface IMFSensorProfileCollection . IMFSensorProfileCollection kan worden verkregen met behulp van de functie MFCreateSensorProfileCollection :
IFACEMETHODIMP
SimpleMediaSource::GetSourceAttributes(
_COM_Outptr_ IMFAttributes** sourceAttributes
)
{
HRESULT hr = S_OK;
auto lock = _critSec.Lock();
if (nullptr == sourceAttributes)
{
return E_POINTER;
}
RETURN_IF_FAILED (_CheckShutdownRequiresLock());
*sourceAttributes = nullptr;
if (_spAttributes.Get() == nullptr)
{
ComPtr<IMFSensorProfileCollection> profileCollection;
ComPtr<IMFSensorProfile> profile;
// Create our source attribute store
RETURN_IF_FAILED (MFCreateAttributes(_spAttributes.GetAddressOf(), 1));
// Create an empty profile collection
RETURN_IF_FAILED (MFCreateSensorProfileCollection(&profileCollection));
// In this example since we have just one stream, we only have one
// pin to add: Pin0
// Legacy profile is mandatory. This is to ensure non-profile
// aware applications can still function, but with degraded
// feature sets.
RETURN_IF_FAILED (MFCreateSensorProfile(KSCAMERAPROFILE_Legacy, 0, nullptr,
profile.ReleaseAndGetAddressOf()));
RETURN_IF_FAILED (profile->AddProfileFilter(0, L"((RES==;FRT<=30,1;SUT==))"));
RETURN_IF_FAILED (profileCollection->AddProfile(profile.Get()));
// High Frame Rate profile will only allow >=60fps
RETURN_IF_FAILED (MFCreateSensorProfile(KSCAMERAPROFILE_HighFrameRate, 0, nullptr,
profile.ReleaseAndGetAddressOf()));
RETURN_IF_FAILED (profile->AddProfileFilter(0, L"((RES==;FRT>=60,1;SUT==))"));
RETURN_IF_FAILED (profileCollection->AddProfile(profile.Get()));
// See the profile collection to the attribute store of the IMFTransform
RETURN_IF_FAILED (_spAttributes->SetUnknown(MF_DEVICEMFT_SENSORPROFILE_COLLECTION,
profileCollection.Get()));
}
return _spAttributes.CopyTo(sourceAttributes);
}
Gezichtsauthenticatieprofiel
Als de aangepaste mediabron is ontworpen ter ondersteuning van Gezichtsherkenning van Windows Hello, is het raadzaam om een profiel voor gezichtsverificatie te publiceren. De vereisten van een Gezichtsverificatieprofiel zijn:
Het DDI-besturingselement voor gezichtsverificatie moet worden ondersteund op één IR-stream. Zie KSPROPERTY_CAMERACONTROL_EXTENDED_FACEAUTH_MODE voor meer informatie.
De IR-stream moet ten minste 340 x 340 bij 15 fps zijn. De indeling moet L8, NV12 zijn, of MJPG met L8-compressie gemarkeerd.
De RGB-stroom moet ten minste 480 x 480 bij 7,5 fps zijn (dit is alleen nodig als Multispectrum-verificatie wordt afgedwongen).
Het profiel voor gezichtsverificatie moet de profiel-id hebben van: KSCAMERAPROFILE_FaceAuth_Mode,0.
We raden u aan om voor elk van de IR- en RGB-streams slechts één mediatype te adverteren voor het Face Authentication-profiel.
Fotostream Instellingen
Als onafhankelijke fotostreams openbaar worden gemaakt door één van de MF_DEVICESTREAM_STREAM_CATEGORY van de stroom als PINNAME_IMAGE te markeren, is een stream met de stroomcategorie PINNAME_VIDEO_CAPTURE vereist (bijvoorbeeld, een enkele stroom die alleen de PINNAME_IMAGE blootlegt, is geen geldige mediabron).
Via IKsControl moet de PROPSETID_VIDCAP_VIDEOCONTROL eigenschappenset worden ondersteund. Zie Eigenschappen van videobeheer voor meer informatie.