Bagikan melalui


Contoh kode encoder

Contoh kode berikut didasarkan pada AVStream Simulated Hardware Sample Driver (AVSHwS). Mereka menunjukkan hal-hal berikut:

  • Cara menentukan laju bit yang didukung encoder

  • Cara menentukan mode pengodean laju bit yang didukung oleh encoder

  • Cara menentukan nilai metadata pada durasi di bawah kunci registri Parameter Perangkat\Kemampuan perangkat encoder

Menerapkan Laju Bit yang Didukung

Cuplikan kode berikut menunjukkan cara menerapkan dukungan untuk properti ENCAPIPARAM_BITRATE . Gunakan struktur KSPROPERTY_STEPPING_LONG untuk menentukan granularitas melangkah 400 bit per detik (bps) dengan batas bawah 400 bps dan batas atas 4.000.000 bps.

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

Jika Anda mengakses halaman properti filter encoder dengan mengklik kanan filter di alat seperti GraphEdit, Anda akan melihat bilah penggeser Laju Bit tempat nilai-nilai ini digunakan.

Selanjutnya, tentukan laju bit pengodean default filter encoder saat instans dibuat. Perhatikan bahwa jenis data yang digunakan adalah ULONG yang sesuai dengan jenis nilai properti yang diperlukan oleh properti ENCAPIPARAM_BITRATE. Nilai ini adalah pengodean default "Laju Bit" yang ditampilkan di halaman properti encoder:

const ULONG BitRateValues [] = {
    1000000
};

Tentukan daftar rentang hukum dan nilai default untuk properti 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
};

Tentukan properti tunggal yang ditentukan untuk kumpulan properti 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)
        )
};

Catatan

Handler get-property mengembalikan laju bit pengodean, dan handler Set-property harus menguji bahwa nilai masuk yang dilewatkan valid sebelum menggunakannya.

Menerapkan Mode Laju Bit Pengodean yang Didukung

Cuplikan kode berikut menunjukkan cara menerapkan dukungan untuk properti ENCAPIPARAM_BITRATE_MODE .

Tentukan mode pengodean yang didukung oleh encoder:

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

Tentukan mode laju bit pengodean default sebagai laju bit variabel rata-rata:

const VIDEOENCODER_BITRATE_MODE BitRateModeDefaultValues [] = {
    VariableBitRateAverage
};

Tentukan daftar rentang hukum dan nilai default untuk properti 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
};

Tentukan properti tunggal yang ditentukan untuk kumpulan properti 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)
        )
};

Catatan

Handler get-property harus mengembalikan mode laju bit pengodean, dan handler Set-property harus menguji bahwa nilai passed-in yang masuk valid sebelum menggunakannya.

Kumpulan properti kemudian ditentukan sebagai tabel otomatisasi struktur 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
    ...,
    ...
};

Menentukan Kemampuan Encoder di Registri

Sampel kode berikut menunjukkan cara membuat kunci registri Kemampuan di bawah kunci registri Parameter Perangkat , dan cara membuat dan menentukan sub kunci dan nilai di bawah kunci Kemampuan . Jalankan kode ini ketika driver menginisialisasi.

Catatan

Kode berikut mengasumsikan adanya satu encoder perangkat keras per perangkat fisik. Jika perangkat keras Anda berisi lebih dari satu encoder maka Anda harus melakukan iterasi melalui daftar yang dikembalikan dalam panggilan ke fungsi IoGetDeviceInterfaces dan mendaftarkan kemampuan untuk setiap encoder.

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