Compartir a través de


Ejemplos de código del codificador

Los ejemplos de código siguientes se basan en el controlador de ejemplo de hardware simulado de AVStream (AVSHwS). Muestran lo siguiente:

  • Cómo especificar las velocidades de bits admitidas del codificador

  • Cómo especificar los modos de codificación de velocidad de bits admitidos por un codificador

  • Cómo especificar valores de metadatos en tiempo de ejecución en la clave del Registro Device Parameters\Capabilities del dispositivo del codificador

Implementación de velocidades de bits admitidas

Los fragmentos de código siguientes muestran cómo implementar la compatibilidad con la propiedad ENCAPIPARAM_BITRATE . Use una estructura de KSPROPERTY_STEPPING_LONG para especificar una granularidad paso a paso de 400 bits por segundo (bps) con un límite inferior de 400 bps y 4.000.000-bps límite superior.

const KSPROPERTY_STEPPING_LONG BitRateRanges [] = {
    {
        400,
        0,
        400,
        4000000
    }
};

Si accede a la página de propiedades del filtro de codificador haciendo clic con el botón derecho en el filtro en una herramienta como GraphEdit, verá la barra deslizante Velocidad de bits donde se usan estos valores.

A continuación, especifique la velocidad de bits de codificación predeterminada del filtro del codificador cuando se crea una instancia de él. Tenga en cuenta que el tipo de datos usado es un ULONG que corresponde al tipo de valor de propiedad requerido por la propiedad ENCAPIPARAM_BITRATE. Este valor es la codificación predeterminada "Velocidad de bits" que se muestra en la página de propiedades del codificador:

const ULONG BitRateValues [] = {
    1000000
};

Especifique la lista de intervalos legales y un valor predeterminado para la propiedad 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
};

Especifique la propiedad única definida para el conjunto de propiedades de 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)
        )
};

Nota:

El controlador get-property devuelve la velocidad de bits de codificación y el controlador set-property debe probar que el valor entrante pasado es válido antes de usarlo.

Implementación de modos de velocidad de bits de codificación compatibles

Los fragmentos de código siguientes muestran cómo implementar la compatibilidad con la propiedad ENCAPIPARAM_BITRATE_MODE .

Defina los modos de codificación admitidos por el codificador:

 const VIDEOENCODER_BITRATE_MODE BitRateModeValues [] = {
    ConstantBitRate,
    VariableBitRateAverage
};

Especifique el modo de velocidad de bits de codificación predeterminada como velocidad de bits variable media:

const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
    VariableBitRateAverage
};

Especifique la lista de intervalos legales y el valor predeterminado de la propiedad 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
};

Especifique la propiedad única definida para el conjunto de propiedades de 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)
        )
};

Nota:

El controlador get-property debe devolver el modo de velocidad de bits de codificación y el controlador set-property debe comprobar que el valor entrante pasado es válido antes de usarlo.

A continuación, los conjuntos de propiedades se especifican como la tabla de automatización de KSFILTER_DESCRIPTOR estructura.

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

Especificación de las funcionalidades del codificador en el Registro

En el ejemplo de código siguiente se muestra cómo crear una clave del Registro Capabilities en la clave del Registro Parámetros de dispositivo y cómo crear y especificar sub claves y valores en la clave Capabilities . Ejecute este código cuando se inicialice el controlador.

Nota:

En el código siguiente se supone la presencia de un único codificador de hardware por dispositivo físico. Si el hardware contiene más de un codificador, debe recorrer en iteración la lista devuelta en la llamada a la función IoGetDeviceInterfaces y registrar las funcionalidades de cada codificador.

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