Udostępnij przez


Przykłady kodu kodera

Poniższe przykłady kodu są oparte na sterowniku AVStream Simulated Hardware Sample Driver (AVSHwS). Przedstawiają one następujące elementy:

  • Jak określić obsługiwane szybkości transmisji bitów kodera

  • Jak określić tryby kodowania szybkości transmisji bitów obsługiwane przez koder

  • Jak określić wartości metadanych podczas działania w ramach klucza rejestru Device Parameters\Capabilities urządzenia kodera

Implementowanie obsługiwanych szybkości bitów

Poniższe fragmenty kodu pokazują, jak zaimplementować obsługę właściwości ENCAPIPARAM_BITRATE . Użyj struktury KSPROPERTY_STEPPING_LONG, aby określić szczegółowość kroku jako 400 bitów na sekundę (bps), przy granicy dolnej wynoszącej 400 bps i granicy górnej wynoszącej 4 000 000 bps.

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

Jeśli uzyskujesz dostęp do strony właściwości filtru kodera, klikając prawym przyciskiem myszy filtr w narzędziu takim jak GraphEdit, zobaczysz pasek suwaka Szybkość transmisji bitów , na którym są używane te wartości.

Następnie określ domyślną częstotliwość kodowania filtru kodera po utworzeniu wystąpienia. Należy pamiętać, że używany typ danych to ULONG, który odpowiada typowi wartości właściwości wymaganemu przez właściwość ENCAPIPARAM_BITRATE. Ta wartość jest domyślnym kodowaniem "Szybkość transmisji bitów", która jest wyświetlana na stronie właściwości kodera:

const ULONG BitRateValues [] = {
    1000000
};

Określ listę zakresów prawnych i wartość domyślną właściwości 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
};

Określ pojedynczą właściwość zdefiniowaną dla zestawu właściwości 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)
        )
};

Uwaga / Notatka

Procedura obsługi get-property zwraca prędkość kodowania, a procedura obsługi set-property musi sprawdzić, czy przekazana wartość wejściowa jest prawidłowa przed użyciem.

Implementowanie obsługiwanych trybów szybkości kodowania bitów

Poniższe fragmenty kodu pokazują, jak zaimplementować obsługę właściwości ENCAPIPARAM_BITRATE_MODE .

Zdefiniuj tryby kodowania obsługiwane przez koder:

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

Określ domyślny tryb szybkości kodowania bitów jako średnią zmienną szybkość bitów:

const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
    VariableBitRateAverage
};

Określ listę zakresów prawnych i wartość domyślną właściwości 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
};

Określ pojedynczą właściwość zdefiniowaną dla zestawu właściwości 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)
        )
};

Uwaga / Notatka

Procedura obsługi get-property powinna zwrócić tryb przepływności bitowej, a procedura obsługi Set-property musi sprawdzić, czy przekazywana wartość jest prawidłowa zanim zostanie użyta.

Zestawy właściwości są następnie określane jako tabela automatyzacji 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
    ...,
    ...
};

Określanie możliwości kodera w rejestrze

W poniższym przykładzie kodu pokazano, jak utworzyć klucz rejestru Capabilities w kluczu rejestru Parametry urządzenia oraz jak utworzyć i określić klucze podrzędne i wartości w kluczu Możliwości. Wykonaj ten kod, gdy sterownik inicjuje.

Uwaga / Notatka

Poniższy kod zakłada obecność jednego kodera sprzętowego na urządzenie fizyczne. Jeśli sprzęt zawiera więcej niż jeden enkoder, musisz wykonać iterację po liście zwróconej w wywołaniu funkcji IoGetDeviceInterfaces i zarejestrować zdolności dla każdego enkodera.

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