Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les exemples de code suivants sont basés sur le AVStream Simulated Hardware Sample Driver (AVSHwS). Ils illustrent les éléments suivants :
Comment spécifier les taux de bits pris en charge par l’encodeur
Comment spécifier les modes d’encodage de débit binaire pris en charge par un encodeur
Comment spécifier des valeurs de métadonnées au moment de l’exécution sous la clé de Registre Device Parameters\Capabilities de l’appareil encodeur
Implémentation des débits de bits pris en charge
Les extraits de code suivants montrent comment implémenter la prise en charge de la propriété ENCAPIPARAM_BITRATE . Utilisez une structure KSPROPERTY_STEPPING_LONG pour spécifier une granularité pas à pas de 400 bits par seconde (bps) avec une limite inférieure de 400 bps et une limite supérieure de 4 000 000 bps.
const KSPROPERTY_STEPPING_LONG BitRateRanges [] = {
{
400,
0,
400,
4000000
}
};
Si vous accédez à la page de propriétés du filtre d’encodeur en cliquant avec le bouton droit sur le filtre dans un outil tel que GraphEdit, vous verrez la barre du curseur vitesse de bits dans laquelle ces valeurs sont utilisées.
Ensuite, spécifiez le taux de bits d’encodage par défaut du filtre d’encodeur lorsqu’une instance de celui-ci est créée. Notez que le type de données utilisé est un ULONG qui correspond au type de valeur de propriété requis par la propriété ENCAPIPARAM_BITRATE. Cette valeur est l’encodage par défaut « Débit de bits » qui s’affiche dans la page de propriétés de l’encodeur :
const ULONG BitRateValues [] = {
1000000
};
Spécifiez la liste des plages juridiques et une valeur par défaut pour la propriété ENCAPIPARAM_BITRATE :
const KSPROPERTY_MEMBERSLIST BitRateMembersList [] = {
{
{
KSPROPERTY_MEMBER_STEPPEDRANGES,
sizeof (BitRateRanges),
SIZEOF_ARRAY (BitRateRanges),
0
},
BitRateRanges
},
{
{
KSPROPERTY_MEMBER_VALUES,
sizeof (BitRateValues),
SIZEOF_ARRAY (BitRateValues),
KSPROPERTY_MEMBER_FLAG_DEFAULT
},
BitRateValues
}
};
const KSPROPERTY_VALUES BitRateValuesSet = {
{
STATICGUIDOF (KSPROPTYPESETID_General),
VT_UI4,
0
},
SIZEOF_ARRAY (BitRateMembersList),
BitRateMembersList
};
Spécifiez la propriété unique définie pour le jeu de propriétés ENCAPIPARAM_BITRATE :
DEFINE_KSPROPERTY_TABLE(ENCAPI_BitRate) {
DEFINE_KSPROPERTY_ITEM (
0,
GetBitRateHandler, //Get-property handler supported
sizeof (KSPROPERTY),
sizeof (ULONG),
SetBitRateHandler, //Set-property handler supported
&BitRateValuesSet,
0,
NULL,
NULL,
sizeof (ULONG)
)
};
Remarque
Le gestionnaire get-property retourne le taux de bits d’encodage, et le gestionnaire set-property doit tester que la valeur transmise entrante est valide avant de l’utiliser.
Implémentation des modes de débit de codage pris en charge
Les extraits de code suivants montrent comment implémenter la prise en charge de la propriété ENCAPIPARAM_BITRATE_MODE .
Définissez les modes d’encodage pris en charge par l’encodeur :
const VIDEOENCODER_BITRATE_MODE BitRateModeValues [] = {
ConstantBitRate,
VariableBitRateAverage
};
Spécifiez le mode de débit d’encodage par défaut comme taux de bits variable moyen :
const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
VariableBitRateAverage
};
Spécifiez la liste des plages juridiques et la valeur par défaut de la propriété ENCAPIPARAM_BITRATE_MODE :
const KSPROPERTY_MEMBERSLIST BitRateModeMembersList [] = {
{
{
KSPROPERTY_MEMBER_VALUES,
sizeof (BitRateModeValues),
SIZEOF_ARRAY (BitRateModeValues),
0
},
BitRateModeValues
},
{
{
KSPROPERTY_MEMBER_VALUES,
sizeof (BitRateModeDefaultValues),
SIZEOF_ARRAY (BitRateModeDefaultValues),
KSPROPERTY_MEMBER_FLAG_DEFAULT
},
BitRateModeDefaultValues
}
};
const KSPROPERTY_VALUES BitRateModeValuesSet = {
{
STATICGUIDOF (KSPROPTYPESETID_General),
VT_I4,
0
},
SIZEOF_ARRAY (BitRateModeMembersList),
BitRateModeMembersList
};
Spécifiez la propriété unique définie pour le jeu de propriétés ENCAPIPARAM_BITRATE_MODE :
DEFINE_KSPROPERTY_TABLE(ENCAPI_BitRateMode) {
DEFINE_KSPROPERTY_ITEM (
0,
GetBitRateModeHandler, //Get-property handler supported
sizeof (KSPROPERTY),
sizeof (VIDEOENCODER_BITRATE_MODE),
SetBitRateModeHandler, //Set-property handler supported
&BitRateModeValuesSet,
0,
NULL,
NULL,
sizeof (VIDEOENCODER_BITRATE_MODE)
)
};
Remarque
Le gestionnaire get-property doit retourner le mode de débit de codage, et le gestionnaire set-property doit tester que la valeur passée entrante est valide avant de l’utiliser.
Les jeux de propriétés sont ensuite spécifiés en tant que table d'automatisation de la structure KSFILTER_DESCRIPTOR.
DEFINE_KSPROPERTY_SET_TABLE(PropertyTable) {
DEFINE_KSPROPERTY_SET(
&ENCAPIPARAM_BITRATE_MODE,
SIZEOF_ARRAY (ENCAPI_BitRateMode),
ENCAPI_BitRateMode,
0,
NULL
),
DEFINE_KSPROPERTY_SET(
&ENCAPIPARAM_BITRATE,
SIZEOF_ARRAY (ENCAPI_BitRate),
ENCAPI_BitRate,
0,
NULL
)
};
DEFINE_KSAUTOMATION_TABLE(FilterTestTable) {
DEFINE_KSAUTOMATION_PROPERTIES(PropertyTable),
DEFINE_KSAUTOMATION_METHODS_NULL,
DEFINE_KSAUTOMATION_EVENTS_NULL
};
const
KSFILTER_DESCRIPTOR
FilterDescriptor = {
...,
&FilterTestTable, // Automation Table
...,
...
};
Spécification des fonctionnalités de l’encodeur dans le Registre
L’exemple de code suivant montre comment créer une clé de Registre De fonctionnalités sous la clé de Registre Paramètres de l’appareil, et comment créer et spécifier des sous-clés et des valeurs sous la clé Fonctionnalités. Exécutez ce code lorsque le pilote initialise.
Remarque
Le code suivant suppose la présence d’un encodeur matériel unique par appareil physique. Si votre matériel contient plusieurs encodeurs, vous devez itérer dans la liste retournée dans l’appel à la fonction IoGetDeviceInterfaces et inscrire les fonctionnalités de chaque encodeur.
/**************************************************************************
CreateDwordValueInCapabilityRegistry()
IN Pdo: PhysicalDeviceObject
IN categoryGUID: Category GUID eg KSCATEGORY_CAPTURE
1. Get Symbolic name for interface
2. Open registry key for storing information about a
particular device interface instance
3. Create Capabilities key under "Device Parameters" key
4. Create a DWORD value "TestCapValueDWORD" under Capabilities
Must be running at IRQL = PASSIVE_LEVEL in the context of a system thread
**************************************************************************/
NTSTATUS CreateDwordValueInCapabilityRegistry(IN PDEVICE_OBJECT pdo, IN GUID categoryGUID)
{
// 1. Get Symbolic name for interface
// pSymbolicNameList can contain multiple strings if pdo is NULL.
// Driver should parse this list of string to get
// the one corresponding to current device interface instance.
PWSTR pSymbolicNameList = NULL;
NTSTATUS ntStatus = IoGetDeviceInterfaces(
&categoryGUID,
pdo,
DEVICE_INTERFACE_INCLUDE_NONACTIVE,
&pSymbolicNameList);
if (NT_SUCCESS(ntStatus) && (NULL != pSymbolicNameList))
{
HANDLE hDeviceParametersKey = NULL;
UNICODE_STRING symbolicName;
// 2. Open registry key for storing information about a
// particular device interface instance
RtlInitUnicodeString(&symbolicName, pSymbolicNameList);
ntStatus = IoOpenDeviceInterfaceRegistryKey(
&symbolicName,
KEY_READ|KEY_WRITE,
&hDeviceParametersKey);
if (NT_SUCCESS(ntStatus))
{
OBJECT_ATTRIBUTES objAttribSubKey;
UNICODE_STRING subKey;
// 3. Create Capabilities key under "Device Parameters" key
RtlInitUnicodeString(&subKey,L"Capabilities");
InitializeObjectAttributes(&objAttribSubKey,
&subKey,
OBJ_KERNEL_HANDLE,
hDeviceParametersKey,
NULL);
HANDLE hCapabilityKeyHandle = NULL;
ntStatus = ZwCreateKey(&hCapabilityKeyHandle,
KEY_READ|KEY_WRITE|KEY_SET_VALUE,
&objAttribSubKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
NULL);
if (NT_SUCCESS(ntStatus))
{
OBJECT_ATTRIBUTES objAttribDwordKeyVal;
UNICODE_STRING subValDword;
// 4. Create a DWORD value "TestCapValueDWORD" under Capabilities
RtlInitUnicodeString(&subValDword,L"TestCapValueDWORD");
ULONG data = 0xaaaaaaaa;
ntStatus = ZwSetValueKey(hCapabilityKeyHandle,&subValDword,0,REG_DWORD,&data,sizeof(ULONG));
ZwClose(hCapabilityKeyHandle);
}
}
ZwClose(hDeviceParametersKey);
ExFreePool(pSymbolicNameList);
}
return ntStatus;
}