• 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 #include "d3d12_video_encoder_bitstream_builder_hevc.h"
25 #include <cmath>
26 
27 static uint8_t
convert_profile12_to_stdprofile(D3D12_VIDEO_ENCODER_PROFILE_HEVC profile)28 convert_profile12_to_stdprofile(D3D12_VIDEO_ENCODER_PROFILE_HEVC profile)
29 {
30     // Main is 1, Main10 is 2, one more than the D3D12 enum definition
31     return static_cast<uint8_t>(profile) + 1u;
32 }
33 
34 void
init_profile_tier_level(HEVCProfileTierLevel * ptl,uint8_t HEVCProfileIdc,uint8_t HEVCLevelIdc,bool isHighTier)35 d3d12_video_bitstream_builder_hevc::init_profile_tier_level(HEVCProfileTierLevel *ptl,
36                         uint8_t HEVCProfileIdc,
37                         uint8_t HEVCLevelIdc,
38                         bool isHighTier)
39 {
40    memset(ptl, 0, sizeof(HEVCProfileTierLevel));
41 
42    ptl->general_profile_space = 0;     // must be 0
43    ptl->general_tier_flag = isHighTier ? 1 : 0;
44    ptl->general_profile_idc = HEVCProfileIdc;
45 
46    memset(ptl->general_profile_compatibility_flag, 0, sizeof(ptl->general_profile_compatibility_flag));
47    ptl->general_profile_compatibility_flag[ptl->general_profile_idc] = 1;
48 
49    ptl->general_progressive_source_flag = 1; // yes
50    ptl->general_interlaced_source_flag = 0;  // no
51    ptl->general_non_packed_constraint_flag = 1; // no frame packing arrangement SEI messages
52    ptl->general_frame_only_constraint_flag = 1;
53    ptl->general_level_idc = HEVCLevelIdc;
54 }
55 
56 void
d3d12_video_encoder_convert_from_d3d12_level_hevc(D3D12_VIDEO_ENCODER_LEVELS_HEVC level12,uint32_t & specLevel)57 d3d12_video_encoder_convert_from_d3d12_level_hevc(D3D12_VIDEO_ENCODER_LEVELS_HEVC level12,
58                                                   uint32_t &specLevel)
59 {
60    specLevel = 3u;
61    switch(level12)
62    {
63       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_1:
64       {
65          specLevel *= 10;
66       } break;
67       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_2:
68       {
69          specLevel *= 20;
70       } break;
71       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_21:
72       {
73          specLevel *= 21;
74       } break;
75       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_3:
76       {
77          specLevel *= 30;
78       } break;
79       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_31:
80       {
81          specLevel *= 31;
82       } break;
83       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_4:
84       {
85          specLevel *= 40;
86       } break;
87       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_41:
88       {
89          specLevel *= 41;
90       } break;
91       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_5:
92       {
93          specLevel *= 50;
94       } break;
95       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_51:
96       {
97          specLevel *= 51;
98       } break;
99       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_52:
100       {
101          specLevel *= 52;
102       } break;
103       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_6 :
104       {
105          specLevel *= 60;
106       } break;
107       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_61 :
108       {
109          specLevel *= 61;
110       } break;
111       case D3D12_VIDEO_ENCODER_LEVELS_HEVC_62 :
112       {
113          specLevel *= 62;
114       } break;
115       default:
116       {
117          unreachable("Unsupported D3D12_VIDEO_ENCODER_LEVELS_HEVC value");
118       } break;
119    }
120 }
121 
122 D3D12_VIDEO_ENCODER_LEVELS_HEVC
d3d12_video_encoder_convert_level_hevc(uint32_t hevcSpecLevel)123 d3d12_video_encoder_convert_level_hevc(uint32_t hevcSpecLevel)
124 {
125    hevcSpecLevel = hevcSpecLevel / 3u;
126    switch(hevcSpecLevel)
127    {
128       case 10:
129       {
130          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_1;
131       } break;
132       case 20:
133       {
134          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_2;
135       } break;
136       case 21:
137       {
138          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_21;
139       } break;
140       case 30:
141       {
142          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_3;
143       } break;
144       case 31:
145       {
146          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_31;
147       } break;
148       case 40:
149       {
150          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_4;
151       } break;
152       case 41:
153       {
154          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_41;
155       } break;
156       case 50:
157       {
158          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_5;
159       } break;
160       case 51:
161       {
162          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_51;
163       } break;
164       case 52:
165       {
166          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_52;
167       } break;
168       case 60:
169       {
170          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_6;
171       } break;
172       case 61:
173       {
174          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_61;
175       } break;
176       case 62:
177       {
178          return D3D12_VIDEO_ENCODER_LEVELS_HEVC_62;
179       } break;
180       default:
181       {
182          unreachable("Unsupported D3D12_VIDEO_ENCODER_LEVELS_HEVC value");
183       } break;
184    }
185 }
186 
187 uint8_t
d3d12_video_encoder_convert_12cusize_to_pixel_size_hevc(const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE & cuSize)188 d3d12_video_encoder_convert_12cusize_to_pixel_size_hevc(const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE& cuSize)
189 {
190     switch(cuSize)
191     {
192         case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8:
193         {
194             return 8u;
195         } break;
196         case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_16x16:
197         {
198             return 16u;
199         } break;
200         case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_32x32:
201         {
202             return 32u;
203         } break;
204         case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_64x64:
205         {
206             return 64u;
207         } break;
208         default:
209         {
210             unreachable(L"Not a supported cu size");
211             return 0u;
212         } break;
213     }
214 }
215 
216 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE
d3d12_video_encoder_convert_pixel_size_hevc_to_12cusize(const uint32_t & cuSize)217 d3d12_video_encoder_convert_pixel_size_hevc_to_12cusize(const uint32_t& cuSize)
218 {
219     switch(cuSize)
220     {
221         case 8u:
222         {
223             return D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_8x8;
224         } break;
225         case 16u:
226         {
227             return D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_16x16;
228         } break;
229         case 32u:
230         {
231             return D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_32x32;
232         } break;
233         case 64u:
234         {
235             return D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_CUSIZE_64x64;
236         } break;
237         default:
238         {
239             unreachable(L"Not a supported cu size");
240         } break;
241     }
242 }
243 
244 uint8_t
d3d12_video_encoder_convert_12tusize_to_pixel_size_hevc(const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE & TUSize)245 d3d12_video_encoder_convert_12tusize_to_pixel_size_hevc(const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE& TUSize)
246 {
247     switch(TUSize)
248     {
249         case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4:
250         {
251             return 4u;
252         } break;
253         case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_8x8:
254         {
255             return 8u;
256         } break;
257         case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_16x16:
258         {
259             return 16u;
260         } break;
261         case D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32:
262         {
263             return 32u;
264         } break;
265         default:
266         {
267             unreachable(L"Not a supported TU size");
268         } break;
269     }
270 }
271 
272 D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE
d3d12_video_encoder_convert_pixel_size_hevc_to_12tusize(const uint32_t & TUSize)273 d3d12_video_encoder_convert_pixel_size_hevc_to_12tusize(const uint32_t& TUSize)
274 {
275     switch(TUSize)
276     {
277         case 4u:
278         {
279             return D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_4x4;
280         } break;
281         case 8u:
282         {
283             return D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_8x8;
284         } break;
285         case 16u:
286         {
287             return D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_16x16;
288         } break;
289         case 32u:
290         {
291             return D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_TUSIZE_32x32;
292         } break;
293         default:
294         {
295             unreachable(L"Not a supported TU size");
296         } break;
297     }
298 }
299 
300 void
build_vps(const D3D12_VIDEO_ENCODER_PROFILE_HEVC & profile,const D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC & level,const DXGI_FORMAT inputFmt,uint8_t maxRefFrames,bool gopHasBFrames,uint8_t vps_video_parameter_set_id,std::vector<BYTE> & headerBitstream,std::vector<BYTE>::iterator placingPositionStart,size_t & writtenBytes,HevcVideoParameterSet * pVPSStruct)301 d3d12_video_bitstream_builder_hevc::build_vps(const D3D12_VIDEO_ENCODER_PROFILE_HEVC& profile,
302          const D3D12_VIDEO_ENCODER_LEVEL_TIER_CONSTRAINTS_HEVC& level,
303          const DXGI_FORMAT inputFmt,
304          uint8_t maxRefFrames,
305          bool gopHasBFrames,
306          uint8_t vps_video_parameter_set_id,
307          std::vector<BYTE> &headerBitstream,
308          std::vector<BYTE>::iterator placingPositionStart,
309          size_t &writtenBytes,
310          HevcVideoParameterSet* pVPSStruct)
311 {
312    uint8_t HEVCProfileIdc = convert_profile12_to_stdprofile(profile);
313    uint32_t HEVCLevelIdc = 0u;
314    d3d12_video_encoder_convert_from_d3d12_level_hevc(level.Level, HEVCLevelIdc);
315    bool isHighTier = (level.Tier == D3D12_VIDEO_ENCODER_TIER_HEVC_HIGH);
316 
317    memset(&m_latest_vps, 0, sizeof(HevcVideoParameterSet));
318    m_latest_vps.nalu = {
319          // forbidden_zero_bit
320          0u,
321          // nal_unit_type
322          HEVC_NALU_VPS_NUT,
323          // nuh_layer_id
324          0u,
325          // nuh_temporal_id_plus1
326          1u
327       };
328 
329    m_latest_vps.vps_video_parameter_set_id = vps_video_parameter_set_id,
330    m_latest_vps.vps_reserved_three_2bits = 3u;
331    m_latest_vps.vps_max_layers_minus1 = 0u;
332    m_latest_vps.vps_max_sub_layers_minus1 = 0u;
333    m_latest_vps.vps_temporal_id_nesting_flag = 1u;
334    m_latest_vps.vps_reserved_0xffff_16bits = 0xFFFF;
335    init_profile_tier_level(&m_latest_vps.ptl, HEVCProfileIdc, HEVCLevelIdc, isHighTier);
336    m_latest_vps.vps_sub_layer_ordering_info_present_flag = 0u;
337    for (int i = (m_latest_vps.vps_sub_layer_ordering_info_present_flag ? 0 : m_latest_vps.vps_max_sub_layers_minus1); i <= m_latest_vps.vps_max_sub_layers_minus1; i++) {
338       m_latest_vps.vps_max_dec_pic_buffering_minus1[i] = (maxRefFrames/*previous reference frames*/ + 1 /*additional current frame recon pic*/) - 1/**minus1 for header*/;
339       m_latest_vps.vps_max_num_reorder_pics[i] = gopHasBFrames ? m_latest_vps.vps_max_dec_pic_buffering_minus1[i] : 0;
340       m_latest_vps.vps_max_latency_increase_plus1[i] = 0; // When vps_max_latency_increase_plus1[ i ] is equal to 0, no corresponding limit is expressed.
341    }
342 
343    // Print built VPS structure
344    debug_printf("[HEVCBitstreamBuilder] HevcVideoParameterSet Structure generated before writing to bitstream:\n");
345    print_vps(m_latest_vps);
346 
347    m_hevcEncoder.vps_to_nalu_bytes(&m_latest_vps, headerBitstream, placingPositionStart, writtenBytes);
348 
349    if(pVPSStruct != nullptr)
350    {
351       *pVPSStruct = m_latest_vps;
352    }
353 }
354 
355 void
build_sps(const HevcVideoParameterSet & parentVPS,const struct pipe_h265_enc_seq_param & seqData,uint8_t seq_parameter_set_id,const D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC & encodeResolution,const D3D12_BOX & crop_window_upper_layer,const UINT picDimensionMultipleRequirement,const DXGI_FORMAT & inputFmt,const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC & codecConfig,const D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_HEVC & hevcGOP,std::vector<BYTE> & headerBitstream,std::vector<BYTE>::iterator placingPositionStart,size_t & writtenBytes,HevcSeqParameterSet * outputSPS)356 d3d12_video_bitstream_builder_hevc::build_sps(const HevcVideoParameterSet& parentVPS,
357          const struct pipe_h265_enc_seq_param & seqData,
358          uint8_t seq_parameter_set_id,
359          const D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC& encodeResolution,
360          const D3D12_BOX& crop_window_upper_layer,
361          const UINT picDimensionMultipleRequirement,
362          const DXGI_FORMAT& inputFmt,
363          const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC& codecConfig,
364          const D3D12_VIDEO_ENCODER_SEQUENCE_GOP_STRUCTURE_HEVC& hevcGOP,
365          std::vector<BYTE> &headerBitstream,
366          std::vector<BYTE>::iterator placingPositionStart,
367          size_t &writtenBytes,
368          HevcSeqParameterSet* outputSPS)
369 {
370    memset(&m_latest_sps, 0, sizeof(HevcSeqParameterSet));
371 
372    // In case is 420 10 bits
373    if(inputFmt == DXGI_FORMAT_P010)
374    {
375       m_latest_sps.bit_depth_luma_minus8 = 2;
376       m_latest_sps.bit_depth_chroma_minus8 = 2;
377    }
378 
379    uint8_t minCuSize = d3d12_video_encoder_convert_12cusize_to_pixel_size_hevc(codecConfig.MinLumaCodingUnitSize);
380    uint8_t maxCuSize = d3d12_video_encoder_convert_12cusize_to_pixel_size_hevc(codecConfig.MaxLumaCodingUnitSize);
381    uint8_t minTuSize = d3d12_video_encoder_convert_12tusize_to_pixel_size_hevc(codecConfig.MinLumaTransformUnitSize);
382    uint8_t maxTuSize = d3d12_video_encoder_convert_12tusize_to_pixel_size_hevc(codecConfig.MaxLumaTransformUnitSize);
383 
384    m_latest_sps.nalu.nal_unit_type = HEVC_NALU_SPS_NUT;
385    m_latest_sps.nalu.nuh_temporal_id_plus1 = 1;
386 
387    m_latest_sps.sps_seq_parameter_set_id = seq_parameter_set_id;
388    m_latest_sps.sps_max_sub_layers_minus1 = parentVPS.vps_max_sub_layers_minus1;
389    m_latest_sps.sps_temporal_id_nesting_flag = parentVPS.vps_temporal_id_nesting_flag;
390 
391    // inherit PTL from parentVPS fully
392    m_latest_sps.ptl = parentVPS.ptl;
393 
394    m_latest_sps.chroma_format_idc = 1; // 420
395 
396    // Codec spec dictates pic_width/height_in_luma_samples must be divisible by minCuSize but HW might have higher req pow 2 multiples
397    assert((picDimensionMultipleRequirement % minCuSize) == 0u);
398 
399    // upper layer passes the viewport, can calculate the difference between it and pic_width_in_luma_samples
400    D3D12_VIDEO_ENCODER_PICTURE_RESOLUTION_DESC viewport = { };
401    viewport.Width = crop_window_upper_layer.front /* passes height */ - ((crop_window_upper_layer.left + crop_window_upper_layer.right) << 1);
402    viewport.Height = crop_window_upper_layer.back /* passes width */- ((crop_window_upper_layer.top + crop_window_upper_layer.bottom) << 1);
403 
404    m_latest_sps.pic_width_in_luma_samples = ALIGN(encodeResolution.Width, picDimensionMultipleRequirement);
405    m_latest_sps.pic_height_in_luma_samples = ALIGN(encodeResolution.Height, picDimensionMultipleRequirement);
406    m_latest_sps.conf_win_right_offset = (m_latest_sps.pic_width_in_luma_samples - viewport.Width) >> 1;
407    m_latest_sps.conf_win_bottom_offset = (m_latest_sps.pic_height_in_luma_samples - viewport.Height) >> 1;
408    m_latest_sps.conformance_window_flag = m_latest_sps.conf_win_left_offset || m_latest_sps.conf_win_right_offset || m_latest_sps.conf_win_top_offset || m_latest_sps.conf_win_bottom_offset;
409 
410    m_latest_sps.log2_max_pic_order_cnt_lsb_minus4 = hevcGOP.log2_max_pic_order_cnt_lsb_minus4;
411    m_latest_sps.maxPicOrderCntLsb = 1 << (m_latest_sps.log2_max_pic_order_cnt_lsb_minus4 + 4);
412 
413    m_latest_sps.sps_sub_layer_ordering_info_present_flag = parentVPS.vps_sub_layer_ordering_info_present_flag;
414    for (int i = (m_latest_sps.sps_sub_layer_ordering_info_present_flag ? 0 : m_latest_sps.sps_max_sub_layers_minus1); i <= m_latest_sps.sps_max_sub_layers_minus1; i++) {
415       m_latest_sps.sps_max_dec_pic_buffering_minus1[i] = parentVPS.vps_max_dec_pic_buffering_minus1[i];
416       m_latest_sps.sps_max_num_reorder_pics[i] = parentVPS.vps_max_num_reorder_pics[i];
417       m_latest_sps.sps_max_latency_increase_plus1[i] = parentVPS.vps_max_latency_increase_plus1[i];
418    }
419 
420    m_latest_sps.log2_min_luma_coding_block_size_minus3 = static_cast<uint8_t>(std::log2(minCuSize) - 3);
421    m_latest_sps.log2_diff_max_min_luma_coding_block_size = static_cast<uint8_t>(std::log2(maxCuSize) - std::log2(minCuSize));
422    m_latest_sps.log2_min_transform_block_size_minus2 = static_cast<uint8_t>(std::log2(minTuSize) - 2);
423    m_latest_sps.log2_diff_max_min_transform_block_size = static_cast<uint8_t>(std::log2(maxTuSize) - std::log2(minTuSize));
424 
425    m_latest_sps.max_transform_hierarchy_depth_inter = codecConfig.max_transform_hierarchy_depth_inter;
426    m_latest_sps.max_transform_hierarchy_depth_intra = codecConfig.max_transform_hierarchy_depth_intra;
427 
428    m_latest_sps.scaling_list_enabled_flag = 0;
429    m_latest_sps.amp_enabled_flag = ((codecConfig.ConfigurationFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_USE_ASYMETRIC_MOTION_PARTITION) != 0) ? 1u : 0u;
430    m_latest_sps.sample_adaptive_offset_enabled_flag = ((codecConfig.ConfigurationFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_SAO_FILTER) != 0) ? 1u : 0u;
431    m_latest_sps.pcm_enabled_flag = 0;
432 
433    m_latest_sps.num_short_term_ref_pic_sets = 0;
434 
435    m_latest_sps.long_term_ref_pics_present_flag = ((codecConfig.ConfigurationFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_LONG_TERM_REFERENCES) != 0) ? 1u : 0u;
436    m_latest_sps.num_long_term_ref_pics_sps = 0; // signal through slice header for now
437 
438    m_latest_sps.sps_temporal_mvp_enabled_flag = 0;
439    m_latest_sps.strong_intra_smoothing_enabled_flag = 0;
440 
441    m_latest_sps.vui_parameters_present_flag = seqData.vui_parameters_present_flag;
442    m_latest_sps.vui.aspect_ratio_idc = seqData.aspect_ratio_idc;
443    m_latest_sps.vui.sar_width = seqData.sar_width;
444    m_latest_sps.vui.sar_height = seqData.sar_height;
445    m_latest_sps.vui.video_format = seqData.video_format;
446    m_latest_sps.vui.video_full_range_flag = seqData.video_full_range_flag;
447    m_latest_sps.vui.colour_primaries = seqData.colour_primaries;
448    m_latest_sps.vui.transfer_characteristics = seqData.transfer_characteristics;
449    m_latest_sps.vui.matrix_coeffs = seqData.matrix_coefficients;
450    m_latest_sps.vui.chroma_sample_loc_type_top_field = seqData.chroma_sample_loc_type_top_field;
451    m_latest_sps.vui.chroma_sample_loc_type_bottom_field = seqData.chroma_sample_loc_type_bottom_field;
452    m_latest_sps.vui.def_disp_win_left_offset = seqData.def_disp_win_left_offset;
453    m_latest_sps.vui.def_disp_win_right_offset = seqData.def_disp_win_right_offset;
454    m_latest_sps.vui.def_disp_win_top_offset = seqData.def_disp_win_top_offset;
455    m_latest_sps.vui.def_disp_win_bottom_offset = seqData.def_disp_win_bottom_offset;
456    m_latest_sps.vui.num_units_in_tick = seqData.num_units_in_tick;
457    m_latest_sps.vui.time_scale = seqData.time_scale;
458    m_latest_sps.vui.num_ticks_poc_diff_one_minus1 = seqData.num_ticks_poc_diff_one_minus1;
459    m_latest_sps.vui.min_spatial_segmentation_idc = seqData.min_spatial_segmentation_idc;
460    m_latest_sps.vui.max_bytes_per_pic_denom = seqData.max_bytes_per_pic_denom;
461    m_latest_sps.vui.max_bits_per_min_cu_denom = seqData.max_bits_per_min_cu_denom;
462    m_latest_sps.vui.log2_max_mv_length_horizontal = seqData.log2_max_mv_length_horizontal;
463    m_latest_sps.vui.log2_max_mv_length_vertical = seqData.log2_max_mv_length_vertical;
464    m_latest_sps.vui.aspect_ratio_info_present_flag = seqData.vui_flags.aspect_ratio_info_present_flag;
465    m_latest_sps.vui.timing_info_present_flag = seqData.vui_flags.timing_info_present_flag;
466    m_latest_sps.vui.video_signal_type_present_flag = seqData.vui_flags.video_signal_type_present_flag;
467    m_latest_sps.vui.colour_description_present_flag = seqData.vui_flags.colour_description_present_flag;
468    m_latest_sps.vui.chroma_loc_info_present_flag = seqData.vui_flags.chroma_loc_info_present_flag;
469    m_latest_sps.vui.overscan_info_present_flag = seqData.vui_flags.overscan_info_present_flag;
470    m_latest_sps.vui.overscan_appropriate_flag = seqData.vui_flags.overscan_appropriate_flag;
471    m_latest_sps.vui.neutral_chroma_indication_flag = seqData.vui_flags.neutral_chroma_indication_flag;
472    m_latest_sps.vui.field_seq_flag = seqData.vui_flags.field_seq_flag;
473    m_latest_sps.vui.frame_field_info_present_flag = seqData.vui_flags.frame_field_info_present_flag;
474    m_latest_sps.vui.default_display_window_flag = seqData.vui_flags.default_display_window_flag;
475    m_latest_sps.vui.poc_proportional_to_timing_flag = seqData.vui_flags.poc_proportional_to_timing_flag;
476    m_latest_sps.vui.hrd_parameters_present_flag = seqData.vui_flags.hrd_parameters_present_flag;
477    m_latest_sps.vui.bitstream_restriction_flag = seqData.vui_flags.bitstream_restriction_flag;
478    m_latest_sps.vui.tiles_fixed_structure_flag = seqData.vui_flags.tiles_fixed_structure_flag;
479    m_latest_sps.vui.motion_vectors_over_pic_boundaries_flag = seqData.vui_flags.motion_vectors_over_pic_boundaries_flag;
480    m_latest_sps.vui.restricted_ref_pic_lists_flag = seqData.vui_flags.restricted_ref_pic_lists_flag;
481 
482    m_latest_sps.sps_extension_flag = 0;
483 
484    // Print built SPS structure
485    debug_printf("[HEVCBitstreamBuilder] HevcSeqParameterSet Structure generated before writing to bitstream:\n");
486    print_sps(m_latest_sps);
487 
488    m_hevcEncoder.sps_to_nalu_bytes(&m_latest_sps, headerBitstream, placingPositionStart, writtenBytes);
489 
490    if(outputSPS != nullptr)
491    {
492       *outputSPS = m_latest_sps;
493    }
494 }
495 
496 void
build_pps(const HevcSeqParameterSet & parentSPS,uint8_t pic_parameter_set_id,const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC & codecConfig,const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC & pictureControl,std::vector<BYTE> & headerBitstream,std::vector<BYTE>::iterator placingPositionStart,size_t & writtenBytes,HevcPicParameterSet * outputPPS)497 d3d12_video_bitstream_builder_hevc::build_pps(const HevcSeqParameterSet& parentSPS,
498          uint8_t pic_parameter_set_id,
499          const D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC& codecConfig,
500          const D3D12_VIDEO_ENCODER_PICTURE_CONTROL_CODEC_DATA_HEVC& pictureControl,
501          std::vector<BYTE> &headerBitstream,
502          std::vector<BYTE>::iterator placingPositionStart,
503          size_t &writtenBytes,
504          HevcPicParameterSet* outputPPS)
505 {
506    memset(&m_latest_pps, 0, sizeof(HevcPicParameterSet));
507 
508    m_latest_pps.nalu.nal_unit_type = HEVC_NALU_PPS_NUT;
509    m_latest_pps.nalu.nuh_temporal_id_plus1 = 1;
510 
511    m_latest_pps.pps_pic_parameter_set_id = pic_parameter_set_id;
512    m_latest_pps.pps_seq_parameter_set_id = parentSPS.sps_seq_parameter_set_id;
513 
514    m_latest_pps.weighted_pred_flag = 0u; // no weighted prediction in D3D12
515 
516    m_latest_pps.num_ref_idx_lx_default_active_minus1[0] = static_cast<uint8_t>(std::max(static_cast<INT>(pictureControl.List0ReferenceFramesCount) - 1, 0));
517    m_latest_pps.num_ref_idx_lx_default_active_minus1[1] = static_cast<uint8_t>(std::max(static_cast<INT>(pictureControl.List1ReferenceFramesCount) - 1, 0));
518 
519    m_latest_pps.num_tile_columns_minus1 = 0u; // no tiling in D3D12
520    m_latest_pps.num_tile_rows_minus1 = 0u; // no tiling in D3D12
521    m_latest_pps.tiles_enabled_flag = 0u; // no tiling in D3D12
522    m_latest_pps.loop_filter_across_tiles_enabled_flag = 0;
523 
524    m_latest_pps.lists_modification_present_flag = 0;
525    m_latest_pps.log2_parallel_merge_level_minus2 = 0;
526 
527    m_latest_pps.deblocking_filter_control_present_flag = 1;
528    m_latest_pps.deblocking_filter_override_enabled_flag = 0;
529    m_latest_pps.pps_deblocking_filter_disabled_flag = 0;
530    m_latest_pps.pps_scaling_list_data_present_flag = 0;
531    m_latest_pps.pps_beta_offset_div2 = 0;
532    m_latest_pps.pps_tc_offset_div2 = 0;
533    m_latest_pps.pps_loop_filter_across_slices_enabled_flag = ((codecConfig.ConfigurationFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_DISABLE_LOOP_FILTER_ACROSS_SLICES) != 0) ? 0 : 1;
534    m_latest_pps.transform_skip_enabled_flag = ((codecConfig.ConfigurationFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_ENABLE_TRANSFORM_SKIPPING) != 0) ? 1 : 0;
535    m_latest_pps.constrained_intra_pred_flag = ((codecConfig.ConfigurationFlags & D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_HEVC_FLAG_USE_CONSTRAINED_INTRAPREDICTION) != 0) ? 1 : 0;
536    m_latest_pps.cabac_init_present_flag = 1;
537    m_latest_pps.pps_slice_chroma_qp_offsets_present_flag = 1;
538    m_latest_pps.cu_qp_delta_enabled_flag = 1;
539 
540    // Print built PPS structure
541    debug_printf("[HEVCBitstreamBuilder] HevcPicParameterSet Structure generated before writing to bitstream:\n");
542    print_pps(m_latest_pps);
543 
544    m_hevcEncoder.pps_to_nalu_bytes(&m_latest_pps, headerBitstream, placingPositionStart, writtenBytes);
545 
546    if(outputPPS != nullptr)
547    {
548       *outputPPS = m_latest_pps;
549    }
550 }
551 
552 void
write_end_of_stream_nalu(std::vector<uint8_t> & headerBitstream,std::vector<uint8_t>::iterator placingPositionStart,size_t & writtenBytes)553 d3d12_video_bitstream_builder_hevc::write_end_of_stream_nalu(std::vector<uint8_t> &         headerBitstream,
554                         std::vector<uint8_t>::iterator placingPositionStart,
555                         size_t &                       writtenBytes)
556 {
557    m_hevcEncoder.write_end_of_stream_nalu(headerBitstream, placingPositionStart, writtenBytes);
558 }
559 void
write_end_of_sequence_nalu(std::vector<uint8_t> & headerBitstream,std::vector<uint8_t>::iterator placingPositionStart,size_t & writtenBytes)560 d3d12_video_bitstream_builder_hevc::write_end_of_sequence_nalu(std::vector<uint8_t> &         headerBitstream,
561                            std::vector<uint8_t>::iterator placingPositionStart,
562                            size_t &                       writtenBytes)
563 {
564    m_hevcEncoder.write_end_of_sequence_nalu(headerBitstream, placingPositionStart, writtenBytes);
565 }
566 
567 void
print_vps(const HevcVideoParameterSet & VPS)568 d3d12_video_bitstream_builder_hevc::print_vps(const HevcVideoParameterSet& VPS)
569 {
570    debug_printf("--------------------------------------\nHevcVideoParameterSet values below:\n");
571 
572    debug_printf("vps_video_parameter_set_id: %d\n", VPS.vps_video_parameter_set_id);
573    debug_printf("vps_reserved_three_2bits: %d\n", VPS.vps_reserved_three_2bits);
574    debug_printf("vps_max_layers_minus1: %d\n", VPS.vps_max_layers_minus1);
575    debug_printf("vps_max_sub_layers_minus1: %d\n", VPS.vps_max_sub_layers_minus1);
576    debug_printf("vps_temporal_id_nesting_flag: %d\n", VPS.vps_temporal_id_nesting_flag);
577 
578    debug_printf("general_profile_space: %d\n", VPS.ptl.general_profile_space);
579    debug_printf("general_tier_flag: %d\n", VPS.ptl.general_tier_flag);
580    debug_printf("general_profile_idc: %d\n", VPS.ptl.general_profile_idc);
581    debug_printf("general_progressive_source_flag: %d\n", VPS.ptl.general_progressive_source_flag);
582    debug_printf("general_interlaced_source_flag: %d\n", VPS.ptl.general_interlaced_source_flag);
583    debug_printf("general_non_packed_constraint_flag: %d\n", VPS.ptl.general_non_packed_constraint_flag);
584    debug_printf("general_frame_only_constraint_flag: %d\n", VPS.ptl.general_frame_only_constraint_flag);
585    debug_printf("general_level_idc: %d\n", VPS.ptl.general_level_idc);
586 
587    debug_printf("vps_sub_layer_ordering_info_present_flag: %d\n", VPS.vps_sub_layer_ordering_info_present_flag);
588    debug_printf("vps_max_dec_pic_buffering_minus1[%d]: %d\n", (0u), VPS.vps_max_dec_pic_buffering_minus1[0u]);
589    debug_printf("vps_max_num_reorder_pics[%d]: %d\n", (0u), VPS.vps_max_num_reorder_pics[0u]);
590    debug_printf("vps_max_latency_increase_plus1[%d]: %d\n", (0u), VPS.vps_max_latency_increase_plus1[0u]);
591    debug_printf("vps_max_layer_id: %d\n", VPS.vps_max_layer_id);
592    debug_printf("vps_num_layer_sets_minus1: %d\n", VPS.vps_num_layer_sets_minus1);
593    debug_printf("vps_timing_info_present_flag: %d\n", VPS.vps_timing_info_present_flag);
594    debug_printf("vps_num_units_in_tick: %d\n", VPS.vps_num_units_in_tick);
595    debug_printf("vps_time_scale: %d\n", VPS.vps_time_scale);
596    debug_printf("vps_poc_proportional_to_timing_flag: %d\n", VPS.vps_poc_proportional_to_timing_flag);
597    debug_printf("vps_num_ticks_poc_diff_one_minus1: %d\n", VPS.vps_num_ticks_poc_diff_one_minus1);
598    debug_printf("vps_num_hrd_parameters: %d\n", VPS.vps_num_hrd_parameters);
599    debug_printf("vps_extension_flag: %d\n", VPS.vps_extension_flag);
600    debug_printf("vps_extension_data_flag: %d\n", VPS.vps_extension_data_flag);
601 
602    debug_printf("HevcVideoParameterSet values end\n--------------------------------------\n");
603 }
604 void
print_sps(const HevcSeqParameterSet & SPS)605 d3d12_video_bitstream_builder_hevc::print_sps(const HevcSeqParameterSet& SPS)
606 {
607    debug_printf("--------------------------------------\nHevcSeqParameterSet values below:\n");
608 
609    debug_printf("sps_video_parameter_set_id: %d\n", SPS.sps_video_parameter_set_id);
610    debug_printf("sps_max_sub_layers_minus1: %d\n", SPS.sps_max_sub_layers_minus1);
611    debug_printf("sps_temporal_id_nesting_flag: %d\n", SPS.sps_temporal_id_nesting_flag);
612 
613    debug_printf("general_profile_space: %d\n", SPS.ptl.general_profile_space);
614    debug_printf("general_tier_flag: %d\n", SPS.ptl.general_tier_flag);
615    debug_printf("general_profile_idc: %d\n", SPS.ptl.general_profile_idc);
616    debug_printf("general_progressive_source_flag: %d\n", SPS.ptl.general_progressive_source_flag);
617    debug_printf("general_interlaced_source_flag: %d\n", SPS.ptl.general_interlaced_source_flag);
618    debug_printf("general_non_packed_constraint_flag: %d\n", SPS.ptl.general_non_packed_constraint_flag);
619    debug_printf("general_frame_only_constraint_flag: %d\n", SPS.ptl.general_frame_only_constraint_flag);
620    debug_printf("general_level_idc: %d\n", SPS.ptl.general_level_idc);
621 
622    debug_printf("sps_seq_parameter_set_id: %d\n", SPS.sps_seq_parameter_set_id);
623    debug_printf("chroma_format_idc: %d\n", SPS.chroma_format_idc);
624    debug_printf("separate_colour_plane_flag: %d\n", SPS.separate_colour_plane_flag);
625    debug_printf("pic_width_in_luma_samples: %d\n", SPS.pic_width_in_luma_samples);
626    debug_printf("pic_height_in_luma_samples: %d\n", SPS.pic_height_in_luma_samples);
627    debug_printf("conformance_window_flag: %d\n", SPS.conformance_window_flag);
628    debug_printf("conf_win_left_offset: %d\n", SPS.conf_win_left_offset);
629    debug_printf("conf_win_right_offset: %d\n", SPS.conf_win_right_offset);
630    debug_printf("conf_win_top_offset: %d\n", SPS.conf_win_top_offset);
631    debug_printf("conf_win_bottom_offset: %d\n", SPS.conf_win_bottom_offset);
632    debug_printf("bit_depth_luma_minus8: %d\n", SPS.bit_depth_luma_minus8);
633    debug_printf("bit_depth_chroma_minus8: %d\n", SPS.bit_depth_chroma_minus8);
634    debug_printf("log2_max_pic_order_cnt_lsb_minus4: %d\n", SPS.log2_max_pic_order_cnt_lsb_minus4);
635    debug_printf("maxPicOrderCntLsb: %d\n", SPS.maxPicOrderCntLsb);
636    debug_printf("sps_sub_layer_ordering_info_present_flag: %d\n", SPS.sps_sub_layer_ordering_info_present_flag);
637 
638    debug_printf("sps_max_dec_pic_buffering_minus1[%d]: %d\n", (0u), SPS.sps_max_dec_pic_buffering_minus1[0u]);
639    debug_printf("sps_max_num_reorder_pics[%d]: %d\n", (0u), SPS.sps_max_num_reorder_pics[0u]);
640    debug_printf("sps_max_latency_increase_plus1[%d]: %d\n", (0u), SPS.sps_max_latency_increase_plus1[0u]);
641 
642    debug_printf("log2_min_luma_coding_block_size_minus3: %d\n", SPS.log2_min_luma_coding_block_size_minus3);
643    debug_printf("log2_diff_max_min_luma_coding_block_size: %d\n", SPS.log2_diff_max_min_luma_coding_block_size);
644    debug_printf("log2_min_transform_block_size_minus2: %d\n", SPS.log2_min_transform_block_size_minus2);
645    debug_printf("log2_diff_max_min_transform_block_size: %d\n", SPS.log2_diff_max_min_transform_block_size);
646    debug_printf("max_transform_hierarchy_depth_inter: %d\n", SPS.max_transform_hierarchy_depth_inter);
647    debug_printf("max_transform_hierarchy_depth_intra: %d\n", SPS.max_transform_hierarchy_depth_intra);
648    debug_printf("scaling_list_enabled_flag: %d\n", SPS.scaling_list_enabled_flag);
649    debug_printf("sps_scaling_list_data_present_flag: %d\n", SPS.sps_scaling_list_data_present_flag);
650    debug_printf("amp_enabled_flag: %d\n", SPS.amp_enabled_flag);
651    debug_printf("sample_adaptive_offset_enabled_flag: %d\n", SPS.sample_adaptive_offset_enabled_flag);
652    debug_printf("pcm_enabled_flag: %d\n", SPS.pcm_enabled_flag);
653    debug_printf("pcm_sample_bit_depth_luma_minus1: %d\n", SPS.pcm_sample_bit_depth_luma_minus1);
654    debug_printf("pcm_sample_bit_depth_chroma_minus1: %d\n", SPS.pcm_sample_bit_depth_chroma_minus1);
655    debug_printf("log2_min_pcm_luma_coding_block_size_minus3: %d\n", SPS.log2_min_pcm_luma_coding_block_size_minus3);
656    debug_printf("log2_diff_max_min_pcm_luma_coding_block_size: %d\n", SPS.log2_diff_max_min_pcm_luma_coding_block_size);
657    debug_printf("pcm_loop_filter_disabled_flag: %d\n", SPS.pcm_loop_filter_disabled_flag);
658    debug_printf("num_short_term_ref_pic_sets: %d\n", SPS.num_short_term_ref_pic_sets);
659 
660    for(UINT idx = 0; idx < SPS.num_short_term_ref_pic_sets ; idx++)
661    {
662       print_rps(&SPS, idx);
663    }
664 
665    debug_printf("long_term_ref_pics_present_flag: %d\n", SPS.long_term_ref_pics_present_flag);
666    debug_printf("num_long_term_ref_pics_sps: %d\n", SPS.num_long_term_ref_pics_sps);
667 
668    for(UINT idx = 0; idx < SPS.num_long_term_ref_pics_sps ; idx++)
669    {
670       debug_printf("lt_ref_pic_poc_lsb_sps[%d]: %d\n", idx, SPS.lt_ref_pic_poc_lsb_sps[idx]);
671       debug_printf("used_by_curr_pic_lt_sps_flag[%d]: %d\n", idx, SPS.used_by_curr_pic_lt_sps_flag[idx]);
672    }
673 
674    debug_printf("sps_temporal_mvp_enabled_flag: %d\n", SPS.sps_temporal_mvp_enabled_flag);
675    debug_printf("strong_intra_smoothing_enabled_flag: %d\n", SPS.strong_intra_smoothing_enabled_flag);
676    debug_printf("vui_parameters_present_flag: %d\n", SPS.vui_parameters_present_flag);
677    debug_printf("aspect_ratio_info_present_flag: %d\n", SPS.vui.aspect_ratio_info_present_flag);
678    debug_printf("aspect_ratio_idc: %d\n", SPS.vui.aspect_ratio_idc);
679    debug_printf("sar_width: %d\n", SPS.vui.sar_width);
680    debug_printf("sar_height: %d\n", SPS.vui.sar_height);
681    debug_printf("overscan_info_present_flag: %d\n", SPS.vui.overscan_info_present_flag);
682    debug_printf("overscan_appropriate_flag: %d\n", SPS.vui.overscan_appropriate_flag);
683    debug_printf("video_signal_type_present_flag: %d\n", SPS.vui.video_signal_type_present_flag);
684    debug_printf("video_format: %d\n", SPS.vui.video_format);
685    debug_printf("video_full_range_flag: %d\n", SPS.vui.video_full_range_flag);
686    debug_printf("colour_description_present_flag: %d\n", SPS.vui.colour_description_present_flag);
687    debug_printf("colour_primaries: %d\n", SPS.vui.colour_primaries);
688    debug_printf("transfer_characteristics: %d\n", SPS.vui.transfer_characteristics);
689    debug_printf("matrix_coeffs: %d\n", SPS.vui.matrix_coeffs);
690    debug_printf("chroma_loc_info_present_flag: %d\n", SPS.vui.chroma_loc_info_present_flag);
691    debug_printf("chroma_sample_loc_type_top_field: %d\n", SPS.vui.chroma_sample_loc_type_top_field);
692    debug_printf("chroma_sample_loc_type_bottom_field: %d\n", SPS.vui.chroma_sample_loc_type_bottom_field);
693    debug_printf("neutral_chroma_indication_flag: %d\n", SPS.vui.neutral_chroma_indication_flag);
694    debug_printf("field_seq_flag: %d\n", SPS.vui.field_seq_flag);
695    debug_printf("frame_field_info_present_flag: %d\n", SPS.vui.frame_field_info_present_flag);
696    debug_printf("default_display_window_flag: %d\n", SPS.vui.default_display_window_flag);
697    debug_printf("def_disp_win_left_offset: %d\n", SPS.vui.def_disp_win_left_offset);
698    debug_printf("def_disp_win_right_offset: %d\n", SPS.vui.def_disp_win_right_offset);
699    debug_printf("def_disp_win_top_offset: %d\n", SPS.vui.def_disp_win_top_offset);
700    debug_printf("def_disp_win_bottom_offset: %d\n", SPS.vui.def_disp_win_bottom_offset);
701    debug_printf("timing_info_present_flag: %d\n", SPS.vui.timing_info_present_flag);
702    debug_printf("num_units_in_tick: %d\n", SPS.vui.num_units_in_tick);
703    debug_printf("time_scale: %d\n", SPS.vui.time_scale);
704    debug_printf("poc_proportional_to_timing_flag: %d\n", SPS.vui.poc_proportional_to_timing_flag);
705    debug_printf("num_ticks_poc_diff_one_minus1: %d\n", SPS.vui.num_ticks_poc_diff_one_minus1);
706    debug_printf("hrd_parameters_present_flag: %d\n", SPS.vui.hrd_parameters_present_flag);
707    debug_printf("bitstream_restriction_flag: %d\n", SPS.vui.bitstream_restriction_flag);
708    debug_printf("tiles_fixed_structure_flag: %d\n", SPS.vui.tiles_fixed_structure_flag);
709    debug_printf("motion_vectors_over_pic_boundaries_flag: %d\n", SPS.vui.motion_vectors_over_pic_boundaries_flag);
710    debug_printf("restricted_ref_pic_lists_flag: %d\n", SPS.vui.restricted_ref_pic_lists_flag);
711    debug_printf("min_spatial_segmentation_idc: %d\n", SPS.vui.min_spatial_segmentation_idc);
712    debug_printf("max_bytes_per_pic_denom: %d\n", SPS.vui.max_bytes_per_pic_denom);
713    debug_printf("max_bits_per_min_cu_denom: %d\n", SPS.vui.max_bits_per_min_cu_denom);
714    debug_printf("log2_max_mv_length_horizontal: %d\n", SPS.vui.log2_max_mv_length_horizontal);
715    debug_printf("log2_max_mv_length_vertical: %d\n", SPS.vui.log2_max_mv_length_vertical);
716    debug_printf("sps_extension_flag: %d\n", SPS.sps_extension_flag);
717    debug_printf("sps_extension_data_flag: %d\n", SPS.sps_extension_data_flag);
718 
719    debug_printf("HevcSeqParameterSet values end\n--------------------------------------\n");
720 }
721 void
print_pps(const HevcPicParameterSet & PPS)722 d3d12_video_bitstream_builder_hevc::print_pps(const HevcPicParameterSet& PPS)
723 {
724    debug_printf("--------------------------------------\nHevcPicParameterSet values below:\n");
725    debug_printf("pps_pic_parameter_set_id: %d\n", PPS.pps_pic_parameter_set_id);
726    debug_printf("pps_seq_parameter_set_id: %d\n", PPS.pps_seq_parameter_set_id);
727    debug_printf("dependent_slice_segments_enabled_flag: %d\n", PPS.dependent_slice_segments_enabled_flag);
728    debug_printf("output_flag_present_flag: %d\n", PPS.output_flag_present_flag);
729    debug_printf("num_extra_slice_header_bits: %d\n", PPS.num_extra_slice_header_bits);
730    debug_printf("sign_data_hiding_enabled_flag: %d\n", PPS.sign_data_hiding_enabled_flag);
731    debug_printf("cabac_init_present_flag: %d\n", PPS.cabac_init_present_flag);
732    debug_printf("num_ref_idx_l0_default_active_minus1: %d\n", PPS.num_ref_idx_lx_default_active_minus1[0]);
733    debug_printf("num_ref_idx_l1_default_active_minus1: %d\n", PPS.num_ref_idx_lx_default_active_minus1[1]);
734    debug_printf("init_qp_minus26: %d\n", PPS.init_qp_minus26);
735    debug_printf("constrained_intra_pred_flag: %d\n", PPS.constrained_intra_pred_flag);
736    debug_printf("transform_skip_enabled_flag: %d\n", PPS.transform_skip_enabled_flag);
737    debug_printf("cu_qp_delta_enabled_flag: %d\n", PPS.cu_qp_delta_enabled_flag);
738    debug_printf("diff_cu_qp_delta_depth: %d\n", PPS.diff_cu_qp_delta_depth);
739    debug_printf("pps_cb_qp_offset: %d\n", PPS.pps_cb_qp_offset);
740    debug_printf("pps_cr_qp_offset: %d\n", PPS.pps_cr_qp_offset);
741    debug_printf("pps_slice_chroma_qp_offsets_present_flag: %d\n", PPS.pps_slice_chroma_qp_offsets_present_flag);
742    debug_printf("weighted_pred_flag: %d\n", PPS.weighted_pred_flag);
743    debug_printf("weighted_bipred_flag: %d\n", PPS.weighted_bipred_flag);
744    debug_printf("transquant_bypass_enabled_flag: %d\n", PPS.transquant_bypass_enabled_flag);
745    debug_printf("tiles_enabled_flag: %d\n", PPS.tiles_enabled_flag);
746    debug_printf("entropy_coding_sync_enabled_flag: %d\n", PPS.entropy_coding_sync_enabled_flag);
747    debug_printf("num_tile_columns_minus1: %d\n", PPS.num_tile_columns_minus1);
748    debug_printf("num_tile_rows_minus1: %d\n", PPS.num_tile_rows_minus1);
749    debug_printf("uniform_spacing_flag: %d\n", PPS.uniform_spacing_flag);
750    debug_printf("column_width_minus1[0]: %d\n", PPS.column_width_minus1[0]); // no tiles in D3D12)
751    debug_printf("row_height_minus1[0]: %d\n", PPS.row_height_minus1[0]); // no tiles in D3D12)
752    debug_printf("loop_filter_across_tiles_enabled_flag: %d\n", PPS.loop_filter_across_tiles_enabled_flag);
753    debug_printf("pps_loop_filter_across_slices_enabled_flag: %d\n", PPS.pps_loop_filter_across_slices_enabled_flag);
754    debug_printf("deblocking_filter_control_present_flag: %d\n", PPS.deblocking_filter_control_present_flag);
755    debug_printf("deblocking_filter_override_enabled_flag: %d\n", PPS.deblocking_filter_override_enabled_flag);
756    debug_printf("pps_deblocking_filter_disabled_flag: %d\n", PPS.pps_deblocking_filter_disabled_flag);
757    debug_printf("pps_beta_offset_div2: %d\n", PPS.pps_beta_offset_div2);
758    debug_printf("pps_tc_offset_div2: %d\n", PPS.pps_tc_offset_div2);
759    debug_printf("pps_scaling_list_data_present_flag: %d\n", PPS.pps_scaling_list_data_present_flag);
760    debug_printf("lists_modification_present_flag: %d\n", PPS.lists_modification_present_flag);
761    debug_printf("log2_parallel_merge_level_minus2: %d\n", PPS.log2_parallel_merge_level_minus2);
762    debug_printf("slice_segment_header_extension_present_flag: %d\n", PPS.slice_segment_header_extension_present_flag);
763    debug_printf("pps_extension_flag: %d\n", PPS.pps_extension_flag);
764    debug_printf("pps_extension_data_flag: %d\n", PPS.pps_extension_data_flag);
765    debug_printf("HevcPicParameterSet values end\n--------------------------------------\n");
766 }
767 
768 void
print_rps(const HevcSeqParameterSet * sps,UINT stRpsIdx)769 d3d12_video_bitstream_builder_hevc::print_rps(const HevcSeqParameterSet* sps, UINT stRpsIdx)
770 {
771    const HEVCReferencePictureSet* rps = &(sps->rpsShortTerm[stRpsIdx]);
772 
773    debug_printf("--------------------------------------\nHEVCReferencePictureSet[%d] values below:\n", stRpsIdx);
774 
775    debug_printf("inter_ref_pic_set_prediction_flag: %d\n", rps->inter_ref_pic_set_prediction_flag);
776 
777    if(rps->inter_ref_pic_set_prediction_flag)
778    {
779       debug_printf("delta_idx_minus1: %d\n", rps->delta_idx_minus1);
780       debug_printf("delta_rps_sign: %d\n", rps->delta_rps_sign);
781       debug_printf("abs_delta_rps_minus1: %d\n", rps->abs_delta_rps_minus1);
782       debug_printf("num_negative_pics: %d\n", rps->num_negative_pics);
783       debug_printf("num_positive_pics: %d\n", rps->num_positive_pics);
784 
785       int32_t RefRpsIdx = stRpsIdx - 1 - rps->delta_idx_minus1;
786       const HEVCReferencePictureSet* rpsRef = &(sps->rpsShortTerm[RefRpsIdx]);
787       auto numberOfPictures = rpsRef->num_negative_pics + rpsRef->num_positive_pics;
788       for (uint8_t j = 0; j <= numberOfPictures; j++) {
789          debug_printf("used_by_curr_pic_flag[%d]: %d\n", j, rps->used_by_curr_pic_flag[j]);
790          if (!rps->used_by_curr_pic_flag[j]) {
791                debug_printf("use_delta_flag[%d]: %d\n", j, rps->use_delta_flag[j]);
792          }
793       }
794    }
795    else
796    {
797       debug_printf("num_negative_pics: %d\n", rps->num_negative_pics);
798       for (uint8_t i = 0; i < rps->num_negative_pics; i++) {
799          debug_printf("delta_poc_s0_minus1[%d]: %d\n", i, rps->delta_poc_s0_minus1[i]);
800          debug_printf("used_by_curr_pic_s0_flag[%d]: %d\n", i, rps->used_by_curr_pic_s0_flag[i]);
801       }
802 
803       debug_printf("num_positive_pics: %d\n", rps->num_positive_pics);
804       for (int32_t i = 0; i < rps->num_positive_pics; i++) {
805          debug_printf("delta_poc_s1_minus1[%d]: %d\n", i, rps->delta_poc_s1_minus1[i]);
806          debug_printf("used_by_curr_pic_s1_flag[%d]: %d\n", i, rps->used_by_curr_pic_s1_flag[i]);
807       }
808    }
809 
810    debug_printf("HEVCReferencePictureSet values end\n--------------------------------------\n");
811 }
812