Příklady kódu kodéru

Následující příklady kódu jsou založené na ovladači AVSHwS (AVStream Simulated Hardware Sample Driver). Demonstrují následující:

  • Určení podporovaných přenosových rychlostí kodéru

  • Jak určit režimy kódování datového toku podporované kódovačem

  • Jak určit hodnoty metadat během běhu programu v klíči registru zařízení kodéru Parametry zařízení\Capabilities

Implementace podporovaných bitových rychlostí

Následující fragmenty kódu ukazují, jak implementovat podporu pro ENCAPIPARAM_BITRATE vlastnost. Pomocí struktury KSPROPERTY_STEPPING_LONG určete velikost kroku 400 bps s dolní mezí 400 bps a horní mezí 4 000 000 bps.

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

Pokud se dostanete na stránku vlastností filtru kodéru tak, že kliknete pravým tlačítkem myši na filtr v nástroji, jako je GraphEdit, zobrazí se posuvník přenosové rychlosti , kde se tyto hodnoty používají.

Dále zadejte výchozí přenosovou rychlost kódování filtru kodéru při vytvoření instance. Všimněte si, že použitý datový typ je ULONG, který odpovídá typu hodnoty vyžadovanému vlastností ENCAPIPARAM_BITRATE. Tato hodnota je výchozí kódování "Bit Rate", které se zobrazuje na stránce vlastností kodéru:

const ULONG BitRateValues [] = {
    1000000
};

Zadejte seznam právních rozsahů a výchozí hodnotu vlastnosti 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
};

Zadejte jednu vlastnost definovanou pro sadu vlastností 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)
        )
};

Poznámka:

Obslužná rutina get-property vrátí přenosovou rychlost kódování a obslužná rutina set-property musí otestovat, že příchozí předaná hodnota je platná před použitím.

Implementace podporovaných režimů přenosové rychlosti kódování

Následující fragmenty kódu ukazují, jak implementovat podporu pro ENCAPIPARAM_BITRATE_MODE vlastnost.

Definujte režimy kódování podporované kodérem:

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

Zadejte výchozí režim přenosové rychlosti kódování jako průměrnou proměnnou bitovou rychlost:

const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
    VariableBitRateAverage
};

Zadejte seznam rozsahů právních předpisů a výchozí hodnotu pro vlastnost 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
};

Zadejte jednu vlastnost definovanou pro sadu vlastností 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)
        )
};

Poznámka:

Obslužná rutina get-property by měla vrátit režim kódování přenosové rychlosti a obslužná rutina set-property musí otestovat, že příchozí předaná hodnota je platná před použitím.

Sady vlastností se pak zadají jako tabulka automatizace struktury 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
    ...,
    ...
};

Určení možností kodéru v registru

Následující ukázka kódu ukazuje, jak vytvořit klíč registru Capabilities pod klíčem registru Parametry zařízení a jak vytvořit a zadat podklíče a hodnoty pod klíčem Capabilities . Tento kód spusťte při inicializaci ovladače.

Poznámka:

Následující kód předpokládá přítomnost jednoho hardwarového kodéru na fyzické zařízení. Pokud váš hardware obsahuje více kodérů, musíte iterovat seznamem vrácený ve volání funkce IoGetDeviceInterfaces a zaregistrovat funkce pro každý kodér.

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