Codebeispiele für Encoder
Die folgenden Codebeispiele basieren auf dem AVStream Simulated Hardware Sample Driver (AVSHwS). Sie veranschaulichen Folgendes:
Angeben der unterstützten Bitraten des Encoders
Angeben der von einem Encoder unterstützten Bitratencodierungsmodi
Angeben von Metadatenwerten zur Laufzeit unter dem Registrierungsschlüssel Device Parameters\Capabilities des Encodergeräts
Implementieren unterstützter Bitraten
Die folgenden Codeausschnitte veranschaulichen, wie Die Unterstützung für die ENCAPIPARAM_BITRATE-Eigenschaft implementiert wird. Verwenden Sie eine KSPROPERTY_STEPPING_LONG-Struktur , um eine Stufengranularität von 400 Bits pro Sekunde (bps) mit einer unteren Und einer Obergrenze von 400 Basispunkten und einer Obergrenze von 4.000.000 Bps anzugeben.
const KSPROPERTY_STEPPING_LONG BitRateRanges [] = {
{
400,
0,
400,
4000000
}
};
Wenn Sie auf die Eigenschaftenseite des Encoderfilters zugreifen, indem Sie in einem Tool wie GraphEdit mit der rechten Maustaste auf den Filter klicken, wird der Schieberegler Bitrate angezeigt, in dem diese Werte verwendet werden.
Geben Sie als Nächstes die Standardcodierungsbitrate des Encoderfilters an, wenn ein instance erstellt wird. Beachten Sie, dass der verwendete Datentyp ein ULONG ist, der dem Eigenschaftswerttyp entspricht, der für die ENCAPIPARAM_BITRATE-Eigenschaft erforderlich ist. Dieser Wert ist die Standardcodierung "Bitrate", die auf der Eigenschaftenseite des Encoders angezeigt wird:
const ULONG BitRateValues [] = {
1000000
};
Geben Sie die Liste der rechtlichen Bereiche und einen Standardwert für die eigenschaft ENCAPIPARAM_BITRATE an:
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
};
Geben Sie die einzelne Eigenschaft an, die für den ENCAPIPARAM_BITRATE-Eigenschaftssatz definiert ist:
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)
)
};
Hinweis
Der get-Property-Handler gibt die Codierungsbitrate zurück, und der Set-Property-Handler muss testen, ob der eingehende übergebene Wert gültig ist, bevor er verwendet wird.
Implementieren unterstützter Codierungsbitratenmodi
Die folgenden Codeausschnitte veranschaulichen, wie Die Unterstützung für die ENCAPIPARAM_BITRATE_MODE-Eigenschaft implementiert wird.
Definieren Sie die vom Encoder unterstützten Codierungsmodi:
const VIDEOENCODER_BITRATE_MODE BitRateModeValues [] = {
ConstantBitRate,
VariableBitRateAverage
};
Geben Sie den Standardmodus für die Codierungsbitrate als durchschnittliche variable Bitrate an:
const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
VariableBitRateAverage
};
Geben Sie die Liste der rechtlichen Bereiche und den Standardwert für die ENCAPIPARAM_BITRATE_MODE-Eigenschaft an:
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
};
Geben Sie die einzelne Eigenschaft an, die für den ENCAPIPARAM_BITRATE_MODE-Eigenschaftensatz definiert ist:
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)
)
};
Hinweis
Der get-Property-Handler sollte den Codierungsbitratenmodus zurückgeben, und der Set-Property-Handler muss testen, ob der eingehende übergebene Wert gültig ist, bevor er verwendet wird.
Die Eigenschaftensätze werden dann als Automatisierungstabelle der KSFILTER_DESCRIPTOR-Struktur angegeben.
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
...,
...
};
Angeben der Funktionen des Encoders in der Registrierung
Im folgenden Codebeispiel wird veranschaulicht, wie Sie einen Capabilities-Registrierungsschlüssel unter dem Registrierungsschlüssel Geräteparameter erstellen und unter dem Schlüssel Capabilities Unterschlüssel und Werte erstellen und angeben. Führen Sie diesen Code aus, wenn der Treiber initialisiert wird.
Hinweis
Im folgenden Code wird davon ausgegangen, dass pro physischem Gerät ein einzelner Hardwareencoder vorhanden ist. Wenn Ihre Hardware mehr als einen Encoder enthält, müssen Sie die Liste durchlaufen, die im Aufruf der IoGetDeviceInterfaces-Funktion zurückgegeben wird, und die Funktionen für jeden Encoder registrieren.
/**************************************************************************
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;
}