Condividi tramite


Esempi di codice del codificatore

Gli esempi di codice seguenti si basano sul driver di esempio hardware simulato AVStream (AVSHwS). Illustrano quanto segue:

  • Come specificare le velocità di bit supportate dal codificatore

  • Come specificare le modalità di codifica della velocità di bit supportate da un codificatore

  • Come specificare i valori dei metadati in fase di esecuzione nella chiave del Registro di sistema dei parametri del dispositivo del codificatore\Capabilities

Implementazione delle frequenze di bit supportate

I frammenti di codice seguenti illustrano come implementare il supporto per la proprietà ENCAPIPARAM_BITRATE . Utilizzare una struttura KSPROPERTY_STEPPING_LONG per specificare una granularità di 400 bit al secondo (bps) con un limite inferiore di 400 bps e un limite superiore di 4.000.000 bps.

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

Se si accede alla pagina delle proprietà del filtro del codificatore facendo clic con il pulsante destro del mouse sul filtro in uno strumento come GraphEdit, verrà visualizzata la barra del dispositivo di scorrimento Velocità bit in cui vengono usati questi valori.

Specificare quindi la velocità di bit di codifica predefinita del filtro del codificatore quando viene creata un'istanza. Si noti che il tipo di dati usato è un ULONG che corrisponde al tipo di valore della proprietà richiesto dalla proprietà ENCAPIPARAM_BITRATE. Questo valore è la codifica predefinita "Velocità bit" visualizzata nella pagina delle proprietà del codificatore:

const ULONG BitRateValues [] = {
    1000000
};

Specificare l'elenco di intervalli legali e un valore predefinito per la proprietà 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
};

Specificare la singola proprietà definita per il set di proprietà 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

Il gestore get-property restituisce la velocità in bit di codifica e il gestore della proprietà Set deve verificare che il valore passato in ingresso sia valido prima di usarlo.

Implementazione delle modalità di velocità dei bit di codifica supportate

I frammenti di codice seguenti illustrano come implementare il supporto per la proprietà ENCAPIPARAM_BITRATE_MODE .

Definire le modalità di codifica supportate dal codificatore:

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

Specificare la modalità di velocità dei bit di codifica predefinita come velocità media di bit variabile:

const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
    VariableBitRateAverage
};

Specificare l'elenco di intervalli legali e il valore predefinito per la proprietà 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
};

Specificare la singola proprietà definita per il set di proprietà 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

Il gestore get-property deve restituire la modalità di velocità in bit di codifica e il gestore della proprietà Set deve verificare che il valore passato in ingresso sia valido prima di usarlo.

I set di proprietà vengono quindi specificati come tabella di automazione della struttura 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
    ...,
    ...
};

Specifica delle funzionalità del codificatore nel Registro di sistema

L'esempio di codice seguente illustra come creare una chiave del Registro di sistema Capabilities nella chiave del Registro di sistema Parametri dispositivo e come creare e specificare sottochiavi e valori nella chiave Capabilities . Eseguire questo codice quando il driver viene inizializzato.

Nota

Il codice seguente presuppone la presenza di un singolo codificatore hardware per dispositivo fisico. Se l'hardware contiene più codificatori, è necessario scorrere l'elenco restituito nella chiamata alla funzione IoGetDeviceInterfaces e registrare le funzionalità per ogni codificatore.

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