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_NALU_WRITER_H264_H 25 #define D3D12_VIDEO_ENC_NALU_WRITER_H264_H 26 27 #include "d3d12_video_encoder_bitstream.h" 28 29 enum H264_NALREF_IDC 30 { 31 NAL_REFIDC_REF = 3, 32 NAL_REFIDC_NONREF = 0 33 }; 34 35 enum H264_NALU_TYPE 36 { 37 NAL_TYPE_UNSPECIFIED = 0, 38 NAL_TYPE_SLICE = 1, 39 NAL_TYPE_SLICEDATA_A = 2, 40 NAL_TYPE_SLICEDATA_B = 3, 41 NAL_TYPE_SLICEDATA_C = 4, 42 NAL_TYPE_IDR = 5, 43 NAL_TYPE_SEI = 6, 44 NAL_TYPE_SPS = 7, 45 NAL_TYPE_PPS = 8, 46 NAL_TYPE_ACCESS_UNIT_DELIMITER = 9, 47 NAL_TYPE_END_OF_SEQUENCE = 10, 48 NAL_TYPE_END_OF_STREAM = 11, 49 NAL_TYPE_FILLER_DATA = 12, 50 NAL_TYPE_SPS_EXTENSION = 13, 51 NAL_TYPE_PREFIX = 14, 52 /* 15...18 RESERVED */ 53 NAL_TYPE_AUXILIARY_SLICE = 19, 54 /* 20...23 RESERVED */ 55 /* 24...31 UNSPECIFIED */ 56 }; 57 58 typedef struct 59 { 60 // nal header 61 H264_NALREF_IDC nal_ref_idc; 62 63 // nal_unit_header_svc_extension( ) 64 uint32_t idr_flag; // u(1) 65 uint32_t priority_id; // u(6) 66 uint32_t no_inter_layer_pred_flag; // u(1) 67 uint32_t dependency_id; // u(3) 68 uint32_t quality_id; // u(4) 69 uint32_t temporal_id; // u(3) 70 uint32_t use_ref_base_pic_flag; // u(1) 71 uint32_t discardable_flag; // u(1) 72 uint32_t output_flag; // u(1) 73 // uint32_t reserved_three_2bits; // u(2) 74 75 // prefix_nal_unit_svc ( ) 76 uint32_t store_ref_base_pic_flag; // u(1) 77 // uint32_t additional_prefix_nal_unit_extension_flag; // u(1) 78 } H264_SLICE_PREFIX_SVC; 79 80 enum H264_SEI_TYPE 81 { 82 H264_SEI_SCALABILITY_INFO = 24, 83 }; 84 85 typedef struct 86 { 87 uint32_t num_layers_minus1; // ue(v) 88 uint32_t temporal_id[/* as per codec spec num_layers_minus1 range */ 2048]; // u(3) 89 } H264_SEI_SCALABILITYINFO; 90 91 typedef struct H264_SEI_MESSAGE 92 { 93 H264_SEI_TYPE payload_type; 94 union 95 { 96 H264_SEI_SCALABILITYINFO scalability_info; 97 }; 98 } H264_SEI_MESSAGE; 99 100 typedef struct H264_HRD_PARAMS 101 { 102 uint32_t cpb_cnt_minus1; 103 uint32_t bit_rate_scale; 104 uint32_t cpb_size_scale; 105 uint32_t bit_rate_value_minus1[32]; 106 uint32_t cpb_size_value_minus1[32]; 107 uint32_t cbr_flag[32]; 108 uint32_t initial_cpb_removal_delay_length_minus1; 109 uint32_t cpb_removal_delay_length_minus1; 110 uint32_t dpb_output_delay_length_minus1; 111 uint32_t time_offset_length; 112 } H264_HRD_PARAMS; 113 114 struct H264_VUI_PARAMS 115 { 116 uint32_t aspect_ratio_info_present_flag; 117 uint32_t aspect_ratio_idc; 118 uint32_t sar_width; 119 uint32_t sar_height; 120 uint32_t overscan_info_present_flag; 121 uint32_t overscan_appropriate_flag; 122 uint32_t video_signal_type_present_flag; 123 uint32_t video_format; 124 uint32_t video_full_range_flag; 125 uint32_t colour_description_present_flag; 126 uint32_t colour_primaries; 127 uint32_t transfer_characteristics; 128 uint32_t matrix_coefficients; 129 uint32_t chroma_loc_info_present_flag; 130 uint32_t chroma_sample_loc_type_top_field; 131 uint32_t chroma_sample_loc_type_bottom_field; 132 uint32_t timing_info_present_flag; 133 uint32_t time_scale; 134 uint32_t num_units_in_tick; 135 uint32_t fixed_frame_rate_flag; 136 uint32_t nal_hrd_parameters_present_flag; 137 H264_HRD_PARAMS nal_hrd_parameters; 138 uint32_t vcl_hrd_parameters_present_flag; 139 H264_HRD_PARAMS vcl_hrd_parameters; 140 uint32_t low_delay_hrd_flag; 141 uint32_t pic_struct_present_flag; 142 uint32_t bitstream_restriction_flag; 143 uint32_t motion_vectors_over_pic_boundaries_flag; 144 uint32_t max_bytes_per_pic_denom; 145 uint32_t max_bits_per_mb_denom; 146 uint32_t log2_max_mv_length_vertical; 147 uint32_t log2_max_mv_length_horizontal; 148 uint32_t num_reorder_frames; 149 uint32_t max_dec_frame_buffering; 150 }; 151 152 struct H264_SPS 153 { 154 uint32_t profile_idc; 155 uint32_t constraint_set_flags; 156 uint32_t level_idc; 157 uint32_t seq_parameter_set_id; 158 uint32_t bit_depth_luma_minus8; 159 uint32_t bit_depth_chroma_minus8; 160 uint32_t log2_max_frame_num_minus4; 161 uint32_t pic_order_cnt_type; 162 uint32_t log2_max_pic_order_cnt_lsb_minus4; 163 uint32_t max_num_ref_frames; 164 uint32_t gaps_in_frame_num_value_allowed_flag; 165 uint32_t pic_width_in_mbs_minus1; 166 uint32_t pic_height_in_map_units_minus1; 167 uint32_t direct_8x8_inference_flag; 168 uint32_t frame_cropping_flag; 169 uint32_t frame_cropping_rect_left_offset; 170 uint32_t frame_cropping_rect_right_offset; 171 uint32_t frame_cropping_rect_top_offset; 172 uint32_t frame_cropping_rect_bottom_offset; 173 uint32_t vui_parameters_present_flag; 174 H264_VUI_PARAMS vui; 175 }; 176 177 struct H264_PPS 178 { 179 uint32_t pic_parameter_set_id; 180 uint32_t seq_parameter_set_id; 181 uint32_t entropy_coding_mode_flag; 182 uint32_t pic_order_present_flag; 183 uint32_t num_ref_idx_l0_active_minus1; 184 uint32_t num_ref_idx_l1_active_minus1; 185 uint32_t constrained_intra_pred_flag; 186 uint32_t transform_8x8_mode_flag; 187 }; 188 189 enum H264_SPEC_PROFILES 190 { 191 // Same as BASELINE (66) with constraint_set1_flag set 192 H264_PROFILE_CONSTRAINED_BASELINE = 66, 193 H264_PROFILE_BASELINE = 66, 194 H264_PROFILE_MAIN = 77, 195 H264_PROFILE_HIGH = 100, 196 H264_PROFILE_HIGH10 = 110, 197 }; 198 199 #define MAX_COMPRESSED_PPS 256 200 #define MAX_COMPRESSED_SPS 256 201 202 class d3d12_video_nalu_writer_h264 203 { 204 public: d3d12_video_nalu_writer_h264()205 d3d12_video_nalu_writer_h264() 206 { } ~d3d12_video_nalu_writer_h264()207 ~d3d12_video_nalu_writer_h264() 208 { } 209 210 // Writes the H264 SPS structure into a bitstream passed in headerBitstream 211 // Function resizes bitstream accordingly and puts result in byte vector 212 void sps_to_nalu_bytes(H264_SPS * pSPS, 213 std::vector<uint8_t> & headerBitstream, 214 std::vector<uint8_t>::iterator placingPositionStart, 215 size_t & writtenBytes); 216 217 // Writes the H264 PPS structure into a bitstream passed in headerBitstream 218 // Function resizes bitstream accordingly and puts result in byte vector 219 void pps_to_nalu_bytes(H264_PPS * pPPS, 220 std::vector<uint8_t> & headerBitstream, 221 BOOL bIsFREXTProfile, 222 std::vector<uint8_t>::iterator placingPositionStart, 223 size_t & writtenBytes); 224 225 void write_end_of_stream_nalu(std::vector<uint8_t> & headerBitstream, 226 std::vector<uint8_t>::iterator placingPositionStart, 227 size_t & writtenBytes); 228 void write_end_of_sequence_nalu(std::vector<uint8_t> & headerBitstream, 229 std::vector<uint8_t>::iterator placingPositionStart, 230 size_t & writtenBytes); 231 232 void write_access_unit_delimiter_nalu(std::vector<uint8_t> & headerBitstream, 233 std::vector<uint8_t>::iterator placingPositionStart, 234 size_t & writtenBytes); 235 void write_sei_nalu(H264_SEI_MESSAGE sei_message, 236 std::vector<uint8_t> & headerBitstream, 237 std::vector<uint8_t>::iterator placingPositionStart, 238 size_t & writtenBytes); 239 240 void write_slice_svc_prefix(const H264_SLICE_PREFIX_SVC & nal_svc_prefix, 241 std::vector<uint8_t> & headerBitstream, 242 std::vector<uint8_t>::iterator placingPositionStart, 243 size_t & writtenBytes); 244 245 private: 246 // Writes from structure into bitstream with RBSP trailing but WITHOUT NAL unit wrap (eg. nal_idc_type, etc) 247 uint32_t write_sps_bytes(d3d12_video_encoder_bitstream *pBitstream, H264_SPS *pSPS); 248 uint32_t write_pps_bytes(d3d12_video_encoder_bitstream *pBitstream, H264_PPS *pPPS, BOOL bIsFREXTProfile); 249 250 // Adds NALU wrapping into structures and ending NALU control bits 251 uint32_t wrap_sps_nalu(d3d12_video_encoder_bitstream *pNALU, d3d12_video_encoder_bitstream *pRBSP); 252 uint32_t wrap_pps_nalu(d3d12_video_encoder_bitstream *pNALU, d3d12_video_encoder_bitstream *pRBSP); 253 254 // Helpers 255 void write_hrd(d3d12_video_encoder_bitstream *pBitstream, H264_HRD_PARAMS *pHrd); 256 void write_nalu_end(d3d12_video_encoder_bitstream *pNALU); 257 void rbsp_trailing(d3d12_video_encoder_bitstream *pBitstream); 258 uint32_t wrap_rbsp_into_nalu(d3d12_video_encoder_bitstream *pNALU, 259 d3d12_video_encoder_bitstream *pRBSP, 260 uint32_t iNaluIdc, 261 uint32_t iNaluType, 262 const H264_SLICE_PREFIX_SVC* pSvcExtendedHeader = NULL); 263 }; 264 265 #endif 266