1// Copyright 2021-2024 The Khronos Group Inc. 2// 3// SPDX-License-Identifier: CC-BY-4.0 4 5= VK_KHR_video_encode_h265 6:toc: left 7:refpage: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/ 8:sectnums: 9 10This document outlines a proposal to enable performing H.265/HEVC video encode operations in Vulkan. 11 12== Problem Statement 13 14The `VK_KHR_video_queue` extension introduces support for video coding operations and the `VK_KHR_video_encode_queue` extension further extends this with APIs specific to video encoding. 15 16The goal of this proposal is to build upon this infrastructure to introduce support for encoding elementary video stream sequences compliant with the H.265/HEVC video compression standard. 17 18 19== Solution Space 20 21As the `VK_KHR_video_queue` and `VK_KHR_video_encode_queue` extensions already laid down the architecture for how codec-specific video encode extensions need to be designed, this extension only needs to define the APIs to provide the necessary codec-specific parameters at various points during the use of the codec-independent APIs. In particular: 22 23 * APIs allowing to specify H.265 video, sequence, and picture parameter sets (VPS, SPS, PPS) to be stored in video session parameters objects 24 * APIs allowing to specify H.265 information specific to the encoded picture, including references to previously stored VPS, SPS, and PPS entries 25 * APIs allowing to specify H.265 reference picture information specific to the active reference pictures and optional reconstructed picture used in video encode operations 26 27Codec-specific encoding parameters are specified by the application through custom definitions provided by a video std header dedicated to H.265 video encoding. 28 29This proposal uses the common H.265 definitions first utilized by the `VK_KHR_video_decode_h265` extension and augments it with another video std header specific to H.265 encoding. Thus this extension uses the following video std headers: 30 31 * `vulkan_video_codec_h265std` - containing common definitions for all H.265 video coding operations 32 * `vulkan_video_codec_h265std_encode` - containing definitions specific to H.265 video encoding operations 33 34These headers can be included as follows: 35 36[source,c] 37---- 38#include <vk_video/vulkan_video_codec_h265std.h> 39#include <vk_video/vulkan_video_codec_h265std_encode.h> 40---- 41 42 43== Proposal 44 45=== Video Std Headers 46 47This extension uses the new `vulkan_video_codec_h265std_encode` video std header. Implementations must always support at least version 1.0.0 of this video std header. 48 49 50=== H.265 Encode Profiles 51 52This extension introduces the new video codec operation `VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR`. This flag can be used to check whether a particular queue family supports encoding H.265/HEVC content, as returned in `VkQueueFamilyVideoPropertiesKHR`. 53 54An H.265 encode profile can be defined through a `VkVideoProfileInfoKHR` structure using this new video codec operation and by including the following new codec-specific profile information structure in the `pNext` chain: 55 56[source,c] 57---- 58typedef struct VkVideoEncodeH265ProfileInfoKHR { 59 VkStructureType sType; 60 const void* pNext; 61 StdVideoH265ProfileIdc stdProfileIdc; 62} VkVideoEncodeH265ProfileInfoKHR; 63---- 64 65`stdProfileIdc` specifies the H.265 profile indicator. 66 67 68=== H.265 Encode Capabilities 69 70Applications need to include the following new structure in the `pNext` chain of `VkVideoCapabilitiesKHR` when calling the `vkGetPhysicalDeviceVideoCapabilitiesKHR` command to retrieve the capabilities specific to H.265 video encoding: 71 72[source,c] 73---- 74typedef struct VkVideoEncodeH265CapabilitiesKHR { 75 VkStructureType sType; 76 void* pNext; 77 VkVideoEncodeH265CapabilityFlagsKHR flags; 78 StdVideoH265LevelIdc maxLevelIdc; 79 uint32_t maxSliceSegmentCount; 80 VkExtent2D maxTiles; 81 VkVideoEncodeH265CtbSizeFlagsKHR ctbSizes; 82 VkVideoEncodeH265TransformBlockSizeFlagsKHR transformBlockSizes; 83 uint32_t maxPPictureL0ReferenceCount; 84 uint32_t maxBPictureL0ReferenceCount; 85 uint32_t maxL1ReferenceCount; 86 uint32_t maxSubLayerCount; 87 VkBool32 expectDyadicTemporalSubLayerPattern; 88 int32_t minQp; 89 int32_t maxQp; 90 VkBool32 prefersGopRemainingFrames; 91 VkBool32 requiresGopRemainingFrames; 92 VkVideoEncodeH265StdFlagsKHR stdSyntaxFlags; 93} VkVideoEncodeH265CapabilitiesKHR; 94---- 95 96`flags` indicates support for various H.265 encoding capabilities: 97 98 * `VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_KHR` - support for generating HRD compliant bitstreams when the related HRD parameters are present 99 * `VK_VIDEO_ENCODE_H265_CAPABILITY_PREDICTION_WEIGHT_TABLE_GENERATED_BIT_KHR` - support for generating the weight tables used by the encoding process, when necessary, instead of the application having to provide them 100 * `VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_KHR` - support for slice segments that do not start/finish at CTB row boundaries 101 * `VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_SEGMENT_TYPE_BIT_KHR` - support for different slice segment types within a frame 102 * `VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_KHR` - support for including B pictures in the L0 reference list 103 * `VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_KHR` - support for including B pictures in the L1 reference list 104 * `VK_VIDEO_ENCODE_H265_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR` - support for using different min/max QP values for each picture type when rate control is enabled 105 * `VK_VIDEO_ENCODE_H265_CAPABILITY_PER_SLICE_SEGMENT_CONSTANT_QP_BIT_KHR` - support for using different constant QP values for each slice segment of a frame when rate control is disabled 106 * `VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILES_PER_SLICE_SEGMENT_BIT_KHR` - support for encoding multiple tiles per slice segment 107 * `VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_SEGMENTS_PER_TILE_BIT_KHR` - support for encoding multiple slice segments per tile 108 109`maxLevelIdc` indicates the maximum supported H.265 level indicator. 110 111`maxSliceSegmentCount` indicates the implementation's upper bound on the number of H.265 slice segments that an encoded frame can contain, although the actual maximum may be smaller for a given frame depending on its dimensions and some of the capability flags described earlier. 112 113The fields of `maxTiles` indicate the maximum number of H.265 tile columns and rows, respectively. 114 115`ctbSizes` and `transformBlockSizes` are bitmasks that indicate the set of CTB and transform block sizes supported by the implementation, respectively. 116 117`maxPPictureL0ReferenceCount`, `maxBPictureL0ReferenceCount`, and `maxL1ReferenceCount` indicate the maximum number of reference frames that the encoded frames can refer to through the L0 and L1 reference lists depending on the type of the picture (P or B), respectively. These capabilities do not restrict the number of references the application can include in the L0 and L1 reference lists as, in practice, implementations may restrict the effective number of used references based on the encoded content and/or the capabilities of the encoder implementation. However, they do indirectly indicate whether encoding P or B pictures are supported. In particular: 118 119 * If `maxPPictureL0ReferenceCount` is zero, then encoding P pictures is not supported by the implementation 120 * If both `maxBPictureL0ReferenceCount` and `maxL1ReferenceCount` are zero, then encoding B pictures is not supported by the implementation 121 122The H.265/HEVC video compression standard supports so called generalized B pictures (also known as low delay B pictures) that use both L0 and L1 references referring to only past frames. This can make the use of P pictures moot. Hence, certain implementations may only advertise support for encoding B pictures (but not P pictures). This, however, should not limit applications in encoding backward-reference-only frames. 123 124`maxSubLayerCount` indicates the number of supported H.265 sub-layers, while `expectDyadicTemporalSubLayerPattern` indicates whether the multi-layer rate control algorithm of the implementation (if support is indicated by `VkVideoEncodeCapabilitiesKHR::maxRateControlLayers` being greater than one for the given H.265 encode profile) expects the application to use a dyadic temporal sub-layer pattern for accurate operation. 125 126`minQp` and `maxQp` indicate the supported range of QP values that can be used in the rate control configurations or as the constant QP to be used when rate control is disabled. 127 128`prefersGopRemainingFrames` and `requiresGopRemainingFrames` indicate whether the implementation prefers or requires, respectively, that the application tracks the remaining number of frames (for each type) in the current GOP (group of pictures), as some implementations may need this information for the accurate operation of their rate control algorithm. 129 130`stdSyntaxFlags` contains a set of flags that provide information to the application about which video std parameters or parameter values are supported to be used directly as specified by the application. These flags do not restrict what video std parameter values the application can specify, rather, they provide guarantees about respecting those. 131 132 133=== H.265 Encode Parameter Sets 134 135The use of video session parameters objects is mandatory when encoding H.265 video streams. Applications need to include the following new structure in the `pNext` chain of `VkVideoSessionParametersCreateInfoKHR` when creating video session parameters objects for H.265 encode use, to specify the parameter set capacity of the created objects: 136 137[source,c] 138---- 139typedef struct VkVideoEncodeH265SessionParametersCreateInfoKHR { 140 VkStructureType sType; 141 const void* pNext; 142 uint32_t maxStdVPSCount; 143 uint32_t maxStdSPSCount; 144 uint32_t maxStdPPSCount; 145 const VkVideoEncodeH265SessionParametersAddInfoKHR* pParametersAddInfo; 146} VkVideoEncodeH265SessionParametersCreateInfoKHR; 147---- 148 149The optional `pParametersAddInfo` member also allows specifying an initial set of parameter sets to add to the created object: 150 151[source,c] 152---- 153typedef struct VkVideoEncodeH265SessionParametersAddInfoKHR { 154 VkStructureType sType; 155 const void* pNext; 156 uint32_t stdVPSCount; 157 const StdVideoH265VideoParameterSet* pStdVPSs; 158 uint32_t stdSPSCount; 159 const StdVideoH265SequenceParameterSet* pStdSPSs; 160 uint32_t stdPPSCount; 161 const StdVideoH265PictureParameterSet* pStdPPSs; 162} VkVideoEncodeH265SessionParametersAddInfoKHR; 163---- 164 165This structure can also be included in the `pNext` chain of `VkVideoSessionParametersUpdateInfoKHR` used in video session parameters update operations to add further parameter sets to an object after its creation. 166 167Individual parameter sets are stored using parameter set IDs as their keys, specifically: 168 169 * H.265 VPS entries are identified using a `vps_video_parameter_set_id` value 170 * H.265 SPS entries are identified using a pair of `sps_video_parameter_set_id` and `sps_seq_parameter_set_id` values 171 * H.265 PPS entries are identified using a triplet of `sps_video_parameter_set_id`, `pps_seq_parameter_set_id`, and `pps_pic_parameter_set_id` values 172 173Please note the inclusion of the VPS ID in the PPS key. This is needed because a PPS is not uniquely identified by its ID and the ID of the parent SPS, as multiple SPS entries may exist with the same ID that have different parent VPS IDs. In order to ensure the uniqueness of keys, all APIs referring to a PPS in this proposal also take the parent VPS ID of the SPS the PPS in question belongs to, to specify the full hierarchy of IDs. 174 175The H.265/HEVC video compression standard always requires a VPS, SPS, and PPS, hence the application has to add an instance of each parameter set to the used parameters object before being able to record video encode operations. 176 177Furthermore, the H.265/HEVC video compression standard also allows modifying existing parameter sets, but as parameters already stored in video session parameters objects cannot be changed in Vulkan, the application has to create new parameters objects in such cases, as described in the proposal for `VK_KHR_video_queue`. 178 179As implementations can override parameters in the VPS, SPS, and PPS entries stored in video session parameters objects, as described in the proposal for `VK_KHR_video_encode_queue`, this proposal introduces additional structures specific to H.265 encode to be used with the `vkGetEncodedVideoSessionParametersKHR` command. 180 181First, the following new structure has to be included in the `pNext` chain of `VkVideoEncodeSessionParametersGetInfoKHR` to identify the H.265 parameter sets that the command is expected to return feedback information or encoded parameter set data for: 182 183[source,c] 184---- 185typedef struct VkVideoEncodeH265SessionParametersGetInfoKHR { 186 VkStructureType sType; 187 const void* pNext; 188 VkBool32 writeStdVPS; 189 VkBool32 writeStdSPS; 190 VkBool32 writeStdPPS; 191 uint32_t stdVPSId; 192 uint32_t stdSPSId; 193 uint32_t stdPPSId; 194} VkVideoEncodeH265SessionParametersGetInfoKHR; 195---- 196 197`writeStdVPS`, `writeStdSPS`, and `writeStdPPS` specify whether VPS, SPS, or PPS feedback/bitstream data is requested. Any combination can be requested, if needed. 198 199`stdVPSId`, `stdSPSId`, and `stdPPSId` are used to identify the VPS, SPS, and/or PPS to request data for. Naturally, `stdPPSId` is only relevant for PPS queries, and `stdSPSId` is only relevant for SPS and/or PPS queries. 200 201When requesting feedback using the `vkGetEncodedVideoSessionParametersKHR` command, the following new structure can be included in the `pNext` chain of `VkVideoEncodeSessionParametersFeedbackInfoKHR`: 202 203[source,c] 204---- 205typedef struct VkVideoEncodeH265SessionParametersFeedbackInfoKHR { 206 VkStructureType sType; 207 void* pNext; 208 VkBool32 hasStdVPSOverrides; 209 VkBool32 hasStdSPSOverrides; 210 VkBool32 hasStdPPSOverrides; 211} VkVideoEncodeH265SessionParametersFeedbackInfoKHR; 212---- 213 214The resulting values of `hasStdVPSOverrides`, `hasStdSPSOverrides`, and `hasStdPPSOverrides` indicate whether overrides were applied to the VPS, SPS, and/or PPS, respectively, if the corresponding `writeStd` field was set in the input parameters. 215 216When requesting encoded bitstream data using the `vkGetEncodedVideoSessionParametersKHR` command, the output host data buffer will be filled with the encoded bitstream of the requested H.265 parameter sets. 217 218As described in great detail in the proposal for the `VK_KHR_video_encode_queue` extension, the application may have the option to encode the parameters otherwise stored in video session parameters object on its own. However, this may not result in a compliant bitstream if the implementation applied overrides to VPS, SPS, or PPS parameters, thus it is generally recommended for applications to use the encoded parameter set data retrieved using the `vkGetEncodedVideoSessionParametersKHR` command. 219 220 221=== H.265 Encoding Parameters 222 223Encode parameters specific to H.265 need to be provided by the application through the `pNext` chain of `VkVideoEncodeInfoKHR`, using the following new structure: 224 225[source,c] 226---- 227typedef struct VkVideoEncodeH265PictureInfoKHR { 228 VkStructureType sType; 229 const void* pNext; 230 uint32_t naluSliceSegmentEntryCount; 231 const VkVideoEncodeH265NaluSliceSegmentInfoKHR* pNaluSliceSegmentEntries; 232 const StdVideoEncodeH265PictureInfo* pStdPictureInfo; 233} VkVideoEncodeH265PictureInfoKHR; 234---- 235 236`naluSliceSegmentEntryCount` specifies the number of slice segments to encode for the frame and the elements of the `pNaluSliceSegmentEntries` array provide additional information for each slice segment, as described later. 237 238`pStdPictureInfo` points to the codec-specific encode parameters defined in the `vulkan_video_codec_h265std_encode` video std header. 239 240The active VPS, SPS, and PPS (sourced from the bound video session parameters object) are identified by the `sps_video_parameter_set_id`, `pps_seq_parameter_set_id`, and `pps_pic_parameter_set_id` parameters. 241 242The structure pointed to by `pStdPictureInfo->pRefLists` specifies the codec-specific parameters related to the reference lists. In particular, it specifies the DPB slots corresponding to the elements of the L0 and L1 reference lists, as well as reference list modification information. 243 244The parameters of individual slice segments are provided through instances of the following new structure: 245 246[source,c] 247---- 248typedef struct VkVideoEncodeH265NaluSliceSegmentInfoKHR { 249 VkStructureType sType; 250 const void* pNext; 251 int32_t constantQp; 252 const StdVideoEncodeH265SliceSegmentHeader* pStdSliceSegmentHeader; 253} VkVideoEncodeH265NaluSliceSegmentInfoKHR; 254---- 255 256`constantQp` specifies the constant QP value to use for the slice when rate control is disabled. 257 258`pStdSliceSegmentHeader` points to the codec-specific encode parameters to use in the slice segment header. 259 260Picture information specific to H.265 for the active reference pictures and the optional reconstructed picture need to be provided by the application through the `pNext` chain of corresponding elements of `VkVideoEncodeInfoKHR::pReferenceSlots` and the `pNext` chain of `VkVideoEncodeInfoKHR::pSetupReferenceSlot`, respectively, using the following new structure: 261 262[source,c] 263---- 264typedef struct VkVideoEncodeH265DpbSlotInfoKHR { 265 VkStructureType sType; 266 const void* pNext; 267 const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo; 268} VkVideoEncodeH265DpbSlotInfoKHR; 269---- 270 271`pStdReferenceInfo` points to the codec-specific reference picture parameters defined in the `vulkan_video_codec_h265std_encode` video std header. 272 273It is the application's responsibility to specify codec-specific parameters that are compliant to the rules defined by the H.265/HEVC video compression standard. While it is not illegal, from the API usage's point of view, to specify non-compliant inputs, they may cause the video encode operation to complete unsuccessfully and will cause the output bitstream and the reconstructed picture, if one is specified, to have undefined contents after the execution of the operation. 274 275Implementations may override some of these parameters in order to conform to any restrictions of the encoder implementation, but that will not affect the overall operation of the encoding. The application has the option to also opt-in for additional optimizing overrides that can result in better performance or efficiency tailored to the usage scenario by creating the video session with the new `VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_PARAMETER_OPTIMIZATIONS_BIT_KHR` flag. 276 277For more information about individual H.265 bitstream syntax elements, calculate derived values, and, in general, how to interpret these parameters, please refer to the corresponding sections of the https://www.itu.int/rec/T-REC-H.265-202108-S/[ITU-T H.265 Specification]. 278 279 280=== H.265 Reference Lists 281 282In order to populate the L0 and L1 reference lists used to encode predictive pictures, the application has to set the corresponding elements of the `RefPicList0` and `RefPicList1` array members of the structure pointed to by `VkVideoEncodeH265PictureInfoKHR::pStdPictureInfo->pRefLists` to the DPB slot indices of the reference pictures, while all unused elements of `RefPicList0` and `RefPicList1` have to be set to `STD_VIDEO_H265_NO_REFERENCE_PICTURE`. As usual, the reference picture resources are specified by including them in the list of active reference pictures according to the codec-independent semantics defined by the `VK_KHR_video_encode_queue` extension. 283 284In all cases the set of DPB slot indices referenced by the L0 and L1 reference lists and the list of active reference pictures specified in `VkVideoEncodeInfoKHR::pReferenceSlots` must match, but the order in which the active reference pictures are included in the `pReferenceSlots` array does not matter. 285 286 287=== H.265 Rate Control 288 289This proposal adds a set of optional rate control parameters specific to H.265 encoding that provide additional guidance to the implementation's rate control algorithm. 290 291When rate control is not disabled and not set to implementation-default behavior, the application can include the following new structure in the `pNext` chain of `VkVideoEncodeRateControlInfoKHR`: 292 293[source,c] 294---- 295typedef struct VkVideoEncodeH265RateControlInfoKHR { 296 VkStructureType sType; 297 const void* pNext; 298 VkVideoEncodeH265RateControlFlagsKHR flags; 299 uint32_t gopFrameCount; 300 uint32_t idrPeriod; 301 uint32_t consecutiveBFrameCount; 302 uint32_t subLayerCount; 303} VkVideoEncodeH265RateControlInfoKHR; 304---- 305 306`flags` can include one or more of the following flags: 307 308 * `VK_VIDEO_ENCODE_H265_RATE_CONTROL_ATTEMPT_HRD_COMPLIANCE_BIT_KHR` can be used to indicate that the application would like the implementation's rate control algorithm to attempt to produce an HRD compliant bitstream when possible 309 * `VK_VIDEO_ENCODE_H265_RATE_CONTROL_REGULAR_GOP_BIT_KHR` can be used to indicate that the application intends to use a regular GOP structure according to the parameters specified in `gopFrameCount`, `idrPeriod`, and `consecutiveBFrameCount` 310 * `VK_VIDEO_ENCODE_H265_RATE_CONTROL_REFERENCE_PATTERN_FLAT_BIT_KHR` can be used to indicate that the application intends to follow a flat reference pattern in the GOP where each P frame uses the last non-B frame as reference, and each B frame uses the last and next non-B frame as forward and backward references, respectively 311 * `VK_VIDEO_ENCODE_H265_RATE_CONTROL_REFERENCE_PATTERN_DYADIC_BIT_KHR` can be used to indicate that the application intends to follow a dyadic reference pattern 312 * `VK_VIDEO_ENCODE_H265_RATE_CONTROL_TEMPORAL_SUB_LAYER_PATTERN_DYADIC_BIT_KHR` can be used to indicate that the application intends to follow a dyadic temporal sub-layer pattern when using multiple temporal sub-layers 313 314`gopFrameCount`, `idrPeriod`, and `consecutiveBFrameCount` specify the GOP size, IDR period, and the number of consecutive B frames between non-B frames, respectively, that define the typical structure of the GOP the implementation's rate control algorithm should expect. If `VK_VIDEO_ENCODE_H265_RATE_CONTROL_REGULAR_GOP_BIT_KHR` is also specified in `flags`, the implementation will expect all GOPs to follow this structure, while otherwise it may assume that the application will diverge from these values from time to time. If any of these values are zero, then the implementation's rate control algorithm will not make any assumptions about the corresponding parameter of the GOP structure. 315 316`subLayerCount` indicates the number of H.265 temporal sub-layers that the application intends to use and it is expected to match the number of rate control layers when multi-layer rate control is used. 317 318The following new structure can be included in the `pNext` chain of `VkVideoEncodeRateControlLayerInfoKHR` to specify additional per-rate-control-layer guidance parameters specific to H.265 encode: 319 320[source,c] 321---- 322typedef struct VkVideoEncodeH265RateControlLayerInfoKHR { 323 VkStructureType sType; 324 const void* pNext; 325 VkBool32 useMinQp; 326 VkVideoEncodeH265QpKHR minQp; 327 VkBool32 useMaxQp; 328 VkVideoEncodeH265QpKHR maxQp; 329 VkBool32 useMaxFrameSize; 330 VkVideoEncodeH265FrameSizeKHR maxFrameSize; 331} VkVideoEncodeH265RateControlLayerInfoKHR; 332---- 333 334When `useMinQp` is set to `VK_TRUE`, `minQp` specifies the lower bound on the QP values, for each picture type, that the implementation's rate control algorithm should use. Similarly, when `useMaxQp` is set to `VK_TRUE`, `maxQp` specifies the upper bound on the QP values. 335 336When `useMaxFrameSize` is set to `VK_TRUE`, `maxFrameSize` specifies the maximum frame size in bytes, for each picture type, that the implementation's rate control algorithm should target. 337 338Some implementations may benefit from or require additional guidance on the remaining number of frames in the currently encoded GOP, as indicated by the `prefersGopRemainingFrames` and `requiresGopRemainingFrames` capabilities, respectively. This may be the case either due to the implementation not being able to track the current position of the encoded stream within the GOP, or because the implementation may be able to use this information to better react to dynamic changes to the GOP structure. This proposal solves this by introducing the following new structure that can be included in the `pNext` chain of `VkVideoBeginCodingInfoKHR`: 339 340[source,c] 341---- 342typedef struct VkVideoEncodeH265GopRemainingFrameInfoKHR { 343 VkStructureType sType; 344 const void* pNext; 345 VkBool32 useGopRemainingFrames; 346 uint32_t gopRemainingI; 347 uint32_t gopRemainingP; 348 uint32_t gopRemainingB; 349} VkVideoEncodeH265GopRemainingFrameInfoKHR; 350---- 351 352When `useGopRemainingFrames` is set to `VK_TRUE`, the implementation's rate control algorithm may use the values specified in `gopRemainingI`, `gopRemainingP`, and `gopRemainingB` as a guidance on the number of remaining frames of the corresponding type in the currently encoded GOP. 353 354 355== Examples 356 357=== Select queue family with H.265 encode support 358 359[source,c] 360---- 361uint32_t queueFamilyIndex; 362uint32_t queueFamilyCount; 363 364vkGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyCount, NULL); 365 366VkQueueFamilyProperties2* props = calloc(queueFamilyCount, 367 sizeof(VkQueueFamilyProperties2)); 368VkQueueFamilyVideoPropertiesKHR* videoProps = calloc(queueFamilyCount, 369 sizeof(VkQueueFamilyVideoPropertiesKHR)); 370 371for (queueFamilyIndex = 0; queueFamilyIndex < queueFamilyCount; ++queueFamilyIndex) { 372 props[queueFamilyIndex].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2; 373 props[queueFamilyIndex].pNext = &videoProps[queueFamilyIndex]; 374 375 videoProps[queueFamilyIndex].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR; 376} 377 378vkGetPhysicalDeviceQueueFamilyProperties2(physicalDevice, &queueFamilyCount, props); 379 380for (queueFamilyIndex = 0; queueFamilyIndex < queueFamilyCount; ++queueFamilyIndex) { 381 if ((props[queueFamilyIndex].queueFamilyProperties.queueFlags & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) != 0 && 382 (videoProps[queueFamilyIndex].videoCodecOperations & VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR) != 0) { 383 break; 384 } 385} 386 387if (queueFamilyIndex < queueFamilyCount) { 388 // Found appropriate queue family 389 ... 390} else { 391 // Did not find a queue family with the needed capabilities 392 ... 393} 394---- 395 396 397=== Check support and query the capabilities for an H.265 encode profile 398 399[source,c] 400---- 401VkResult result; 402 403VkVideoEncodeH265ProfileInfoKHR encodeH265ProfileInfo = { 404 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR, 405 .pNext = NULL, 406 .stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN 407}; 408 409VkVideoProfileInfoKHR profileInfo = { 410 .sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, 411 .pNext = &encodeH265ProfileInfo, 412 .videoCodecOperation = VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR, 413 .chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR, 414 .lumaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, 415 .chromaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR 416}; 417 418VkVideoEncodeH265CapabilitiesKHR encodeH265Capabilities = { 419 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_KHR, 420 .pNext = NULL, 421}; 422 423VkVideoEncodeCapabilitiesKHR encodeCapabilities = { 424 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR, 425 .pNext = &encodeH265Capabilities 426} 427 428VkVideoCapabilitiesKHR capabilities = { 429 .sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR, 430 .pNext = &encodeCapabilities 431}; 432 433result = vkGetPhysicalDeviceVideoCapabilitiesKHR(physicalDevice, &profileInfo, &capabilities); 434 435if (result == VK_SUCCESS) { 436 // Profile is supported, check additional capabilities 437 ... 438} else { 439 // Profile is not supported, result provides additional information about why 440 ... 441} 442---- 443 444=== Create and update H.265 video session parameters objects 445 446[source,c] 447---- 448VkVideoSessionParametersKHR videoSessionParams = VK_NULL_HANDLE; 449 450VkVideoEncodeH265SessionParametersCreateInfoKHR encodeH265CreateInfo = { 451 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR, 452 .pNext = NULL, 453 .maxStdVPSCount = ... // VPS capacity 454 .maxStdSPSCount = ... // SPS capacity 455 .maxStdPPSCount = ... // PPS capacity 456 .pParametersAddInfo = ... // parameters to add at creation time or NULL 457}; 458 459VkVideoSessionParametersCreateInfoKHR createInfo = { 460 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR, 461 .pNext = &encodeH265CreateInfo, 462 .flags = 0, 463 .videoSessionParametersTemplate = ... // template to use or VK_NULL_HANDLE 464 .videoSession = videoSession 465}; 466 467vkCreateVideoSessionParametersKHR(device, &createInfo, NULL, &videoSessionParams); 468 469... 470 471StdVideoH265VideoParameterSet vps = {}; 472// parse and populate VPS parameters 473... 474 475StdVideoH265SequenceParameterSet sps = {}; 476// parse and populate SPS parameters 477... 478 479StdVideoH265PictureParameterSet pps = {}; 480// parse and populate PPS parameters 481... 482 483VkVideoEncodeH265SessionParametersAddInfoKHR encodeH265AddInfo = { 484 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR, 485 .pNext = NULL, 486 .stdVPSCount = 1, 487 .pStdVPSs = &vps, 488 .stdSPSCount = 1, 489 .pStdSPSs = &sps, 490 .stdPPSCount = 1, 491 .pStdPPSs = &pps 492}; 493 494VkVideoSessionParametersUpdateInfoKHR updateInfo = { 495 .sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR, 496 .pNext = &encodeH265AddInfo, 497 .updateSequenceCount = 1 // incremented for each subsequent update 498}; 499 500vkUpdateVideoSessionParametersKHR(device, &videoSessionParams, &updateInfo); 501---- 502 503 504=== Record H.265 encode operation producing an I frame that is also set up as a reference 505 506[source,c] 507---- 508// Bound reference resource list provided has to include reconstructed picture resource 509vkCmdBeginVideoCodingKHR(commandBuffer, ...); 510 511StdVideoEncodeH265ReferenceInfo stdReferenceInfo = {}; 512// Populate H.265 reference picture info for the reconstructed picture 513stdReferenceInfo.pic_type = STD_VIDEO_H265_PICTURE_TYPE_I; 514... 515 516VkVideoEncodeH265DpbSlotInfoKHR encodeH265DpbSlotInfo = { 517 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR, 518 .pNext = NULL, 519 .pStdReferenceInfo = &stdReferenceInfo 520}; 521 522VkVideoReferenceSlotInfoKHR setupSlotInfo = { 523 .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR, 524 .pNext = &encodeH265DpbSlotInfo 525 ... 526}; 527 528StdVideoEncodeH265ReferenceListsInfo stdRefListInfo = {}; 529// No references are used so just initialize the RefPicLists 530for (uint32_t i = 0; i < STD_VIDEO_H265_MAX_NUM_LIST_REF; ++i) { 531 stdRefListInfo.RefPicList0[i] = STD_VIDEO_H265_NO_REFERENCE_PICTURE; 532 stdRefListInfo.RefPicList1[i] = STD_VIDEO_H265_NO_REFERENCE_PICTURE; 533} 534// Populate other H.265 reference list parameters 535... 536 537StdVideoEncodeH265PictureInfo stdPictureInfo = {}; 538// Populate H.265 picture info for the encode input picture 539... 540// Make sure that the reconstructed picture is requested to be set up as reference 541stdPictureInfo.flags.is_reference = 1; 542... 543stdPictureInfo.pic_type = STD_VIDEO_H265_PICTURE_TYPE_I; 544... 545stdPictureInfo.pRefLists = &stdRefListInfo; 546... 547 548VkVideoEncodeH265PictureInfoKHR encodeH265PictureInfo = { 549 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR, 550 .pNext = NULL, 551 .naluSliceSegmentEntryCount = ... // number of slice segments to encode 552 .pNaluSliceSegmentEntries = ... // pointer to the array of slice segment parameters 553 .pStdPictureInfo = &stdPictureInfo 554}; 555 556VkVideoEncodeInfoKHR encodeInfo = { 557 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR, 558 .pNext = &encodeH265PictureInfo, 559 ... 560 .pSetupReferenceSlot = &setupSlotInfo, 561 ... 562}; 563 564vkCmdEncodeVideoKHR(commandBuffer, &encodeInfo); 565 566vkCmdEndVideoCodingKHR(commandBuffer, ...); 567---- 568 569 570=== Record H.265 encode operation producing a P frame with a single backward reference 571 572[source,c] 573---- 574// Bound reference resource list provided has to include the used reference picture resource 575vkCmdBeginVideoCodingKHR(commandBuffer, ...); 576 577StdVideoEncodeH265ReferenceInfo stdBackwardReferenceInfo = {}; 578// Populate H.265 reference picture info for the backward referenced picture 579... 580 581VkVideoEncodeH265DpbSlotInfoKHR encodeH265DpbSlotInfo = { 582 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR, 583 .pNext = NULL, 584 .pStdReferenceInfo = &stdBackwardReferenceInfo 585}; 586 587VkVideoReferenceSlotInfoKHR referenceSlotInfo = { 588 .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR, 589 .pNext = &encodeH265DpbSlotInfo, 590 .slotIndex = ... // DPB slot index of the backward reference picture 591 ... 592}; 593 594StdVideoEncodeH265ReferenceListsInfo stdRefListInfo = {}; 595// Initialize the RefPicLists and add the backward reference to the L0 list 596for (uint32_t i = 0; i < STD_VIDEO_H265_MAX_NUM_LIST_REF; ++i) { 597 stdRefListInfo.RefPicList0[i] = STD_VIDEO_H265_NO_REFERENCE_PICTURE; 598 stdRefListInfo.RefPicList1[i] = STD_VIDEO_H265_NO_REFERENCE_PICTURE; 599} 600stdRefListInfo.RefPicList0[0] = ... // DPB slot index of the backward reference picture 601// Populate other H.265 reference list parameters 602... 603 604StdVideoEncodeH265PictureInfo stdPictureInfo = {}; 605// Populate H.265 picture info for the encode input picture 606... 607stdPictureInfo.pic_type = STD_VIDEO_H265_PICTURE_TYPE_P; 608... 609stdPictureInfo.pRefLists = &stdRefListInfo; 610... 611 612VkVideoEncodeH265PictureInfoKHR encodeH265PictureInfo = { 613 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR, 614 .pNext = NULL, 615 .naluSliceSegmentEntryCount = ... // number of slice segments to encode 616 .pNaluSliceSegmentEntries = ... // pointer to the array of slice segment parameters 617 .pStdPictureInfo = &stdPictureInfo 618}; 619 620VkVideoEncodeInfoKHR encodeInfo = { 621 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR, 622 .pNext = &encodeH265PictureInfo, 623 ... 624 .referenceSlotCount = 1, 625 .pReferenceSlots = &referenceSlotInfo 626}; 627 628vkCmdEncodeVideoKHR(commandBuffer, &encodeInfo); 629 630vkCmdEndVideoCodingKHR(commandBuffer, ...); 631---- 632 633 634=== Record H.265 encode operation producing a B frame with a forward and a backward reference 635 636[source,c] 637---- 638// Bound reference resource list provided has to include the used reference picture resources 639vkCmdBeginVideoCodingKHR(commandBuffer, ...); 640 641StdVideoEncodeH265ReferenceInfo stdBackwardReferenceInfo = {}; 642// Populate H.265 reference picture info for the backward referenced picture 643... 644 645StdVideoEncodeH265ReferenceInfo stdForwardReferenceInfo = {}; 646// Populate H.265 reference picture info for the forward referenced picture 647... 648 649VkVideoEncodeH265DpbSlotInfoKHR encodeH265DpbSlotInfo[] = { 650 { 651 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR, 652 .pNext = NULL, 653 .pStdReferenceInfo = &stdBackwardReferenceInfo 654 }, 655 { 656 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR, 657 .pNext = NULL, 658 .pStdReferenceInfo = &stdForwardReferenceInfo 659 } 660}; 661 662VkVideoReferenceSlotInfoKHR referenceSlotInfo[] = { 663 { 664 .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR, 665 .pNext = &encodeH265DpbSlotInfo[0], 666 .slotIndex = ... // DPB slot index of the backward reference picture 667 ... 668 }, 669 { 670 .sType = VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR, 671 .pNext = &encodeH265DpbSlotInfo[1], 672 .slotIndex = ... // DPB slot index of the forward reference picture 673 ... 674 } 675}; 676 677StdVideoEncodeH265ReferenceListsInfo stdRefListInfo = {}; 678// Initialize the RefPicLists, add the backward reference to the L0 list, 679// and add the forward reference to the L1 list 680for (uint32_t i = 0; i < STD_VIDEO_H265_MAX_NUM_LIST_REF; ++i) { 681 stdRefListInfo.RefPicList0[i] = STD_VIDEO_H265_NO_REFERENCE_PICTURE; 682 stdRefListInfo.RefPicList1[i] = STD_VIDEO_H265_NO_REFERENCE_PICTURE; 683} 684stdRefListInfo.RefPicList0[0] = ... // DPB slot index of the backward reference picture 685stdRefListInfo.RefPicList1[0] = ... // DPB slot index of the forward reference picture 686// Populate other H.265 reference list parameters 687... 688 689StdVideoEncodeH265PictureInfo stdPictureInfo = {}; 690// Populate H.265 picture info for the encode input picture 691... 692stdPictureInfo.pic_type = STD_VIDEO_H265_PICTURE_TYPE_B; 693... 694stdPictureInfo.pRefLists = &stdRefListInfo; 695... 696 697VkVideoEncodeH265PictureInfoKHR encodeH265PictureInfo = { 698 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR, 699 .pNext = NULL, 700 .naluSliceSegmentEntryCount = ... // number of slice segments to encode 701 .pNaluSliceSegmentEntries = ... // pointer to the array of slice segment parameters 702 .pStdPictureInfo = &stdPictureInfo 703}; 704 705VkVideoEncodeInfoKHR encodeInfo = { 706 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR, 707 .pNext = &encodeH265PictureInfo, 708 ... 709 .referenceSlotCount = sizeof(referenceSlotInfo) / sizeof(referenceSlotInfo[0]), 710 .pReferenceSlots = &referenceSlotInfo[0] 711}; 712 713vkCmdEncodeVideoKHR(commandBuffer, &encodeInfo); 714 715vkCmdEndVideoCodingKHR(commandBuffer, ...); 716---- 717 718 719=== Change the rate control configuration of an H.265 encode session with optional H.265 controls 720 721[source,c] 722---- 723vkCmdBeginVideoCodingKHR(commandBuffer, ...); 724 725// Include the optional H.265 rate control layer information 726// In this example we restrict the QP range to be used by the implementation 727VkVideoEncodeH265RateControlLayerInfoKHR rateControlLayersH265[] = { 728 { 729 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_KHR, 730 .pNext = NULL, 731 .useMinQp = VK_TRUE, 732 .minQp = { /* min I frame QP */, /* min P frame QP */, /* min B frame QP */ }, 733 .useMaxQp = VK_TRUE, 734 .minQp = { /* max I frame QP */, /* max P frame QP */, /* max B frame QP */ }, 735 .useMaxFrameSize = VK_FALSE, 736 .maxFrameSize = { 0, 0, 0 } 737 }, 738 ... 739}; 740 741VkVideoEncodeRateControlLayerInfoKHR rateControlLayers[] = { 742 { 743 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR, 744 .pNext = &rateControlLayersH265[0], 745 ... 746 }, 747 ... 748}; 749 750// Include the optional H.265 global rate control information 751VkVideoEncodeH265RateControlInfoKHR rateControlInfoH265 = { 752 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_KHR, 753 .pNext = NULL, 754 .flags = VK_VIDEO_ENCODE_H265_RATE_CONTROL_REGULAR_GOP_BIT_KHR // Indicate the use of a regular GOP structure... 755 | VK_VIDEO_ENCODE_H265_RATE_CONTROL_TEMPORAL_SUB_LAYER_PATTERN_DYADIC_BIT_KHR, // ... and a dyadic temporal sub-layer pattern 756 // Indicate a GOP structure of the form IBBBPBBBPBBBI with an IDR frame at the beginning of every 10th GOP 757 .gopFrameCount = 12, 758 .idrPeriod = 120, 759 .consecutiveBFrameCount = 3, 760 // This example uses multiple temporal sub-layers with per layer rate control 761 .subLayerCount = sizeof(rateControlLayers) / sizeof(rateControlLayers[0]) 762}; 763 764VkVideoEncodeRateControlInfoKHR rateControlInfo = { 765 .sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR, 766 .pNext = &rateControlInfoH265, 767 ... 768 .layerCount = sizeof(rateControlLayers) / sizeof(rateControlLayers[0]), 769 .pLayers = rateControlLayers, 770 ... 771}; 772 773// Change the rate control configuration for the video session 774VkVideoCodingControlInfoKHR controlInfo = { 775 .sType = VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR, 776 .pNext = &rateControlInfo, 777 .flags = VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_BIT_KHR 778}; 779 780vkCmdControlVideoCodingKHR(commandBuffer, &controlInfo); 781 782... 783 784vkCmdEndVideoCodingKHR(commandBuffer, ...); 785---- 786 787 788== Issues 789 790=== RESOLVED: In what form should codec-specific parameters be provided? 791 792In the form of structures defined by the `vulkan_video_codec_h265std_encode` and `vulkan_video_codec_h265std` video std headers. Applications are responsible to populate the structures defined by the video std headers. It is also the application's responsibility to maintain and manage these data structures, as needed, to be able to provide them as inputs to video encode operations where needed. 793 794 795=== RESOLVED: Why the `vulkan_video_codec_h265std` video std header does not have a version number? 796 797The `vulkan_video_codec_h265std` video std header was introduced to share common definitions used in both H.265/HEVC video decoding and video encoding, as the two functionalities were designed in parallel. However, as no video coding extension uses this video std header directly, only as a dependency of the video std header specific to the particular video coding operation, no separate versioning scheme was deemed necessary. 798 799 800=== RESOLVED: What are the requirements for the codec-specific input parameters? 801 802It is legal from an API usage perspective for the application to provide any values for the codec-specific input parameters (parameter sets, picture information, etc.). However, if the input data does not conform to the requirements of the H.265/HEVC video compression standard, then video encode operations may complete unsuccessfully and, in general, the outputs produced by the video encode operation will have undefined contents. 803 804In addition, certain commands may return the `VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR` error if any of the specified codec-specific parameters do not adhere to the syntactic or semantic requirements of the H.265/HEVC video compression standard or if values derived from parameters according to the rules defined by the H.265/HEVC video compression standard do not adhere to the capabilities of the H.265/HEVC video compression standard or the implementation. In particular, in this extension the following commands may return this error code: 805 806 * `vkCreateVideoSessionParametersKHR` or `vkUpdateVideoSessionParametersKHR` - if the specified parameter sets are invalid according to these rules 807 * `vkEndCommandBuffer` - if the codec-specific picture information provided to video encode operations are invalid according to these rules 808 809Generating errors in the cases above, however, is not required so applications should not rely on receiving an error code for the purposes of verifying the correctness of the used codec-specific parameters. 810 811 812=== RESOLVED: Do we want to allow the application to specify separate reference lists for each slice segment? 813 814Not in this extension. While the H.265/HEVC video compression standard seems to support this, such flexibility is not exposed here for the sake of simplicity. If the need arises to support per slice segment reference lists, a layered extension can introduce the necessary APIs to enable it. 815 816 817=== RESOLVED: Are generalized P and B frames (aka low delay B frames) supported? 818 819Yes, in fact, some implementations do not support encoding P frames but do support encoding B frames with backward-only references. In order to maximize portability, applications should check for B frame support and use low delay B frames to encode frames with backward-only references even when P frame support is not available on a given implementation. 820 821 822=== RESOLVED: What codec-specific parameters are guaranteed to not be overridden by implementations? 823 824This proposal only requires that implementations do not override the `pic_type` and `slice_type` parameters, as the used picture and slice types are fundamental to the general operation of H.265 encoding. In addition, bits set in the `stdSyntaxFlags` capability provide additional guarantees about other Video Std parameters that the implementation will use without overriding them. No further restrictions are included in this extension regarding codec-specific parameter overrides, however, future extensions may include capability flags providing additional guarantees based on the needs of the users of the API. 825 826 827=== RESOLVED: Can implementations override the values of `pic_width_in_luma_samples` and/or `pic_height_in_luma_samples`? 828 829Yes. Implementations may have limitations on the size of the coding blocks they can produce within CTBs amongst other implementation-specific alignment limitations which may require overriding the values of `pic_width_in_luma_samples` and/or `pic_height_in_luma_samples`. This can be safely done without affecting the effective coded extent of the encoded frames by making corresponding adjustments to the values of `conf_win_right_offset` and/or `conf_win_bottom_offset`. Allowing implementations to perform such codec-specific parameter overrides enables better portability and avoids the need for application developers having to navigate an unnecessarily complex set of capabilities that would otherwise be necessary to account for the quirks of individual hardware implementations. 830 831 832=== RESOLVED: How is reference picture setup requested for H.265 encode operations? 833 834As specifying a reconstructed picture DPB slot and resource is always required per the latest revision of the video extensions, additional codec syntax controls whether reference picture setup is requested and, in response, the DPB slot is activated with the reconstructed picture. 835 836For H.265 encode, reference picture setup is requested and the DPB slot specified for the reconstructed picture is activated with the picture if and only if the `StdVideoEncodeH265PictureInfo::flags.is_reference` flag is set. 837 838 839== Further Functionality 840 841Future extensions can further extend the capabilities provided here, e.g. exposing support for encode modes allowing per-slice-segment input and/or output. 842