Freigeben über


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;
}