1 // Copyright (c) 2019-2020 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #pragma once
22 
23 #include "mfx_common.h"
24 #if defined(MFX_ENABLE_H265_VIDEO_ENCODE)
25 
26 #include "hevcehw_base.h"
27 #include "hevcehw_ddi.h"
28 #include "ehw_resources_pool.h"
29 #include "ehw_device.h"
30 #include <vector>
31 
32 namespace HEVCEHW
33 {
34 namespace Base
35 {
36     static const GUID DXVA2_Intel_Encode_HEVC_Main =
37     { 0x28566328, 0xf041, 0x4466,{ 0x8b, 0x14, 0x8f, 0x58, 0x31, 0xe7, 0x8f, 0x8b } };
38     static const GUID DXVA2_Intel_Encode_HEVC_Main10 =
39     { 0x6b4a94db, 0x54fe, 0x4ae1,{ 0x9b, 0xe4, 0x7a, 0x7d, 0xad, 0x00, 0x46, 0x00 } };
40     static const GUID DXVA2_Intel_LowpowerEncode_HEVC_Main =
41     { 0xb8b28e0c, 0xecab, 0x4217,{ 0x8c, 0x82, 0xea, 0xaa, 0x97, 0x55, 0xaa, 0xf0 } };
42     static const GUID DXVA2_Intel_LowpowerEncode_HEVC_Main10 =
43     { 0x8732ecfd, 0x9747, 0x4897,{ 0xb4, 0x2a, 0xe5, 0x34, 0xf9, 0xff, 0x2b, 0x7a } };
44     static const GUID DXVA2_Intel_Encode_HEVC_Main422 =
45     { 0x056a6e36, 0xf3a8, 0x4d00,{ 0x96, 0x63, 0x7e, 0x94, 0x30, 0x35, 0x8b, 0xf9 } };
46     static const GUID DXVA2_Intel_Encode_HEVC_Main422_10 =
47     { 0xe139b5ca, 0x47b2, 0x40e1,{ 0xaf, 0x1c, 0xad, 0x71, 0xa6, 0x7a, 0x18, 0x36 } };
48     static const GUID DXVA2_Intel_Encode_HEVC_Main444 =
49     { 0x5415a68c, 0x231e, 0x46f4,{ 0x87, 0x8b, 0x5e, 0x9a, 0x22, 0xe9, 0x67, 0xe9 } };
50     static const GUID DXVA2_Intel_Encode_HEVC_Main444_10 =
51     { 0x161be912, 0x44c2, 0x49c0,{ 0xb6, 0x1e, 0xd9, 0x46, 0x85, 0x2b, 0x32, 0xa1 } };
52     static const GUID DXVA2_Intel_LowpowerEncode_HEVC_Main422 =
53     { 0xcee393ab, 0x1030, 0x4f7b,{ 0x8d, 0xbc, 0x55, 0x62, 0x9c, 0x72, 0xf1, 0x7e } };
54     static const GUID DXVA2_Intel_LowpowerEncode_HEVC_Main422_10 =
55     { 0x580da148, 0xe4bf, 0x49b1,{ 0x94, 0x3b, 0x42, 0x14, 0xab, 0x05, 0xa6, 0xff } };
56     static const GUID DXVA2_Intel_LowpowerEncode_HEVC_Main444 =
57     { 0x87b2ae39, 0xc9a5, 0x4c53,{ 0x86, 0xb8, 0xa5, 0x2d, 0x7e, 0xdb, 0xa4, 0x88 } };
58     static const GUID DXVA2_Intel_LowpowerEncode_HEVC_Main444_10 =
59     { 0x10e19ac8, 0xbf39, 0x4443,{ 0xbe, 0xc3, 0x1b, 0x0c, 0xbf, 0xe4, 0xc7, 0xaa } };
60 
61     class EndOfBuffer : public std::exception
62     {
63     public:
EndOfBuffer()64         EndOfBuffer() : std::exception() {}
65     };
66 
67     constexpr mfxU8  MAX_DPB_SIZE               = 15;
68     constexpr mfxU8  IDX_INVALID                = 0xff;
69     constexpr mfxU8  HW_SURF_ALIGN_W            = 16;
70     constexpr mfxU8  HW_SURF_ALIGN_H            = 16;
71     constexpr mfxU16 MAX_SLICES                 = 600; // conforms to level 6 limits
72     constexpr mfxU8  DEFAULT_LTR_INTERVAL       = 16;
73     constexpr mfxU8  DEFAULT_PPYR_INTERVAL      = 3;
74     constexpr mfxU16 GOP_INFINITE               = 0xFFFF;
75     constexpr mfxU8  MAX_NUM_TILE_COLUMNS       = 20;
76     constexpr mfxU8  MAX_NUM_TILE_ROWS          = 22;
77     constexpr mfxU8  MAX_NUM_LONG_TERM_PICS     = 8;
78     constexpr mfxU16 MIN_TILE_WIDTH_IN_SAMPLES  = 256;
79     constexpr mfxU16 MIN_TILE_HEIGHT_IN_SAMPLES = 64;
80 
81     enum NALU_TYPE
82     {
83         TRAIL_N = 0,
84         TRAIL_R,
85         TSA_N, TSA_R,
86         STSA_N, STSA_R,
87         RADL_N, RADL_R,
88         RASL_N, RASL_R,
89         RSV_VCL_N10, RSV_VCL_R11, RSV_VCL_N12, RSV_VCL_R13, RSV_VCL_N14, RSV_VCL_R15,
90         BLA_W_LP, BLA_W_RADL, BLA_N_LP,
91         IDR_W_RADL, IDR_N_LP,
92         CRA_NUT,
93         RSV_IRAP_VCL22, RSV_IRAP_VCL23,
94         RSV_VCL24, RSV_VCL25, RSV_VCL26, RSV_VCL27, RSV_VCL28, RSV_VCL29, RSV_VCL30, RSV_VCL31,
95         VPS_NUT,
96         SPS_NUT,
97         PPS_NUT,
98         AUD_NUT,
99         EOS_NUT,
100         EOB_NUT,
101         FD_NUT,
102         PREFIX_SEI_NUT,
103         SUFFIX_SEI_NUT,
104         RSV_NVCL41, RSV_NVCL42, RSV_NVCL43, RSV_NVCL44, RSV_NVCL45, RSV_NVCL46, RSV_NVCL47,
105         UNSPEC48, UNSPEC49, UNSPEC50, UNSPEC51, UNSPEC52, UNSPEC53, UNSPEC54, UNSPEC55,
106         UNSPEC56, UNSPEC57, UNSPEC58, UNSPEC59, UNSPEC60, UNSPEC61, UNSPEC62, UNSPEC63,
107         num_NALU_TYPE
108     };
109 
110     struct PTL
111     {
112         mfxU8  profile_space : 2;
113         mfxU8  tier_flag     : 1;
114         mfxU8  profile_idc   : 5;
115 
116         mfxU8  progressive_source_flag    : 1;
117         mfxU8  interlaced_source_flag     : 1;
118         mfxU8  non_packed_constraint_flag : 1;
119         mfxU8  frame_only_constraint_flag : 1;
120         mfxU8  profile_present_flag       : 1;
121         mfxU8  level_present_flag         : 1;
122         mfxU8                             : 2;
123         mfxU8  level_idc;
124 
125         mfxU32 profile_compatibility_flags;
126 
127         union
128         {
129             mfxU32 rext_constraint_flags_0_31;
130 
131             struct
132             {
133                 mfxU32 max_12bit        : 1;
134                 mfxU32 max_10bit        : 1;
135                 mfxU32 max_8bit         : 1;
136                 mfxU32 max_422chroma    : 1;
137                 mfxU32 max_420chroma    : 1;
138                 mfxU32 max_monochrome   : 1;
139                 mfxU32 intra            : 1;
140                 mfxU32 one_picture_only : 1;
141                 mfxU32 lower_bit_rate   : 1;
142                 mfxU32                  : 23;
143             } constraint;
144         };
145         mfxU32 rext_constraint_flags_32_42  : 11;
146         mfxU32 inbld_flag                   :  1;
147         mfxU32                              : 20;
148     };
149 
150     struct SubLayerOrdering
151     {
152         mfxU8  max_dec_pic_buffering_minus1 : 4;
153         mfxU8  max_num_reorder_pics         : 4;
154         mfxU32 max_latency_increase_plus1;
155     };
156 
157     struct STRPS
158     {
159         mfxU8  inter_ref_pic_set_prediction_flag : 1;
160         mfxU8  delta_idx_minus1                  : 6;
161         mfxU8  delta_rps_sign                    : 1;
162 
163         mfxU8  num_negative_pics : 4;
164         mfxU8  num_positive_pics : 4;
165 
166         mfxU16 abs_delta_rps_minus1;
167         mfxU16 WeightInGop;
168 
169         struct Pic
170         {
171             mfxU8 used_by_curr_pic_flag   : 1;
172             mfxU8 use_delta_flag          : 1;
173             mfxI16 DeltaPocSX;
174 
175             union
176             {
177                 struct
178                 {
179                     mfxU16 delta_poc_s0_minus1      : 15;
180                     mfxU16 used_by_curr_pic_s0_flag : 1;
181                 };
182                 struct
183                 {
184                     mfxU16 delta_poc_s1_minus1      : 15;
185                     mfxU16 used_by_curr_pic_s1_flag : 1;
186                 };
187                 struct
188                 {
189                     mfxU16 delta_poc_sx_minus1      : 15;
190                     mfxU16 used_by_curr_pic_sx_flag : 1;
191                 };
192             };
193         }pic[16];
194     };
195 
196     using STRPSPic = STRPS::Pic;
197 
198     struct LayersInfo
199     {
200         mfxU8 sub_layer_ordering_info_present_flag : 1;
201         PTL general;
202         struct SubLayer : PTL, SubLayerOrdering {} sub_layer[8];
203     };
204 
205 
206     struct HRDInfo
207     {
208         mfxU16 nal_hrd_parameters_present_flag              : 1;
209         mfxU16 vcl_hrd_parameters_present_flag              : 1;
210         mfxU16 sub_pic_hrd_params_present_flag              : 1;
211         mfxU16 du_cpb_removal_delay_increment_length_minus1 : 5;
212         mfxU16 sub_pic_cpb_params_in_pic_timing_sei_flag    : 1;
213         mfxU16 dpb_output_delay_du_length_minus1            : 5;
214 
215         mfxU16 tick_divisor_minus2                          : 8;
216         mfxU16 bit_rate_scale                               : 4;
217         mfxU16 cpb_size_scale                               : 4;
218 
219         mfxU8  cpb_size_du_scale                            : 4;
220         mfxU16 initial_cpb_removal_delay_length_minus1      : 5;
221         mfxU16 au_cpb_removal_delay_length_minus1           : 5;
222         mfxU16 dpb_output_delay_length_minus1               : 5;
223 
224         struct SubLayer
225         {
226             mfxU8  fixed_pic_rate_general_flag     :  1;
227             mfxU8  fixed_pic_rate_within_cvs_flag  :  1;
228             mfxU8  low_delay_hrd_flag              :  1;
229 
230             mfxU16 elemental_duration_in_tc_minus1 : 11;
231             mfxU16 cpb_cnt_minus1                  :  5;
232 
233             struct CPB
234             {
235                 mfxU32 bit_rate_value_minus1;
236                 mfxU32 cpb_size_value_minus1;
237                 mfxU32 cpb_size_du_value_minus1;
238                 mfxU32 bit_rate_du_value_minus1;
239                 mfxU8  cbr_flag;
240             } cpb[32];
241         } sl[8];
242     };
243 
244     struct BufferingPeriodSEI
245     {
246         mfxU8  seq_parameter_set_id         : 4;
247         mfxU8  irap_cpb_params_present_flag : 1;
248         mfxU8  concatenation_flag           : 1;
249 
250         mfxU32 cpb_delay_offset;
251         mfxU32 dpb_delay_offset;
252         mfxU32 au_cpb_removal_delay_delta_minus1;
253 
254         struct CPB{
255             mfxU32 initial_cpb_removal_delay;
256             mfxU32 initial_cpb_removal_offset;
257             mfxU32 initial_alt_cpb_removal_delay;
258             mfxU32 initial_alt_cpb_removal_offset;
259         } nal[32], vcl[32];
260     };
261 
262     struct PicTimingSEI
263     {
264         mfxU8  pic_struct                       : 4;
265         mfxU8  source_scan_type                 : 2;
266         mfxU8  duplicate_flag                   : 1;
267         mfxU8  du_common_cpb_removal_delay_flag : 1;
268 
269         mfxU32 au_cpb_removal_delay_minus1;
270         mfxU32 pic_dpb_output_delay;
271         mfxU32 pic_dpb_output_du_delay;
272         mfxU32 num_decoding_units_minus1;
273         mfxU32 du_common_cpb_removal_delay_increment_minus1;
274 
275         mfxU32* num_nalus_in_du_minus1;
276         mfxU32* du_cpb_removal_delay_increment_minus1;
277     };
278 
279     struct VPS : LayersInfo
280     {
281         mfxU16 video_parameter_set_id   : 4;
282         mfxU16 reserved_three_2bits     : 2;
283         mfxU16 max_layers_minus1        : 6;
284         mfxU16 max_sub_layers_minus1    : 3;
285         mfxU16 temporal_id_nesting_flag : 1;
286         mfxU16 reserved_0xffff_16bits;
287 
288         mfxU16 max_layer_id          :  6;
289         mfxU16 num_layer_sets_minus1 : 10;
290 
291         //mfxU8** layer_id_included_flag; // max [1024][64];
292 
293         mfxU32 num_units_in_tick;
294         mfxU32 time_scale;
295         mfxU32 timing_info_present_flag        : 1;
296         mfxU32 poc_proportional_to_timing_flag : 1;
297         mfxU32 num_ticks_poc_diff_one_minus1 : 10;
298         mfxU32 num_hrd_parameters            : 10;
299 
300         //VPSHRD* hrd; //max 1024
301     };
302 
303 
304     struct VUI
305     {
306         mfxU8  aspect_ratio_info_present_flag : 1;
307         mfxU8  aspect_ratio_idc;
308         mfxU16 sar_width;
309         mfxU16 sar_height;
310 
311         mfxU8  overscan_info_present_flag      : 1;
312         mfxU8  overscan_appropriate_flag       : 1;
313         mfxU8  video_signal_type_present_flag  : 1;
314         mfxU8  video_format                    : 3;
315         mfxU8  video_full_range_flag           : 1;
316         mfxU8  colour_description_present_flag : 1;
317         mfxU8  colour_primaries;
318         mfxU8  transfer_characteristics;
319         mfxU8  matrix_coeffs;
320 
321         mfxU8  chroma_loc_info_present_flag        : 1;
322         mfxU8  chroma_sample_loc_type_top_field    : 3;
323         mfxU8  chroma_sample_loc_type_bottom_field : 3;
324 
325         mfxU8  neutral_chroma_indication_flag : 1;
326         mfxU8  field_seq_flag                 : 1;
327         mfxU8  frame_field_info_present_flag  : 1;
328         mfxU8  default_display_window_flag    : 1;
329 
330         mfxU32 def_disp_win_left_offset;
331         mfxU32 def_disp_win_right_offset;
332         mfxU32 def_disp_win_top_offset;
333         mfxU32 def_disp_win_bottom_offset;
334 
335         mfxU8  timing_info_present_flag        : 1;
336         mfxU8  hrd_parameters_present_flag     : 1;
337         mfxU8  poc_proportional_to_timing_flag : 1;
338 
339         mfxU8  bitstream_restriction_flag              : 1;
340         mfxU8  tiles_fixed_structure_flag              : 1;
341         mfxU8  motion_vectors_over_pic_boundaries_flag : 1;
342         mfxU8  restricted_ref_pic_lists_flag           : 1;
343 
344         mfxU32 num_units_in_tick;
345         mfxU32 time_scale;
346         mfxU32 num_ticks_poc_diff_one_minus1;
347 
348         mfxU32 min_spatial_segmentation_idc : 12;
349         mfxU32 max_bytes_per_pic_denom      :  5;
350         mfxU32 max_bits_per_min_cu_denom    :  5;
351         mfxU16 log2_max_mv_length_horizontal : 5;
352         mfxU16 log2_max_mv_length_vertical   : 4;
353 
354         HRDInfo hrd;
355     };
356 
357     struct ScalingList
358     {
359         mfxU8 scalingLists0[6][16];
360         mfxU8 scalingLists1[6][64];
361         mfxU8 scalingLists2[6][64];
362         mfxU8 scalingLists3[2][64];
363         mfxU8 scalingListDCCoefSizeID2[6];
364         mfxU8 scalingListDCCoefSizeID3[2];
365     };
366 
367     struct SPS : LayersInfo
368     {
369         mfxU8  video_parameter_set_id   : 4;
370         mfxU8  max_sub_layers_minus1    : 3;
371         mfxU8  temporal_id_nesting_flag : 1;
372 
373         mfxU8  seq_parameter_set_id       : 4;
374         mfxU8  chroma_format_idc          : 2;
375         mfxU8  separate_colour_plane_flag : 1;
376         mfxU8  conformance_window_flag    : 1;
377 
378         mfxU32 pic_width_in_luma_samples;
379         mfxU32 pic_height_in_luma_samples;
380 
381         mfxU32 conf_win_left_offset;
382         mfxU32 conf_win_right_offset;
383         mfxU32 conf_win_top_offset;
384         mfxU32 conf_win_bottom_offset;
385 
386         mfxU8  bit_depth_luma_minus8                : 3;
387         mfxU8  bit_depth_chroma_minus8              : 3;
388         mfxU8  log2_max_pic_order_cnt_lsb_minus4    : 4;
389         //mfxU8  sub_layer_ordering_info_present_flag : 1;
390 
391         mfxU32 log2_min_luma_coding_block_size_minus3;
392         mfxU32 log2_diff_max_min_luma_coding_block_size;
393         mfxU32 log2_min_transform_block_size_minus2;
394         mfxU32 log2_diff_max_min_transform_block_size;
395         mfxU32 max_transform_hierarchy_depth_inter;
396         mfxU32 max_transform_hierarchy_depth_intra;
397 
398         mfxU8  scaling_list_enabled_flag      : 1;
399         mfxU8  scaling_list_data_present_flag : 1;
400 
401         mfxU8  amp_enabled_flag                    : 1;
402         mfxU8  sample_adaptive_offset_enabled_flag : 1;
403 
404         mfxU8  pcm_enabled_flag                    : 1;
405         mfxU8  pcm_loop_filter_disabled_flag       : 1;
406         mfxU8  pcm_sample_bit_depth_luma_minus1    : 4;
407         mfxU8  pcm_sample_bit_depth_chroma_minus1  : 4;
408         mfxU32 log2_min_pcm_luma_coding_block_size_minus3;
409         mfxU32 log2_diff_max_min_pcm_luma_coding_block_size;
410 
411         mfxU8  long_term_ref_pics_present_flag : 1;
412         mfxU8  num_long_term_ref_pics_sps      : 6;
413 
414         mfxU16 lt_ref_pic_poc_lsb_sps[32];
415         mfxU8  used_by_curr_pic_lt_sps_flag[32];
416 
417         mfxU8  temporal_mvp_enabled_flag           : 1;
418         mfxU8  strong_intra_smoothing_enabled_flag : 1;
419         mfxU8  vui_parameters_present_flag         : 1;
420         mfxU8  extension_flag                      : 1;
421         mfxU8  extension_data_flag                 : 1;
422 
423         mfxU8 range_extension_flag                    : 1;
424         mfxU8 transform_skip_rotation_enabled_flag    : 1;
425         mfxU8 transform_skip_context_enabled_flag     : 1;
426         mfxU8 implicit_rdpcm_enabled_flag             : 1;
427         mfxU8 explicit_rdpcm_enabled_flag             : 1;
428         mfxU8 extended_precision_processing_flag      : 1;
429         mfxU8 intra_smoothing_disabled_flag           : 1;
430         mfxU8 high_precision_offsets_enabled_flag     : 1;
431         mfxU8 persistent_rice_adaptation_enabled_flag : 1;
432         mfxU8 cabac_bypass_alignment_enabled_flag     : 1;
433 
434         mfxU8 low_delay_mode    : 1;
435         mfxU8 hierarchical_flag : 1;
436 
437         mfxU8 ExtensionFlags;
438         mfxU8 num_short_term_ref_pic_sets;
439         STRPS strps[65];
440 
441         ScalingList scl;
442         VUI vui;
443     };
444 
445     struct PPS
446     {
447         mfxU16 pic_parameter_set_id : 6;
448         mfxU16 seq_parameter_set_id : 4;
449         mfxU16 dependent_slice_segments_enabled_flag : 1;
450         mfxU16 output_flag_present_flag              : 1;
451         mfxU16 num_extra_slice_header_bits           : 3;
452         mfxU16 sign_data_hiding_enabled_flag         : 1;
453         mfxU16 cabac_init_present_flag               : 1;
454         mfxU16 num_ref_idx_l0_default_active_minus1  : 4;
455         mfxU16 num_ref_idx_l1_default_active_minus1  : 4;
456         mfxU16 constrained_intra_pred_flag           : 1;
457         mfxU16 transform_skip_enabled_flag           : 1;
458         mfxU16 cu_qp_delta_enabled_flag              : 1;
459         mfxU16 slice_segment_header_extension_present_flag : 1;
460 
461         mfxU32 diff_cu_qp_delta_depth;
462         mfxI32 init_qp_minus26;
463         mfxI16 cb_qp_offset : 6;
464         mfxI16 cr_qp_offset : 6;
465 
466         mfxU8  slice_chroma_qp_offsets_present_flag  : 1;
467         mfxU8  weighted_pred_flag                    : 1;
468         mfxU8  weighted_bipred_flag                  : 1;
469         mfxU8  transquant_bypass_enabled_flag        : 1;
470         mfxU8  tiles_enabled_flag                    : 1;
471         mfxU8  entropy_coding_sync_enabled_flag      : 1;
472         mfxU8  uniform_spacing_flag                  : 1;
473         mfxU8  loop_filter_across_tiles_enabled_flag : 1;
474 
475         mfxU16 num_tile_columns_minus1;
476         mfxU16 num_tile_rows_minus1;
477 
478         mfxU16 column_width[MAX_NUM_TILE_COLUMNS - 1];
479         mfxU16 row_height[MAX_NUM_TILE_ROWS - 1];
480 
481         mfxU8  loop_filter_across_slices_enabled_flag  : 1;
482         mfxU8  deblocking_filter_control_present_flag  : 1;
483         mfxU8  deblocking_filter_override_enabled_flag : 1;
484         mfxU8  deblocking_filter_disabled_flag         : 1;
485         mfxU8  scaling_list_data_present_flag          : 1;
486         mfxU8  lists_modification_present_flag         : 1;
487         mfxU8  extension_flag                          : 1;
488         mfxU8  extension_data_flag                     : 1;
489 
490         mfxI8  beta_offset_div2 : 4;
491         mfxI8  tc_offset_div2   : 4;
492 
493         //ScalingListData* sld;
494 
495         mfxU16 log2_parallel_merge_level_minus2;
496 
497         mfxU32 range_extension_flag                      : 1;
498         mfxU32 cross_component_prediction_enabled_flag   : 1;
499         mfxU32 chroma_qp_offset_list_enabled_flag        : 1;
500         mfxU32 log2_sao_offset_scale_luma                : 3;
501         mfxU32 log2_sao_offset_scale_chroma              : 3;
502         mfxU32 chroma_qp_offset_list_len_minus1          : 3;
503         mfxU32 diff_cu_chroma_qp_offset_depth            : 5;
504         mfxU32 log2_max_transform_skip_block_size_minus2 : 5;
505         mfxU32                                           : 10;
506         mfxI8  cb_qp_offset_list[6];
507         mfxI8  cr_qp_offset_list[6];
508 
509         mfxU8 ExtensionFlags;
510     };
511 
512     struct Slice
513     {
514         mfxU8  no_output_of_prior_pics_flag    : 1;
515         mfxU8  pic_parameter_set_id            : 6;
516         mfxU8  dependent_slice_segment_flag    : 1;
517 
518         mfxU32 segment_address;
519 
520         mfxU8  reserved_flags;
521         mfxU8  type                       : 2;
522         mfxU8  colour_plane_id            : 2;
523         mfxU8  short_term_ref_pic_set_idx;
524 
525         mfxU8  pic_output_flag                 : 1;
526         mfxU8  short_term_ref_pic_set_sps_flag : 1;
527         mfxU8  num_long_term_sps               : 6;
528 
529         mfxU8  first_slice_segment_in_pic_flag  : 1;
530         mfxU8  temporal_mvp_enabled_flag        : 1;
531         mfxU8  sao_luma_flag                    : 1;
532         mfxU8  sao_chroma_flag                  : 1;
533         mfxU8  num_ref_idx_active_override_flag : 1;
534         mfxU8  mvd_l1_zero_flag                 : 1;
535         mfxU8  cabac_init_flag                  : 1;
536         mfxU8  collocated_from_l0_flag          : 1;
537 
538         mfxU8  collocated_ref_idx            : 4;
539         mfxU8  five_minus_max_num_merge_cand : 3;
540 
541         mfxU8  num_ref_idx_l0_active_minus1 : 4;
542         mfxU8  num_ref_idx_l1_active_minus1 : 4;
543 
544         mfxU32 pic_order_cnt_lsb;
545         mfxU16 num_long_term_pics;
546 
547         mfxI8  slice_qp_delta;
548         mfxI16 slice_cb_qp_offset : 6;
549         mfxI16 slice_cr_qp_offset : 6;
550 
551         mfxU8  deblocking_filter_override_flag        : 1;
552         mfxU8  deblocking_filter_disabled_flag        : 1;
553         mfxU8  loop_filter_across_slices_enabled_flag : 1;
554         mfxU8  offset_len_minus1                      : 5;
555 
556         mfxI8  beta_offset_div2 : 4;
557         mfxI8  tc_offset_div2   : 4;
558 
559         mfxU32 num_entry_point_offsets;
560 
561         STRPS strps;
562 
563         struct LongTerm
564         {
565             mfxU8  lt_idx_sps                 :  5;
566             mfxU8  used_by_curr_pic_lt_flag   :  1;
567             mfxU8  delta_poc_msb_present_flag :  1;
568             mfxU32 poc_lsb_lt;
569             mfxU32 delta_poc_msb_cycle_lt;
570         } lt[MAX_NUM_LONG_TERM_PICS];
571 
572         mfxU8  ref_pic_list_modification_flag_lx[2];
573         mfxU8  list_entry_lx[2][16];
574 
575         mfxU16 luma_log2_weight_denom   : 3;
576         mfxU16 chroma_log2_weight_denom : 3;
577         mfxI16 pwt[2][16][3][2]; //[list][list entry][Y, Cb, Cr][weight, offset]
578     };
579 
580     struct NALU
581     {
582         mfxU16 long_start_code       : 1;
583         mfxU16 nal_unit_type         : 6;
584         mfxU16 nuh_layer_id          : 6;
585         mfxU16 nuh_temporal_id_plus1 : 3;
586     };
587 
588     using Resource = MfxEncodeHW::ResPool::Resource;
589 
590     struct IAllocation
591         : public Storable
592     {
593         using TAlloc = CallChain<mfxStatus, const mfxFrameAllocRequest&, bool /*isCopyRequired*/>;
594         TAlloc Alloc;
595 
596         using TAllocOpaque = CallChain<mfxStatus
597             , const mfxFrameInfo &
598             , mfxU16 /*type*/
599             , mfxFrameSurface1 ** /*surfaces*/
600             , mfxU16 /*numSurface*/>;
601         TAllocOpaque AllocOpaque;
602 
603         using TGetResponse = CallChain<mfxFrameAllocResponse>;
604         TGetResponse GetResponse;
605 
606         using TGetInfo = CallChain<mfxFrameInfo>;
607         TGetInfo GetInfo;
608 
609         using TAcquire = CallChain<Resource>;
610         TAcquire Acquire;
611 
612         using TRelease = CallChain<void, mfxU32 /*idx*/>;
613         TRelease Release;
614 
615         using TClearFlag = CallChain<void, mfxU32 /*idx*/>;
616         TClearFlag ClearFlag;
617 
618         using TSetFlag = CallChain<void, mfxU32 /*idx*/, mfxU32 /*flag*/>;
619         TSetFlag SetFlag;
620 
621         using TGetFlag = CallChain<mfxU32, mfxU32 /*idx*/>;
622         TGetFlag GetFlag;
623 
624         using TUnlockAll = CallChain<void>;
625         TUnlockAll UnlockAll;
626 
627         std::unique_ptr<Storable> m_pthis;
628     };
629 
630     class IBsReader
631     {
632     public:
~IBsReader()633         virtual ~IBsReader() {}
634         virtual mfxU32 GetBit() = 0;
635         virtual mfxU32 GetBits(mfxU32 n) = 0;
636         virtual mfxU32 GetUE() = 0;
637         virtual mfxI32 GetSE() = 0;
638 
639         //conditional read
640         template<class TDefault>
CondBits(bool bRead,mfxU32 nBits,TDefault defaultVal)641         mfxU32 CondBits(bool bRead, mfxU32 nBits, TDefault defaultVal)
642         {
643             return bRead ? GetBits(nBits) : mfxU32(defaultVal);
644         }
645         template<class TDefault>
CondBit(bool bRead,TDefault defaultVal)646         mfxU32 CondBit(bool bRead, TDefault defaultVal)
647         {
648             return bRead ? GetBit() : mfxU32(defaultVal);
649         }
650         template<class TDefault>
CondUE(bool bRead,TDefault defaultVal)651         mfxU32 CondUE(bool bRead, TDefault defaultVal)
652         {
653             return bRead ? GetUE() : mfxU32(defaultVal);
654         }
655         template<class TDefault>
CondSE(bool bRead,TDefault defaultVal)656         mfxI32 CondSE(bool bRead, TDefault defaultVal)
657         {
658             return bRead ? GetSE() : mfxI32(defaultVal);
659         }
660 
661     };
662 
663     class IBsWriter
664     {
665     public:
~IBsWriter()666         virtual ~IBsWriter() {}
667         virtual void PutBits(mfxU32 n, mfxU32 b) = 0;
668         virtual void PutBit(mfxU32 b) = 0;
669         virtual void PutUE(mfxU32 b) = 0;
670         virtual void PutSE(mfxI32 b) = 0;
671     };
672 
673     struct SliceInfo
674     {
675         mfxU32 SegmentAddress;
676         mfxU32 NumLCU;
677     };
678 
679     constexpr mfxU8 CODING_TYPE_I  = 1;
680     constexpr mfxU8 CODING_TYPE_P  = 2;
681     constexpr mfxU8 CODING_TYPE_B  = 3; //regular B, or no reference to other B frames
682     constexpr mfxU8 CODING_TYPE_B1 = 4; //B1, reference to only I, P or regular B frames
683     constexpr mfxU8 CODING_TYPE_B2 = 5; //B2, references include B1
684 
685     // Min frame params required for Reorder, RPL/DPB management
686     struct FrameBaseInfo
687         : Storable
688     {
689         mfxI32   POC            = -1;
690         mfxU16   FrameType      = 0;
691         bool     isLDB          = false; // is "low-delay B"
692         mfxU8    TemporalID     = 0;
693         mfxU32   BPyramidOrder  = mfxU32(MFX_FRAMEORDER_UNKNOWN);
694         mfxU32   PyramidLevel   = 0;
695         bool     bBottomField   = false;
696         bool     b2ndField      = false;
697     };
698 
699     typedef struct _DpbFrame
700         : FrameBaseInfo
701     {
702         mfxU32   DisplayOrder   = mfxU32(-1);
703         mfxU32   EncodedOrder   = mfxU32(-1);
704         bool     isLTR          = false; // is "long-term"
705         mfxU8    CodingType     = 0;
706         Resource Raw;
707         Resource Rec;
708         mfxFrameSurface1* pSurfIn = nullptr; //input surface, may be opaque
709     } DpbFrame, DpbArray[MAX_DPB_SIZE];
710 
711     enum eSkipMode
712     {
713         SKIPFRAME_NO = 0
714         , SKIPFRAME_INSERT_DUMMY
715         , SKIPFRAME_INSERT_DUMMY_PROTECTED
716         , SKIPFRAME_INSERT_NOTHING
717         , SKIPFRAME_BRC_ONLY
718         , SKIPFRAME_EXT_PSEUDO
719     };
720 
721     enum eSkipCmd
722     {
723         SKIPCMD_NeedInputReplacement        = (1 << 0)
724         , SKIPCMD_NeedDriverCall            = (1 << 1)
725         , SKIPCMD_NeedSkipSliceGen          = (1 << 2)
726         , SKIPCMD_NeedCurrentFrameSkipping  = (1 << 3)
727         , SKIPCMD_NeedNumSkipAdding         = (1 << 4)
728     };
729 
730     struct IntraRefreshState
731     {
732         mfxU16  refrType;
733         mfxU16  IntraLocation;
734         mfxU16  IntraSize;
735         mfxI16  IntRefQPDelta;
736         bool    firstFrameInCycle;
737     };
738 
739     enum eInsertHeader
740     {
741         INSERT_AUD      = 0x01,
742         INSERT_VPS      = 0x02,
743         INSERT_SPS      = 0x04,
744         INSERT_PPS      = 0x08,
745         INSERT_BPSEI    = 0x10,
746         INSERT_PTSEI    = 0x20,
747         INSERT_DCVSEI   = 0x40,
748         INSERT_LLISEI   = 0x80,
749         INSERT_SEI      = (INSERT_BPSEI | INSERT_PTSEI | INSERT_DCVSEI | INSERT_LLISEI)
750     };
751 
752     enum eRecFlag
753     {
754         REC_SKIPPED = 1
755         , REC_READY = 2
756     };
757 
758     struct TaskCommonPar
759         : DpbFrame
760     {
761         mfxU32              stage               = 0;
762         mfxU32              MinFrameSize        = 0;
763         mfxU32              BsDataLength        = 0;
764         mfxU32              BsBytesAvailable    = 0;
765         mfxU8*              pBsData             = nullptr;
766         mfxU32*             pBsDataLength       = nullptr;
767         mfxBitstream*       pBsOut              = nullptr;
768         mfxFrameSurface1*   pSurfReal           = nullptr;
769         mfxEncodeCtrl       ctrl                = {};
770         mfxU32              SkipCMD             = 0;
771         Resource            BS;
772         Resource            CUQP;
773         mfxHDLPair          HDLRaw              = {};
774         bool                bCUQPMap            = false;
775         bool                bForceSync          = false;
776         bool                bSkip               = false;
777         bool                bResetBRC           = false;
778         bool                bDontPatchBS        = false;
779         bool                bRecode             = false;
780         bool                bForceLongStartCode = false;
781         IntraRefreshState   IRState             = {};
782         mfxI32              PrevIPoc            = -1;
783         mfxI32              PrevRAP             = -1;
784         mfxU16              NumRecode           = 0;
785         mfxI8               QpY                 = 0;
786         mfxI8               m_minQP             = 0;
787         mfxI8               m_maxQP             = 0;
788 
789         mfxU8               SliceNUT            = 0;
790         mfxU32              InsertHeaders       = 0;
791         mfxU32              RepackHeaders       = 0;
792         mfxU32              StatusReportId      = mfxU32(-1);
793 
794         mfxU32              initial_cpb_removal_delay   = 0;
795         mfxU32              initial_cpb_removal_offset  = 0;
796         mfxU32              cpb_removal_delay           = 0;
797         //dpb_output_delay = (DisplayOrder + sps.sub_layer[0].max_num_reorder_pics - EncodedOrder);
798         mfxU32              TCBRCTargetFrameSize        = 0;
799         mfxU8 RefPicList[2][MAX_DPB_SIZE] =
800         {
801             {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
802             {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
803         };
804         mfxU8 NumRefActive[2] = {};
805 
806         struct DPBs
807         {
808             DpbArray
809                 Active   // available during task execution (modified dpb[BEFORE] )
810                 , After  // after task execution (ACTIVE + curTask if ref)
811                 , Before // after previous task execution (prevTask dpb[AFTER])
812                 ;
813         } DPB;
814         std::list<mfxPayload> PLInternal = {};
815     };
816 
Invalidate(TaskCommonPar & par)817     inline void Invalidate(TaskCommonPar& par)
818     {
819         par = TaskCommonPar();
820     }
isValid(DpbFrame const & frame)821     inline bool isValid(DpbFrame const & frame) { return IDX_INVALID != frame.Rec.Idx; }
isDpbEnd(DpbArray const & dpb,mfxU32 idx)822     inline bool isDpbEnd(DpbArray const & dpb, mfxU32 idx) { return idx >= MAX_DPB_SIZE || !isValid(dpb[idx]); }
823 
824     class FrameLocker
825         : public mfxFrameData
826     {
827     public:
828         mfxU32 Pitch;
829 
830         FrameLocker(VideoCORE& core, mfxMemId memId, bool external = false)
831             : m_data(*this)
832             , m_core(core)
833             , m_memId(memId)
834         {
835             m_data   = {};
836             m_status = Lock(external);
837             Pitch    = (mfxFrameData::PitchHigh << 16) + mfxFrameData::PitchLow;
838         }
839         FrameLocker(VideoCORE& core, mfxFrameData& data, bool external = false)
m_data(data)840             : m_data(data)
841             , m_core(core)
842             , m_memId(data.MemId)
843             , m_status(Lock(external))
844         {
845             Pitch = (mfxFrameData::PitchHigh << 16) + mfxFrameData::PitchLow;
846         }
847 
~FrameLocker()848         ~FrameLocker()
849         {
850             Unlock();
851         }
852 
853         enum { LOCK_NO, LOCK_INT, LOCK_EXT };
854 
Unlock()855         mfxStatus Unlock()
856         {
857             mfxStatus mfxSts = MFX_ERR_NONE;
858             if (m_status == LOCK_INT)
859                 mfxSts = m_core.UnlockFrame(m_memId, &m_data);
860             else if (m_status == LOCK_EXT)
861                 mfxSts = m_core.UnlockExternalFrame(m_memId, &m_data);
862             m_status = LOCK_NO;
863             return mfxSts;
864         }
865 
866 
Lock(bool external)867         mfxU32 Lock(bool external)
868         {
869             mfxU32 status = LOCK_NO;
870             if (!m_data.Y && !m_data.Y410)
871             {
872                 status = external
873                     ? (m_core.LockExternalFrame(m_memId, &m_data) == MFX_ERR_NONE ? LOCK_EXT : LOCK_NO)
874                     : (m_core.LockFrame(m_memId, &m_data) == MFX_ERR_NONE ? LOCK_INT : LOCK_NO);
875             }
876             return status;
877         }
878 
879     private:
880         FrameLocker(FrameLocker const &) = delete;
881         FrameLocker & operator =(FrameLocker const &) = delete;
882 
883         mfxFrameData& m_data;
884         VideoCORE&    m_core;
885         mfxMemId      m_memId;
886         mfxU32        m_status;
887     };
888 
889     enum ePackInfo
890     {
891         PACK_QPDOffset = 0
892         , PACK_SAOOffset
893         , PACK_VUIOffset
894         , PACK_PWTOffset
895         , PACK_PWTLength
896         , NUM_PACK_INFO
897     };
898 
899     using MfxEncodeHW::PackedData;
900 
901     struct PackedHeaders
902     {
903         PackedData VPS;
904         PackedData SPS;
905         PackedData PPS;
906         PackedData AUD[3];
907         PackedData PrefixSEI;
908         PackedData SuffixSEI;
909         std::vector<PackedData> SSH;
910     };
911 
912     using MfxEncodeHW::DDIExecParam;
913 
914     template<class T>
915     inline T& Deref(const DDIExecParam::Param& par, mfxU32 idx = 0)
916     {
917         ThrowAssert(
918             !par.pData
919             || (par.Size * std::max<mfxU32>(par.Num, 1)) < (sizeof(T) * (idx + 1))
920             , "Invalid DDIExecParam::Param data");
921         return *((T*)par.pData);
922     }
923 
924     using DDIFeedbackParam = MfxEncodeHW::DDIFeedback;
925 
926     struct BsDataInfo
927     {
928         mfxU8  *Data;
929         mfxU32 DataOffset;
930         mfxU32 DataLength;
931         mfxU32 MaxLength;
932     };
933 
934     enum eResetFlags
935     {
936         RF_SPS_CHANGED      = (1 << 0)
937         , RF_PPS_CHANGED    = (1 << 1)
938         , RF_IDR_REQUIRED   = (1 << 2)
939         , RF_BRC_RESET      = (1 << 3)
940         , RF_CANCEL_TASKS   = (1 << 4)
941     };
942 
943     struct ResetHint
944     {
945         mfxU32 Flags;
946     };
947 
948     struct VAGUID
949     {
950         mfxU32 Profile;
951         mfxU32 Entrypoint;
952     };
953 
954     struct LessGUID
955     {
operatorLessGUID956         bool operator()(const GUID& l, const GUID& r) const
957         {
958             bool bEQ = true;
959             bool bLT = l.Data1 < r.Data1;
960 
961             bEQ &= l.Data1 == r.Data1;
962             bLT |= bEQ && l.Data2 < r.Data2;
963 
964             bEQ &= l.Data2 == r.Data2;
965             bLT |= bEQ && l.Data3 < r.Data3;
966 
967             bEQ &= l.Data3 == r.Data3;
968             bLT |= bEQ && std::lexicographical_compare(l.Data4, std::end(l.Data4), r.Data4, std::end(r.Data4));
969 
970             return bLT;
971         }
972     };
973 
974     /*SliceStructure indicates the restrictions set on the slice structure.*/
975     enum SliceStructure
976     {
977         // Once slice for the whole frame
978         ONESLICE              = 0
979         /*Slices are composed of a power of 2 number of rows and each slice
980           must have the same size (width and height) except for the last one,
981           which must be smaller or equal to the previous slices. */
982         , POW2ROW             = 1
983         /*Slices are composed of any number of rows, but all must have the same
984         size (width and height) except for the last one, which must be smaller
985         or equal to the previous slices.*/
986         , ROWSLICE            = 2
987         //Arbitrary number of rows per slice for all slices.
988         , ARBITRARY_ROW_SLICE = 3
989         //Arbitrary number of macroblocks per slice for all slices.
990         , ARBITRARY_MB_SLICE  = 4
991     };
992 
993     typedef std::list<StorageRW>::iterator TTaskIt;
994 
995     template<class T, mfxU32 K>
996     struct TaskItWrap
997     {
998         using iterator_category = std::bidirectional_iterator_tag;
999         using value_type = T;
1000         using pointer = value_type*;
1001         using reference = value_type&;
1002         using difference_type = ptrdiff_t;
1003         using iterator_type = TaskItWrap;
1004 
TaskItWrapTaskItWrap1005         TaskItWrap(TTaskIt _it) : it(_it) {}
1006 
1007         bool operator==(const TTaskIt& other) const
1008         {
1009             return it == other;
1010         }
1011         bool operator!=(const TTaskIt& other) const
1012         {
1013             return it != other;
1014         }
1015         bool operator==(const iterator_type& other) const
1016         {
1017             return it == other.it;
1018         }
1019         bool operator!=(const iterator_type& other) const
1020         {
1021             return it != other.it;
1022         }
1023         pointer operator->()
1024         {
1025             return &it->Write<value_type>(K);
1026         }
1027         reference operator*() const
1028         {
1029             return it->Write<value_type>(K);
1030         }
1031         iterator_type& operator++()
1032         {
1033             ++it; return *this;
1034         }
1035         iterator_type operator++(int)
1036         {
1037             iterator_type tmp(it); ++it; return tmp;
1038         }
1039         iterator_type& operator--()
1040         {
1041             --it; return *this;
1042         }
1043         iterator_type operator--(int)
1044         {
1045             iterator_type tmp(it); --it; return tmp;
1046         }
1047 
1048         TTaskIt it;
1049     };
1050 
1051     struct Reorderer
1052         : CallChain<TTaskIt, const DpbArray&, TTaskIt, TTaskIt, bool>
1053     {
1054         mfxU16 BufferSize = 0;
1055         mfxU16 MaxReorder = 0;
1056         NotNull<DpbArray*> DPB;
1057 
1058         using TBaseCC = CallChain<TTaskIt, const DpbArray&, TTaskIt, TTaskIt, bool>;
1059 
operatorReorderer1060         TTaskIt operator()(TTaskIt itBegin, TTaskIt itEnd, bool bFlush)
1061         {
1062             return TBaseCC::operator()((const DpbArray&)*DPB, itBegin, itEnd, bFlush);
1063         }
1064     };
1065 
1066     class EncodeCapsHevc
1067         : public ENCODE_CAPS_HEVC
1068         , public Storable
1069     {
1070     public:
EncodeCapsHevc()1071         EncodeCapsHevc()
1072             : ENCODE_CAPS_HEVC({})
1073         {}
1074 
1075         struct MsdkExt
1076         {
1077             bool bSingleSliceMultiTile = false;
1078             bool CQPSupport            = false;
1079             bool CBRSupport            = false;
1080             bool VBRSupport            = false;
1081             bool ICQSupport            = false;
1082             bool PSliceSupport         = false;
1083         } msdk;
1084     };
1085 
1086     struct Defaults
1087     {
1088         struct Param
1089         {
ParamDefaults::Param1090             Param(
1091                 const mfxVideoParam& _par
1092                 , const EncodeCapsHevc& _caps
1093                 , eMFXHWType _hw
1094                 , const Defaults& _d)
1095                 : mvp(_par)
1096                 , caps(_caps)
1097                 , hw(_hw)
1098                 , base(_d)
1099             {}
1100             const mfxVideoParam&    mvp;
1101             const EncodeCapsHevc&   caps;
1102             eMFXHWType              hw;
1103             const Defaults&         base;
1104         };
1105 
1106         template<class TRV>
1107         using TChain = CallChain<TRV, const Param&>;
1108         std::map<mfxU32, bool> SetForFeature;
1109 
1110         TChain<mfxU16> GetCodedPicWidth;
1111         TChain<mfxU16> GetCodedPicHeight;
1112         TChain<mfxU16> GetCodedPicAlignment;
1113         TChain<mfxU16> GetMaxDPB;
1114         TChain<mfxU16> GetNumTemporalLayers;
1115         TChain<mfxU16> GetGopPicSize;
1116         TChain<mfxU16> GetGopRefDist;
1117         TChain<mfxU16> GetNumBPyramidLayers;
1118         TChain<mfxU16> GetNumRefFrames;
1119         TChain<mfxU16> GetNumRefBPyramid;
1120         TChain<mfxU16> GetNumRefPPyramid;
1121         TChain<mfxU16> GetNumRefNoPyramid;
1122         TChain<mfxU16> GetMinRefForBPyramid;
1123         TChain<mfxU16> GetMinRefForBNoPyramid;
1124         TChain<mfxU16> GetBRefType;
1125         TChain<mfxU16> GetPRefType;
1126         TChain<mfxU16> GetTargetBitDepthLuma;
1127         TChain<mfxU16> GetTargetChromaFormat;
1128         TChain<mfxU16> GetMaxBitDepth;
1129         TChain<mfxU16> GetMaxBitDepthByFourCC;
1130         TChain<mfxU16> GetMaxChroma;
1131         TChain<mfxU16> GetMaxChromaByFourCC;
1132         TChain<mfxU16> GetRateControlMethod;
1133         TChain<mfxU16> GetProfile;
1134         TChain<mfxU16> GetMBBRC;
1135         TChain<mfxU16> GetAsyncDepth;
1136         TChain<mfxU16> GetNumSlices;
1137         TChain<mfxU16> GetLCUSize;
1138         TChain<bool>   GetHRDConformanceON;
1139         TChain<mfxU16> GetPicTimingSEI;
1140         TChain<mfxU16> GetPPyrInterval;
1141         TChain<mfxU32> GetTargetKbps;
1142         TChain<mfxU32> GetMaxKbps;
1143         TChain<mfxU32> GetBufferSizeInKB;
1144         TChain<std::tuple<mfxU16, mfxU16>> GetNumTiles; // (NumTileColumns, NumTileRows)
1145         TChain<std::tuple<mfxU16, mfxU16, mfxU16>> GetMaxNumRef;
1146         TChain<std::tuple<mfxU32, mfxU32>> GetFrameRate;
1147         TChain<std::tuple<mfxU16, mfxU16, mfxU16>> GetQPMFX; //I,P,B
1148         TChain<mfxU8> GetMinQPMFX;
1149         TChain<mfxU8> GetMaxQPMFX;
1150         TChain<mfxU8> GetHighestTId;
1151         TChain<mfxU8> GetNumReorderFrames;
1152         TChain<bool>  GetNonStdReordering;
1153 
1154         using TGetNumRefActive = CallChain<
1155             bool //bExternal
1156             , const Defaults::Param&
1157             , mfxU16(*)[8] //P
1158             , mfxU16(*)[8] //BL0
1159             , mfxU16(*)[8]>; //BL1
1160         TGetNumRefActive GetNumRefActive;
1161 
1162         using TGetQPOffset = CallChain<
1163             mfxU16 //EnableQPOffset
1164             , const Defaults::Param&
1165             , mfxI16(*)[8]>;//QPOffset
1166         TGetQPOffset GetQPOffset;
1167 
1168         using TGetGUID = CallChain<
1169             bool //bSupported
1170             , const Defaults::Param&
1171             , GUID&>;
1172         TGetGUID GetGUID;
1173 
1174         using TGetFrameType = CallChain<
1175             mfxU16 // FrameType
1176             , const Defaults::Param&
1177             , mfxU32//DisplayOrder
1178             , mfxU32>; //LastIDR
1179         TGetFrameType GetFrameType;
1180 
1181         using TGetPLayer = CallChain<
1182             mfxU8 //layer
1183             , const Defaults::Param&
1184             , mfxU32>; //order
1185         TGetPLayer GetPLayer;
1186         using TGetTId = TGetPLayer;
1187         TGetTId GetTId;
1188 
1189         using TGetRPLFromExt = CallChain<
1190             std::tuple<mfxU8, mfxU8> //nL0, nL1
1191             , const Defaults::Param&
1192             , const DpbArray &
1193             , mfxU16, mfxU16 //maxL0, maxL1
1194             , const mfxExtAVCRefLists&
1195             , mfxU8(&)[2][MAX_DPB_SIZE]>; //out RPL
1196         TGetRPLFromExt GetRPLFromExt;
1197 
1198         using TGetRPL = CallChain<
1199             std::tuple<mfxU8, mfxU8> //nL0, nL1
1200             , const Defaults::Param&
1201             , const DpbArray &
1202             , mfxU16, mfxU16 //maxL0, maxL1
1203             , const FrameBaseInfo&
1204             , mfxU8(&)[2][MAX_DPB_SIZE]>; //out RPL
1205         TGetRPL GetRPL;
1206         TGetRPL GetRPLMod; // apply hw/other specific modifications to RPL (final)
1207 
1208         using TGetRPLFromCtrl = CallChain<
1209             std::tuple<mfxU8, mfxU8> //nL0, nL1
1210             , const Defaults::Param&
1211             , const DpbArray &
1212             , mfxU16, mfxU16 //maxL0, maxL1
1213             , const FrameBaseInfo&
1214             , const mfxExtAVCRefListCtrl&
1215             , mfxU8(&)[2][MAX_DPB_SIZE]>; //out RPL
1216         TGetRPLFromCtrl GetRPLFromCtrl;
1217 
1218         using TCmpRef = CallChain<
1219             bool                      // refA > refB
1220             , const Defaults::Param&
1221             , const FrameBaseInfo&    // curFrame
1222             , const FrameBaseInfo&    // refA
1223             , const FrameBaseInfo&>;  // refB
1224         TCmpRef CmpRefLX[2];
1225         using TGetWeakRef = CallChain<
1226             const DpbFrame*
1227             , const Defaults::Param&
1228             , const FrameBaseInfo&    // curFrame
1229             , const DpbFrame*         // begin
1230             , const DpbFrame*>;       // end
1231         TGetWeakRef GetWeakRef;
1232 
1233         using TGetPreReorderInfo = CallChain<
1234             mfxStatus
1235             , const Defaults::Param&
1236             , FrameBaseInfo&
1237             , const mfxFrameSurface1*   //pSurfIn
1238             , const mfxEncodeCtrl*      //pCtrl
1239             , mfxU32                    //prevIDROrder
1240             , mfxI32                    //prevIPOC
1241             , mfxU32>;                  //frameOrder
1242         TGetPreReorderInfo GetPreReorderInfo; // fill all info available at pre-reorder
1243 
1244         using TGetFrameNumRefActive = CallChain<
1245             std::tuple<mfxU8,mfxU8>
1246             , const Defaults::Param&
1247             , const FrameBaseInfo&>;
1248         TGetFrameNumRefActive GetFrameNumRefActive;
1249 
1250         using TGetTileSlices = CallChain<
1251             mfxU16
1252             , const Defaults::Param&
1253             , std::vector<SliceInfo>&
1254             , mfxU32   //SliceStructure
1255             , mfxU32   //nCol
1256             , mfxU32   //nRow
1257             , mfxU32>; //nSlice
1258         TGetTileSlices GetTileSlices;
1259 
1260         using TGetSlices = CallChain <
1261             mfxU16
1262             , const Defaults::Param&
1263             , std::vector<SliceInfo>&>;
1264         TGetSlices GetSlices;
1265 
1266         using TGetVPS = CallChain<mfxStatus, const Defaults::Param&, VPS&>;
1267         TGetVPS GetVPS;
1268         using TGetSPS = CallChain<mfxStatus, const Defaults::Param&, const VPS&, SPS&>;
1269         TGetSPS GetSPS;
1270         using TGetPPS = CallChain<mfxStatus, const Defaults::Param&, const SPS&, PPS&>;
1271         TGetPPS GetPPS;
1272 
1273         using TGetSHNUT = CallChain<
1274             mfxU8                       //NUT
1275             , const Defaults::Param&
1276             , const TaskCommonPar&      //task
1277             , bool>;                    //RAPIntra
1278         TGetSHNUT GetSHNUT;
1279         using TGetFrameOrder = CallChain<
1280             mfxU32                 //FrameOrder
1281             , const Defaults::Param&
1282             , const StorageR&      //task
1283             , mfxU32>;             //prevFrameOrder
1284         TGetFrameOrder GetFrameOrder;
1285 
1286         using TRunFastCopyWrapper = CallChain<
1287             mfxStatus
1288             , mfxFrameSurface1 & /* surfDst */
1289             , mfxU16 /* dstMemType */
1290             , mfxFrameSurface1 & /* surfSrc */
1291             , mfxU16 /* srcMemType */
1292         >;
1293         TRunFastCopyWrapper RunFastCopyWrapper;
1294 
1295         //for Query w/o caps:
1296         using TPreCheck = CallChain<mfxStatus, const mfxVideoParam&>;
1297         TPreCheck PreCheckCodecId;
1298         TPreCheck PreCheckChromaFormat;
1299 
1300         template<class TRV>
1301         using TGetHWDefault = CallChain <TRV, const mfxVideoParam&, eMFXHWType>;
1302         TGetHWDefault<mfxU16> GetLowPower;
1303 
1304         //for Query w/caps (check + fix)
1305         using TCheckAndFix = CallChain<mfxStatus, const Defaults::Param&, mfxVideoParam&>;
1306         TCheckAndFix CheckLCUSize;
1307         TCheckAndFix CheckLowDelayBRC;
1308         TCheckAndFix CheckLevel;
1309         TCheckAndFix CheckSurfSize;
1310         TCheckAndFix CheckProfile;
1311         TCheckAndFix CheckFourCC;
1312         TCheckAndFix CheckInputFormatByFourCC;
1313         TCheckAndFix CheckTargetChromaFormat;
1314         TCheckAndFix CheckTargetBitDepth;
1315         TCheckAndFix CheckFourCCByTargetFormat;
1316         TCheckAndFix CheckWinBRC;
1317         TCheckAndFix CheckSAO;
1318         TCheckAndFix CheckNumRefActive;
1319     };
1320 
1321     enum eFeatureId
1322     {
1323           FEATURE_LEGACY = 0
1324         , FEATURE_DDI
1325         , FEATURE_DDI_PACKER
1326         , FEATURE_PARSER
1327         , FEATURE_HRD
1328         , FEATURE_ALLOCATOR
1329         , FEATURE_TASK_MANAGER
1330         , FEATURE_PACKER
1331         , FEATURE_BLOCKING_SYNC
1332         , FEATURE_EXT_BRC
1333         , FEATURE_DIRTY_RECT
1334         , FEATURE_DPB_REPORT
1335         , FEATURE_DUMP_FILES
1336         , FEATURE_EXTDDI
1337         , FEATURE_HDR_SEI
1338         , FEATURE_MAX_FRAME_SIZE
1339         , FEATURE_PROTECTED
1340         , FEATURE_GPU_HANG
1341         , FEATURE_ROI
1342         , FEATURE_INTERLACE
1343         , FEATURE_BRC_SLIDING_WINDOW
1344         , FEATURE_MB_PER_SEC
1345         , FEATURE_ENCODED_FRAME_INFO
1346         , FEATURE_WEIGHTPRED
1347         , FEATURE_QMATRIX
1348         , FEATURE_UNITS_INFO
1349         , FEATURE_FEI
1350         , FEATURE_RECON_INFO
1351         , NUM_FEATURES
1352     };
1353 
1354     enum eStages
1355     {
1356         S_NEW = 0
1357         , S_PREPARE
1358         , S_REORDER
1359         , S_SUBMIT
1360         , S_QUERY
1361         , NUM_STAGES
1362     };
1363 
1364     struct PriorityParam
1365     {
1366         mfxU32        m_MaxContextPriority;
1367     };
1368 
1369     struct Glob
1370     {
1371         static const StorageR::TKey _KD = __LINE__ + 1;
1372         using VideoCore           = StorageVar<__LINE__ - _KD, VideoCORE>;
1373         using RTErr               = StorageVar<__LINE__ - _KD, mfxStatus>;
1374         using GUID                = StorageVar<__LINE__ - _KD, ::GUID>;
1375         using EncodeCaps          = StorageVar<__LINE__ - _KD, EncodeCapsHevc>;
1376         using VideoParam          = StorageVar<__LINE__ - _KD, ExtBuffer::Param<mfxVideoParam>>;
1377         using VPS                 = StorageVar<__LINE__ - _KD, Base::VPS>;
1378         using SPS                 = StorageVar<__LINE__ - _KD, Base::SPS>;
1379         using PPS                 = StorageVar<__LINE__ - _KD, Base::PPS>;
1380         using SliceInfo           = StorageVar<__LINE__ - _KD, std::vector<Base::SliceInfo>>;
1381         using AllocRaw            = StorageVar<__LINE__ - _KD, IAllocation>;
1382         using AllocOpq            = StorageVar<__LINE__ - _KD, IAllocation>;
1383         using AllocRec            = StorageVar<__LINE__ - _KD, IAllocation>;
1384         using AllocBS             = StorageVar<__LINE__ - _KD, IAllocation>;
1385         using AllocMBQP           = StorageVar<__LINE__ - _KD, IAllocation>;
1386         using PackedHeaders       = StorageVar<__LINE__ - _KD, Base::PackedHeaders>;
1387         using DDI_Resources       = StorageVar<__LINE__ - _KD, std::list<DDIExecParam>>;
1388         using DDI_SubmitParam     = StorageVar<__LINE__ - _KD, std::list<DDIExecParam>>;
1389         using DDI_Feedback        = StorageVar<__LINE__ - _KD, DDIFeedbackParam>;
1390         using DDI_Execute         = StorageVar<__LINE__ - _KD, CallChain<mfxStatus, const DDIExecParam&>>;
1391         using RealState           = StorageVar<__LINE__ - _KD, StorageW>;//available during Reset
1392         using ResetHint           = StorageVar<__LINE__ - _KD, Base::ResetHint>; //available during Reset
1393         using Reorder             = StorageVar<__LINE__ - _KD, Reorderer>;
1394         using NeedRextConstraints = StorageVar<__LINE__ - _KD, std::function<bool(const Base::PTL&)>>;
1395         using ReadSpsExt          = StorageVar<__LINE__ - _KD, std::function<bool(const Base::SPS&, mfxU8, IBsReader&)>>;
1396         using ReadPpsExt          = StorageVar<__LINE__ - _KD, std::function<bool(const Base::PPS&, mfxU8, IBsReader&)>>;
1397         using PackSpsExt          = StorageVar<__LINE__ - _KD, std::function<bool(const Base::SPS&, mfxU8, IBsWriter&)>>;
1398         using PackPpsExt          = StorageVar<__LINE__ - _KD, std::function<bool(const Base::PPS&, mfxU8, IBsWriter&)>>;
1399         using GuidToVa            = StorageVar<__LINE__ - _KD, std::map<::GUID, VAGUID, LessGUID>>;
1400         using Defaults            = StorageVar<__LINE__ - _KD, Base::Defaults>;
1401         using PriorityPar         = StorageVar<__LINE__ - _KD, Base::PriorityParam>;
1402         static const StorageR::TKey ReservedKey0 = __LINE__ - _KD;
1403         static const StorageR::TKey NUM_KEYS = __LINE__ - _KD;
1404     };
1405 
1406     struct Tmp
1407     {
1408         static const StorageR::TKey _KD = __LINE__ + 1;
1409         using MakeAlloc     = StorageVar<__LINE__ - _KD, std::function<IAllocation*(VideoCORE&)>>;
1410         using BSAllocInfo   = StorageVar<__LINE__ - _KD, mfxFrameAllocRequest>;
1411         using MBQPAllocInfo = StorageVar<__LINE__ - _KD, mfxFrameAllocRequest>;
1412         using RecInfo       = StorageVar<__LINE__ - _KD, mfxFrameAllocRequest>;
1413         using RawInfo       = StorageVar<__LINE__ - _KD, mfxFrameAllocRequest>;
1414         using CurrTask      = StorageVar<__LINE__ - _KD, StorageW>;
1415         using BsDataInfo    = StorageVar<__LINE__ - _KD, Base::BsDataInfo>;
1416         using DDI_InitParam = StorageVar<__LINE__ - _KD, std::list<DDIExecParam>>;
1417         static const StorageR::TKey NUM_KEYS = __LINE__ - _KD;
1418     };
1419 
1420     struct Task
1421     {
1422         static const StorageR::TKey _KD = __LINE__ + 1;
1423         using Common = StorageVar<__LINE__ - _KD, TaskCommonPar>;
1424         using SSH    = StorageVar<__LINE__ - _KD, Base::Slice>;
1425         static const StorageR::TKey ReservedKey0 = __LINE__ - _KD;
1426         static const StorageR::TKey NUM_KEYS = __LINE__ - _KD;
1427     };
1428 
1429     template<class TEB>
GetRTExtBuffer(const StorageR & glob,const StorageR & task)1430     inline const TEB& GetRTExtBuffer(const StorageR& glob, const StorageR& task)
1431     {
1432         const TEB* pEB = ExtBuffer::Get(Task::Common::Get(task).ctrl);
1433         if (pEB)
1434             return *pEB;
1435         return ExtBuffer::Get(Glob::VideoParam::Get(glob));
1436     }
1437 
1438 } //namespace Base
1439 } //namespace HEVCEHW
1440 
1441 #endif
1442