Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makalede, Çerçeve Sunucusu mimarisi içinde özel medya kaynağının uygulanması hakkında bilgi sağlanır.
AV Stream ve Özel Medya Kaynağı seçenekleri
Çerçeve Sunucusu mimarisinde video yakalama akışı desteği sağlamaya karar verirken iki ana seçenek vardır: AV Stream ve Özel Medya Kaynağı.
AV Stream modeli, AV Stream miniport sürücüsü (çekirdek modu sürücüsü) kullanan standart kamera sürücüsü modelidir. AV Stream sürücüleri genellikle iki ana kategoriye ayrılır: MIPI tabanlı sürücüler ve USB Video Sınıfı sürücüleri.
Özel Medya Kaynağı seçeneği için sürücü modeli tamamen özel (özel) olabilir veya geleneksel olmayan bir kamera kaynağını (dosya veya ağ kaynakları gibi) temel alabilir.
AV Akış Sürücüsü
AV Stream Sürücüsü yaklaşımının temel avantajı, PnP ve Güç Yönetimi/Cihaz Yönetimi'nin ZATEN AV Stream çerçevesi tarafından işlenmesidir.
Ancak, temel alınan kaynağın donanımla arabirim oluşturmak için çekirdek modu sürücüsüne sahip bir fiziksel cihaz olması gerektiği anlamına da gelir. UVC cihazları için, Windows UVC 1.5 sınıf sürücüsü dahili olarak sağlanır, bu nedenle cihazların yalnızca kendi üretici yazılımını uygulaması yeterlidir.
MIPI tabanlı cihazlarda satıcının kendi AV Stream miniport sürücüsünü uygulaması gerekir.
Özel Medya Kaynağı
Cihaz sürücüsü zaten kullanılabilir olan (ancak AV Stream miniport sürücüsü olmayan) kaynaklar veya geleneksel olmayan kamera yakalama kullanan kaynaklar için AV Stream Sürücüsü uygun olmayabilir. Örneğin, ağ üzerinden bağlanan bir IP Kamerası BIR AV Stream Driver modeline sığmaz.
Böyle durumlarda, Çerçeve Sunucusu modelini kullanan bir Özel Medya Kaynağı alternatif olabilir.
| Özellikler | Özel Medya Kaynağı | AV Akış Sürücüsü |
|---|---|---|
| PnP ve Güç Yönetimi | Kaynak ve/veya saplama sürücüsü tarafından uygulanmalıdır | AV Stream çerçevesi tarafından sağlanır |
| Kullanıcı modu eklentisi | Mevcut değil. Özel Medya Kaynağı, OEM/IHV'ye özgü kullanıcı modu mantığını içerir. | Eski uygulama için DMFT, Platform DMFT ve MFT0 |
| Algılayıcı Grubu | Destekleniyor | Destekleniyor |
| Kamera Profili V2 | Destekleniyor | Destekleniyor |
| Kamera Profili V1 | Desteklenmiyor | Destekleniyor |
Özel Medya Kaynağı Gereksinimleri
Windows Kamera Çerçeve Sunucusu (Çerçeve Sunucusu olarak adlandırılır) hizmetinin kullanıma sunulmasıyla birlikte, bu özel bir Medya Kaynağı aracılığıyla gerçekleştirilebilir. Bunun için iki ana bileşen gerekir:
Kamera cihazı arabirimini kaydetmek/etkinleştirmek için tasarlanmış saplamalı sürücüye sahip bir sürücü paketi.
Özel Medya Kaynağını barındıran BIR COM DLL'i.
İlk gereksinim iki amaç için gereklidir:
Özel Medya Kaynağının güvenilir bir işlem aracılığıyla yüklendiğinden emin olmak için bir inceleme işlemi (sürücü paketi WHQL sertifikası gerektirir).
Standart PnP numaralandırması ve "kamera" bulma desteği.
Güvenlik
Çerçeve Sunucusu için Özel Medya Kaynağı, güvenlik açısından genel Özel Medya Kaynağından aşağıdaki şekilde farklıdır:
Çerçeve Sunucusu Özel Medya Kaynağı Yerel Hizmet olarak çalışır (Yerel Sistemle karıştırılmamalıdır; Yerel Hizmet, Windows makinelerinde düşük ayrıcalıklı bir hesaptır).
Çerçeve Sunucusu Özel Medya Kaynağı Oturum 0'da (Sistem Hizmeti oturumu) çalışır ve kullanıcı masaüstüyle etkileşim kuramaz.
Bu kısıtlamalar göz önüne alındığında, Çerçeve Sunucusu Özel Medya Kaynakları dosya sisteminin veya kayıt defterinin korumalı bölümlerine erişmeyi denememelidir. Genel olarak, okuma erişimine izin verilir, ancak yazma erişimine izin verilmez.
Gösteri
Çerçeve Sunucusu modelinin bir parçası olarak, Özel Medya Kaynaklarının Çerçeve Sunucusu tarafından nasıl oluşturulacağıyla ilgili iki durum vardır:
Sensör Grubu oluşturulması/yayımlanması sırasında.
"Kamera" etkinleştirmesi sırasında
Algılayıcı Grubu oluşturma işlemi genellikle cihaz kurulumu ve/veya güç döngüsü sırasında gerçekleştirilir. Bunu göz önünde bulundurarak, Özel Medya Kaynaklarının oluşturulması sırasında önemli işlemlerden kaçınmasını ve bu tür etkinlikleri IMFMediaSource::Start işlevine ertelemesini kesinlikle öneririz. Algılayıcı Grubu oluşturma işlemi Özel Medya Kaynağı'nı başlatmayı denemez, yalnızca çeşitli kullanılabilir akışları/medya türlerini ve kaynak/akış öznitelik bilgilerini sorgular.
Saplama Sürücüsü
Sürücü paketi ve geçici sürücü için iki minimum gereksinim vardır.
Saplama sürücüsü WDF (UMDF veya KMDF) veya WDM sürücü modeli kullanılarak yazılabilir.
Sürücü gereksinimleri şunlardır:
- Numaralandırılabilmesi için "kamera" (Özel Medya Kaynağı) cihaz arabiriminizi KSCATEGORY_VIDEO_CAMERA kategorisine kaydedin.
Uyarı
Eski DirectShow uygulamaları tarafından numaralandırmaya izin vermek için sürücünüzün KSCATEGORY_VIDEO ve KSCATEGORY_CAPTURE altına da kaydolması gerekir.
- Özel Medya Kaynağı COM nesnenizin CoCreate-able CLSID'sini bildiren cihaz arabirimi düğümü altına bir kayıt defteri girdisi ekleyin (sürücünüzdeki INF DDInstall.Interface bölümündeki AddReg yönergesini kullanın). Bu, şu kayıt defteri değeri adı kullanılarak eklenmelidir: CustomCaptureSourceClsid.
Bu, "kamera" kaynağının uygulamalar tarafından bulunmasını sağlar ve etkinleştirildiğinde, Çerçeve Sunucusu hizmetine etkinleştirme çağrısını kesmesi ve Ortak Oluşturulmuş Özel Medya Kaynağı'na yeniden yönlendirmesi konusunda bilgilendirir.
Örnek INF
Aşağıdaki örnekte Özel Medya Kaynağı saplama sürücüsü için tipik bir INF gösterilmektedir:
;/*++
;
;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
Yukarıdaki "Özel Medya Kaynağı" KSCATEGORY_VIDEO,KSCATEGORY_CAPTURE ve KSCATEGORY_VIDEO_CAMERA altına kaydolarak, "kameranın" standart RGB kamera arayan UWP ve UWP olmayan uygulamalar için bulunabilir olmasını sağlar.
Özel Medya Kaynağı RGB olmayan akışları da (IR, Derinlik vb.) destekliyorsa, opsiyonel olarak KSCATEGORY_SENSOR_CAMERA altına da kaydedilebilir.
Uyarı
ÇOĞU USB tabanlı web kamerası YUY2 ve MJPG biçimlerini kullanıma sunar. Bu davranış nedeniyle, birçok eski DirectShow uygulaması YUY2/MJPG'nin kullanılabilir olduğu varsayımıyla yazılır. Bu tür bir uygulamayla uyumluluğu sağlamak için, eski uygulama uyumluluğu isteniyorsa YUY2 medya türünün Özel Medya Kaynağınızdan kullanılabilir duruma getirilmesini öneririz.
Saplama Sürücüsü Uygulaması
INF'ye ek olarak, sürücü saplaması kamera cihazı arabirimlerini de kaydetmeli ve etkinleştirmelidir. Bu genellikle DRIVER_ADD_DEVICE işlemi sırasında yapılır.
Bkz. WDM tabanlı sürücüler için DRIVER_ADD_DEVICE geri çağırma işlevi ve UMDF/KMDF sürücüleri için WdfDriverCreate işlevi.
Aşağıda, bu işlemi işleyen BIR UMDF sürücü saplaması kod alıntısı yer alır:
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 İşlemi
Diğer tüm fiziksel kameralarda olduğu gibi, temel alınan kaynak kaldırıldığında/eklendiğinde cihazı etkinleştirmek ve devre dışı bırakmak için en azından stub sürücünüzün PnP işlemlerini yönetmesi önerilir. Örneğin, Özel Medya Kaynağınız bir ağ kaynağı (IP kamerası gibi) kullanıyorsa, bu ağ kaynağı artık kullanılabilir olmadığında bir cihazın kaldırılmasını tetiklemeniz gerekebilir.
Bu, uygulamaların PnP API'leri aracılığıyla cihaz ekleme/kaldırmayı dinlemesini sağlar. Ve artık kullanılabilir olmayan bir kaynağın numaralandırılmamasını sağlar.
UMDF ve KMDF sürücüleri için WdfDeviceSetDeviceState işlevi belgelerine bakın.
WMD sürücüleri için IoSetDeviceInterfaceState işlevi belgelerine bakın.
Özel Medya Kaynak DLL'i
Özel Medya Kaynağı, aşağıdaki arabirimleri uygulaması gereken standart bir inproc COM sunucusudur:
Uyarı
IMFMediaSourceEx, IMFMediaSource'tan devralır ve IMFMediaSource, IMFMediaEventGenerator'dan devralır.
Özel Medya Kaynağı içinde desteklenen her akış aşağıdaki arabirimleri desteklemelidir:
IMFMediaEventGenerator
IMFMediaStream2
Uyarı
IMFMediaStream2, IMFMediaStream'den devralır ve IMFMediaStream, IMFMediaEventGenerator'dan devralır.
Özel Medya Kaynağı oluşturma hakkında Özel Medya Kaynağı Yazma belgelerine bakın. Bu bölümün geri kalanında, Çerçeve Sunucusu çerçevesi içinde Özel Medya Kaynağınızı desteklemek için gereken farklar açıklanmaktadır.
IMFGetService
IMFGetService , Çerçeve Sunucusu Özel Medya Kaynağı için zorunlu bir arabirimdir. Özel Medya Kaynağınızın başka hizmet arabirimlerini kullanıma sunması gerekmiyorsa, IMFGetServiceMF_E_UNSUPPORTED_SERVICE döndürebilir.
Aşağıdaki örnekte, destek hizmeti arabirimleri olmayan bir IMFGetService uygulaması gösterilmektedir:
_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
Yukarıda gösterildiği gibi, hem kaynak hem de kaynak içindeki tek tek akışların kendi IMFMediaEventGenerator arabirimini desteklemesi gerekir. Kaynaktan gelen MF işlem hattı verileri ve denetim akışlarının tamamı, belirli IMFMediaEvent gönderilerek olay oluşturucu aracılığıyla yönetilir.
IMFMediaEventGenerator'ı uygulamak için Özel Medya Kaynağı'nın MFCreateEventQueueAPI'sini kullanarak bir IMFMediaEventQueue oluşturması ve IMFMediaEventGenerator için tüm yöntemleri kuyruk nesnesine yönlendirmesi gerekir:
IMFMediaEventGenerator aşağıdaki yöntemlere sahiptir:
// 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);
Aşağıdaki kod , IMFMediaEventGenerator arabiriminin önerilen uygulamasını gösterir. Özel Medya Kaynağı uygulaması , IMFMediaEventGenerator arabirimini kullanıma sunar ve bu arabirimin yöntemleri, istekleri medya kaynağı oluşturma/başlatma sırasında oluşturulan IMFMediaEventQueue nesnesine yönlendirmektedir.
Aşağıdaki kodda _spEventQueue nesnesi MFCreateEventQueue işlevi kullanılarak oluşturulan IMFMediaEventQueue nesnesidir:
// 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;
}
Arama ve Duraklatma
Çerçeve Sunucusu çerçevesi aracılığıyla desteklenen özel Medya Kaynakları Arama veya Duraklatma işlemlerini desteklemez. Özel Medya Kaynağınızın bu işlemler için destek sağlaması gerekmez ve MFSourceSeeked veya MEStreamSeeked olayını göndermemelidir.
IMFMediaSource::PauseMF_E_INVALID_STATE_TRANSITION döndürmelidir (veya kaynak zaten kapatılmışsa MF_E_SHUTDOWN döndürmelidir).
IKsControl
IKsControl , kamerayla ilgili tüm denetimler için standart kontrol arabirimidir. Özel Medya Kaynağınız herhangi bir kamera denetimi uygularsa IKsControl arabirimi, işlem hattının denetim G/Ç'sini nasıl yönlendirdiğini gösterir.
Daha fazla bilgi için aşağıdaki Denetim Kümesi belgeleri makalelerine bakın:
Denetimler isteğe bağlıdır ve desteklenmiyorsa döndürülmesi önerilen hata kodu HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND)'dir.
Aşağıdaki kod, desteklenen denetimleri olmayan örnek bir IKsControl uygulamasıdır:
// 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
Özel Medya Kaynağı Yazma bölümünde açıklandığı gibi, IMFMediaSource::Start yönteminin tamamlanması sırasında kaynak olay kuyruğuna gönderilen bir MENewStream medya olayı aracılığıyla Özel Medya Kaynağınızdan çerçeve çalışmasına IMFMediaStream2 arabirimi sağlanır:
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;
}
Bu, IMFPresentationDescriptor aracılığıyla seçilen her akış için yapılmalıdır.
Video akışı olan Özel Medya Kaynakları için MEEndOfStream ve MEEndOfPresentation olayları gönderilmemelidir.
Akış Öznitelikleri
Tüm Özel Medya Kaynağı akışlarında MF_DEVICESTREAM_STREAM_CATEGORYPINNAME_VIDEO_CAPTURE olarak ayarlanmış olmalıdır. PINNAME_VIDEO_PREVIEW Özel Medya Kaynakları için desteklenmez.
Uyarı
desteklense de PINNAME_IMAGE önerilmez. PINNAME_IMAGE ile bir akışın açığa çıkartılması için Özel Medya Kaynağı'nın tüm fotoğraf tetikleyici denetimlerini desteklemesi gerekir. Daha fazla ayrıntı için aşağıdaki Fotoğraf Akışı Denetimleri bölümüne bakın.
MF_DEVICESTREAM_STREAM_ID tüm akışlar için zorunlu bir özniteliktir. 0 tabanlı bir dizin olmalıdır. Dolayısıyla ilk akışın kimliği 0, ikinci akış 1 kimliği vb. olur.
Akışta önerilen özniteliklerin listesi aşağıdadır:
MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES
MF_DEVICESTREAM_ATTRIBUTE_FRAMESOURCE_TYPES , akış türünün bit maskelenmiş değeri olan bir UINT32 özniteliğidir. Aşağıdakilerden herhangi birine ayarlanabilir (bu türler bit maskesi bayrağı olsa da, mümkünse kaynak türlerinin karıştırılmaması önerilir):
| Türü | Bayrak | Açıklama |
|---|---|---|
| MFÇerçeveKaynağıTürleri_Renk | 0x0001 | Standart RGB renk akışı |
| MFFrameSourceTypes_Kızılötesi | 0x0002 | IR akışı |
| MFFrameSourceTypes_Derinlik | 0x0004 | Derinlik akışı |
| MFÇerçeveKaynakTürleri_Resim | 0x0008 | Görüntü akışı (video olmayan alt tür, genellikle JPEG) |
| MFFrameSourceTypes_Özel | 0x0080 | Özel akış türü |
MF_DEVICESTREAM_FRAMESERVER_SHARED
MF_DEVICESTREAM_FRAMESERVER_SHARED , 0 veya 1 olarak ayarlanabilen bir UINT32 özniteliğidir. 1 olarak ayarlanırsa, akışı Çerçeve Sunucusu tarafından "paylaşılabilir" olarak işaretler. Bu, başka bir uygulama tarafından kullanıldığında bile uygulamaların akışı paylaşılan modda açmasına olanak tanır.
Bu öznitelik ayarlanmamışsa, Frame Server işaretlenmemiş ilk akışın paylaşılmasına izin verir (Özel Medya Kaynağı'nda yalnızca bir akış varsa, bu akış paylaşılan olarak işaretlenir).
Bu öznitelik 0 olarak ayarlanırsa, Çerçeve Sunucusu paylaşılan uygulamalardan akışı engeller. Özel Medya Kaynağı bu özniteliği 0 olarak ayarlayarak tüm akışları işaretliyorsa, hiçbir ortak kullanılan uygulama kaynağı başlatamaz.
Örnek Ayırma
Tüm medya çerçeveleri bir IMFSample olarak üretilmelidir. Özel Medya Kaynakları, bir IMFSample örneği ayırmak için MFCreateSample işlevini ve medya arabellekleri eklemek için AddBuffer yöntemini kullanmalıdır.
Her IMFSample örnek zamanı ve örnek süresi ayarlanmış olmalıdır. Tüm örnek zaman damgaları QPC süresini (QueryPerformanceCounter) temel almalıdır.
Özel Medya Kaynaklarının mümkün olduğunca MFGetSystemTime işlevini kullanması önerilir. Bu işlev QueryPerformanceCounter etrafında bir sarmalayıcıdır ve QPC tiklerini 100 nanosaniye birimlerine dönüştürür.
Özel Medya Kaynakları bir iç saat kullanabilir, ancak tüm zaman damgalarının geçerli QPC'ye göre 100 nanosaniyelik birimlerle bağıntılı olması gerekir.
Medya AraBelleği
IMFSample'a eklenen tüm medya arabellekleri standart MF arabellek ayırma işlevlerini kullanmalıdır. Özel Medya Kaynakları kendi IMFMediaBuffer arabirimlerini uygulamamalı veya medya arabelleğini doğrudan ayırmaya çalışmamalıdır. Örneğin, yeni, malloc, VirtualAlloc vb. yöntemler çerçeve verileri için kullanılmamalıdır.
Medya çerçevelerini ayırmak için aşağıdaki API'lerden herhangi birini kullanın:
MFCreateMemoryBuffer ve MFCreateAlignedMemoryBuffer , dize dışı hizalanmış medya verileri için kullanılmalıdır. Bunlar genellikle özel alt tür veya sıkıştırılmış alt tür (H264/HEVC/MJPG gibi) olabilir.
Sistem belleği kullanan bilinen sıkıştırılmamış medya türleri (YUY2, NV12 vb.) için MFCreate2DMediaBuffer kullanılması önerilir.
DX yüzeylerini kullanmak için (işleme ve/veya kodlama gibi GPU hızlandırılmış işlemler için), MFCreateDXGISurfaceBuffer kullanılmalıdır.
MFCreateDXGISurfaceBuffer , DX yüzeyini oluşturmaz. Yüzey, medya kaynağına IMFMediaSourceEx::SetD3DManager yöntemi aracılığıyla geçirilen DXGI yöneticisi kullanılarak oluşturulur.
IMFDXGIDeviceManager::OpenDeviceHandle, seçilen D3D cihazıyla ilişkili tanıtıcıyı sağlar. ID3D11Cihaz arabirimi daha sonra IMFDXGIDeviceManager::GetVideoService yöntemi kullanılarak elde edilebilir.
Kullanılan arabellek türü ne olursa olsun, oluşturulan IMFSample medya akışının IMFMediaEventGenerator üzerindeki MEMediaSample olayı aracılığıyla işlem hattına sağlanmalıdır.
Hem Özel Medya Kaynağı hem de IMFMediaStream'in temel koleksiyonu için aynı IMFMediaEventQueue'yi kullanmak mümkün olsa da, bunu yapmanın medya kaynağı olaylarının ve akış olaylarının (medya akışını içeren) serileştirilmesine neden olacağı belirtilmelidir. Birden çok akışı olan kaynaklar için bu tercih edilmez.
Aşağıdaki kod alıntısı, medya akışının örnek uygulamasını gösterir:
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;
}
IMFActivate'i kullanıma sunan özel Medya Kaynağı uzantısı (Windows 10, sürüm 1809'da kullanılabilir)
Özel Medya Kaynağı için desteklenmesi gereken arabirimlerin yukarıdaki listesine ek olarak, Çerçeve Sunucusu mimarisi içinde Özel Medya Kaynağı işlemi tarafından uygulanan sınırlamalardan biri, işlem hattı üzerinden "etkinleştirilen" UMDF sürücüsünün yalnızca bir örneğinin bulunabilmesidir.
Örneğin, fiziksel cihazınız bir AV Olmayan Stream sürücü paketine ek olarak bir UMDF saplama sürücü yüklüyorsa ve bu fiziksel cihazlardan birden fazlasını bir bilgisayara eklerseniz, UMDF sürücüsünün her örneği benzersiz bir sembolik bağlantı adı alacak, ancak Özel Medya Kaynağı için etkinleştirme yolunun, oluşturulma sırasında Özel Medya Kaynağı ile ilişkili sembolik bağlantı adını iletecek bir yolu bulunmaz.
Özel Medya Kaynağı, Özel Medya Kaynağı'nın öznitelik deposunda (Özel Medya Kaynağı'ndan IMFMediaSourceEx::GetSourceAttributes yöntemi aracılığıyla döndürülen öznitelik deposu) standart MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK özniteliğini IMFMediaSource::Start çağrıldığında arayabilir.
Ancak bu, HW kaynak alımını oluşturma/başlatma zamanı yerine başlangıç zamanına erteleyeceğinden daha yüksek başlatma gecikmesine neden olabilir.
Bu nedenle, Windows 10, sürüm 1809'da Özel Medya Kaynakları isteğe bağlı olarak bir IMFActivate arabirimini kullanıma verebilir.
Uyarı
IMFActivate , IMFAttributes'ten devralır.
IMFActivate
Özel Medya Kaynağı için COM sunucusu IMFActivate arabirimini destekliyorsa cihaz başlatma bilgileri, IMFActivate tarafından devralınan IMFAttributes aracılığıyla COM sunucusuna sağlanır. Dolayısıyla , IMFActivate::ActivateObject çağrıldığında, IMFActivate öznitelik deposu UMDF saplama sürücüsünün sembolik bağlantı adını ve kaynak oluşturma/başlatma sırasında işlem hattı/uygulama tarafından sağlanan diğer yapılandırma ayarlarını içerir.
Özel Medya Kaynağı, ihtiyaç duyduğu donanım kaynaklarını almak için bu yöntem çağrısını kullanmalıdır.
Uyarı
Donanım kaynağı alımı 200 milisaniyeden uzun sürüyorsa, donanım kaynağının zaman uyumsuz olarak alınması önerilir. Özel Medya Kaynağının etkinleştirilmesi, donanım kaynağı alımını engellememelidir. Bunun yerine , IMFMediaSource::Start işlemi donanım kaynağı alımına göre seri hale getirilmelidir.
IMFActivate, DetachObject ve ShutdownObject tarafından kullanıma sunulan diğer iki yöntem E_NOTIMPL döndürmelidir.
Özel Medya Kaynağı, IMFMediaSource ile aynı COM nesnesi içinde IMFActivate ve IMFAttributes arabirimini uygulamayı seçebilir. Bu yapılırsa, IMFMediaSourceEx::GetSourceAttributes'in, IMFActivate'ten gelenlerle aynı IMFAttributes arabirimini geri döndürmesi tavsiye edilir.
Özel Medya Kaynağı, aynı nesneyle IMFActivate ve IMFAttributes'i uygulamazsa, Özel Medya Kaynağı'nın kaynak öznitelik deposuna, IMFActivate öznitelik deposunda ayarlanmış olan tüm öznitelikleri kopyalaması gerekir.
Kodlanmış Kamera Akışı
Özel Medya Kaynağı sıkıştırılmış medya türlerini (HEVC veya H264 temel akışları) kullanıma sunabilir ve işletim sistemi işlem hattı Özel Medya Kaynağı'ndaki kodlama parametrelerinin kaynağını ve yapılandırmasını tam olarak destekler (kodlama parametreleri IKsControl::KsProperty çağrısı olarak yönlendirilen ICodecAPI aracılığıyla iletilir):
// 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
);
IKsControl::KsProperty yöntemine geçirilen KSPROPERTY yapısı aşağıdaki bilgilere sahiptir:
KSPROPERTY.Set = Encoder Property GUID
KSPROPERTY.Id = 0
KSPROPERTY.Flags = (KSPROPERTY_TYPE_SET or KSPROPERTY_TYPE_GET)
Burada Kodlayıcı Özellik GUID'i , Codec API Özellikleri'nde tanımlanan kullanılabilir özelliklerin listesidir.
Kodlayıcı Özelliğinin yükü, yukarıda bildirilen KsProperty yönteminin pPropertyData alanı üzerinden geçirilir.
Yakalama Altyapısı Gereksinimleri
Kodlanmış kaynaklar Çerçeve Sunucusu tarafından tam olarak destekleniyor olsa da, Windows.Media.Capture.MediaCapture nesnesi tarafından kullanılan istemci tarafı Yakalama Altyapısı (IMFCaptureEngine) ek gereksinimler uygular:
Akışın tümü kodlanmış (HEVC veya H264) veya tümü sıkıştırılmamış olmalıdır (bu bağlamda MJPG sıkıştırılmamış olarak kabul edilir).
En az bir sıkıştırılmamış akış kullanılabilir olmalıdır.
Uyarı
Bu gereksinimler, bu makalede özetlenen Özel Medya Kaynağı gereksinimlerine ek olarak sağlanır. Ancak Yakalama Altyapısı Gereksinimleri yalnızca istemci uygulaması ÖZEL Medya Kaynağını IMFCaptureEngine veya Windows.Media.Capture.MediaCapture API'sini kullanarak kullandığında uygulanır.
Kamera Profilleri (Windows 10, sürüm 1803 ve sonraki sürümlerde kullanılabilir)
Özel Medya Kaynakları için Kamera Profili desteği sağlanır. Önerilen mekanizma, kaynağın özniteliklerinden (IMFMediaSourceEx::GetSourceAttributes) elde edilen MF_DEVICEMFT_SENSORPROFILE_COLLECTION özniteliği aracılığıyla profili yayımlamaktır.
MF_DEVICEMFT_SENSORPROFILE_COLLECTION özniteliği, IMFSensorProfileCollection arabiriminin IUnknown değeridir. IMFSensorProfileCollection, MFCreateSensorProfileCollection işlevi kullanılarak alınabilir:
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);
}
Yüz Doğrulama Profili
Özel Medya Kaynağı Windows Hello Yüz Tanıma'yı destekleyecek şekilde tasarlandıysa, bir Yüz Doğrulama Profili yayımlamanız önerilir. Yüz Doğrulama Profilinin gereksinimleri şunlardır:
Yüz Tanıma Kimlik Doğrulaması DDI Denetimi tek bir IR akışında desteklenmelidir. Daha fazla bilgi için bkz. KSPROPERTY_CAMERACONTROL_EXTENDED_FACEAUTH_MODE.
IR akışı 15 fps'de en az 340 x 340 olmalıdır. Biçim L8, NV12 veya L8 sıkıştırma ile işaretlenmiş MJPG olmalıdır.
RGB akışı 7,5 fps'de en az 480 x 480 olmalıdır (bu yalnızca Multispectrum kimlik doğrulaması zorunlu kılınırsa gereklidir).
Yüz Tanıma Kimlik Doğrulama Profilinin Profil Kimliği: KSCAMERAPROFILE_FaceAuth_Mode,0 olmalıdır.
Yüz Tanıma Kimlik Doğrulama Profilinin IR ve RGB akışlarının her biri için yalnızca bir medya türünü tanıtmanızı öneririz.
Fotoğraf Akışı Kontrolleri
AkışınMF_DEVICESTREAM_STREAM_CATEGORY birini PINNAME_IMAGE olarak işaretleyerek bağımsız fotoğraf akışları kullanıma sunulursa, PINNAME_VIDEO_CAPTURE akış kategorisine sahip bir akış gerekir (örneğin, yalnızca PINNAME_IMAGE gösteren tek bir akış geçerli bir medya kaynağı değildir).
IKsControl aracılığıyla PROPSETID_VIDCAP_VIDEOCONTROL özellik kümesinin desteklenmesi gerekir. Daha fazla bilgi için bkz. Video Denetimi Özellikleri.