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