V4L2 kamerasının CPU belleğine inmesi gerekmez. V4L2_MEMORY_DMABUF ile
kamera sürücüsü her capture buffer’ını DMA-Buf olarak export eder —
VAAPI’nin export ettiği fd tipinin aynısıdır. Bunu Vulkan’a import ettiğinizde
kamera sensörü grid shader’ı doğrudan besler. Decode yazılarında VAAPI
kareleri için kurulan sıfır kopya pipeline’ının capture tarafıdır.
V4L2 tarafı — DMA-Buf buffer’ları isteyin
v4l2.cpp
int fd = open("/dev/video0", O_RDWR);
v4l2_format fmt{};
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; // veya V4L2_PIX_FMT_…
fmt.fmt.pix_mp.width = 1920;
fmt.fmt.pix_mp.height = 1080;
ioctl(fd, VIDIOC_S_FMT, &fmt);
v4l2_requestbuffers req{};
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
req.memory = V4L2_MEMORY_DMABUF; // ← DMA-Buf olarak export et
ioctl(fd, VIDIOC_REQBUFS, &req);
// kare başına dequeue → buffer'ın fd'si DMA-Buf'tur:
v4l2_buffer buf{};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
buf.memory = V4L2_MEMORY_DMABUF;
buf.length = nPlanes;
buf.m.planes = planes;
ioctl(fd, VIDIOC_DQBUF, &buf);
// buf.m.planes[i].m.fd — karenin plane'leri için DMA-Buf fd'leri
Vulkan tarafı — decode ile aynı import
import.cpp
// decoder yoluyla aynı — fd → VkDeviceMemory → VkImage:
vk::ImportMemoryFdInfoKHR imp{};
imp.handleType = vk::ExternalMemoryHandleTypeFlagBits::eDmaBufEXT;
imp.fd = dup(buf.m.planes[0].m.fd);
// kamera bir modifier sunuyorsa image tiling = eDrmFormatModifierEXT,
// sunmuyorsa açık stride'lı eLinear
Mekanizma, decoder yazılarındaki VK_EXT_external_memory_dma_buf +
VK_EXT_image_drm_format_modifier ikilisinin birebir aynısıdır — kamera
karesi de sadece başka bir DMA-Buf’tur.
Tüm pipeline
pipe.txt
/dev/video0 ──► V4L2 DQBUF → DMA-Buf fd
──► vkImportMemoryFdKHR → VkImage
──► grid shader'da örnekle
──► render → swapchain
CPU piksel yolu yok — VAAPI decode ile aynı, ancak *kaynak*
decoder değil sensör.VAAPI’ye göre konumu
compare.txt
V4L2 DMA-Buf: USB/CSI kameralar, capture card'lar — ham veya
vendor'a özel sıkıştırılmış sensör verisi,
sıkıştırılmamış YUV/RGB
VAAPI DMA-Buf: IP kameralar, dosyalar — VCN/VCU bloğunda decode edilen
sıkıştırılmış bitstream, çıktı YUV plane'leridir
ikisi de: aynı import API'si, aynı modifier mekanizması, aynı
foreign-queue transferiIP kameraları (VAAPI decode) ve yerel bir USB kamerayı (V4L2) karıştıran bir kamera duvarı, Vulkan tarafının tamamını paylaşır — tek fark fd’nin nereden geldiğidir.
Pratik kurallar
REQBUFS‘ta varsayılanMMAPdeğilV4L2_MEMORY_DMABUFkullanın; kamera sürücüsü export’u desteklemelidir (modern sürücülerin çoğu destekler).- Çok düzlemli için
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE— NV12/YUV kameralar plane’leribuf.m.planes[]üzerinden sunar; tek düzlemli formatlar_CAPTURE+buf.m.fdkullanır. - Decoder’ın import kodunu yeniden kullanın — FFmpeg’in
AVDRMFrameDescriptor‘ı ilev4l2_bufferplane’leri farklı sarmalayıcılardaki aynı veridir; {fd, offset, stride, format, modifier} değerlerine normalize edin. - Foreign-queue transferi (
VK_EXT_queue_family_foreign) aynen geçerlidir — V4L2 sürücüsü buffer’ı kendi context’inde yazmıştır. - Buffer’ları hemen iade edin —
VIDIOC_QBUF, DMA-Buf’u bir sonraki kare için geri koyar; fd’leri elde tutmak kamerayı aç bırakır.
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow