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 H264_HRD_PARAMS 59 { 60 uint32_t cpb_cnt_minus1; 61 uint32_t bit_rate_scale; 62 uint32_t cpb_size_scale; 63 uint32_t bit_rate_value_minus1[32]; 64 uint32_t cpb_size_value_minus1[32]; 65 uint32_t cbr_flag[32]; 66 uint32_t initial_cpb_removal_delay_length_minus1; 67 uint32_t cpb_removal_delay_length_minus1; 68 uint32_t dpb_output_delay_length_minus1; 69 uint32_t time_offset_length; 70 } H264_HRD_PARAMS; 71 72 struct H264_VUI_PARAMS 73 { 74 uint32_t aspect_ratio_info_present_flag; 75 uint32_t aspect_ratio_idc; 76 uint32_t sar_width; 77 uint32_t sar_height; 78 uint32_t overscan_info_present_flag; 79 uint32_t overscan_appropriate_flag; 80 uint32_t video_signal_type_present_flag; 81 uint32_t video_format; 82 uint32_t video_full_range_flag; 83 uint32_t colour_description_present_flag; 84 uint32_t colour_primaries; 85 uint32_t transfer_characteristics; 86 uint32_t matrix_coefficients; 87 uint32_t chroma_loc_info_present_flag; 88 uint32_t chroma_sample_loc_type_top_field; 89 uint32_t chroma_sample_loc_type_bottom_field; 90 uint32_t timing_info_present_flag; 91 uint32_t time_scale; 92 uint32_t num_units_in_tick; 93 uint32_t fixed_frame_rate_flag; 94 uint32_t nal_hrd_parameters_present_flag; 95 H264_HRD_PARAMS nal_hrd_parameters; 96 uint32_t vcl_hrd_parameters_present_flag; 97 H264_HRD_PARAMS vcl_hrd_parameters; 98 uint32_t low_delay_hrd_flag; 99 uint32_t pic_struct_present_flag; 100 uint32_t bitstream_restriction_flag; 101 uint32_t motion_vectors_over_pic_boundaries_flag; 102 uint32_t max_bytes_per_pic_denom; 103 uint32_t max_bits_per_mb_denom; 104 uint32_t log2_max_mv_length_vertical; 105 uint32_t log2_max_mv_length_horizontal; 106 uint32_t num_reorder_frames; 107 uint32_t max_dec_frame_buffering; 108 }; 109 110 struct H264_SPS 111 { 112 uint32_t profile_idc; 113 uint32_t constraint_set_flags; 114 uint32_t level_idc; 115 uint32_t seq_parameter_set_id; 116 uint32_t bit_depth_luma_minus8; 117 uint32_t bit_depth_chroma_minus8; 118 uint32_t log2_max_frame_num_minus4; 119 uint32_t pic_order_cnt_type; 120 uint32_t log2_max_pic_order_cnt_lsb_minus4; 121 uint32_t max_num_ref_frames; 122 uint32_t gaps_in_frame_num_value_allowed_flag; 123 uint32_t pic_width_in_mbs_minus1; 124 uint32_t pic_height_in_map_units_minus1; 125 uint32_t direct_8x8_inference_flag; 126 uint32_t frame_cropping_flag; 127 uint32_t frame_cropping_rect_left_offset; 128 uint32_t frame_cropping_rect_right_offset; 129 uint32_t frame_cropping_rect_top_offset; 130 uint32_t frame_cropping_rect_bottom_offset; 131 uint32_t vui_parameters_present_flag; 132 H264_VUI_PARAMS vui; 133 }; 134 135 struct H264_PPS 136 { 137 uint32_t pic_parameter_set_id; 138 uint32_t seq_parameter_set_id; 139 uint32_t entropy_coding_mode_flag; 140 uint32_t pic_order_present_flag; 141 uint32_t num_ref_idx_l0_active_minus1; 142 uint32_t num_ref_idx_l1_active_minus1; 143 uint32_t constrained_intra_pred_flag; 144 uint32_t transform_8x8_mode_flag; 145 }; 146 147 enum H264_SPEC_PROFILES 148 { 149 // Same as BASELINE (66) with constraint_set1_flag set 150 H264_PROFILE_CONSTRAINED_BASELINE = 66, 151 H264_PROFILE_BASELINE = 66, 152 H264_PROFILE_MAIN = 77, 153 H264_PROFILE_HIGH = 100, 154 H264_PROFILE_HIGH10 = 110, 155 }; 156 157 #define MAX_COMPRESSED_PPS 256 158 #define MAX_COMPRESSED_SPS 256 159 160 class d3d12_video_nalu_writer_h264 161 { 162 public: d3d12_video_nalu_writer_h264()163 d3d12_video_nalu_writer_h264() 164 { } ~d3d12_video_nalu_writer_h264()165 ~d3d12_video_nalu_writer_h264() 166 { } 167 168 // Writes the H264 SPS structure into a bitstream passed in headerBitstream 169 // Function resizes bitstream accordingly and puts result in byte vector 170 void sps_to_nalu_bytes(H264_SPS * pSPS, 171 std::vector<uint8_t> & headerBitstream, 172 std::vector<uint8_t>::iterator placingPositionStart, 173 size_t & writtenBytes); 174 175 // Writes the H264 PPS structure into a bitstream passed in headerBitstream 176 // Function resizes bitstream accordingly and puts result in byte vector 177 void pps_to_nalu_bytes(H264_PPS * pPPS, 178 std::vector<uint8_t> & headerBitstream, 179 BOOL bIsFREXTProfile, 180 std::vector<uint8_t>::iterator placingPositionStart, 181 size_t & writtenBytes); 182 183 void write_end_of_stream_nalu(std::vector<uint8_t> & headerBitstream, 184 std::vector<uint8_t>::iterator placingPositionStart, 185 size_t & writtenBytes); 186 void write_end_of_sequence_nalu(std::vector<uint8_t> & headerBitstream, 187 std::vector<uint8_t>::iterator placingPositionStart, 188 size_t & writtenBytes); 189 190 void write_access_unit_delimiter_nalu(std::vector<uint8_t> & headerBitstream, 191 std::vector<uint8_t>::iterator placingPositionStart, 192 size_t & writtenBytes); 193 194 private: 195 // Writes from structure into bitstream with RBSP trailing but WITHOUT NAL unit wrap (eg. nal_idc_type, etc) 196 uint32_t write_sps_bytes(d3d12_video_encoder_bitstream *pBitstream, H264_SPS *pSPS); 197 uint32_t write_pps_bytes(d3d12_video_encoder_bitstream *pBitstream, H264_PPS *pPPS, BOOL bIsFREXTProfile); 198 199 // Adds NALU wrapping into structures and ending NALU control bits 200 uint32_t wrap_sps_nalu(d3d12_video_encoder_bitstream *pNALU, d3d12_video_encoder_bitstream *pRBSP); 201 uint32_t wrap_pps_nalu(d3d12_video_encoder_bitstream *pNALU, d3d12_video_encoder_bitstream *pRBSP); 202 203 // Helpers 204 void write_hrd(d3d12_video_encoder_bitstream *pBitstream, H264_HRD_PARAMS *pHrd); 205 void write_nalu_end(d3d12_video_encoder_bitstream *pNALU); 206 void rbsp_trailing(d3d12_video_encoder_bitstream *pBitstream); 207 uint32_t wrap_rbsp_into_nalu(d3d12_video_encoder_bitstream *pNALU, 208 d3d12_video_encoder_bitstream *pRBSP, 209 uint32_t iNaluIdc, 210 uint32_t iNaluType); 211 }; 212 213 #endif 214