• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_HEVC_H
25 #define D3D12_VIDEO_ENC_NALU_WRITER_HEVC_H
26 
27 #include "d3d12_video_encoder_bitstream.h"
28 
29 #define HEVC_MAX_REF_PICS       16
30 #define HEVC_MAX_SUB_LAYERS_NUM 7
31 #define HEVC_MAX_TILE_NUM       64
32 
33 #define MAX_COMPRESSED_NALU (10*1024)
34 
35 enum HEVCNaluType {
36    HEVC_NALU_TRAIL_N = 0,
37    HEVC_NALU_TRAIL_R = 1,
38    HEVC_NALU_TSA_N = 2,
39    HEVC_NALU_TSA_R = 3,
40    HEVC_NALU_STSA_N = 4,
41    HEVC_NALU_STSA_R = 5,
42    HEVC_NALU_RADL_N = 6,
43    HEVC_NALU_RADL_R = 7,
44    HEVC_NALU_RASL_N = 8,
45    HEVC_NALU_RASL_R = 9,
46    HEVC_NALU_RSV_VCL_N10 = 10,
47    HEVC_NALU_RSV_VCL_N12 = 12,
48    HEVC_NALU_RSV_VCL_N14 = 14,
49    HEVC_NALU_RSV_VCL_R11 = 11,
50    HEVC_NALU_RSV_VCL_R13 = 13,
51    HEVC_NALU_RSV_VCL_R15 = 15,
52    HEVC_NALU_BLA_W_LP = 16,
53    HEVC_NALU_BLA_W_RADL = 17,
54    HEVC_NALU_BLA_N_LP = 18,
55    HEVC_NALU_IDR_W_RADL = 19,
56    HEVC_NALU_IDR_N_LP = 20,
57    HEVC_NALU_CRA_NUT = 21,
58    HEVC_NALU_RSV_IRAP_VCL22 = 22,
59    HEVC_NALU_RSV_IRAP_VCL23 = 23,
60    HEVC_NALU_RSV_VCL_24 = 24,
61    HEVC_NALU_RSV_VCL_25 = 25,
62    HEVC_NALU_RSV_VCL_26 = 26,
63    HEVC_NALU_RSV_VCL_27 = 27,
64    HEVC_NALU_RSV_VCL_28 = 28,
65    HEVC_NALU_RSV_VCL_29 = 29,
66    HEVC_NALU_RSV_VCL_30 = 30,
67    HEVC_NALU_RSV_VCL_31 = 31,
68    HEVC_NALU_VPS_NUT = 32,
69    HEVC_NALU_SPS_NUT = 33,
70    HEVC_NALU_PPS_NUT = 34,
71    HEVC_NALU_AUD_NUT = 35,
72    HEVC_NALU_EOS_NUT = 36,
73    HEVC_NALU_EOB_NUT = 37,
74    HEVC_NALU_FD_NUT = 38,
75    HEVC_NALU_PREFIX_SEI_NUT = 39,
76    HEVC_NALU_SUFFIX_SEI_NUT = 40,
77 };
78 
79 struct HEVCNaluHeader {
80    uint8_t forbidden_zero_bit;
81    uint8_t nal_unit_type;
82    uint8_t nuh_layer_id;
83    uint8_t nuh_temporal_id_plus1;
84 };
85 
86 struct HEVCProfileTierLevel {
87    uint8_t        general_profile_space;
88    uint8_t        general_tier_flag;
89    uint8_t        general_profile_idc;
90    uint8_t        general_profile_compatibility_flag[32];
91    uint8_t        general_progressive_source_flag;
92    uint8_t        general_interlaced_source_flag;
93    uint8_t        general_non_packed_constraint_flag;
94    uint8_t        general_frame_only_constraint_flag;
95    uint8_t        general_level_idc;
96    uint8_t        sub_layer_profile_present_flag[HEVC_MAX_SUB_LAYERS_NUM - 1];
97    uint8_t        sub_layer_level_present_flag[HEVC_MAX_SUB_LAYERS_NUM - 1];
98    uint8_t        sub_layer_profile_space[HEVC_MAX_SUB_LAYERS_NUM - 1];
99    uint8_t        sub_layer_tier_flag[HEVC_MAX_SUB_LAYERS_NUM - 1];
100    uint8_t        sub_layer_profile_idc[HEVC_MAX_SUB_LAYERS_NUM - 1];
101    uint8_t        sub_layer_profile_compatibility_flag[HEVC_MAX_SUB_LAYERS_NUM - 1][32];
102    uint8_t        sub_layer_progressive_source_flag[HEVC_MAX_SUB_LAYERS_NUM - 1];
103    uint8_t        sub_layer_interlaced_source_flag[HEVC_MAX_SUB_LAYERS_NUM - 1];
104    uint8_t        sub_layer_non_packed_constraint_flag[HEVC_MAX_SUB_LAYERS_NUM - 1];
105    uint8_t        sub_layer_frame_only_constraint_flag[HEVC_MAX_SUB_LAYERS_NUM - 1];
106    int32_t        sub_layer_level_idc[HEVC_MAX_SUB_LAYERS_NUM - 1];
107 };
108 
109 struct ReferencePictureSet {
110    int32_t  numberOfPictures;
111    int32_t  numberOfNegativePictures;
112    int32_t  numberOfPositivePictures;
113    int32_t  numberOfLongtermPictures;
114    int32_t  deltaPOC[HEVC_MAX_REF_PICS];
115    int32_t  POC[HEVC_MAX_REF_PICS];
116    uint8_t  used[HEVC_MAX_REF_PICS];
117    uint8_t  interRPSPrediction;
118    int32_t  deltaRIdxMinus1;
119    int32_t  deltaRPS;
120    int32_t  numRefIdc;
121    int32_t  refIdc[HEVC_MAX_REF_PICS + 1];
122    uint8_t  bCheckLTMSB[HEVC_MAX_REF_PICS];
123    int32_t  pocLSBLT[HEVC_MAX_REF_PICS];
124    int32_t  deltaPOCMSBCycleLT[HEVC_MAX_REF_PICS];
125    uint8_t  deltaPocMSBPresentFlag[HEVC_MAX_REF_PICS];
126 };
127 
128 struct HEVCReferencePictureSet {
129    uint8_t         inter_ref_pic_set_prediction_flag;
130    union {
131       struct {
132          uint32_t        delta_idx_minus1;
133          uint8_t         delta_rps_sign;
134          uint32_t        abs_delta_rps_minus1;
135          uint8_t         used_by_curr_pic_flag[HEVC_MAX_REF_PICS];
136          uint8_t         use_delta_flag[HEVC_MAX_REF_PICS];
137       };
138       struct {
139          int32_t         num_negative_pics;
140          int32_t         num_positive_pics;
141          int32_t         delta_poc_s0_minus1[HEVC_MAX_REF_PICS];
142          uint8_t         used_by_curr_pic_s0_flag[HEVC_MAX_REF_PICS];
143          int32_t         delta_poc_s1_minus1[HEVC_MAX_REF_PICS];
144          uint8_t         used_by_curr_pic_s1_flag[HEVC_MAX_REF_PICS];
145       };
146    };
147 };
148 
149 struct HEVCVideoUsabilityInfo {
150     uint8_t     aspect_ratio_info_present_flag;
151     uint8_t     aspect_ratio_idc;
152     int32_t     sar_width;
153     int32_t     sar_height;
154     uint8_t     overscan_info_present_flag;
155     uint8_t     overscan_appropriate_flag;
156     uint8_t     video_signal_type_present_flag;
157     uint8_t     video_format;
158     uint8_t     video_full_range_flag;
159     uint8_t     colour_description_present_flag;
160     uint8_t     colour_primaries;
161     uint8_t     transfer_characteristics;
162     uint8_t     matrix_coeffs;
163     uint8_t     chroma_loc_info_present_flag;
164     int32_t     chroma_sample_loc_type_top_field;
165     int32_t     chroma_sample_loc_type_bottom_field;
166     uint8_t     neutral_chroma_indication_flag;
167     uint8_t     field_seq_flag;
168     uint8_t     frame_field_info_present_flag;
169     uint8_t     default_display_window_flag;
170     int32_t     def_disp_win_left_offset;
171     int32_t     def_disp_win_right_offset;
172     int32_t     def_disp_win_top_offset;
173     int32_t     def_disp_win_bottom_offset;
174     uint8_t     timing_info_present_flag;
175     uint32_t    num_units_in_tick;
176     uint32_t    time_scale;
177     uint8_t     poc_proportional_to_timing_flag;
178     uint32_t    num_ticks_poc_diff_one_minus1;
179     uint8_t     hrd_parameters_present_flag;
180     uint8_t     bitstream_restriction_flag;
181     uint8_t     tiles_fixed_structure_flag;
182     uint8_t     motion_vectors_over_pic_boundaries_flag;
183     uint8_t     restricted_ref_pic_lists_flag;
184     uint32_t    min_spatial_segmentation_idc;
185     uint32_t    max_bytes_per_pic_denom;
186     uint32_t    max_bits_per_min_cu_denom;
187     uint32_t    log2_max_mv_length_horizontal;
188     uint32_t    log2_max_mv_length_vertical;
189 };
190 
191 struct HevcSeqParameterSet {
192    HEVCNaluHeader  nalu;
193    uint8_t         sps_video_parameter_set_id;
194    uint8_t         sps_max_sub_layers_minus1;
195    uint8_t         sps_temporal_id_nesting_flag;
196    HEVCProfileTierLevel ptl;
197    uint8_t         sps_seq_parameter_set_id;
198    uint8_t         chroma_format_idc;
199    uint8_t         separate_colour_plane_flag;
200    int32_t         pic_width_in_luma_samples;
201    int32_t         pic_height_in_luma_samples;
202    uint8_t         conformance_window_flag;
203    int32_t         conf_win_left_offset;
204    int32_t         conf_win_right_offset;
205    int32_t         conf_win_top_offset;
206    int32_t         conf_win_bottom_offset;
207    uint8_t         bit_depth_luma_minus8;
208    uint8_t         bit_depth_chroma_minus8;
209    uint8_t         log2_max_pic_order_cnt_lsb_minus4;
210    int             maxPicOrderCntLsb;
211    uint8_t         sps_sub_layer_ordering_info_present_flag;
212    int32_t         sps_max_dec_pic_buffering_minus1[HEVC_MAX_SUB_LAYERS_NUM];
213    int32_t         sps_max_num_reorder_pics[HEVC_MAX_SUB_LAYERS_NUM];
214    int32_t         sps_max_latency_increase_plus1[HEVC_MAX_SUB_LAYERS_NUM];
215    uint8_t         log2_min_luma_coding_block_size_minus3;
216    uint8_t         log2_diff_max_min_luma_coding_block_size;
217    uint8_t         log2_min_transform_block_size_minus2;
218    uint8_t         log2_diff_max_min_transform_block_size;
219    uint8_t         max_transform_hierarchy_depth_inter;
220    uint8_t         max_transform_hierarchy_depth_intra;
221    uint8_t         scaling_list_enabled_flag;
222    uint8_t         sps_scaling_list_data_present_flag;
223    uint8_t         scaling_list_pred_mode_flag[4][6];
224    uint32_t        scaling_list_pred_matrix_id_delta[4][6];
225    int32_t         scaling_list_dc_coef_minus8[2][6];
226    int32_t         scaling_list_delta_coef;
227    int32_t         ScalingList[4][6][64];
228    uint8_t         amp_enabled_flag;
229    uint8_t         sample_adaptive_offset_enabled_flag;
230    uint8_t         pcm_enabled_flag;
231    uint8_t         pcm_sample_bit_depth_luma_minus1;
232    uint8_t         pcm_sample_bit_depth_chroma_minus1;
233    int32_t         log2_min_pcm_luma_coding_block_size_minus3;
234    int32_t         log2_diff_max_min_pcm_luma_coding_block_size;
235    uint8_t         pcm_loop_filter_disabled_flag;
236    uint8_t         num_short_term_ref_pic_sets;
237    HEVCReferencePictureSet rpsShortTerm[64];
238    uint8_t         long_term_ref_pics_present_flag;
239    uint8_t         num_long_term_ref_pics_sps;
240    int32_t         lt_ref_pic_poc_lsb_sps[32];
241    uint8_t         used_by_curr_pic_lt_sps_flag[32];
242    uint8_t         sps_temporal_mvp_enabled_flag;
243    uint8_t         strong_intra_smoothing_enabled_flag;
244    uint8_t         vui_parameters_present_flag;
245    HEVCVideoUsabilityInfo vui;
246    uint8_t         sps_extension_flag;
247    uint8_t         sps_extension_data_flag;
248 };
249 
250 struct HevcPicParameterSet {
251    HEVCNaluHeader  nalu;
252    uint8_t         pps_pic_parameter_set_id;
253    uint8_t         pps_seq_parameter_set_id;
254    uint8_t         dependent_slice_segments_enabled_flag;
255    uint8_t         output_flag_present_flag;
256    uint8_t         num_extra_slice_header_bits;
257    uint8_t         sign_data_hiding_enabled_flag;
258    uint8_t         cabac_init_present_flag;
259    uint8_t         num_ref_idx_lx_default_active_minus1[2];
260    int8_t          init_qp_minus26;
261    uint8_t         constrained_intra_pred_flag;
262    uint8_t         transform_skip_enabled_flag;
263    uint8_t         cu_qp_delta_enabled_flag;
264    uint8_t         diff_cu_qp_delta_depth;
265    int8_t          pps_cb_qp_offset;
266    int8_t          pps_cr_qp_offset;
267    uint8_t         pps_slice_chroma_qp_offsets_present_flag;
268    uint8_t         weighted_pred_flag;
269    uint8_t         weighted_bipred_flag;
270    uint8_t         transquant_bypass_enabled_flag;
271    uint8_t         tiles_enabled_flag;
272    uint8_t         entropy_coding_sync_enabled_flag;
273    int32_t         num_tile_columns_minus1;
274    int32_t         num_tile_rows_minus1;
275    uint8_t         uniform_spacing_flag;
276    int32_t         column_width_minus1[HEVC_MAX_TILE_NUM];
277    int32_t         row_height_minus1[HEVC_MAX_TILE_NUM];
278    uint8_t         loop_filter_across_tiles_enabled_flag;
279    uint8_t         pps_loop_filter_across_slices_enabled_flag;
280    uint8_t         deblocking_filter_control_present_flag;
281    uint8_t         deblocking_filter_override_enabled_flag;
282    uint8_t         pps_deblocking_filter_disabled_flag;
283    int8_t          pps_beta_offset_div2;
284    int8_t          pps_tc_offset_div2;
285    uint8_t         pps_scaling_list_data_present_flag;
286    uint8_t         lists_modification_present_flag;
287    uint8_t         log2_parallel_merge_level_minus2;
288    uint8_t         slice_segment_header_extension_present_flag;
289    uint8_t         pps_extension_flag;
290    uint8_t         pps_extension_data_flag;
291 };
292 
293 struct HevcVideoParameterSet {
294    HEVCNaluHeader nalu;
295    uint8_t        vps_video_parameter_set_id;
296    uint8_t        vps_reserved_three_2bits;
297    uint8_t        vps_max_layers_minus1;
298    uint8_t        vps_max_sub_layers_minus1;
299    uint8_t        vps_temporal_id_nesting_flag;
300    int32_t        vps_reserved_0xffff_16bits;
301    HEVCProfileTierLevel ptl;
302    uint8_t        vps_sub_layer_ordering_info_present_flag;
303    uint8_t        vps_max_dec_pic_buffering_minus1[HEVC_MAX_SUB_LAYERS_NUM];
304    uint8_t        vps_max_num_reorder_pics[HEVC_MAX_SUB_LAYERS_NUM];
305    uint8_t        vps_max_latency_increase_plus1[HEVC_MAX_SUB_LAYERS_NUM];
306    uint8_t        vps_max_layer_id;
307    uint8_t        vps_num_layer_sets_minus1;
308    uint8_t        layer_id_included_flag[1024][1];
309    uint8_t        vps_timing_info_present_flag;
310    uint32_t       vps_num_units_in_tick;
311    uint32_t       vps_time_scale;
312    uint8_t        vps_poc_proportional_to_timing_flag;
313    uint32_t       vps_num_ticks_poc_diff_one_minus1;
314    uint32_t       vps_num_hrd_parameters;
315    uint32_t       hrd_layer_set_idx[1024];
316    uint8_t        cprms_present_flag[1024];
317    uint8_t        vps_extension_flag;
318    uint8_t        vps_extension_data_flag;
319 };
320 
321 class d3d12_video_nalu_writer_hevc
322 {
323 public:
d3d12_video_nalu_writer_hevc()324    d3d12_video_nalu_writer_hevc() { }
~d3d12_video_nalu_writer_hevc()325    ~d3d12_video_nalu_writer_hevc() { }
326 
327    // Writes the HEVC VPS structure into a bitstream passed in headerBitstream
328    // Function resizes bitstream accordingly and puts result in byte vector
329    void vps_to_nalu_bytes(HevcVideoParameterSet *pVPS,
330                         std::vector<BYTE>
331                         &headerBitstream,
332                         std::vector<BYTE>::iterator
333                         placingPositionStart,
334                         size_t &writtenBytes);
335 
336    // Writes the HEVC SPS structure into a bitstream passed in headerBitstream
337    // Function resizes bitstream accordingly and puts result in byte vector
338    void sps_to_nalu_bytes(HevcSeqParameterSet *pSPS,
339                         std::vector<BYTE>
340                         &headerBitstream,
341                         std::vector<BYTE>::iterator
342                         placingPositionStart,
343                         size_t &writtenBytes);
344 
345    // Writes the HEVC PPS structure into a bitstream passed in headerBitstream
346    // Function resizes bitstream accordingly and puts result in byte vector
347    void pps_to_nalu_bytes(HevcPicParameterSet *pPPS,
348                         std::vector<BYTE>
349                         &headerBitstream,
350                         std::vector<BYTE>::iterator
351                         placingPositionStart,
352                         size_t &writtenBytes);
353 
354    void write_end_of_stream_nalu(std::vector<BYTE> &headerBitstream,
355                                  std::vector<BYTE>::iterator
356                                  placingPositionStart,
357                                  size_t
358                                  &writtenBytes);
359    void write_end_of_sequence_nalu(std::vector<BYTE>
360                                  &headerBitstream,
361                                  std::vector<BYTE>::iterator
362                                  placingPositionStart,
363                                  size_t &writtenBytes);
364 
365 private:
366 
367    // Writes from structure into bitstream with RBSP trailing but WITHOUT NAL unit wrap (eg. nal_idc_type, etc)
368    uint32_t write_vps_bytes(d3d12_video_encoder_bitstream *pBitstream, HevcVideoParameterSet *pSPS);
369    uint32_t write_sps_bytes(d3d12_video_encoder_bitstream *pBitstream, HevcSeqParameterSet *pSPS);
370    uint32_t write_pps_bytes(d3d12_video_encoder_bitstream *pBitstream, HevcPicParameterSet *pPPS);
371 
372    // Adds NALU wrapping into structures and ending NALU control bits
373    uint32_t wrap_rbsp_into_nalu(d3d12_video_encoder_bitstream *pNALU, d3d12_video_encoder_bitstream *pRBSP, HEVCNaluHeader *pHeader);
374 
375    // Helpers
376    void     write_nalu_end(d3d12_video_encoder_bitstream *pNALU);
377    void     rbsp_trailing(d3d12_video_encoder_bitstream *pBitstream);
378    void     write_profile_tier_level(d3d12_video_encoder_bitstream* rbsp, HEVCProfileTierLevel* ptl);
379 
380    void generic_write_bytes(std::vector<BYTE> &headerBitstream,
381                            std::vector<BYTE>::iterator placingPositionStart,
382                            size_t &writtenBytes,
383                            void *pStructure);
384    uint32_t
385    write_bytes_from_struct(d3d12_video_encoder_bitstream *pBitstream, void *pData, uint8_t nal_unit_type);
386 
387    void write_rps(d3d12_video_encoder_bitstream* rbsp, HevcSeqParameterSet* sps, int stRpsIdx, bool sliceRPS);
388 };
389 
390 #endif
391