• 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_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