Freigeben über


Codebeispiele für Encoder

Die folgenden Codebeispiele basieren auf dem AVStream Simulated Hardware Sample Driver (AVSHwS). Sie zeigen Folgendes:

  • Angeben der unterstützten Bitraten des Encoders

  • Angeben der Bitratencodierungsmodi, die von einem Encoder unterstützt werden

  • Angeben von Metadatenwerten zur Laufzeit unter dem Registrierungsschlüssel "Geräteparameter\Eigenschaften" des Encoder-Gerä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 Schritt-Granularität von 400 Bit pro Sekunde (bps) mit einer Untergrenze von 400 Bps 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 mit der rechten Maustaste auf den Filter in einem Tool wie GraphEdit klicken, wird die Schiebereglerleiste der Bitrate angezeigt, in der diese Werte verwendet werden.

Geben Sie als Nächstes die Standardcodierungsbitrate des Encoderfilters an, die verwendet wird, wenn eine Instanz davon erstellt wird. Beachten Sie, dass der verwendete Datentyp ein ULONG-Wert ist, der dem Eigenschaftswerttyp entspricht, der von der ENCAPIPARAM_BITRATE-Eigenschaft benötigt wird. Dieser Wert ist die Standardcodierung "Bitrate", die auf der Eigenschaftenseite des Encoders angezeigt wird:

const ULONG BitRateValues [] = {
    1000000
};

Geben Sie die Liste der gesetzlichen 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 für den ENCAPIPARAM_BITRATE Eigenschaftensatz definierte einzelne Eigenschaft an:

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 ihn verwendet.

Implementieren unterstützter Codierungsbitratemodi

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 standardmäßigen Codierungsbitratemodus als durchschnittliche variable Bitrate an:

const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
    VariableBitRateAverage
};

Geben Sie die Liste der gesetzlichen Bereiche und den Standardwert für die eigenschaft ENCAPIPARAM_BITRATE_MODE 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 Codierungsbitratemodus zurückgeben, und der Set-Property-Handler muss testen, ob der eingehende übergebene Wert gültig ist, bevor er ihn verwendet.

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 Registrierungsschlüssel "Capabilities " unter dem Registrierungsschlüssel " Geräteparameter " erstellen und unter dem Schlüssel "Funktionen " Unterschlüssel erstellen und angeben. Führen Sie diesen Code aus, wenn der Treiber initialisiert wird.

Hinweis

Im folgenden Code wird davon ausgegangen, dass ein einzelner Hardware-Encoder pro physischem Gerät vorhanden ist. Wenn Ihre Hardware mehrere Encoder enthält, müssen Sie die im Aufruf der IoGetDeviceInterfaces-Funktion zurückgegebene Liste durchlaufen 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;
}