VK_KHR_video_decode_av1 ile GPU'da AV1 kod çözme

H.264 ve HEVC decode (VK_KHR_video_decode_h264/h265) eski codec’leri kapsar — AV1 (VK_KHR_video_decode_av1) modern olandır: YouTube/Netflix’in gönderdiği codec, 8K akışları yazılım decoder’larını boğan. Vulkan yolu H.264 ile aynı kalıptır — bir video session, bir DPB, vkCmdDecodeVideoKHR — AV1’in kendi parametreleri VkVideoDecodeAV1* yapılarından geçirilir.

Oturum kurulumu

session.cpp
// Codec'e özel profil + kabiliyetler:
vk::VideoDecodeAV1ProfileInfoKHR av1prof{};
av1prof.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN;   // veya _HIGH/_PROFESSIONAL
av1prof.filmGrainSupport = VK_FALSE;              // film grain sentezi
                                                  // GPU'da? pahalı.

vk::VideoProfileInfoKHR prof{};
prof.pNext = &av1prof;
prof.videoCodecOperation =
    vk::VideoCodecOperationFlagBitsKHR::eDecodeAV1;

auto caps = phys.getVideoCapabilitiesKHR(prof);
// caps.maxDpbSlots, caps.maxActiveReferencePictures,
//   caps.maxCodedExtent, …

vk::VideoSessionCreateInfoKHR vs{};
vs.queueFamilyIndex = decQueue;   // eVideoDecodeKHR'lı queue
vs.pVideoProfile    = &prof;
vs.pictureFormat    = vk::Format::eG8B8R82Plane420Unorm;
vs.referencePictureFormat = vs.pictureFormat;
vs.maxDpbSlots      = caps.maxDpbSlots;
vs.maxActiveReferencePictures = caps.maxActiveReferencePictures;
auto sess = dev.createVideoSessionKHR(vs);

Frame kod çözme

decode.cpp
// AV1'in frame parametreleri STD header'dan gelir
// (vulkan_video_codec_av1std.h — StdVideoAV1SequenceHeader, …):
vk::VideoDecodeAV1PictureInfoKHR pic{};
pic.pStdPictureInfo = &stdPic;    // ayrıştırılmış frame header
pic.pNext           = nullptr;
pic.pReferenceNameSlotIndices…  // hangi DPB slotları ref

vk::VideoDecodeInfoKHR dec{};
dec.pNext = &pic;
dec.srcBuffer          = bitstreamBuf;   // OBU frame verisi
dec.srcBufferOffset    = off;
dec.srcBufferRange     = len;
dec.dstPictureResource = {imgView, eVideoDecodeDstKHR};
dec.referenceSlotCount = n;
dec.pReferenceSlots    = refs;           // VkVideoReferenceSlotInfoKHR

cmd.beginVideoCodingKHR(begin);
cmd.decodeVideoKHR(dec);                 // ASIL çağrı
cmd.endVideoCodingKHR({});

H.264’ten farkları

diffs.txt
segmentation map      — AV1'de segment başına özellik flag'leri vardır;
                        decoder onu üretir; caps.needsExtraSourceImage?/
                        segment map'i kontrol edin
film grain            — AV1'in imza özelliği: decode sonrası uygulanan
                        sentetik grain. filmGrainSupport=false =
                        decoder grain'i kapalı bırakır; true = GPU
                        yapar (ekstra pass)
tile/strip decode     — AV1'in tile modeli decode komutunun slice/
                        segment bölümlemesine farklı eşlenir
frame header parsing  — OBU header'ı hâlâ CPU tarafında ayrıştırıp
                        StdVideoAV1SequenceHeader/FrameHeader
                        beslersiniz

Pragmatik yol — FFmpeg yapıyor

ffmpeg.sh
# FFmpeg ≥7, hwcontext_vulkan decode ile AV1'i sunar:
ffmpeg -init_hw_device vulkan=vk0 -hwaccel vulkan \
       -hwaccel_output_format vulkan -i in.av1.webm -f null -
#   → tamamen GPU'da, frame'ler AV_PIX_FMT_VULKAN VkImage olarak gelir

AVVkFrame‘in VkImage‘ı doğrudan nasıl verdiğini hwcontext_vulkan yazısında görün — aynı tesisat, codec’ten bağımsız.

Pratik kurallar

  • AV1 decode-kabiliyetli queue ister — QueueFlagBitsKHR::eVideoDecodeKHR ve eDecodeAV1 ile vkGetPhysicalDeviceVideoCapabilitiesKHR‘yi kontrol edin; bazı sürücülere destek geç geldi.
  • Film grain (filmGrainSupport) pahalı kısımdır — decode sonrası bir yazılım grain pass’i genelde sürücüye sormaktan ucuzdur.
  • AV1’in referans modeli (8 ref frame, show_existing_frame hileleri) AV1’de maxActiveReferencePictures‘ın H.264’ten büyük olması demektir — 2’yi sabit kodlamayın.
  • Session parametreleri (VkVideoDecodeAV1SessionParametersCreateInfoKHR) sequence header’ı taşır — OBU’ları kendiniz ayrıştırın veya FFmpeg’in av1 parser’ını kullanın.
  • Gerçek kullanım için hwcontext_vulkan ile eşleştirin — AV1 decode tesisatını elle yazmak günlerce iş; FFmpeg’in hwaccel’i zaten çözüyor.

Check out similar posts by category: Vulkan C++