EVT_ACX_STREAM_ALLOCATE_RTPACKETS fungsi panggilan balik (acxstreams.h)
Peristiwa EvtAcxStreamAllocateRtPackets memberi tahu driver untuk mengalokasikan RtPackets untuk streaming.
Sintaks
EVT_ACX_STREAM_ALLOCATE_RTPACKETS EvtAcxStreamAllocateRtpackets;
NTSTATUS EvtAcxStreamAllocateRtpackets(
ACXSTREAM Stream,
ULONG PacketCount,
ULONG PacketSize,
PACX_RTPACKET *Packets
)
{...}
Parameter
Stream
Objek ACXSTREAM mewakili aliran audio yang dibuat oleh sirkuit. Aliran terdiri dari daftar elemen yang dibuat berdasarkan elemen sirkuit induk. Untuk informasi selengkapnya, lihat ACX - Ringkasan Objek ACX.
PacketCount
Menentukan jumlah paket yang akan dialokasikan. Nilai yang valid adalah 1 atau 2. Aliran berbasis peristiwa akan menggunakan dua paket sementara aliran berbasis timer akan menggunakan satu paket.
PacketSize
Ukuran paket, diukur dalam byte.
Packets
Penunjuk yang menerima penunjuk ke array struktur ACX_RTPACKET yang menjelaskan lokasi dan ukuran paket.
Versi ACX awal hanya mendukung buffer WdfMemoryDescriptorTypeMdl untuk anggota ACX_RTPACKET RtPacketBuffer. RtPacketBuffer harus diratakan halaman dan memiliki jumlah byte yang selaras dengan halaman.
Menampilkan nilai
Mengembalikan STATUS_SUCCESS
jika panggilan berhasil. Jika tidak, kode kesalahan akan menampilkan kode kesalahan yang sesuai. Untuk informasi selengkapnya, lihat Menggunakan Nilai NTSTATUS.
Keterangan
Versi ACX awal akan memanggil dengan PacketCount = 1 atau PacketCount = 2 ketika StreamModel adalah AcxStreamModelRtPacket. Dengan PacketCount = 2, driver dapat mengalokasikan satu buffer yang dibagikan antara dua paket atau driver dapat mengalokasikan dua buffer terpisah.
Jika driver mengalokasikan satu buffer untuk dibagikan di dua paket, struktur ACX_RTPACKET kedua harus memiliki WDF_MEMORY_DESCRIPTOR_TYPE = WdfMemoryDescriptorTypeInvalid. RtPacketOffset untuk struktur ACX_RTPACKET kedua harus menjadi offset yang valid ke dalam RtPacketBuffer dari struktur ACX_RTPACKET pertama dan harus selaras dengan RtPacketOffset + RtPacketSize struktur ACX_RTPACKET pertama.
EvtAcxStreamAllocateRtPackets dipanggil sebelum EvtAcxStreamPrepareHardware untuk memungkinkan alokasi paket RT terjadi sebelum EvtAcxStreamPrepareHardware.
Alokasi buffer biasanya hanya melibatkan alokasi memori sistem sedemikian rupa sehingga dapat digunakan dengan perangkat keras DMA. Biasanya, alokasi buffer tidak akan berpengaruh pada perangkat keras streaming. Fase siapkan perangkat keras digunakan karena driver siap menjalankan streaming, dengan menyelesaikan tugas seperti memesan bandwidth, memprogram DMA, dan menyelesaikan persiapan untuk permintaan menjalankan aliran. Biasanya, menyiapkan kode perangkat keras akan menggunakan buffer yang dialokasikan untuk menyiapkan DMA dan aktivitas terkait agar siap memulai streaming.
Contoh
Contoh penggunaan ditunjukkan di bawah ini.
//
// Init RT streaming callbacks.
//
ACX_RT_STREAM_CALLBACKS_INIT(&rtCallbacks);
rtCallbacks.EvtAcxStreamAllocateRtPackets = Codec_EvtStreamAllocateRtPackets;
...
#pragma code_seg("PAGE")
NTSTATUS
Codec_EvtStreamAllocateRtPackets(
_In_ ACXSTREAM Stream,
_In_ ULONG PacketCount,
_In_ ULONG PacketSize,
_Out_ PACX_RTPACKET *Packets
)
{
NTSTATUS status = STATUS_SUCCESS;
PCODEC_STREAM_CONTEXT ctx;
PACX_RTPACKET packets = NULL;
PVOID packetBuffer = NULL;
ULONG i;
ULONG packetAllocSizeInPages = 0;
ULONG packetAllocSizeInBytes = 0;
ULONG firstPacketOffset = 0;
size_t packetsSize = 0;
PAGED_CODE();
ctx = GetCodecStreamContext(Stream);
if (PacketCount > 2)
{
status = STATUS_INVALID_PARAMETER;
goto exit;
}
status = RtlSizeTMult(PacketCount, sizeof(ACX_RTPACKET), &packetsSize);
if (!NT_SUCCESS(status)) {
goto exit;
}
packets = (PACX_RTPACKET)ExAllocatePool2(POOL_FLAG_NON_PAGED, packetsSize, DRIVER_TAG);
if (!packets) {
status = STATUS_NO_MEMORY;
goto exit;
}
// We need to allocate page-aligned buffers, to ensure no kernel memory leaks
// to user space. Round up the packet size to page aligned, then calculate
// the first packet's buffer offset so packet 0 ends on a page boundary and
// packet 1 begins on a page boundary.
status = RtlULongAdd(PacketSize, PAGE_SIZE - 1, &packetAllocSizeInPages);
if (!NT_SUCCESS(status)) {
goto exit;
}
packetAllocSizeInPages = packetAllocSizeInPages / PAGE_SIZE;
packetAllocSizeInBytes = PAGE_SIZE * packetAllocSizeInPages;
firstPacketOffset = packetAllocSizeInBytes - PacketSize;
for (i = 0; i < PacketCount; ++i)
{
PMDL pMdl = NULL;
ACX_RTPACKET_INIT(&packets[i]);
packetBuffer = ExAllocatePool2(POOL_FLAG_NON_PAGED, packetAllocSizeInBytes, DRIVER_TAG);
if (packetBuffer == NULL) {
status = STATUS_NO_MEMORY;
goto exit;
}
pMdl = IoAllocateMdl(packetBuffer, packetAllocSizeInBytes, FALSE, TRUE, NULL);
if (pMdl == NULL) {
status = STATUS_NO_MEMORY;
goto exit;
}
MmBuildMdlForNonPagedPool(pMdl);
WDF_MEMORY_DESCRIPTOR_INIT_MDL(
&((packets)[i].RtPacketBuffer),
pMdl,
packetAllocSizeInBytes);
packets[i].RtPacketSize = PacketSize;
if (i == 0)
{
packets[i].RtPacketOffset = firstPacketOffset;
}
else
{
packets[i].RtPacketOffset = 0;
}
m_Packets[i] = packetBuffer;
packetBuffer = NULL;
}
*Packets = packets;
packets = NULL;
ctx->PacketsCount = PacketCount;
ctx->PacketSize = PacketSize;
ctx->FirstPacketOffset = firstPacketOffset;
exit:
if (packetBuffer)
{
ExFreePoolWithTag(packetBuffer, DRIVER_TAG);
}
if (packets)
{
FreeRtPackets(packets, PacketCount);
}
return status;
}
Persyaratan ACX
Versi ACX minimum: 1.0
Untuk informasi selengkapnya tentang versi ACX, lihat Gambaran umum versi ACX.
Persyaratan
Persyaratan | Nilai |
---|---|
Header | acxstreams.h |
IRQL | PASSIVE_LEVEL |
Lihat juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk