1 /* 2 * Copyright © Microsoft Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #ifndef D3D12_VIDEO_ENC_H 25 #define D3D12_VIDEO_ENC_H 26 27 #include "d3d12_video_types.h" 28 #include "d3d12_video_encoder_references_manager.h" 29 #include "d3d12_video_dpb_storage_manager.h" 30 #include "d3d12_video_encoder_bitstream_builder_h264.h" 31 32 /// 33 /// Pipe video interface starts 34 /// 35 36 /** 37 * creates a video encoder 38 */ 39 struct pipe_video_codec * 40 d3d12_video_encoder_create_encoder(struct pipe_context *context, const struct pipe_video_codec *templ); 41 42 /** 43 * destroy this video encoder 44 */ 45 void 46 d3d12_video_encoder_destroy(struct pipe_video_codec *codec); 47 48 /** 49 * start encoding of a new frame 50 */ 51 void 52 d3d12_video_encoder_begin_frame(struct pipe_video_codec * codec, 53 struct pipe_video_buffer *target, 54 struct pipe_picture_desc *picture); 55 56 /** 57 * encode to a bitstream 58 */ 59 void 60 d3d12_video_encoder_encode_bitstream(struct pipe_video_codec * codec, 61 struct pipe_video_buffer *source, 62 struct pipe_resource * destination, 63 void ** feedback); 64 65 /** 66 * get encoder feedback 67 */ 68 void 69 d3d12_video_encoder_get_feedback(struct pipe_video_codec *codec, void *feedback, unsigned *size); 70 71 /** 72 * end encoding of the current frame 73 */ 74 void 75 d3d12_video_encoder_end_frame(struct pipe_video_codec * codec, 76 struct pipe_video_buffer *target, 77 struct pipe_picture_desc *picture); 78 79 /** 80 * flush any outstanding command buffers to the hardware 81 * should be called before a video_buffer is acessed by the gallium frontend again 82 */ 83 void 84 d3d12_video_encoder_flush(struct pipe_video_codec *codec); 85 86 /// 87 /// Pipe video interface ends 88 /// 89 90 enum d3d12_video_encoder_config_dirty_flags 91 { 92 d3d12_video_encoder_config_dirty_flag_none = 0x0, 93 d3d12_video_encoder_config_dirty_flag_codec = 0x1, 94 d3d12_video_encoder_config_dirty_flag_profile = 0x2, 95 d3d12_video_encoder_config_dirty_flag_level = 0x4, 96 d3d12_video_encoder_config_dirty_flag_codec_config = 0x8, 97 d3d12_video_encoder_config_dirty_flag_input_format = 0x10, 98 d3d12_video_encoder_config_dirty_flag_resolution = 0x20, 99 d3d12_video_encoder_config_dirty_flag_rate_control = 0x40, 100 d3d12_video_encoder_config_dirty_flag_slices = 0x80, 101 d3d12_video_encoder_config_dirty_flag_gop = 0x100, 102 d3d12_video_encoder_config_dirty_flag_motion_precision_limit = 0x200, 103 }; 104 DEFINE_ENUM_FLAG_OPERATORS(d3d12_video_encoder_config_dirty_flags); 105 106 /// 107 /// d3d12_video_encoder functions starts 108 /// 109 110 struct d3d12_video_encoder 111 { 112 struct pipe_video_codec base; 113 struct pipe_screen * m_screen; 114 struct d3d12_screen * m_pD3D12Screen; 115 116 /// 117 /// D3D12 objects and context info 118 /// 119 120 const uint m_NodeMask = 0u; 121 const uint m_NodeIndex = 0u; 122 123 ComPtr<ID3D12Fence> m_spFence; 124 uint m_fenceValue = 1u; 125 126 ComPtr<ID3D12VideoDevice3> m_spD3D12VideoDevice; 127 ComPtr<ID3D12VideoEncoder> m_spVideoEncoder; 128 ComPtr<ID3D12VideoEncoderHeap> m_spVideoEncoderHeap; 129 ComPtr<ID3D12CommandQueue> m_spEncodeCommandQueue; 130 ComPtr<ID3D12CommandAllocator> m_spCommandAllocator; 131 ComPtr<ID3D12VideoEncodeCommandList2> m_spEncodeCommandList; 132 std::vector<D3D12_RESOURCE_BARRIER> m_transitionsBeforeCloseCmdList; 133 134 std::unique_ptr<d3d12_video_encoder_references_manager_interface> m_upDPBManager; 135 std::unique_ptr<d3d12_video_dpb_storage_manager_interface> m_upDPBStorageManager; 136 std::unique_ptr<d3d12_video_bitstream_builder_interface> m_upBitstreamBuilder; 137 138 bool m_needsGPUFlush = false; 139 140 ComPtr<ID3D12Resource> m_spResolvedMetadataBuffer; 141 ComPtr<ID3D12Resource> m_spMetadataOutputBuffer; 142 143 std::vector<uint8_t> m_BitstreamHeadersBuffer; 144 145 struct 146 { 147 bool m_fArrayOfTexturesDpb; 148 149 D3D12_VIDEO_ENCODER_SUPPORT_FLAGS m_SupportFlags; 150 D3D12_VIDEO_ENCODER_VALIDATION_FLAGS m_ValidationFlags; 151 D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOLUTION_SUPPORT_LIMITS m_currentResolutionSupportCaps; 152 union 153 { 154 D3D12_VIDEO_ENCODER_PROFILE_H264 m_H264Profile; 155 D3D12_VIDEO_ENCODER_PROFILE_HEVC m_HEVCProfile; 156 } m_encoderSuggestedProfileDesc = {}; 157 158 union 159 { 160 D3D12_VIDEO_ENCODER_LEVELS_H264 m_H264LevelSetting; 161 D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC m_HEVCLevelSetting; 162 } m_encoderLevelSuggestedDesc = {}; 163 164 // Required size for the layout-resolved metadata buffer of current frame to be encoded 165 size_t m_resolvedLayoutMetadataBufferRequiredSize; 166 167 // The maximum number of slices that the output of the current frame to be encoded will contain 168 uint32_t m_MaxSlicesInOutput; 169 170 D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS m_ResourceRequirementsCaps; 171 172 } m_currentEncodeCapabilities; 173 174 struct 175 { 176 d3d12_video_encoder_config_dirty_flags m_ConfigDirtyFlags = d3d12_video_encoder_config_dirty_flag_none; 177 178 D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC m_currentResolution = {}; 179 D3D12_BOX m_FrameCroppingCodecConfig = {}; 180 181 D3D12_FEATURE_DATA_FORMAT_INFO m_encodeFormatInfo = {}; 182 183 D3D12_VIDEO_ENCODER_CODEC m_encoderCodecDesc = {}; 184 185 D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAGS m_seqFlags = D3D12_VIDEO_ENCODER_SEQUENCE_CONTROL_FLAG_NONE; 186 187 /// As the following D3D12 Encode types have pointers in their structures, we need to keep a deep copy of them 188 189 union 190 { 191 D3D12_VIDEO_ENCODER_PROFILE_H264 m_H264Profile; 192 D3D12_VIDEO_ENCODER_PROFILE_HEVC m_HEVCProfile; 193 } m_encoderProfileDesc = {}; 194 195 union 196 { 197 D3D12_VIDEO_ENCODER_LEVELS_H264 m_H264LevelSetting; 198 D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC m_HEVCLevelSetting; 199 } m_encoderLevelDesc = {}; 200 201 struct 202 { 203 D3D12_VIDEO_ENCODER_RATE_CONTROL_MODE m_Mode; 204 D3D12_VIDEO_ENCODER_RATE_CONTROL_FLAGS m_Flags; 205 DXGI_RATIONAL m_FrameRate; 206 union 207 { 208 D3D12_VIDEO_ENCODER_RATE_CONTROL_CQP m_Configuration_CQP; 209 D3D12_VIDEO_ENCODER_RATE_CONTROL_CBR m_Configuration_CBR; 210 D3D12_VIDEO_ENCODER_RATE_CONTROL_VBR m_Configuration_VBR; 211 D3D12_VIDEO_ENCODER_RATE_CONTROL_QVBR m_Configuration_QVBR; 212 } m_Config; 213 } m_encoderRateControlDesc = {}; 214 215 union 216 { 217 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264 m_H264Config; 218 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC m_HEVCConfig; 219 } m_encoderCodecSpecificConfigDesc = {}; 220 221 222 D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE m_encoderSliceConfigMode; 223 union 224 { 225 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES m_SlicesPartition_H264; 226 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES m_SlicesPartition_HEVC; 227 } m_encoderSliceConfigDesc = {}; 228 229 union 230 { 231 D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_H264 m_H264GroupOfPictures; 232 D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_HEVC m_HEVCGroupOfPictures; 233 } m_encoderGOPConfigDesc = {}; 234 235 union 236 { 237 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_H264 m_H264PicData; 238 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC m_HEVCPicData; 239 } m_encoderPicParamsDesc = {}; 240 241 D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE m_encoderMotionPrecisionLimit = 242 D3D12_VIDEO_ENCODER_MOTION_ESTIMATION_PRECISION_MODE_MAXIMUM; 243 244 D3D12_VIDEO_ENCODER_INTRA_REFRESH m_IntraRefresh = { D3D12_VIDEO_ENCODER_INTRA_REFRESH_MODE_NONE, 0 }; 245 uint32_t m_IntraRefreshCurrentFrameIndex = 0; 246 247 } m_currentEncodeConfig; 248 }; 249 250 bool 251 d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc); 252 bool 253 d3d12_video_encoder_reconfigure_session(struct d3d12_video_encoder *pD3D12Enc, 254 struct pipe_video_buffer * srcTexture, 255 struct pipe_picture_desc * picture); 256 bool 257 d3d12_video_encoder_update_current_encoder_config_state(struct d3d12_video_encoder *pD3D12Enc, 258 struct pipe_video_buffer * srcTexture, 259 struct pipe_picture_desc * picture); 260 bool 261 d3d12_video_encoder_reconfigure_encoder_objects(struct d3d12_video_encoder *pD3D12Enc, 262 struct pipe_video_buffer * srcTexture, 263 struct pipe_picture_desc * picture); 264 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA 265 d3d12_video_encoder_get_current_picture_param_settings(struct d3d12_video_encoder *pD3D12Enc); 266 D3D12_VIDEO_ENCODER_LEVEL_SETTING 267 d3d12_video_encoder_get_current_level_desc(struct d3d12_video_encoder *pD3D12Enc); 268 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION 269 d3d12_video_encoder_get_current_codec_config_desc(struct d3d12_video_encoder *pD3D12Enc); 270 D3D12_VIDEO_ENCODER_PROFILE_DESC 271 d3d12_video_encoder_get_current_profile_desc(struct d3d12_video_encoder *pD3D12Enc); 272 D3D12_VIDEO_ENCODER_RATE_CONTROL 273 d3d12_video_encoder_get_current_rate_control_settings(struct d3d12_video_encoder *pD3D12Enc); 274 D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA 275 d3d12_video_encoder_get_current_slice_param_settings(struct d3d12_video_encoder *pD3D12Enc); 276 D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE 277 d3d12_video_encoder_get_current_gop_desc(struct d3d12_video_encoder *pD3D12Enc); 278 uint32_t 279 d3d12_video_encoder_get_current_max_dpb_capacity(struct d3d12_video_encoder *pD3D12Enc); 280 void 281 d3d12_video_encoder_create_reference_picture_manager(struct d3d12_video_encoder *pD3D12Enc); 282 void 283 d3d12_video_encoder_update_picparams_tracking(struct d3d12_video_encoder *pD3D12Enc, 284 struct pipe_video_buffer * srcTexture, 285 struct pipe_picture_desc * picture); 286 void 287 d3d12_video_encoder_calculate_metadata_resolved_buffer_size(uint32_t maxSliceNumber, size_t &bufferSize); 288 uint32_t 289 d3d12_video_encoder_calculate_max_slices_count_in_output( 290 D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE slicesMode, 291 const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_SUBREGIONS_LAYOUT_DATA_SLICES *slicesConfig, 292 uint32_t MaxSubregionsNumberFromCaps, 293 D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC sequenceTargetResolution, 294 uint32_t SubregionBlockPixelsSize); 295 bool 296 d3d12_video_encoder_prepare_output_buffers(struct d3d12_video_encoder *pD3D12Enc, 297 struct pipe_video_buffer * srcTexture, 298 struct pipe_picture_desc * picture); 299 uint32_t 300 d3d12_video_encoder_build_codec_headers(struct d3d12_video_encoder *pD3D12Enc); 301 void 302 d3d12_video_encoder_extract_encode_metadata( 303 struct d3d12_video_encoder * pD3D12Dec, 304 ID3D12Resource * pResolvedMetadataBuffer, 305 size_t resourceMetadataSize, 306 D3D12_VIDEO_ENCODER_OUTPUT_METADATA & encoderMetadata, 307 std::vector<D3D12_VIDEO_ENCODER_FRAME_SUBREGION_METADATA> &pSubregionsMetadata); 308 309 D3D12_VIDEO_ENCODER_CODEC 310 d3d12_video_encoder_get_current_codec(struct d3d12_video_encoder *pD3D12Enc); 311 312 bool d3d12_video_encoder_negotiate_requested_features_and_d3d12_driver_caps(struct d3d12_video_encoder *pD3D12Enc, D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT &capEncoderSupportData); 313 bool d3d12_video_encoder_query_d3d12_driver_caps(struct d3d12_video_encoder *pD3D12Enc, D3D12_FEATURE_DATA_VIDEO_ENCODER_SUPPORT &capEncoderSupportData); 314 bool d3d12_video_encoder_check_subregion_mode_support(struct d3d12_video_encoder *pD3D12Enc, D3D12_VIDEO_ENCODER_FRAME_SUBREGION_LAYOUT_MODE requestedSlicesMode); 315 316 /// 317 /// d3d12_video_encoder functions ends 318 /// 319 320 #endif 321