{
  "schemaVersion": 1,
  "contentVersion": "ca42e61ede0a24f789d7287a0001244ad22f4abf",
  "id": "docs/tools/hardware-encoders/vulkan",
  "collection": "docs",
  "title": "Vulkan Video",
  "description": "Vulkan Video encoding runs on the GPU's video engine through the Vulkan API, used from FFmpeg as h264_vulkan, hevc_vulkan and av1_vulkan.",
  "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/",
  "apiUrl": "https://encode.wiki/api/v1/documents/docs/tools/hardware-encoders/vulkan.json",
  "markdownUrl": "https://encode.wiki/api/v1/markdown/docs/tools/hardware-encoders/vulkan.md",
  "status": "current",
  "tags": [],
  "license": "CC BY-SA 4.0",
  "dates": {
    "lastVerified": "2026-10-08T00:00:00.000Z"
  },
  "authors": [],
  "sources": [
    {
      "title": "FFmpeg 9.0.2 AV1 Vulkan encoder",
      "url": "https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/vulkan_encode_av1.c",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg 9.0.2 common Vulkan encoder code",
      "url": "https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/vulkan_encode.c",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg 9.0.2 Changelog",
      "url": "https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/Changelog",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFmpeg 9.0.2 configure (Vulkan header requirements)",
      "url": "https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/configure",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    }
  ],
  "headings": [
    {
      "depth": 2,
      "text": "Hardware or software encoder?",
      "anchor": "hardware-or-software-encoder"
    },
    {
      "depth": 2,
      "text": "Check that your driver can encode",
      "anchor": "check-that-your-driver-can-encode"
    },
    {
      "depth": 2,
      "text": "Quality-oriented encode",
      "anchor": "quality-oriented-encode"
    },
    {
      "depth": 2,
      "text": "Full-GPU pipeline",
      "anchor": "full-gpu-pipeline"
    },
    {
      "depth": 2,
      "text": "Options that matter",
      "anchor": "options-that-matter"
    },
    {
      "depth": 2,
      "text": "Pitfalls",
      "anchor": "pitfalls"
    },
    {
      "depth": 2,
      "text": "Full option reference",
      "anchor": "full-option-reference"
    },
    {
      "depth": 3,
      "text": "Private options",
      "anchor": "private-options"
    },
    {
      "depth": 3,
      "text": "Codec-specific generic initialization overrides",
      "anchor": "codec-specific-generic-initialization-overrides"
    }
  ],
  "sections": [
    {
      "id": "_preamble",
      "title": "Page introduction",
      "depth": 0,
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/_preamble.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/_preamble.md",
      "checksum": "12ce0fe597c21758634151e1e28cadbc9adeeca8abba749b44afa8c6d620b113",
      "bytes": 875
    },
    {
      "id": "hardware-or-software-encoder",
      "title": "Hardware or software encoder?",
      "depth": 2,
      "anchor": "hardware-or-software-encoder",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#hardware-or-software-encoder",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/hardware-or-software-encoder.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/hardware-or-software-encoder.md",
      "checksum": "c79747b9160b4b28f8fbba7a3ed851fa37d648cd88b48578844a0e07e47f6731",
      "bytes": 367
    },
    {
      "id": "check-that-your-driver-can-encode",
      "title": "Check that your driver can encode",
      "depth": 2,
      "anchor": "check-that-your-driver-can-encode",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#check-that-your-driver-can-encode",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/check-that-your-driver-can-encode.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/check-that-your-driver-can-encode.md",
      "checksum": "a7a4acad61bd21693079c65ff2808889c323b2d76f7d723c379065c03191e018",
      "bytes": 667
    },
    {
      "id": "quality-oriented-encode",
      "title": "Quality-oriented encode",
      "depth": 2,
      "anchor": "quality-oriented-encode",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#quality-oriented-encode",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/quality-oriented-encode.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/quality-oriented-encode.md",
      "checksum": "b72bfa946c0ac84e81b23dc3d621860872a0094793610a27b2706c2741f4358b",
      "bytes": 1035
    },
    {
      "id": "full-gpu-pipeline",
      "title": "Full-GPU pipeline",
      "depth": 2,
      "anchor": "full-gpu-pipeline",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#full-gpu-pipeline",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/full-gpu-pipeline.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/full-gpu-pipeline.md",
      "checksum": "aa00993bcd096700e6f7d56633086b4a46bbe45efd95f3ffabaa41c5d66fb8f3",
      "bytes": 303
    },
    {
      "id": "options-that-matter",
      "title": "Options that matter",
      "depth": 2,
      "anchor": "options-that-matter",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#options-that-matter",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/options-that-matter.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/options-that-matter.md",
      "checksum": "2beba85732607764ef0dcb6e6ac5eea8c590b8ba7065f3c5bb0e8c18d735a2b1",
      "bytes": 883
    },
    {
      "id": "pitfalls",
      "title": "Pitfalls",
      "depth": 2,
      "anchor": "pitfalls",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#pitfalls",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/pitfalls.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/pitfalls.md",
      "checksum": "3987fb3c1affbc94a8aac1b7eb9c8aef080b6e8acfa4608bbd4830f4b3f254c0",
      "bytes": 389
    },
    {
      "id": "full-option-reference",
      "title": "Full option reference",
      "depth": 2,
      "anchor": "full-option-reference",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#full-option-reference",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/full-option-reference.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/full-option-reference.md",
      "checksum": "dc1c049af8e9816a55bbb04808b0919080492f91ba37c71e145966667c9f191b",
      "bytes": 2994
    },
    {
      "id": "private-options",
      "title": "Private options",
      "depth": 3,
      "anchor": "private-options",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#private-options",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/private-options.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/private-options.md",
      "checksum": "2960fc404c2943130722573582b4a22b5ef23472ed2c02d2b6bb488f1101fec1",
      "bytes": 2261
    },
    {
      "id": "codec-specific-generic-initialization-overrides",
      "title": "Codec-specific generic initialization overrides",
      "depth": 3,
      "anchor": "codec-specific-generic-initialization-overrides",
      "canonicalUrl": "https://encode.wiki/tools/hardware-encoders/vulkan/#codec-specific-generic-initialization-overrides",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/codec-specific-generic-initialization-overrides.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/tools/hardware-encoders/vulkan/codec-specific-generic-initialization-overrides.md",
      "checksum": "a47908a0411afd83596eb40117cea9ad4e000c2ab26646956901483e6b926f96",
      "bytes": 449
    }
  ],
  "outboundReferences": [
    "/tools/hardware-encoders/amf/",
    "/tools/hardware-encoders/nvenc/",
    "/tools/hardware-encoders/nvenc/#hardware-or-software-encoder",
    "/tools/hardware-encoders/vaapi/",
    "/tools/software-encoders/svt-av1/",
    "/tools/software-encoders/x264/",
    "/tools/software-encoders/x265/"
  ],
  "checksum": "1f7bdb512f10c7f7cb5c740b8e1336099d74a5dd1b2078f200d7532151ca28a1",
  "contentFormat": "markdown",
  "markdown": "Vulkan Video exposes the fixed-function video engines of a GPU through the cross-vendor Vulkan API instead of a vendor API like [NVENC](/tools/hardware-encoders/nvenc/), [AMF](/tools/hardware-encoders/amf/) or [VAAPI](/tools/hardware-encoders/vaapi/). FFmpeg has `h264_vulkan` and `hevc_vulkan` (added in FFmpeg 7.1) and `av1_vulkan` (added in 8.0). The same engine is used underneath, so the quality is that of the GPU's hardware encoder, not something new.\n\nIt is the newest and least settled hardware path. Driver support is uneven and still changing, there are fewer tuning options than in the vendor APIs, and for most people the vendor encoder on the same GPU is the better choice. It is interesting mainly where a driver offers Vulkan Video but no other encode API, or when you want the encode on the same Vulkan device as your filters (`scale_vulkan`, `libplacebo`).\n\n## Hardware or software encoder?\n\nThe usual hardware trade-off applies: fast and efficient, but worse than [x264](/tools/software-encoders/x264/), [x265](/tools/software-encoders/x265/) or [SVT-AV1](/tools/software-encoders/svt-av1/) at slow presets in quality per bit. See [NVENC: hardware or software](/tools/hardware-encoders/nvenc/#hardware-or-software-encoder).\n\n## Check that your driver can encode\n\nThe device must expose the encode extensions: `VK_KHR_video_encode_queue` plus `VK_KHR_video_encode_h264`, `_h265` or `_av1`.\n\n```sh\nvulkaninfo | grep -i video_encode\n```\n\nFFmpeg fails at start-up with \"Device does not support the VK_KHR_video_encode_queue extension\" when it is missing. A Vulkan graphics device or decode support does not imply encode support. At build time FFmpeg needs Vulkan headers 1.3.277 or newer, and 1.4.317 or newer for `av1_vulkan`.\n\nFFmpeg 9 also has Vulkan compute encoders for ProRes (`prores_ks_vulkan`) and FFV1 (`ffv1_vulkan`). Those run on shaders and have nothing to do with the video engine.\n\n## Quality-oriented encode\n\n```sh\nffmpeg -init_hw_device vulkan=vk -filter_hw_device vk -i input.mkv -vf 'format=nv12,hwupload' -c:v hevc_vulkan -qp 26 -c:a copy output.mkv\n```\n\n`-qp N` (or `-global_quality N`) selects constant-quantizer mode, the only quality-targeted mode here. The option accepts 0–255, but H.264 and HEVC quantizers stop at 51, while AV1's go to 255 and need values several times higher for similar quality:\n\n```sh\nffmpeg -init_hw_device vulkan=vk -filter_hw_device vk -i input.mkv -vf 'format=nv12,hwupload' -c:v av1_vulkan -qp 100 -c:a copy output.mkv\n```\n\nFor a size target give `-b:v 6M -maxrate 9M`; FFmpeg picks VBR if the driver has it, otherwise CBR (force either with `-rc_mode vbr` or `-rc_mode cbr`). With no rate options at all, FFmpeg falls back to a fixed QP of 18 for every codec, which for AV1 means very large files. `-tune hq` and `-usage transcode` are hints that suit offline encodes, and `-quality N` picks a slower, higher-quality driver preset where the driver offers more than one level.\n\n## Full-GPU pipeline\n\n```sh\nffmpeg -hwaccel vulkan -hwaccel_output_format vulkan -i input.mkv -vf scale_vulkan=w=1920:h=1080 -c:v hevc_vulkan -qp 26 output.mkv\n```\n\nVulkan decode covers H.264, HEVC, AV1 and VP9 in FFmpeg. As elsewhere, a filter without a Vulkan version forces `hwdownload,format=nv12`.\n\n## Options that matter\n\n| Option | What it does |\n| --- | --- |\n| `-rc_mode` | `auto` (CQP if a QP is set, VBR or CBR if a bitrate is), `driver`, `cqp`, `cbr`, `vbr`. FFmpeg errors out if the driver lacks the requested mode. |\n| `-qp` | Quantizer for `cqp`. |\n| `-quality` | Driver-defined quality level, higher is slower. The effective range comes from the device. |\n| `-tune` | `default`, `hq`, `ll`, `ull`, `lossless`. A hint; drivers may ignore it. |\n| `-usage`, `-content` | Hints: `transcode`, `stream`, `record`, `conference` and `camera`, `desktop`, `rendered`. |\n| `-b_depth`, `-bf` | B-frame structure. Defaults `1` and `2`. |\n| `-g`, `-idr_interval` | GOP length (default 300) and IDR spacing in I-frames. |\n| `-async_depth` | Frames in flight. |\n| `-profile`, `-level`, `-tier` | AV1: `main`, `high`, `professional`; level names are the AV1 level numbers (`40`, `51`). |\n\n## Pitfalls\n\n- Vulkan device selection matters when a machine has both hardware and software (llvmpipe) Vulkan devices. Pick the GPU with `vulkan=vk:N`.\n- Frames need to be in Vulkan memory; `hwupload` with `-filter_hw_device` handles that for software-decoded input.\n- The AV1 wrapper's numeric level IDs are sequence-level indices, not Android's flags or NVENC's numbers. Use the names.\n\n## Full option reference\n\nEvery private option of `av1_vulkan` in FFmpeg 9.0.2; `h264_vulkan` and `hevc_vulkan` share the GOP, rate-control, quality and hint options. `INT_MAX` is 2147483647; `rc_mode` `auto` is stored as `UINT32_MAX` (4294967295).\n\n{/* ffmpeg-parameters:start */}\n\n### Private options\n\n| Parameter | Type | Default | Meaning | Range / named values |\n| --- | --- | --- | --- | --- |\n| `-idr_interval` | `int` | `0` | Number of non-key I-frames between key frames; 0 makes every I-frame a key frame. | `0` to `INT_MAX` |\n| `-b_depth` | `int` | `1` | B-frame reference depth: 1 = flat B-frames, higher builds a hierarchy. Needs `-bf`. | `1` to `INT_MAX` |\n| `-async_depth` | `int` | `2` | Frames in flight on the GPU; raise it for single-stream throughput. | `1` to `64` |\n| `-qp` | `int` | `-1` | Constant QP for all frames (selects `cqp`). | `-1` to `255` |\n| `-quality` | `int` | `0` | Driver quality level, from 0 to the driver maximum; higher is slower. Out-of-range values are rejected. | `0` to `INT_MAX` |\n| `-rc_mode` | `int` | `auto` | Rate control: `driver`, `cqp`, `cbr`, `vbr`. `auto` uses CQP with `-qp`/`-global_quality`, VBR (or CBR) with `-b:v`, and otherwise CQP at QP 18. | `0` to `UINT32_MAX`; `auto`=`4294967295`, `driver`=`0`, `cqp`=`1`, `cbr`=`2`, `vbr`=`4` |\n| `-tune` | `int` | `default` | Tuning hint: `hq`, `ll`, `ull`, `lossless`; `default` leaves it to the driver. | `0` to `INT_MAX`; `default`=`0`, `hq`=`1`, `ll`=`2`, `ull`=`3`, `lossless`=`4` |\n| `-usage` | `flags` | `0` | Usage hint (combinable): `transcode`, `stream`, `record`, `conference`. | `default`, `transcode`, `stream`, `record`, `conference` |\n| `-content` | `flags` | `0` | Content hint (combinable): `camera`, `desktop`, `rendered`. | `default`, `camera`, `desktop`, `rendered` |\n| `-profile` | `int` | `-99` | AV1 profile: `main`, `high`, `professional`. -99 chooses from the input format. | `-99` to `65535`; `main`=`0`, `high`=`1`, `professional`=`2` |\n| `-tier` | `int` | `main` | AV1 tier: `main` or `high`. | `0` to `1`; `main`=`0`, `high`=`1` |\n| `-level` | `int` | `-99` | AV1 level; -99 chooses automatically. | `-99` to `255`; `20`=`0`, `21`=`1`, `22`=`2`, `23`=`3`, `30`=`4`, `31`=`5`, `32`=`6`, `33`=`7`, `40`=`8`, `41`=`9`, `42`=`10`, `43`=`11`, `50`=`12`, `51`=`13`, `52`=`14`, `53`=`15`, `60`=`16`, `61`=`17`, `62`=`18`, `63`=`19`, `70`=`20`, `71`=`21`, `72`=`22`, `73`=`23` |\n| `-units` | `flags` | `hdr` | Metadata to write: `hdr` writes mastering-display and content-light-level metadata from the input. | `hdr` |\n\n### Codec-specific generic initialization overrides\n\nThe wrapper replaces these generic FFmpeg defaults for this encoder. `-b` is in bits/s; `-g` and\n`-bf` count frames. `-1`, and `0` for `-b` and `-refs`, leave the value to the preset, driver or\nrate-control logic.\n\n| Generic parameter | Default |\n| --- | --- |\n| `-b` | `0` |\n| `-bf` | `2` |\n| `-g` | `300` |\n| `-qmin` | `1` |\n| `-qmax` | `255` |\n| `-refs` | `0` |\n\n{/* ffmpeg-parameters:end */}\n"
}
