共用方式為


編碼器程式碼範例

下列程式碼範例是以 AVStream 模擬硬體範例驅動程式為基礎, (AVSHwS) 。 它們示範下列專案:

  • 如何指定編碼器支援的位元速率

  • 如何指定編碼器支援的位元速率編碼模式

  • 如何在執行時間在編碼器裝置的 裝置參數\功能 登錄機碼下指定中繼資料值

實作支援的位元速率

下列程式碼片段示範如何實作 對 ENCAPIPARAM_BITRATE 屬性的支援。 使用 KSPROPERTY_STEPPING_LONG 結構來指定每秒 400 位的逐步資料細微性, (bps) 400-bps 下限和 4,000,000-bps 上限。

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

如果您在 GraphEdit 之類的工具中以滑鼠右鍵按一下篩選準則,即可存取編碼器篩選的屬性頁,您會看到使用這些值的 [位元速率 ] 滑杆列。

接下來,在建立編碼器的實例時,指定編碼器篩選的預設編碼位元速率。 請注意,使用的資料類型是 ULONG,其對應于 ENCAPIPARAM_BITRATE 屬性所需的屬性值類型。 此值是編碼器屬性頁中顯示的預設編碼「位元速率」:

const ULONG BitRateValues [] = {
    1000000
};

指定法律範圍清單和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
};

指定為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)
        )
};

注意

get-property處理常式會傳回編碼位元速率,而 Set-property處理常式必須先測試傳入傳入傳入的值是否有效,才能使用它。

實作支援的編碼位元速率模式

下列程式碼片段示範如何實作 對 ENCAPIPARAM_BITRATE_MODE 屬性的支援。

定義編碼器支援的編碼模式:

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

將預設編碼位元速率模式指定為平均變數位元速率:

const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
    VariableBitRateAverage
};

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

指定為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)
        )
};

注意

get-property處理常式應該會傳回編碼位元速率模式,而 Set-property處理常式必須先測試傳入傳入傳入的值是否有效,才能使用它。

屬性集接著會指定為 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
    ...,
    ...
};

在登錄中指定編碼器的功能

下列程式碼範例示範如何在[裝置參數] 登錄機碼下建立功能登錄機碼,以及如何在[功能] 機碼下建立及指定子機碼和值。 當驅動程式初始化時,請執行此程式碼。

注意

下列程式碼假設每個實體裝置有單一硬體編碼器。 如果您的硬體包含多個編碼器,則必須逐一查看 呼叫 IoGetDeviceInterfaces 函式中傳回的清單,並註冊每個編碼器的功能。

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