• 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_DEMILITER = 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 struct H264_SPS
59 {
60    uint32_t profile_idc;
61    uint32_t constraint_set3_flag;
62    uint32_t level_idc;
63    uint32_t seq_parameter_set_id;
64    uint32_t bit_depth_luma_minus8;
65    uint32_t bit_depth_chroma_minus8;
66    uint32_t log2_max_frame_num_minus4;
67    uint32_t pic_order_cnt_type;
68    uint32_t log2_max_pic_order_cnt_lsb_minus4;
69    uint32_t max_num_ref_frames;
70    uint32_t gaps_in_frame_num_value_allowed_flag;
71    uint32_t pic_width_in_mbs_minus1;
72    uint32_t pic_height_in_map_units_minus1;
73    uint32_t direct_8x8_inference_flag;
74    uint32_t frame_cropping_flag;
75    uint32_t frame_cropping_rect_left_offset;
76    uint32_t frame_cropping_rect_right_offset;
77    uint32_t frame_cropping_rect_top_offset;
78    uint32_t frame_cropping_rect_bottom_offset;
79 };
80 
81 struct H264_PPS
82 {
83    uint32_t pic_parameter_set_id;
84    uint32_t seq_parameter_set_id;
85    uint32_t entropy_coding_mode_flag;
86    uint32_t pic_order_present_flag;
87    uint32_t num_ref_idx_l0_active_minus1;
88    uint32_t num_ref_idx_l1_active_minus1;
89    uint32_t constrained_intra_pred_flag;
90    uint32_t transform_8x8_mode_flag;
91 };
92 
93 enum H264_SPEC_PROFILES
94 {
95    H264_PROFILE_MAIN   = 77,
96    H264_PROFILE_HIGH   = 100,
97    H264_PROFILE_HIGH10 = 110,
98 };
99 
100 #define MAX_COMPRESSED_PPS 256
101 #define MAX_COMPRESSED_SPS 256
102 
103 class d3d12_video_nalu_writer_h264
104 {
105  public:
d3d12_video_nalu_writer_h264()106    d3d12_video_nalu_writer_h264()
107    { }
~d3d12_video_nalu_writer_h264()108    ~d3d12_video_nalu_writer_h264()
109    { }
110 
111    // Writes the H264 SPS structure into a bitstream passed in headerBitstream
112    // Function resizes bitstream accordingly and puts result in byte vector
113    void sps_to_nalu_bytes(H264_SPS *                     pSPS,
114                           std::vector<uint8_t> &         headerBitstream,
115                           std::vector<uint8_t>::iterator placingPositionStart,
116                           size_t &                       writtenBytes);
117 
118    // Writes the H264 PPS structure into a bitstream passed in headerBitstream
119    // Function resizes bitstream accordingly and puts result in byte vector
120    void pps_to_nalu_bytes(H264_PPS *                     pPPS,
121                           std::vector<uint8_t> &         headerBitstream,
122                           BOOL                           bIsFREXTProfile,
123                           std::vector<uint8_t>::iterator placingPositionStart,
124                           size_t &                       writtenBytes);
125 
126    void write_end_of_stream_nalu(std::vector<uint8_t> &         headerBitstream,
127                                  std::vector<uint8_t>::iterator placingPositionStart,
128                                  size_t &                       writtenBytes);
129    void write_end_of_sequence_nalu(std::vector<uint8_t> &         headerBitstream,
130                                    std::vector<uint8_t>::iterator placingPositionStart,
131                                    size_t &                       writtenBytes);
132 
133  private:
134    // Writes from structure into bitstream with RBSP trailing but WITHOUT NAL unit wrap (eg. nal_idc_type, etc)
135    uint32_t write_sps_bytes(d3d12_video_encoder_bitstream *pBitstream, H264_SPS *pSPS);
136    uint32_t write_pps_bytes(d3d12_video_encoder_bitstream *pBitstream, H264_PPS *pPPS, BOOL bIsFREXTProfile);
137 
138    // Adds NALU wrapping into structures and ending NALU control bits
139    uint32_t wrap_sps_nalu(d3d12_video_encoder_bitstream *pNALU, d3d12_video_encoder_bitstream *pRBSP);
140    uint32_t wrap_pps_nalu(d3d12_video_encoder_bitstream *pNALU, d3d12_video_encoder_bitstream *pRBSP);
141 
142    // Helpers
143    void     write_nalu_end(d3d12_video_encoder_bitstream *pNALU);
144    void     rbsp_trailing(d3d12_video_encoder_bitstream *pBitstream);
145    uint32_t wrap_rbsp_into_nalu(d3d12_video_encoder_bitstream *pNALU,
146                                 d3d12_video_encoder_bitstream *pRBSP,
147                                 uint32_t                       iNaluIdc,
148                                 uint32_t                       iNaluType);
149 };
150 
151 #endif
152