The Hardware Context System provides a unified abstraction layer for managing hardware-accelerated processing in FFmpeg. The primary public interface is libavutil/hwcontext.h, which exposes AVHWDeviceContext and AVHWFramesContext — backend-agnostic types used to represent a hardware device and a pool of hardware frames respectively. Each supported backend (CUDA, VAAPI, Vulkan, etc.) extends these with backend-specific context structures defined in separate headers such as libavutil/hwcontext_vulkan.h.
This document focuses on:
hwcontext.h)For information about AVFrame and buffer management, see page 3.1.1. For Vulkan-specific codec and filter implementations, see page 7.1.
Sources: libavutil/hwcontext_vulkan.h1-50 libavutil/hwcontext_vulkan.c1-74
The hardware context system uses a two-level hierarchy:
Device Context (AVHWDeviceContext): Represents a hardware device and its capabilities. Contains the Vulkan device, queue families, extensions, and features.
Frames Context (AVHWFramesContext): Represents a pool of frames with specific format and dimensions. Contains image format information and execution pools for operations.
Sources: libavutil/hwcontext_vulkan.h59-275 libavutil/hwcontext_vulkan.c123-171 libavutil/hwcontext_vulkan.c173-194
The general API is declared in libavutil/hwcontext.h and is backend-agnostic. Callers interact with AVHWDeviceContext and AVHWFramesContext using the av_hw* functions regardless of the underlying hardware type.
The AVHWDeviceType enum identifies the hardware backend. Each type has a corresponding hwcontext_<name>.h header that defines the backend-specific public context structure (e.g., AVVulkanDeviceContext in hwcontext_vulkan.h).
| Enum Value | Backend Header | Platform |
|---|---|---|
AV_HWDEVICE_TYPE_CUDA | hwcontext_cuda.h | Linux, Windows |
AV_HWDEVICE_TYPE_DRM | hwcontext_drm.h | Linux |
AV_HWDEVICE_TYPE_DXVA2 | hwcontext_dxva2.h | Windows |
AV_HWDEVICE_TYPE_D3D11VA | hwcontext_d3d11va.h | Windows |
AV_HWDEVICE_TYPE_D3D12VA | hwcontext_d3d12va.h | Windows |
AV_HWDEVICE_TYPE_VAAPI | hwcontext_vaapi.h | Linux |
AV_HWDEVICE_TYPE_VDPAU | hwcontext_vdpau.h | Linux |
AV_HWDEVICE_TYPE_OPENCL | hwcontext_opencl.h | Cross-platform |
AV_HWDEVICE_TYPE_QSV | hwcontext_qsv.h | Linux, Windows |
AV_HWDEVICE_TYPE_MEDIACODEC | hwcontext_mediacodec.h | Android |
AV_HWDEVICE_TYPE_VULKAN | hwcontext_vulkan.h | Cross-platform |
Use av_hwdevice_find_type_by_name() to map a name string (e.g. "vulkan", "cuda") to a type value, and av_hwdevice_get_type_name() to do the reverse.
Device context functions:
| Function | Purpose |
|---|---|
av_hwdevice_ctx_alloc(type) | Allocate an AVHWDeviceContext of the given type; caller fills in backend fields |
av_hwdevice_ctx_init(ref) | Initialize a manually-filled device context |
av_hwdevice_ctx_create(ref, type, device, opts, flags) | Allocate and open a device in one call; most common entry point |
av_hwdevice_ctx_create_derived(dst, type, src, flags) | Create a context of a new type interoperating with an existing context (e.g., VAAPI from DRM) |
Frames context functions:
| Function | Purpose |
|---|---|
av_hwframes_ctx_alloc(device_ref) | Allocate an AVHWFramesContext linked to a device context |
av_hwframes_ctx_init(ref) | Initialize the frames context (creates the frame pool) |
av_hwframe_get_buffer(frames_ref, frame, flags) | Allocate a hardware frame from the pool |
av_hwframe_transfer_data(dst, src, flags) | Transfer data between hardware and software frames |
av_hwframe_map(dst, src, flags) | Map a hardware frame into a different address space (e.g., host-visible) |
av_hwframe_transfer_get_formats(frames_ref, dir, formats, flags) | Query the pixel formats available for av_hwframe_transfer_data |
Title: AVHWDeviceContext and AVHWFramesContext lifecycle
Sources: libavutil/hwcontext_vulkan.h59-275
The AVVulkanDeviceContext structure defines the public API for device management. Key fields:
| Field | Type | Purpose |
|---|---|---|
inst | VkInstance | Vulkan instance (required version 1.3+) |
phys_dev | VkPhysicalDevice | Physical device handle |
act_dev | VkDevice | Logical device handle |
qf | AVVulkanDeviceQueueFamily* | Array of queue families |
nb_qf | int | Number of queue families |
enabled_inst_extensions | const char** | Enabled instance extensions |
enabled_dev_extensions | const char** | Enabled device extensions |
device_features | VkPhysicalDeviceFeatures2 | Enabled device features |
Sources: libavutil/hwcontext_vulkan.h59-208
The VulkanDevicePriv structure contains internal state not exposed through the public API:
use_linear_images, contiguous_planesSources: libavutil/hwcontext_vulkan.c123-171
Queue families are managed through AVVulkanDeviceQueueFamily structures. The system supports:
The function ff_vk_qf_find() at libavutil/vulkan.c288-299 locates appropriate queue families based on required capabilities.
Sources: libavutil/hwcontext_vulkan.h33-45 libavutil/vulkan.c288-299
The AVVulkanFramesContext defines frame pool properties:
| Field | Type | Purpose |
|---|---|---|
format[3] | VkFormat | Vulkan formats for each plane (up to 3 planes) |
tiling | VkImageTiling | VK_IMAGE_TILING_OPTIMAL or LINEAR |
usage | VkImageUsageFlags | Image usage flags (SAMPLED, STORAGE, TRANSFER, VIDEO_DECODE) |
create_pnext | void* | Extended creation info (DRM modifiers, etc.) |
alloc_pnext | void* | Extended allocation info (external memory) |
img_flags | VkImageCreateFlags | Image creation flags |
Sources: libavutil/hwcontext_vulkan.h244-275
VulkanFramesPriv maintains execution pools for different operation types:
Each pool contains multiple FFVkExecContext instances for parallel command buffer recording.
Sources: libavutil/hwcontext_vulkan.c173-194 libavutil/vulkan.c301-364
Memory allocation follows this pattern:
vkGetImageMemoryRequirements2() determines size and alignmentff_vk_alloc_mem() at libavutil/hwcontext_vulkan.c1033-1131 finds compatible memory typevkAllocateMemory() allocates device memoryvkBindImageMemory2() binds memory to imageMemory type selection prioritizes:
DEVICE_LOCAL for GPU operationsHOST_VISIBLE + HOST_COHERENT for staging buffersHOST_CACHED when available for read operationsSources: libavutil/hwcontext_vulkan.c1033-1131 libavutil/hwcontext_vulkan.c1174-1299
FFVkBuffer at libavutil/vulkan.h125-143 encapsulates Vulkan buffer management:
| Field | Purpose |
|---|---|
buf | VkBuffer handle |
mem | Associated VkDeviceMemory |
mapped_mem | CPU-side pointer when mapped |
address | Device address for shader access |
virtual_offset | Offset for host-mapped buffers |
Key buffer functions:
ff_vk_create_buf(): Create and allocate bufferff_vk_map_buffer(): Map to CPU address spaceff_vk_flush_buffer(): Flush CPU writes to deviceff_vk_get_pooled_buffer(): Get buffer from thread-safe poolSources: libavutil/vulkan.h125-143 libavutil/vulkan.c1167-1341
Transfer operations use staging buffers for CPU-GPU communication:
Upload (vulkan_transfer_data_from() at libavutil/hwcontext_vulkan.c2761-3031):
HOST_VISIBLE memorymemcpy()vkCmdCopyBufferToImage() commandDownload (vulkan_transfer_data_to() at libavutil/hwcontext_vulkan.c3033-3327):
HOST_VISIBLE memoryvkCmdCopyImageToBuffer() commandmemcpy()Sources: libavutil/hwcontext_vulkan.c2761-3327
When VK_EXT_host_image_copy is available, the system can perform direct CPU-GPU transfers without staging buffers. This is checked at libavutil/hwcontext_vulkan.c2794-2828 and uses vkCopyMemoryToImageEXT() for uploads and vkCopyImageToMemoryEXT() for downloads.
Sources: libavutil/hwcontext_vulkan.c2794-2828 libavutil/hwcontext_vulkan.c3073-3147
DMA-BUF support enables zero-copy sharing with other APIs:
Export (Vulkan to DMA-BUF):
FF_VK_EXT_EXTERNAL_DMABUF_MEMORY flagvkGetMemoryFdKHR() to get file descriptorImport (DMA-BUF to Vulkan):
VkImportMemoryFdInfoKHR with external FDpNext to VkMemoryAllocateInfoDRM Modifiers: When FF_VK_EXT_DRM_MODIFIER_FLAGS is enabled, images can specify format modifiers for optimal hardware layout compatibility.
Sources: libavutil/hwcontext_vulkan.c1301-1473 libavutil/hwcontext_vulkan.c1992-2253
AVVkFrameInternal at libavutil/hwcontext_vulkan.c196-212 caches CUDA imports for performance:
The CUDA import is expensive, so memory and semaphores are kept imported throughout the frame's lifetime.
Sources: libavutil/hwcontext_vulkan.c196-212 libavutil/hwcontext_vulkan.c2373-2696
The function ff_vk_host_map_buffer() at libavutil/vulkan.c1343-1410 can map system RAM directly as a Vulkan buffer without copying:
vkGetMemoryHostPointerPropertiesEXT()VkImportMemoryHostPointerInfoEXT with host pointerpNext chainThis requires FF_VK_EXT_EXTERNAL_HOST_MEMORY extension and proper alignment.
Sources: libavutil/vulkan.c1343-1410 libavutil/hwcontext_vulkan.c1033-1131
FFVulkanContext at libavutil/vulkan.h313-365 is the internal context used throughout Vulkan operations:
Key fields:
vkfn: All Vulkan function pointers loaded via ff_vk_load_functions()extensions: Bitmask of enabled extensions (FFVulkanExtensions)props, mprops, feats: Device capabilitiesqfs[]: Array of enabled queue family indicesInitialization: ff_vk_load_props() at libavutil/vulkan.c147-286 queries all device properties and capabilities.
Sources: libavutil/vulkan.h313-365 libavutil/vulkan.c147-286
The execution pool system provides thread-safe command buffer management:
FFVkExecPool (ff_vk_exec_pool_init() at libavutil/vulkan.c366-527):
FFVkExecContext instances (typically 2-4 per pool)FFVkExecContext:
Typical usage:
Sources: libavutil/vulkan.h291-311 libavutil/vulkan.h145-208 libavutil/vulkan.c366-627
The format system maintains a comprehensive mapping table at libavutil/hwcontext_vulkan.c402-519:
Format entry structure:
vkf: Primary Vulkan format (e.g., VK_FORMAT_G8_B8R8_2PLANE_420_UNORM)pixfmt: Corresponding AVPixelFormat (e.g., AV_PIX_FMT_NV12)aspect: Image aspect flags for plane selectionvk_planes: Number of Vulkan planes in native formatnb_images: Number of separate images to createfallback[]: Alternative formats if native format unsupportedFormat selection (vkfmt_from_pixfmt2() at libavutil/hwcontext_vulkan.c538-629):
Sources: libavutil/hwcontext_vulkan.c402-629
Extension management uses a 64-bit bitmask for efficient checking:
Extension flags (defined in libavutil/vulkan_functions.h29-75):
FF_VK_EXT_NO_FLAG (always enabled), FF_VK_EXT_PORTABILITY_SUBSETFF_VK_EXT_VIDEO_DECODE_H264, FF_VK_EXT_VIDEO_DECODE_HEVC, etc.Optional extensions (libavutil/hwcontext_vulkan.c686-758):
AVVulkanDeviceContextFeature management (libavutil/hwcontext_vulkan.c75-121 libavutil/hwcontext_vulkan.c215-288):
VulkanDeviceFeatures structure chains all feature structuresSources: libavutil/vulkan_functions.h29-75 libavutil/hwcontext_vulkan.c75-288 libavutil/hwcontext_vulkan.c686-758
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.