• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2018 Advanced Micro Devices, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #include "util/u_handle_table.h"
29 #include "util/u_video.h"
30 #include "va_private.h"
31 
32 #include "util/vl_rbsp.h"
33 
34 enum HEVCSEIPayloadType {
35    MASTERING_DISPLAY_COLOUR_VOLUME  = 137,
36    CONTENT_LIGHT_LEVEL_INFO         = 144,
37 };
38 
39 VAStatus
vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver * drv,vlVaContext * context,vlVaBuffer * buf)40 vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
41 {
42    VAEncPictureParameterBufferHEVC *h265;
43    vlVaBuffer *coded_buf;
44    vlVaSurface *surf;
45    int i, j;
46 
47    h265 = buf->data;
48    context->desc.h265enc.decoded_curr_pic = h265->decoded_curr_pic.picture_id;
49    context->desc.h265enc.not_referenced = !h265->pic_fields.bits.reference_pic_flag;
50 
51    for (i = 0; i < 15; i++)
52       context->desc.h265enc.reference_frames[i] = h265->reference_frames[i].picture_id;
53 
54    /* Evict unused surfaces */
55    for (i = 0; i < context->desc.h265enc.dpb_size; i++) {
56       struct pipe_h265_enc_dpb_entry *dpb = &context->desc.h265enc.dpb[i];
57       if (!dpb->id || dpb->id == h265->decoded_curr_pic.picture_id)
58          continue;
59       for (j = 0; j < ARRAY_SIZE(h265->reference_frames); j++) {
60          if (h265->reference_frames[j].picture_id == dpb->id) {
61             dpb->evict = false;
62             break;
63          }
64       }
65       if (j == ARRAY_SIZE(h265->reference_frames)) {
66          if (dpb->evict) {
67             surf = handle_table_get(drv->htab, dpb->id);
68             assert(surf);
69             surf->is_dpb = false;
70             surf->buffer = NULL;
71             /* Keep the buffer for reuse later */
72             dpb->id = 0;
73          }
74          dpb->evict = !dpb->evict;
75       }
76    }
77 
78    surf = handle_table_get(drv->htab, h265->decoded_curr_pic.picture_id);
79    if (!surf)
80       return VA_STATUS_ERROR_INVALID_PARAMETER;
81 
82    for (i = 0; i < ARRAY_SIZE(context->desc.h265enc.dpb); i++) {
83       if (context->desc.h265enc.dpb[i].id == h265->decoded_curr_pic.picture_id) {
84          assert(surf->is_dpb);
85          break;
86       }
87       if (!surf->is_dpb && !context->desc.h265enc.dpb[i].id) {
88          surf->is_dpb = true;
89          if (surf->buffer) {
90             surf->buffer->destroy(surf->buffer);
91             surf->buffer = NULL;
92          }
93          if (context->decoder->create_dpb_buffer) {
94             struct pipe_video_buffer *buffer = context->desc.h265enc.dpb[i].buffer;
95             if (!buffer) {
96                /* Find unused buffer */
97                for (j = 0; j < context->desc.h265enc.dpb_size; j++) {
98                   struct pipe_h265_enc_dpb_entry *dpb = &context->desc.h265enc.dpb[j];
99                   if (!dpb->id && dpb->buffer) {
100                      buffer = dpb->buffer;
101                      dpb->buffer = NULL;
102                      break;
103                   }
104                }
105             }
106             if (!buffer)
107                buffer = context->decoder->create_dpb_buffer(context->decoder, &context->desc.base, &surf->templat);
108             surf->buffer = buffer;
109          }
110          vlVaSetSurfaceContext(drv, surf, context);
111          if (i == context->desc.h265enc.dpb_size)
112             context->desc.h265enc.dpb_size++;
113          break;
114       }
115    }
116    if (i == ARRAY_SIZE(context->desc.h265enc.dpb))
117       return VA_STATUS_ERROR_INVALID_PARAMETER;
118    context->desc.h265enc.dpb_curr_pic = i;
119    context->desc.h265enc.dpb[i].id = h265->decoded_curr_pic.picture_id;
120    context->desc.h265enc.dpb[i].pic_order_cnt = h265->decoded_curr_pic.pic_order_cnt;
121    context->desc.h265enc.dpb[i].is_ltr = h265->decoded_curr_pic.flags & VA_PICTURE_HEVC_LONG_TERM_REFERENCE;
122    context->desc.h265enc.dpb[i].buffer = surf->buffer;
123    context->desc.h265enc.dpb[i].evict = false;
124 
125    context->desc.h265enc.pic_order_cnt = h265->decoded_curr_pic.pic_order_cnt;
126    coded_buf = handle_table_get(drv->htab, h265->coded_buf);
127    if (!coded_buf)
128       return VA_STATUS_ERROR_INVALID_BUFFER;
129 
130    if (!coded_buf->derived_surface.resource)
131       coded_buf->derived_surface.resource = pipe_buffer_create(drv->pipe->screen, PIPE_BIND_VERTEX_BUFFER,
132                                             PIPE_USAGE_STAGING, coded_buf->size);
133 
134    context->coded_buf = coded_buf;
135    context->desc.h265enc.pic.log2_parallel_merge_level_minus2 = h265->log2_parallel_merge_level_minus2;
136    context->desc.h265enc.pic.nal_unit_type = h265->nal_unit_type;
137    context->desc.h265enc.rc[0].init_qp = h265->pic_init_qp;
138 
139    switch(h265->pic_fields.bits.coding_type) {
140    case 1:
141       if (h265->pic_fields.bits.idr_pic_flag)
142          context->desc.h265enc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_IDR;
143       else
144          context->desc.h265enc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_I;
145       break;
146    case 2:
147       context->desc.h265enc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_P;
148       break;
149    case 3:
150    case 4:
151    case 5:
152       context->desc.h265enc.picture_type = PIPE_H2645_ENC_PICTURE_TYPE_B;
153       break;
154    }
155 
156    context->desc.h265enc.pic.constrained_intra_pred_flag = h265->pic_fields.bits.constrained_intra_pred_flag;
157    context->desc.h265enc.pic.pps_loop_filter_across_slices_enabled_flag = h265->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag;
158    context->desc.h265enc.pic.transform_skip_enabled_flag = h265->pic_fields.bits.transform_skip_enabled_flag;
159    context->desc.h265enc.pic.cu_qp_delta_enabled_flag = h265->pic_fields.bits.cu_qp_delta_enabled_flag;
160    context->desc.h265enc.pic.diff_cu_qp_delta_depth = h265->diff_cu_qp_delta_depth;
161 
162    _mesa_hash_table_insert(context->desc.h265enc.frame_idx,
163                        UINT_TO_PTR(h265->decoded_curr_pic.picture_id + 1),
164                        UINT_TO_PTR(context->desc.h265enc.frame_num));
165 
166    /* Initialize slice descriptors for this picture */
167    context->desc.h265enc.num_slice_descriptors = 0;
168    memset(&context->desc.h265enc.slices_descriptors, 0, sizeof(context->desc.h265enc.slices_descriptors));
169 
170    context->desc.h265enc.num_ref_idx_l0_active_minus1 = h265->num_ref_idx_l0_default_active_minus1;
171    context->desc.h265enc.num_ref_idx_l1_active_minus1 = h265->num_ref_idx_l1_default_active_minus1;
172 
173    return VA_STATUS_SUCCESS;
174 }
175 
176 static uint8_t
vlVaDpbIndex(vlVaContext * context,VASurfaceID id)177 vlVaDpbIndex(vlVaContext *context, VASurfaceID id)
178 {
179    for (uint8_t i = 0; i < context->desc.h265enc.dpb_size; i++) {
180       if (context->desc.h265enc.dpb[i].id == id)
181          return i;
182    }
183    return PIPE_H2645_LIST_REF_INVALID_ENTRY;
184 }
185 
186 VAStatus
vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver * drv,vlVaContext * context,vlVaBuffer * buf)187 vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
188 {
189    VAEncSliceParameterBufferHEVC *h265;
190    unsigned slice_qp;
191 
192    h265 = buf->data;
193 
194    /* Handle the slice control parameters */
195    struct h265_slice_descriptor slice_descriptor;
196    memset(&slice_descriptor, 0, sizeof(slice_descriptor));
197    slice_descriptor.slice_segment_address = h265->slice_segment_address;
198    slice_descriptor.num_ctu_in_slice = h265->num_ctu_in_slice;
199    slice_descriptor.slice_type = h265->slice_type;
200    assert(slice_descriptor.slice_type <= PIPE_H265_SLICE_TYPE_I);
201 
202    if (context->desc.h265enc.num_slice_descriptors < ARRAY_SIZE(context->desc.h265enc.slices_descriptors))
203       context->desc.h265enc.slices_descriptors[context->desc.h265enc.num_slice_descriptors++] = slice_descriptor;
204    else
205       return VA_STATUS_ERROR_NOT_ENOUGH_BUFFER;
206 
207    /* Only use parameters for first slice */
208    if (h265->slice_segment_address)
209       return VA_STATUS_SUCCESS;
210 
211    memset(&context->desc.h265enc.ref_idx_l0_list, VA_INVALID_ID, sizeof(context->desc.h265enc.ref_idx_l0_list));
212    memset(&context->desc.h265enc.ref_idx_l1_list, VA_INVALID_ID, sizeof(context->desc.h265enc.ref_idx_l1_list));
213    memset(&context->desc.h265enc.ref_list0, PIPE_H2645_LIST_REF_INVALID_ENTRY, sizeof(context->desc.h265enc.ref_list0));
214    memset(&context->desc.h265enc.ref_list1, PIPE_H2645_LIST_REF_INVALID_ENTRY, sizeof(context->desc.h265enc.ref_list1));
215 
216    if (h265->slice_fields.bits.num_ref_idx_active_override_flag) {
217       context->desc.h265enc.num_ref_idx_l0_active_minus1 = h265->num_ref_idx_l0_active_minus1;
218       context->desc.h265enc.num_ref_idx_l1_active_minus1 = h265->num_ref_idx_l1_active_minus1;
219    }
220 
221    if (h265->slice_type != PIPE_H265_SLICE_TYPE_I) {
222       for (int i = 0; i < 15; i++) {
223          if (h265->ref_pic_list0[i].picture_id != VA_INVALID_ID) {
224             context->desc.h265enc.ref_list0[i] = vlVaDpbIndex(context, h265->ref_pic_list0[i].picture_id);
225             if (context->desc.h265enc.ref_list0[i] == PIPE_H2645_LIST_REF_INVALID_ENTRY)
226                return VA_STATUS_ERROR_INVALID_PARAMETER;
227 
228             context->desc.h265enc.ref_idx_l0_list[i] = PTR_TO_UINT(util_hash_table_get(context->desc.h265enc.frame_idx,
229                                     UINT_TO_PTR(h265->ref_pic_list0[i].picture_id + 1)));
230          }
231          if (h265->ref_pic_list1[i].picture_id != VA_INVALID_ID && h265->slice_type == PIPE_H265_SLICE_TYPE_B) {
232             context->desc.h265enc.ref_list1[i] = vlVaDpbIndex(context, h265->ref_pic_list1[i].picture_id);
233             if (context->desc.h265enc.ref_list1[i] == PIPE_H2645_LIST_REF_INVALID_ENTRY)
234                return VA_STATUS_ERROR_INVALID_PARAMETER;
235 
236             context->desc.h265enc.ref_idx_l1_list[i] = PTR_TO_UINT(util_hash_table_get(context->desc.h265enc.frame_idx,
237                                     UINT_TO_PTR(h265->ref_pic_list1[i].picture_id + 1)));
238          }
239       }
240    }
241 
242    context->desc.h265enc.slice.max_num_merge_cand = h265->max_num_merge_cand;
243    context->desc.h265enc.slice.slice_cb_qp_offset = h265->slice_cb_qp_offset;
244    context->desc.h265enc.slice.slice_cr_qp_offset = h265->slice_cr_qp_offset;
245    context->desc.h265enc.slice.slice_beta_offset_div2 = h265->slice_beta_offset_div2;
246    context->desc.h265enc.slice.slice_tc_offset_div2 = h265->slice_tc_offset_div2;
247    context->desc.h265enc.slice.cabac_init_flag = h265->slice_fields.bits.cabac_init_flag;
248    context->desc.h265enc.slice.slice_deblocking_filter_disabled_flag = h265->slice_fields.bits.slice_deblocking_filter_disabled_flag;
249    context->desc.h265enc.slice.slice_loop_filter_across_slices_enabled_flag = h265->slice_fields.bits.slice_loop_filter_across_slices_enabled_flag;
250 
251    slice_qp = context->desc.h265enc.rc[0].init_qp + h265->slice_qp_delta;
252 
253    switch (context->desc.h265enc.picture_type) {
254    case PIPE_H2645_ENC_PICTURE_TYPE_I:
255    case PIPE_H2645_ENC_PICTURE_TYPE_IDR:
256       context->desc.h265enc.rc[0].quant_i_frames = slice_qp;
257       break;
258    case PIPE_H2645_ENC_PICTURE_TYPE_P:
259       context->desc.h265enc.rc[0].quant_p_frames = slice_qp;
260       break;
261    case PIPE_H2645_ENC_PICTURE_TYPE_B:
262       context->desc.h265enc.rc[0].quant_b_frames = slice_qp;
263       break;
264    default:
265       break;
266    }
267 
268    return VA_STATUS_SUCCESS;
269 }
270 
271 VAStatus
vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver * drv,vlVaContext * context,vlVaBuffer * buf)272 vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
273 {
274    VAEncSequenceParameterBufferHEVC *h265 = buf->data;
275    uint32_t num_units_in_tick = 0, time_scale = 0;
276 
277    context->desc.h265enc.seq.general_profile_idc = h265->general_profile_idc;
278    context->desc.h265enc.seq.general_level_idc = h265->general_level_idc;
279    context->desc.h265enc.seq.general_tier_flag = h265->general_tier_flag;
280    context->desc.h265enc.seq.intra_period = h265->intra_period;
281    context->desc.h265enc.seq.ip_period = h265->ip_period;
282    context->desc.h265enc.seq.pic_width_in_luma_samples = h265->pic_width_in_luma_samples;
283    context->desc.h265enc.seq.pic_height_in_luma_samples = h265->pic_height_in_luma_samples;
284    context->desc.h265enc.seq.chroma_format_idc = h265->seq_fields.bits.chroma_format_idc;
285    context->desc.h265enc.seq.bit_depth_luma_minus8 = h265->seq_fields.bits.bit_depth_luma_minus8;
286    context->desc.h265enc.seq.bit_depth_chroma_minus8 = h265->seq_fields.bits.bit_depth_chroma_minus8;
287    context->desc.h265enc.seq.strong_intra_smoothing_enabled_flag = h265->seq_fields.bits.strong_intra_smoothing_enabled_flag;
288    context->desc.h265enc.seq.amp_enabled_flag = h265->seq_fields.bits.amp_enabled_flag;
289    context->desc.h265enc.seq.sample_adaptive_offset_enabled_flag = h265->seq_fields.bits.sample_adaptive_offset_enabled_flag;
290    context->desc.h265enc.seq.pcm_enabled_flag = h265->seq_fields.bits.pcm_enabled_flag;
291    context->desc.h265enc.seq.sps_temporal_mvp_enabled_flag = h265->seq_fields.bits.sps_temporal_mvp_enabled_flag;
292    context->desc.h265enc.seq.log2_min_luma_coding_block_size_minus3 = h265->log2_min_luma_coding_block_size_minus3;
293    context->desc.h265enc.seq.log2_diff_max_min_luma_coding_block_size = h265->log2_diff_max_min_luma_coding_block_size;
294    context->desc.h265enc.seq.log2_min_transform_block_size_minus2 = h265->log2_min_transform_block_size_minus2;
295    context->desc.h265enc.seq.log2_diff_max_min_transform_block_size = h265->log2_diff_max_min_transform_block_size;
296    context->desc.h265enc.seq.max_transform_hierarchy_depth_inter = h265->max_transform_hierarchy_depth_inter;
297    context->desc.h265enc.seq.max_transform_hierarchy_depth_intra = h265->max_transform_hierarchy_depth_intra;
298 
299    context->desc.h265enc.seq.vui_parameters_present_flag = h265->vui_parameters_present_flag;
300    if (h265->vui_parameters_present_flag) {
301       context->desc.h265enc.seq.vui_flags.aspect_ratio_info_present_flag =
302          h265->vui_fields.bits.aspect_ratio_info_present_flag;
303          context->desc.h265enc.seq.aspect_ratio_idc = h265->aspect_ratio_idc;
304       context->desc.h265enc.seq.sar_width = h265->sar_width;
305       context->desc.h265enc.seq.sar_height = h265->sar_height;
306 
307       context->desc.h265enc.seq.vui_flags.timing_info_present_flag =
308          h265->vui_fields.bits.vui_timing_info_present_flag;
309       num_units_in_tick = h265->vui_num_units_in_tick;
310       time_scale  = h265->vui_time_scale;
311       context->desc.h265enc.seq.vui_flags.neutral_chroma_indication_flag =
312          h265->vui_fields.bits.neutral_chroma_indication_flag;
313       context->desc.h265enc.seq.vui_flags.field_seq_flag =
314          h265->vui_fields.bits.field_seq_flag;
315       context->desc.h265enc.seq.vui_flags.bitstream_restriction_flag =
316          h265->vui_fields.bits.bitstream_restriction_flag;
317       context->desc.h265enc.seq.vui_flags.tiles_fixed_structure_flag =
318          h265->vui_fields.bits.tiles_fixed_structure_flag;
319       context->desc.h265enc.seq.vui_flags.motion_vectors_over_pic_boundaries_flag =
320          h265->vui_fields.bits.motion_vectors_over_pic_boundaries_flag;
321       context->desc.h265enc.seq.vui_flags.restricted_ref_pic_lists_flag =
322          h265->vui_fields.bits.restricted_ref_pic_lists_flag;
323       context->desc.h265enc.seq.log2_max_mv_length_vertical =
324          h265->vui_fields.bits.log2_max_mv_length_vertical;
325       context->desc.h265enc.seq.log2_max_mv_length_horizontal =
326          h265->vui_fields.bits.log2_max_mv_length_horizontal;
327       context->desc.h265enc.seq.min_spatial_segmentation_idc =
328          h265->min_spatial_segmentation_idc;
329       context->desc.h265enc.seq.max_bytes_per_pic_denom =
330          h265->max_bytes_per_pic_denom;
331    } else {
332       context->desc.h265enc.seq.vui_flags.timing_info_present_flag = 0;
333       context->desc.h265enc.seq.vui_flags.neutral_chroma_indication_flag = 0;
334       context->desc.h265enc.seq.vui_flags.field_seq_flag = 0;
335       context->desc.h265enc.seq.vui_flags.bitstream_restriction_flag = 0;
336       context->desc.h265enc.seq.vui_flags.tiles_fixed_structure_flag = 0;
337       context->desc.h265enc.seq.vui_flags.motion_vectors_over_pic_boundaries_flag = 0;
338       context->desc.h265enc.seq.vui_flags.restricted_ref_pic_lists_flag = 0;
339       context->desc.h265enc.seq.log2_max_mv_length_vertical = 0;
340       context->desc.h265enc.seq.log2_max_mv_length_horizontal = 0;
341       context->desc.h265enc.seq.min_spatial_segmentation_idc = 0;
342       context->desc.h265enc.seq.max_bytes_per_pic_denom = 0;
343    }
344 
345    if (!context->desc.h265enc.seq.vui_flags.timing_info_present_flag) {
346       /* if not present, set default value */
347       num_units_in_tick = PIPE_DEFAULT_FRAME_RATE_DEN;
348       time_scale  = PIPE_DEFAULT_FRAME_RATE_NUM;
349    }
350 
351    context->desc.h265enc.seq.num_units_in_tick = num_units_in_tick;
352    context->desc.h265enc.seq.time_scale = time_scale;
353    context->desc.h265enc.rc[0].frame_rate_num = time_scale;
354    context->desc.h265enc.rc[0].frame_rate_den = num_units_in_tick;
355 
356    return VA_STATUS_SUCCESS;
357 }
358 
359 VAStatus
vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext * context,VAEncMiscParameterBuffer * misc)360 vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
361 {
362    unsigned temporal_id;
363    VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data;
364 
365    temporal_id = context->desc.h265enc.rc[0].rate_ctrl_method !=
366                  PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE ?
367                  rc->rc_flags.bits.temporal_id :
368                  0;
369 
370    if (context->desc.h265enc.seq.num_temporal_layers > 0 &&
371        temporal_id >= context->desc.h265enc.seq.num_temporal_layers)
372       return VA_STATUS_ERROR_INVALID_PARAMETER;
373 
374    if (context->desc.h265enc.rc[temporal_id].rate_ctrl_method ==
375          PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT)
376       context->desc.h265enc.rc[temporal_id].target_bitrate = rc->bits_per_second;
377    else
378       context->desc.h265enc.rc[temporal_id].target_bitrate =
379          rc->bits_per_second * (rc->target_percentage / 100.0);
380    context->desc.h265enc.rc[temporal_id].peak_bitrate = rc->bits_per_second;
381    if (context->desc.h265enc.rc[temporal_id].target_bitrate < 2000000)
382       context->desc.h265enc.rc[temporal_id].vbv_buffer_size =
383          MIN2((context->desc.h265enc.rc[temporal_id].target_bitrate * 2.75), 2000000);
384    else
385       context->desc.h265enc.rc[temporal_id].vbv_buffer_size = context->desc.h265enc.rc[0].target_bitrate;
386 
387    context->desc.h265enc.rc[temporal_id].fill_data_enable = !(rc->rc_flags.bits.disable_bit_stuffing);
388    /* context->desc.h265enc.rc[temporal_id].skip_frame_enable = !(rc->rc_flags.bits.disable_frame_skip); */
389    context->desc.h265enc.rc[temporal_id].skip_frame_enable = 0;
390    context->desc.h265enc.rc[temporal_id].max_qp = rc->max_qp;
391    context->desc.h265enc.rc[temporal_id].min_qp = rc->min_qp;
392    /* Distinguishes from the default params set for these values in other
393       functions and app specific params passed down */
394    context->desc.h265enc.rc[temporal_id].app_requested_qp_range = ((rc->max_qp > 0) || (rc->min_qp > 0));
395 
396    if (context->desc.h265enc.rc[temporal_id].rate_ctrl_method ==
397        PIPE_H2645_ENC_RATE_CONTROL_METHOD_QUALITY_VARIABLE)
398       context->desc.h265enc.rc[temporal_id].vbr_quality_factor =
399          rc->quality_factor;
400 
401    return VA_STATUS_SUCCESS;
402 }
403 
404 VAStatus
vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext * context,VAEncMiscParameterBuffer * misc)405 vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
406 {
407    unsigned temporal_id;
408    VAEncMiscParameterFrameRate *fr = (VAEncMiscParameterFrameRate *)misc->data;
409 
410    temporal_id = context->desc.h265enc.rc[0].rate_ctrl_method !=
411                  PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE ?
412                  fr->framerate_flags.bits.temporal_id :
413                  0;
414 
415    if (context->desc.h265enc.seq.num_temporal_layers > 0 &&
416        temporal_id >= context->desc.h265enc.seq.num_temporal_layers)
417       return VA_STATUS_ERROR_INVALID_PARAMETER;
418 
419    if (fr->framerate & 0xffff0000) {
420       context->desc.h265enc.rc[temporal_id].frame_rate_num = fr->framerate       & 0xffff;
421       context->desc.h265enc.rc[temporal_id].frame_rate_den = fr->framerate >> 16 & 0xffff;
422    } else {
423       context->desc.h265enc.rc[temporal_id].frame_rate_num = fr->framerate;
424       context->desc.h265enc.rc[temporal_id].frame_rate_den = 1;
425    }
426 
427    return VA_STATUS_SUCCESS;
428 }
429 
430 VAStatus
vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(vlVaContext * context,VAEncMiscParameterBuffer * misc)431 vlVaHandleVAEncMiscParameterTypeQualityLevelHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
432 {
433    VAEncMiscParameterBufferQualityLevel *ql = (VAEncMiscParameterBufferQualityLevel *)misc->data;
434    vlVaHandleVAEncMiscParameterTypeQualityLevel(&context->desc.h265enc.quality_modes,
435                                (vlVaQualityBits *)&ql->quality_level);
436 
437    return VA_STATUS_SUCCESS;
438 }
439 
profile_tier(struct vl_rbsp * rbsp,struct pipe_h265_profile_tier * pt)440 static void profile_tier(struct vl_rbsp *rbsp, struct pipe_h265_profile_tier *pt)
441 {
442    pt->general_profile_space = vl_rbsp_u(rbsp, 2);
443    pt->general_tier_flag = vl_rbsp_u(rbsp, 1);
444    pt->general_profile_idc = vl_rbsp_u(rbsp, 5);
445    pt->general_profile_compatibility_flag = vl_rbsp_u(rbsp, 32);
446    pt->general_progressive_source_flag = vl_rbsp_u(rbsp, 1);
447    pt->general_interlaced_source_flag = vl_rbsp_u(rbsp, 1);
448    pt->general_non_packed_constraint_flag = vl_rbsp_u(rbsp, 1);
449    pt->general_frame_only_constraint_flag = vl_rbsp_u(rbsp, 1);
450 
451    /* general_reserved_zero_44bits */
452    vl_rbsp_u(rbsp, 16);
453    vl_rbsp_u(rbsp, 16);
454    vl_rbsp_u(rbsp, 12);
455 }
456 
profile_tier_level(struct vl_rbsp * rbsp,int max_sublayers_minus1,struct pipe_h265_profile_tier_level * ptl)457 static void profile_tier_level(struct vl_rbsp *rbsp,
458                                int max_sublayers_minus1,
459                                struct pipe_h265_profile_tier_level *ptl)
460 {
461    int i;
462 
463    profile_tier(rbsp, &ptl->profile_tier);
464    ptl->general_level_idc = vl_rbsp_u(rbsp, 8);
465 
466    for (i = 0; i < max_sublayers_minus1; ++i) {
467       ptl->sub_layer_profile_present_flag[i] = vl_rbsp_u(rbsp, 1);
468       ptl->sub_layer_level_present_flag[i] = vl_rbsp_u(rbsp, 1);
469    }
470 
471    if (max_sublayers_minus1 > 0)
472       for (i = max_sublayers_minus1; i < 8; ++i)
473          vl_rbsp_u(rbsp, 2);        /* reserved_zero_2bits */
474 
475    for (i = 0; i < max_sublayers_minus1; ++i) {
476       if (ptl->sub_layer_profile_present_flag[i])
477          profile_tier(rbsp, &ptl->sub_layer_profile_tier[i]);
478 
479       if (ptl->sub_layer_level_present_flag[i])
480          ptl->sub_layer_level_idc[i] = vl_rbsp_u(rbsp, 8);
481    }
482 }
483 
parse_enc_hrd_sublayer_params_hevc(uint32_t cpb_cnt,uint32_t sub_pic_hrd_params_present_flag,struct vl_rbsp * rbsp,struct pipe_h265_enc_sublayer_hrd_params * sublayer_params)484 static void parse_enc_hrd_sublayer_params_hevc(uint32_t cpb_cnt,
485                                                uint32_t sub_pic_hrd_params_present_flag,
486                                                struct vl_rbsp *rbsp,
487                                                struct pipe_h265_enc_sublayer_hrd_params* sublayer_params)
488 {
489    for (unsigned i = 0; i < cpb_cnt; i++ ) {
490       sublayer_params->bit_rate_value_minus1[i] = vl_rbsp_ue(rbsp);
491       sublayer_params->cpb_size_value_minus1[i] = vl_rbsp_ue(rbsp);
492       if( sub_pic_hrd_params_present_flag ) {
493          sublayer_params->cpb_size_du_value_minus1[i] = vl_rbsp_ue(rbsp);
494          sublayer_params->bit_rate_du_value_minus1[i] = vl_rbsp_ue(rbsp);
495       }
496       sublayer_params->cbr_flag[i] = vl_rbsp_u(rbsp, 1);
497    }
498 }
499 
parse_enc_hrd_params_hevc(struct vl_rbsp * rbsp,uint32_t commonInfPresentFlag,uint32_t sps_max_sub_layers_minus1,struct pipe_h265_enc_hrd_params * hrdParams)500 static void parse_enc_hrd_params_hevc(struct vl_rbsp *rbsp,
501                                       uint32_t commonInfPresentFlag,
502                                       uint32_t sps_max_sub_layers_minus1,
503                                       struct pipe_h265_enc_hrd_params* hrdParams)
504 {
505    if (commonInfPresentFlag) {
506       hrdParams->nal_hrd_parameters_present_flag = vl_rbsp_u(rbsp, 1);
507       hrdParams->vcl_hrd_parameters_present_flag = vl_rbsp_u(rbsp, 1);
508       if (hrdParams->nal_hrd_parameters_present_flag || hrdParams->vcl_hrd_parameters_present_flag) {
509          hrdParams->sub_pic_hrd_params_present_flag = vl_rbsp_u(rbsp, 1);
510          if (hrdParams->sub_pic_hrd_params_present_flag) {
511             hrdParams->tick_divisor_minus2 = vl_rbsp_u(rbsp, 8);
512             hrdParams->du_cpb_removal_delay_increment_length_minus1 = vl_rbsp_u(rbsp, 5);
513             hrdParams->sub_pic_cpb_params_in_pic_timing_sei_flag  = vl_rbsp_u(rbsp, 1);
514             hrdParams->dpb_output_delay_du_length_minus1 = vl_rbsp_u(rbsp, 5);
515          }
516          hrdParams->bit_rate_scale = vl_rbsp_u(rbsp, 4);
517          hrdParams->cpb_rate_scale = vl_rbsp_u(rbsp, 4);
518          if (hrdParams->sub_pic_hrd_params_present_flag)
519             hrdParams->cpb_size_du_scale = vl_rbsp_u(rbsp, 4);
520          hrdParams->initial_cpb_removal_delay_length_minus1 = vl_rbsp_u(rbsp, 5);
521          hrdParams->au_cpb_removal_delay_length_minus1 = vl_rbsp_u(rbsp, 5);
522          hrdParams->dpb_output_delay_length_minus1 = vl_rbsp_u(rbsp, 5);
523       }
524    }
525 
526    for (unsigned i = 0; i <= sps_max_sub_layers_minus1; i++) {
527       hrdParams->fixed_pic_rate_general_flag[i] = vl_rbsp_u(rbsp, 1);
528       if (!hrdParams->fixed_pic_rate_general_flag[i])
529          hrdParams->fixed_pic_rate_within_cvs_flag[i] = vl_rbsp_u(rbsp, 1);
530       if (hrdParams->fixed_pic_rate_within_cvs_flag[i])
531          hrdParams->elemental_duration_in_tc_minus1[i] = vl_rbsp_ue(rbsp);
532       else
533          hrdParams->low_delay_hrd_flag[i] = vl_rbsp_u(rbsp, 1);
534       if (!hrdParams->low_delay_hrd_flag[i])
535          hrdParams->cpb_cnt_minus1[i] = vl_rbsp_ue(rbsp);
536 
537       if (hrdParams->nal_hrd_parameters_present_flag)
538          parse_enc_hrd_sublayer_params_hevc(hrdParams->cpb_cnt_minus1[i] + 1,
539                                             hrdParams->sub_pic_hrd_params_present_flag,
540                                             rbsp,
541                                             &hrdParams->nal_hrd_parameters[i]);
542 
543       if (hrdParams->vcl_hrd_parameters_present_flag)
544          parse_enc_hrd_sublayer_params_hevc(hrdParams->cpb_cnt_minus1[i] + 1,
545                                             hrdParams->sub_pic_hrd_params_present_flag,
546                                             rbsp,
547                                             &hrdParams->vlc_hrd_parameters[i]);
548    }
549 }
550 /* dummy function for consuming the scaling list data if it is available */
scaling_list_data(struct vl_rbsp * rbsp)551 static void scaling_list_data(struct vl_rbsp *rbsp)
552 {
553    unsigned size_id, matrix_id, coef_num;
554    unsigned pre_mode_flag;
555    for (size_id = 0; size_id < 4; size_id++) {
556       for (matrix_id = 0; matrix_id < 6; matrix_id += (size_id == 3) ? 3 : 1) {
557          pre_mode_flag = vl_rbsp_u(rbsp, 1);
558          if (pre_mode_flag == 0)
559             vl_rbsp_ue(rbsp);
560          else {
561             coef_num = MIN2(64, (1 << (4 + (size_id << 1))));
562             if (size_id > 1)
563                vl_rbsp_se(rbsp);
564             for (unsigned i = 0; i < coef_num; i++)
565                vl_rbsp_se(rbsp);
566          }
567       }
568    }
569 }
570 
571 /* i is the working rps, st_rps is the start
572  * returns num_pic_total_curr */
st_ref_pic_set(unsigned index,unsigned num_short_term_ref_pic_sets,struct pipe_h265_st_ref_pic_set * st_rps,struct vl_rbsp * rbsp)573 static unsigned st_ref_pic_set(unsigned index,
574                                unsigned num_short_term_ref_pic_sets,
575                                struct pipe_h265_st_ref_pic_set *st_rps,
576                                struct vl_rbsp *rbsp)
577 {
578    struct pipe_h265_st_ref_pic_set *ref_rps = NULL;
579    struct pipe_h265_st_ref_pic_set *rps = &st_rps[index];
580    unsigned i, num_pic_total_curr = 0;
581 
582    rps->inter_ref_pic_set_prediction_flag = index ? vl_rbsp_u(rbsp, 1) : 0;
583 
584    if (rps->inter_ref_pic_set_prediction_flag) {
585       if (index == num_short_term_ref_pic_sets)
586          rps->delta_idx_minus1 = vl_rbsp_ue(rbsp);
587       rps->delta_rps_sign = vl_rbsp_u(rbsp, 1);
588       rps->abs_delta_rps_minus1 = vl_rbsp_ue(rbsp);
589       ref_rps = st_rps + index +
590          (1 - 2 * rps->delta_rps_sign) * (st_rps->delta_idx_minus1 + 1);
591       for (i = 0; i <= (ref_rps->num_negative_pics + ref_rps->num_positive_pics); i++) {
592          rps->used_by_curr_pic_flag[i] = vl_rbsp_u(rbsp, 1);
593          if (!rps->used_by_curr_pic_flag[i])
594             rps->use_delta_flag[i] = vl_rbsp_u(rbsp, 1);
595       }
596    } else {
597       rps->num_negative_pics = vl_rbsp_ue(rbsp);
598       rps->num_positive_pics = vl_rbsp_ue(rbsp);
599       for (i = 0; i < rps->num_negative_pics; i++) {
600          rps->delta_poc_s0_minus1[i] = vl_rbsp_ue(rbsp);
601          rps->used_by_curr_pic_s0_flag[i] = vl_rbsp_u(rbsp, 1);
602          if (rps->used_by_curr_pic_s0_flag[i])
603             num_pic_total_curr++;
604       }
605       for (i = 0; i < st_rps->num_positive_pics; i++) {
606          rps->delta_poc_s1_minus1[i] = vl_rbsp_ue(rbsp);
607          rps->used_by_curr_pic_s1_flag[i] = vl_rbsp_u(rbsp, 1);
608          if (rps->used_by_curr_pic_s1_flag[i])
609             num_pic_total_curr++;
610       }
611    }
612 
613    return num_pic_total_curr;
614 }
615 
parseEncSliceParamsH265(vlVaContext * context,struct vl_rbsp * rbsp,unsigned nal_unit_type,unsigned temporal_id)616 static void parseEncSliceParamsH265(vlVaContext *context,
617                                     struct vl_rbsp *rbsp,
618                                     unsigned nal_unit_type,
619                                     unsigned temporal_id)
620 {
621    struct pipe_h265_enc_pic_param *pic = &context->desc.h265enc.pic;
622    struct pipe_h265_enc_seq_param *seq = &context->desc.h265enc.seq;
623    struct pipe_h265_enc_slice_param *slice = &context->desc.h265enc.slice;
624    unsigned num_pic_total_curr = 0;
625 
626    /* Only parse first slice */
627    if (!vl_rbsp_u(rbsp, 1)) /* first_slice_segment_in_pic_flag */
628       return;
629 
630    pic->nal_unit_type = nal_unit_type;
631    pic->temporal_id = temporal_id;
632 
633    if (nal_unit_type >= PIPE_H265_NAL_BLA_W_LP && nal_unit_type <= PIPE_H265_NAL_RSV_IRAP_VCL23)
634       slice->no_output_of_prior_pics_flag = vl_rbsp_u(rbsp, 1);
635 
636    vl_rbsp_ue(rbsp); /* slice_pic_parameter_set_id */
637 
638    if (slice->dependent_slice_segment_flag)
639       return;
640 
641    for (uint8_t i = 0; i < pic->num_extra_slice_header_bits; i++)
642       vl_rbsp_u(rbsp, 1);
643 
644    slice->slice_type = vl_rbsp_ue(rbsp);
645 
646    if (pic->output_flag_present_flag)
647       slice->pic_output_flag = vl_rbsp_u(rbsp, 1);
648 
649    if (nal_unit_type != PIPE_H265_NAL_IDR_W_RADL && nal_unit_type != PIPE_H265_NAL_IDR_N_LP) {
650       slice->slice_pic_order_cnt_lsb = vl_rbsp_u(rbsp, seq->log2_max_pic_order_cnt_lsb_minus4 + 4);
651       slice->short_term_ref_pic_set_sps_flag = vl_rbsp_u(rbsp, 1);
652       if (!slice->short_term_ref_pic_set_sps_flag) {
653          num_pic_total_curr = st_ref_pic_set(seq->num_short_term_ref_pic_sets, seq->num_short_term_ref_pic_sets,
654                                              seq->st_ref_pic_set, rbsp);
655       }
656       else if (seq->num_short_term_ref_pic_sets > 1)
657          slice->short_term_ref_pic_set_idx = vl_rbsp_u(rbsp, util_logbase2_ceil(seq->num_short_term_ref_pic_sets));
658       if (seq->long_term_ref_pics_present_flag) {
659          slice->num_long_term_sps = 0;
660          if (seq->num_long_term_ref_pics_sps > 0)
661             slice->num_long_term_sps = vl_rbsp_ue(rbsp);
662          slice->num_long_term_pics = vl_rbsp_ue(rbsp);
663          for (unsigned i = 0; i < (slice->num_long_term_sps + slice->num_long_term_pics); i++) {
664             if (i < slice->num_long_term_sps) {
665                if (seq->num_long_term_ref_pics_sps > 1)
666                   slice->lt_idx_sps[i] = vl_rbsp_u(rbsp, util_logbase2_ceil(seq->num_long_term_ref_pics_sps));
667             } else {
668                slice->poc_lsb_lt[i] = vl_rbsp_u(rbsp, seq->log2_max_pic_order_cnt_lsb_minus4 + 4);
669                slice->used_by_curr_pic_lt_flag[i] = vl_rbsp_u(rbsp, 1);
670                if (slice->used_by_curr_pic_lt_flag[i])
671                   num_pic_total_curr++;
672             }
673             slice->delta_poc_msb_present_flag[i] = vl_rbsp_u(rbsp, 1);
674             if (slice->delta_poc_msb_present_flag[i])
675                slice->delta_poc_msb_cycle_lt[i] = vl_rbsp_ue(rbsp);
676          }
677       }
678    }
679 
680    if (context->desc.h265enc.seq.sample_adaptive_offset_enabled_flag) {
681       slice->slice_sao_luma_flag = vl_rbsp_u(rbsp, 1);
682       slice->slice_sao_chroma_flag = vl_rbsp_u(rbsp, 1);
683    }
684 
685    if (slice->slice_type == PIPE_H265_SLICE_TYPE_P || slice->slice_type == PIPE_H265_SLICE_TYPE_B) {
686       slice->num_ref_idx_active_override_flag = vl_rbsp_u(rbsp, 1);
687       if (slice->num_ref_idx_active_override_flag) {
688          slice->num_ref_idx_l0_active_minus1 = vl_rbsp_ue(rbsp);
689          if (slice->slice_type == PIPE_H265_SLICE_TYPE_B)
690             slice->num_ref_idx_l1_active_minus1 = vl_rbsp_ue(rbsp);
691       }
692       if (pic->lists_modification_present_flag && num_pic_total_curr > 1) {
693          unsigned num_bits = util_logbase2_ceil(num_pic_total_curr);
694          unsigned num_ref_l0_minus1 = slice->num_ref_idx_active_override_flag ?
695             slice->num_ref_idx_l0_active_minus1 : pic->num_ref_idx_l0_default_active_minus1;
696          slice->ref_pic_lists_modification.ref_pic_list_modification_flag_l0 = vl_rbsp_u(rbsp, 1);
697          if (slice->ref_pic_lists_modification.ref_pic_list_modification_flag_l0) {
698             for (unsigned i = 0; i <= num_ref_l0_minus1; i++)
699                slice->ref_pic_lists_modification.list_entry_l0[i] = vl_rbsp_u(rbsp, num_bits);
700          }
701          if (slice->slice_type == PIPE_H265_SLICE_TYPE_B) {
702             unsigned num_ref_l1_minus1 = slice->num_ref_idx_active_override_flag ?
703                slice->num_ref_idx_l1_active_minus1 : pic->num_ref_idx_l1_default_active_minus1;
704             slice->ref_pic_lists_modification.ref_pic_list_modification_flag_l1 = vl_rbsp_u(rbsp, 1);
705             if (slice->ref_pic_lists_modification.ref_pic_list_modification_flag_l1) {
706                for (unsigned i = 0; i <= num_ref_l1_minus1; i++)
707                   slice->ref_pic_lists_modification.list_entry_l1[i] = vl_rbsp_u(rbsp, num_bits);
708             }
709          }
710       }
711       if (slice->slice_type == PIPE_H265_SLICE_TYPE_B)
712          slice->mvd_l1_zero_flag = vl_rbsp_u(rbsp, 1);
713       if (pic->cabac_init_present_flag)
714          slice->cabac_init_flag = vl_rbsp_u(rbsp, 1);
715       slice->max_num_merge_cand = 5 - vl_rbsp_ue(rbsp);
716    }
717 
718    slice->slice_qp_delta = vl_rbsp_se(rbsp);
719 
720    if (pic->pps_slice_chroma_qp_offsets_present_flag) {
721       slice->slice_cb_qp_offset = vl_rbsp_se(rbsp);
722       slice->slice_cr_qp_offset = vl_rbsp_se(rbsp);
723    }
724 
725    if (pic->deblocking_filter_override_enabled_flag)
726       slice->deblocking_filter_override_flag = vl_rbsp_u(rbsp, 1);
727 
728    if (slice->deblocking_filter_override_flag) {
729       slice->slice_deblocking_filter_disabled_flag = vl_rbsp_u(rbsp, 1);
730       if (!slice->slice_deblocking_filter_disabled_flag) {
731          slice->slice_beta_offset_div2 = vl_rbsp_se(rbsp);
732          slice->slice_tc_offset_div2 = vl_rbsp_se(rbsp);
733       }
734    }
735 
736    if (pic->pps_loop_filter_across_slices_enabled_flag &&
737        (slice->slice_sao_luma_flag ||
738         slice->slice_sao_chroma_flag ||
739         !slice->slice_deblocking_filter_disabled_flag))
740       slice->slice_loop_filter_across_slices_enabled_flag = vl_rbsp_u(rbsp, 1);
741 }
742 
parseEncVpsParamsH265(vlVaContext * context,struct vl_rbsp * rbsp)743 static void parseEncVpsParamsH265(vlVaContext *context, struct vl_rbsp *rbsp)
744 {
745    struct pipe_h265_enc_vid_param *vid = &context->desc.h265enc.vid;
746    unsigned i;
747 
748    vl_rbsp_u(rbsp, 4); /* vps_video_parameter_set_id */
749    vid->vps_base_layer_internal_flag = vl_rbsp_u(rbsp, 1);
750    vid->vps_base_layer_available_flag = vl_rbsp_u(rbsp, 1);
751    vid->vps_max_layers_minus1 = vl_rbsp_u(rbsp, 6);
752    vid->vps_max_sub_layers_minus1 = vl_rbsp_u(rbsp, 3);
753    vid->vps_temporal_id_nesting_flag = vl_rbsp_u(rbsp, 1);
754    vl_rbsp_u(rbsp, 16); /* vps_reserved_0xffff_16bits */
755    profile_tier_level(rbsp, vid->vps_max_sub_layers_minus1, &vid->profile_tier_level);
756    vid->vps_sub_layer_ordering_info_present_flag = vl_rbsp_u(rbsp, 1);
757    i = vid->vps_sub_layer_ordering_info_present_flag ? 0 : vid->vps_max_sub_layers_minus1;
758    for (; i <= vid->vps_max_sub_layers_minus1; i++) {
759       vid->vps_max_dec_pic_buffering_minus1[i] = vl_rbsp_ue(rbsp);
760       vid->vps_max_num_reorder_pics[i] = vl_rbsp_ue(rbsp);
761       vid->vps_max_latency_increase_plus1[i] = vl_rbsp_ue(rbsp);
762    }
763    vid->vps_max_layer_id = vl_rbsp_u(rbsp, 6);
764    vid->vps_num_layer_sets_minus1 = vl_rbsp_ue(rbsp);
765    for (unsigned i = 0; i <= vid->vps_num_layer_sets_minus1; i++) {
766       for (unsigned j = 0; j <= vid->vps_max_layer_id; j++)
767          vl_rbsp_u(rbsp, 1); /* layer_id_included_flag[i][j] */
768    }
769    vid->vps_timing_info_present_flag = vl_rbsp_u(rbsp, 1);
770    if (vid->vps_timing_info_present_flag) {
771       vid->vps_num_units_in_tick = vl_rbsp_u(rbsp, 32);
772       vid->vps_time_scale = vl_rbsp_u(rbsp, 32);
773       vid->vps_poc_proportional_to_timing_flag = vl_rbsp_u(rbsp, 1);
774       if (vid->vps_poc_proportional_to_timing_flag)
775          vid->vps_num_ticks_poc_diff_one_minus1 = vl_rbsp_ue(rbsp);
776    }
777 }
778 
parseEncPpsParamsH265(vlVaContext * context,struct vl_rbsp * rbsp)779 static void parseEncPpsParamsH265(vlVaContext *context, struct vl_rbsp *rbsp)
780 {
781    struct pipe_h265_enc_pic_param *pic = &context->desc.h265enc.pic;
782 
783    vl_rbsp_ue(rbsp); /* pps_pic_parameter_set_id */
784    vl_rbsp_ue(rbsp); /* pps_seq_parameter_set_id */
785    pic->dependent_slice_segments_enabled_flag = vl_rbsp_u(rbsp, 1);
786    pic->output_flag_present_flag = vl_rbsp_u(rbsp, 1);
787    pic->num_extra_slice_header_bits = vl_rbsp_u(rbsp, 3);
788    pic->sign_data_hiding_enabled_flag = vl_rbsp_u(rbsp, 1);
789    pic->cabac_init_present_flag = vl_rbsp_u(rbsp, 1);
790    pic->num_ref_idx_l0_default_active_minus1 = vl_rbsp_ue(rbsp);
791    pic->num_ref_idx_l1_default_active_minus1 = vl_rbsp_ue(rbsp);
792    pic->init_qp_minus26 = vl_rbsp_se(rbsp);
793    pic->constrained_intra_pred_flag = vl_rbsp_u(rbsp, 1);
794    pic->transform_skip_enabled_flag = vl_rbsp_u(rbsp, 1);
795    pic->cu_qp_delta_enabled_flag = vl_rbsp_u(rbsp, 1);
796    if (pic->cu_qp_delta_enabled_flag)
797       pic->diff_cu_qp_delta_depth = vl_rbsp_ue(rbsp);
798    pic->pps_cb_qp_offset = vl_rbsp_se(rbsp);
799    pic->pps_cr_qp_offset = vl_rbsp_se(rbsp);
800    pic->pps_slice_chroma_qp_offsets_present_flag = vl_rbsp_u(rbsp, 1);
801    pic->weighted_pred_flag = vl_rbsp_u(rbsp, 1);
802    pic->weighted_bipred_flag = vl_rbsp_u(rbsp, 1);
803    pic->transquant_bypass_enabled_flag = vl_rbsp_u(rbsp, 1);
804    unsigned tiles_enabled_flag = vl_rbsp_u(rbsp, 1);
805    pic->entropy_coding_sync_enabled_flag = vl_rbsp_u(rbsp, 1);
806    if (tiles_enabled_flag) {
807       unsigned num_tile_columns_minus1 = vl_rbsp_ue(rbsp);
808       unsigned num_tile_rows_minus1 = vl_rbsp_ue(rbsp);
809       if (!vl_rbsp_u(rbsp, 1)) { /* uniform_spacing_flag */
810          for (unsigned i = 0; i < num_tile_columns_minus1; i++)
811             vl_rbsp_ue(rbsp); /* column_width_minus1[i] */
812          for (unsigned i = 0; i < num_tile_rows_minus1; i++)
813             vl_rbsp_ue(rbsp); /* row_height_minus1[i] */
814       }
815       vl_rbsp_u(rbsp, 1); /* loop_filter_across_tiles_enabled_flag */
816    }
817    pic->pps_loop_filter_across_slices_enabled_flag = vl_rbsp_u(rbsp, 1);
818    pic->deblocking_filter_control_present_flag = vl_rbsp_u(rbsp, 1);
819    if (pic->deblocking_filter_control_present_flag) {
820       pic->deblocking_filter_override_enabled_flag = vl_rbsp_u(rbsp, 1);
821       pic->pps_deblocking_filter_disabled_flag = vl_rbsp_u(rbsp, 1);
822       if (!pic->pps_deblocking_filter_disabled_flag) {
823          pic->pps_beta_offset_div2 = vl_rbsp_se(rbsp);
824          pic->pps_tc_offset_div2 = vl_rbsp_se(rbsp);
825       }
826    }
827 }
828 
parseEncSpsParamsH265(vlVaContext * context,struct vl_rbsp * rbsp)829 static void parseEncSpsParamsH265(vlVaContext *context, struct vl_rbsp *rbsp)
830 {
831    unsigned i;
832 
833    vl_rbsp_u(rbsp, 4);     /* sps_video_parameter_set_id */
834    context->desc.h265enc.seq.sps_max_sub_layers_minus1 = vl_rbsp_u(rbsp, 3);
835    context->desc.h265enc.seq.sps_temporal_id_nesting_flag = vl_rbsp_u(rbsp, 1);
836 
837    /* level_idc */
838    profile_tier_level(rbsp, context->desc.h265enc.seq.sps_max_sub_layers_minus1,
839                       &context->desc.h265enc.seq.profile_tier_level);
840 
841    vl_rbsp_ue(rbsp);       /* sps_seq_parameter_set_id */
842    context->desc.h265enc.seq.chroma_format_idc = vl_rbsp_ue(rbsp);
843    if (context->desc.h265enc.seq.chroma_format_idc == 3)
844       vl_rbsp_u(rbsp, 1);  /* separate_colour_plane_flag */
845 
846    context->desc.h265enc.seq.pic_width_in_luma_samples = vl_rbsp_ue(rbsp);
847    context->desc.h265enc.seq.pic_height_in_luma_samples = vl_rbsp_ue(rbsp);
848 
849    /* conformance_window_flag - used for cropping */
850    context->desc.h265enc.seq.conformance_window_flag = vl_rbsp_u(rbsp, 1);
851    if (context->desc.h265enc.seq.conformance_window_flag) {
852       context->desc.h265enc.seq.conf_win_left_offset = vl_rbsp_ue(rbsp);
853       context->desc.h265enc.seq.conf_win_right_offset = vl_rbsp_ue(rbsp);
854       context->desc.h265enc.seq.conf_win_top_offset = vl_rbsp_ue(rbsp);
855       context->desc.h265enc.seq.conf_win_bottom_offset = vl_rbsp_ue(rbsp);
856    }
857 
858    context->desc.h265enc.seq.bit_depth_luma_minus8 = vl_rbsp_ue(rbsp);
859    context->desc.h265enc.seq.bit_depth_chroma_minus8 = vl_rbsp_ue(rbsp);
860    context->desc.h265enc.seq.log2_max_pic_order_cnt_lsb_minus4 = vl_rbsp_ue(rbsp);
861 
862    context->desc.h265enc.seq.sps_sub_layer_ordering_info_present_flag = vl_rbsp_u(rbsp, 1);
863    i = context->desc.h265enc.seq.sps_sub_layer_ordering_info_present_flag ? 0 : context->desc.h265enc.seq.sps_max_sub_layers_minus1;
864    for (; i <= context->desc.h265enc.seq.sps_max_sub_layers_minus1; ++i) {
865       context->desc.h265enc.seq.sps_max_dec_pic_buffering_minus1[i] = vl_rbsp_ue(rbsp);
866       context->desc.h265enc.seq.sps_max_num_reorder_pics[i] = vl_rbsp_ue(rbsp);
867       context->desc.h265enc.seq.sps_max_latency_increase_plus1[i] = vl_rbsp_ue(rbsp);
868    }
869 
870    context->desc.h265enc.seq.log2_min_luma_coding_block_size_minus3 = vl_rbsp_ue(rbsp);
871    context->desc.h265enc.seq.log2_diff_max_min_luma_coding_block_size = vl_rbsp_ue(rbsp);
872    context->desc.h265enc.seq.log2_min_transform_block_size_minus2 = vl_rbsp_ue(rbsp);
873    context->desc.h265enc.seq.log2_diff_max_min_transform_block_size = vl_rbsp_ue(rbsp);
874    context->desc.h265enc.seq.max_transform_hierarchy_depth_inter = vl_rbsp_ue(rbsp);
875    context->desc.h265enc.seq.max_transform_hierarchy_depth_intra = vl_rbsp_ue(rbsp);
876 
877    if (vl_rbsp_u(rbsp, 1)) /* scaling_list_enabled_flag */
878       if (vl_rbsp_u(rbsp, 1)) /* sps_scaling_list_data_present_flag */
879          scaling_list_data(rbsp);
880 
881    context->desc.h265enc.seq.amp_enabled_flag = vl_rbsp_u(rbsp, 1);
882    context->desc.h265enc.seq.sample_adaptive_offset_enabled_flag = vl_rbsp_u(rbsp, 1);
883 
884    context->desc.h265enc.seq.pcm_enabled_flag = vl_rbsp_u(rbsp, 1);
885    if (context->desc.h265enc.seq.pcm_enabled_flag) {
886       vl_rbsp_u(rbsp, 4); /* pcm_sample_bit_depth_luma_minus1 */
887       vl_rbsp_u(rbsp, 4); /* pcm_sample_bit_depth_chroma_minus1 */
888       vl_rbsp_ue(rbsp); /* log2_min_pcm_luma_coding_block_size_minus3 */
889       vl_rbsp_ue(rbsp); /* log2_diff_max_min_pcm_luma_coding_block_size */
890       vl_rbsp_u(rbsp, 1); /* pcm_loop_filter_disabled_flag */
891    }
892 
893    context->desc.h265enc.seq.num_short_term_ref_pic_sets = vl_rbsp_ue(rbsp);
894    for (i = 0; i < context->desc.h265enc.seq.num_short_term_ref_pic_sets; i++) {
895       st_ref_pic_set(i, context->desc.h265enc.seq.num_short_term_ref_pic_sets,
896                      context->desc.h265enc.seq.st_ref_pic_set, rbsp);
897    }
898 
899    context->desc.h265enc.seq.long_term_ref_pics_present_flag = vl_rbsp_u(rbsp, 1);
900    if (context->desc.h265enc.seq.long_term_ref_pics_present_flag) {
901       context->desc.h265enc.seq.num_long_term_ref_pics_sps = vl_rbsp_ue(rbsp);
902       for (i = 0; i < context->desc.h265enc.seq.num_long_term_ref_pics_sps; i++) {
903          context->desc.h265enc.seq.lt_ref_pic_poc_lsb_sps[i] =
904             vl_rbsp_u(rbsp, context->desc.h265enc.seq.log2_max_pic_order_cnt_lsb_minus4 + 4);
905          context->desc.h265enc.seq.used_by_curr_pic_lt_sps_flag[i] =
906             vl_rbsp_u(rbsp, 1);
907       }
908    }
909 
910    context->desc.h265enc.seq.sps_temporal_mvp_enabled_flag = vl_rbsp_u(rbsp, 1);
911    context->desc.h265enc.seq.strong_intra_smoothing_enabled_flag = vl_rbsp_u(rbsp, 1);
912 
913    context->desc.h265enc.seq.vui_parameters_present_flag = vl_rbsp_u(rbsp, 1);
914    if (context->desc.h265enc.seq.vui_parameters_present_flag) {
915       context->desc.h265enc.seq.vui_flags.aspect_ratio_info_present_flag = vl_rbsp_u(rbsp, 1);
916       if (context->desc.h265enc.seq.vui_flags.aspect_ratio_info_present_flag) {
917          context->desc.h265enc.seq.aspect_ratio_idc = vl_rbsp_u(rbsp, 8);
918          if (context->desc.h265enc.seq.aspect_ratio_idc == 255 /* Extended_SAR */) {
919             context->desc.h265enc.seq.sar_width = vl_rbsp_u(rbsp, 16);
920             context->desc.h265enc.seq.sar_height = vl_rbsp_u(rbsp, 16);
921          }
922       }
923 
924       context->desc.h265enc.seq.vui_flags.overscan_info_present_flag = vl_rbsp_u(rbsp, 1);
925       if (context->desc.h265enc.seq.vui_flags.overscan_info_present_flag)
926          context->desc.h265enc.seq.vui_flags.overscan_appropriate_flag = vl_rbsp_u(rbsp, 1);
927 
928       context->desc.h265enc.seq.vui_flags.video_signal_type_present_flag = vl_rbsp_u(rbsp, 1);
929       if (context->desc.h265enc.seq.vui_flags.video_signal_type_present_flag) {
930          context->desc.h265enc.seq.video_format = vl_rbsp_u(rbsp, 3);
931          context->desc.h265enc.seq.video_full_range_flag = vl_rbsp_u(rbsp, 1);
932          context->desc.h265enc.seq.vui_flags.colour_description_present_flag = vl_rbsp_u(rbsp, 1);
933          if (context->desc.h265enc.seq.vui_flags.colour_description_present_flag) {
934             context->desc.h265enc.seq.colour_primaries = vl_rbsp_u(rbsp, 8);
935             context->desc.h265enc.seq.transfer_characteristics = vl_rbsp_u(rbsp, 8);
936             context->desc.h265enc.seq.matrix_coefficients = vl_rbsp_u(rbsp, 8);
937          }
938       }
939 
940       context->desc.h265enc.seq.vui_flags.chroma_loc_info_present_flag = vl_rbsp_u(rbsp, 1);
941       if (context->desc.h265enc.seq.vui_flags.chroma_loc_info_present_flag) {
942          context->desc.h265enc.seq.chroma_sample_loc_type_top_field = vl_rbsp_ue(rbsp);
943          context->desc.h265enc.seq.chroma_sample_loc_type_bottom_field = vl_rbsp_ue(rbsp);
944       }
945 
946       context->desc.h265enc.seq.vui_flags.neutral_chroma_indication_flag = vl_rbsp_u(rbsp, 1);
947       context->desc.h265enc.seq.vui_flags.field_seq_flag = vl_rbsp_u(rbsp, 1);
948       context->desc.h265enc.seq.vui_flags.frame_field_info_present_flag = vl_rbsp_u(rbsp, 1);
949       context->desc.h265enc.seq.vui_flags.default_display_window_flag = vl_rbsp_u(rbsp, 1);
950 
951       if (context->desc.h265enc.seq.vui_flags.default_display_window_flag) {
952          context->desc.h265enc.seq.def_disp_win_left_offset = vl_rbsp_ue(rbsp);
953          context->desc.h265enc.seq.def_disp_win_right_offset = vl_rbsp_ue(rbsp);
954          context->desc.h265enc.seq.def_disp_win_top_offset = vl_rbsp_ue(rbsp);
955          context->desc.h265enc.seq.def_disp_win_bottom_offset = vl_rbsp_ue(rbsp);
956       }
957 
958       context->desc.h265enc.seq.vui_flags.timing_info_present_flag = vl_rbsp_u(rbsp, 1);
959 
960       if (context->desc.h265enc.seq.vui_flags.timing_info_present_flag) {
961          uint32_t num_units_in_tick_high = vl_rbsp_u(rbsp, 16);
962          uint32_t num_units_in_tick_low = vl_rbsp_u(rbsp, 16);
963          context->desc.h265enc.seq.num_units_in_tick = (num_units_in_tick_high << 16) | num_units_in_tick_low;
964 
965          uint32_t time_scale_high = vl_rbsp_u(rbsp, 16);
966          uint32_t time_scale_low = vl_rbsp_u(rbsp, 16);
967          context->desc.h265enc.seq.time_scale = (time_scale_high << 16) | time_scale_low;
968 
969          context->desc.h265enc.seq.vui_flags.poc_proportional_to_timing_flag = vl_rbsp_u(rbsp, 1);
970          if (context->desc.h265enc.seq.vui_flags.poc_proportional_to_timing_flag) {
971             context->desc.h265enc.seq.num_ticks_poc_diff_one_minus1 = vl_rbsp_ue(rbsp);
972             context->desc.h265enc.seq.vui_flags.hrd_parameters_present_flag = vl_rbsp_u(rbsp, 1);
973             if (context->desc.h265enc.seq.vui_flags.hrd_parameters_present_flag)
974                parse_enc_hrd_params_hevc(rbsp,
975                                          1,
976                                          context->desc.h265enc.seq.sps_max_sub_layers_minus1,
977                                          &context->desc.h265enc.seq.hrd_parameters);
978          }
979       }
980 
981       context->desc.h265enc.seq.vui_flags.bitstream_restriction_flag = vl_rbsp_u(rbsp, 1);
982       if (context->desc.h265enc.seq.vui_flags.bitstream_restriction_flag) {
983          context->desc.h265enc.seq.vui_flags.tiles_fixed_structure_flag = vl_rbsp_u(rbsp, 1);
984          context->desc.h265enc.seq.vui_flags.motion_vectors_over_pic_boundaries_flag = vl_rbsp_u(rbsp, 1);
985          context->desc.h265enc.seq.vui_flags.restricted_ref_pic_lists_flag = vl_rbsp_u(rbsp, 1);
986          context->desc.h265enc.seq.min_spatial_segmentation_idc = vl_rbsp_ue(rbsp);
987          context->desc.h265enc.seq.max_bytes_per_pic_denom = vl_rbsp_ue(rbsp);
988          context->desc.h265enc.seq.max_bits_per_min_cu_denom = vl_rbsp_ue(rbsp);
989          context->desc.h265enc.seq.log2_max_mv_length_horizontal = vl_rbsp_ue(rbsp);
990          context->desc.h265enc.seq.log2_max_mv_length_vertical = vl_rbsp_ue(rbsp);
991       }
992    }
993 }
994 
parseEncSeiPayloadH265(vlVaContext * context,struct vl_rbsp * rbsp,int payloadType,int payloadSize)995 static void parseEncSeiPayloadH265(vlVaContext *context, struct vl_rbsp *rbsp, int payloadType, int payloadSize)
996 {
997    switch (payloadType) {
998    case MASTERING_DISPLAY_COLOUR_VOLUME:
999       for (int32_t i = 0; i < 3; i++) {
1000          context->desc.h265enc.metadata_hdr_mdcv.primary_chromaticity_x[i] = vl_rbsp_u(rbsp, 16);
1001          context->desc.h265enc.metadata_hdr_mdcv.primary_chromaticity_y[i] = vl_rbsp_u(rbsp, 16);
1002       }
1003       context->desc.h265enc.metadata_hdr_mdcv.white_point_chromaticity_x = vl_rbsp_u(rbsp, 16);
1004       context->desc.h265enc.metadata_hdr_mdcv.white_point_chromaticity_y = vl_rbsp_u(rbsp, 16);
1005       context->desc.h265enc.metadata_hdr_mdcv.luminance_max = vl_rbsp_u(rbsp, 32);
1006       context->desc.h265enc.metadata_hdr_mdcv.luminance_min = vl_rbsp_u(rbsp, 32);
1007       break;
1008    case CONTENT_LIGHT_LEVEL_INFO:
1009       context->desc.h265enc.metadata_hdr_cll.max_cll= vl_rbsp_u(rbsp, 16);
1010       context->desc.h265enc.metadata_hdr_cll.max_fall= vl_rbsp_u(rbsp, 16);
1011       break;
1012    default:
1013       break;
1014    }
1015 }
1016 
parseEncSeiH265(vlVaContext * context,struct vl_rbsp * rbsp)1017 static void parseEncSeiH265(vlVaContext *context, struct vl_rbsp *rbsp)
1018 {
1019    do {
1020       /* sei_message() */
1021       int payloadType = 0;
1022       int payloadSize = 0;
1023 
1024       int byte = 0xFF;
1025       while (byte == 0xFF) {
1026          byte = vl_rbsp_u(rbsp, 8);
1027          payloadType += byte;
1028       }
1029 
1030       byte = 0xFF;
1031       while (byte == 0xFF) {
1032          byte = vl_rbsp_u(rbsp, 8);
1033          payloadSize += byte;
1034       }
1035       parseEncSeiPayloadH265(context, rbsp, payloadType, payloadSize);
1036 
1037    } while (vl_rbsp_more_data(rbsp));
1038 }
1039 
1040 VAStatus
vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext * context,vlVaBuffer * buf)1041 vlVaHandleVAEncPackedHeaderDataBufferTypeHEVC(vlVaContext *context, vlVaBuffer *buf)
1042 {
1043    struct vl_vlc vlc = {0};
1044    uint8_t *data = buf->data;
1045    int nal_start = -1;
1046    unsigned nal_unit_type = 0, emulation_bytes_start = 0;
1047    bool is_slice = false;
1048 
1049    vl_vlc_init(&vlc, 1, (const void * const*)&data, &buf->size);
1050 
1051    while (vl_vlc_bits_left(&vlc) > 0) {
1052       /* search the first 64 bytes for a startcode */
1053       for (int i = 0; i < 64 && vl_vlc_bits_left(&vlc) >= 24; ++i) {
1054          if (vl_vlc_peekbits(&vlc, 24) == 0x000001)
1055             break;
1056          vl_vlc_eatbits(&vlc, 8);
1057          vl_vlc_fillbits(&vlc);
1058       }
1059 
1060       unsigned start = vlc.data - data - vl_vlc_valid_bits(&vlc) / 8;
1061       emulation_bytes_start = 5; /* 3 bytes startcode + 2 bytes header */
1062       /* handle 4 bytes startcode */
1063       if (start > 0 && data[start - 1] == 0x00) {
1064          start--;
1065          emulation_bytes_start++;
1066       }
1067       if (nal_start >= 0) {
1068          vlVaAddRawHeader(&context->desc.h265enc.raw_headers, nal_unit_type,
1069                           start - nal_start, data + nal_start, is_slice, 0);
1070       }
1071       nal_start = start;
1072       is_slice = false;
1073 
1074       vl_vlc_eatbits(&vlc, 24); /* eat the startcode */
1075 
1076       if (vl_vlc_valid_bits(&vlc) < 15)
1077          vl_vlc_fillbits(&vlc);
1078 
1079       vl_vlc_eatbits(&vlc, 1);
1080       nal_unit_type = vl_vlc_get_uimsbf(&vlc, 6);
1081       vl_vlc_eatbits(&vlc, 6);
1082       unsigned temporal_id = vl_vlc_get_uimsbf(&vlc, 3) - 1;
1083 
1084       struct vl_rbsp rbsp;
1085       vl_rbsp_init(&rbsp, &vlc, ~0, context->packed_header_emulation_bytes);
1086 
1087       switch (nal_unit_type) {
1088       case PIPE_H265_NAL_TRAIL_N:
1089       case PIPE_H265_NAL_TRAIL_R:
1090       case PIPE_H265_NAL_TSA_N:
1091       case PIPE_H265_NAL_TSA_R:
1092       case PIPE_H265_NAL_IDR_W_RADL:
1093       case PIPE_H265_NAL_IDR_N_LP:
1094       case PIPE_H265_NAL_CRA_NUT:
1095          is_slice = true;
1096          parseEncSliceParamsH265(context, &rbsp, nal_unit_type, temporal_id);
1097          break;
1098       case PIPE_H265_NAL_VPS:
1099          parseEncVpsParamsH265(context, &rbsp);
1100          break;
1101       case PIPE_H265_NAL_SPS:
1102          parseEncSpsParamsH265(context, &rbsp);
1103          break;
1104       case PIPE_H265_NAL_PPS:
1105          parseEncPpsParamsH265(context, &rbsp);
1106          break;
1107       case PIPE_H265_NAL_PREFIX_SEI:
1108          parseEncSeiH265(context, &rbsp);
1109          break;
1110       default:
1111          break;
1112       }
1113 
1114       if (!context->packed_header_emulation_bytes)
1115          break;
1116    }
1117 
1118    if (nal_start >= 0) {
1119       vlVaAddRawHeader(&context->desc.h265enc.raw_headers, nal_unit_type,
1120                        buf->size - nal_start, data + nal_start, is_slice,
1121                        context->packed_header_emulation_bytes ? 0 : emulation_bytes_start);
1122    }
1123 
1124    return VA_STATUS_SUCCESS;
1125 }
1126 
1127 VAStatus
vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(vlVaContext * context,VAEncMiscParameterBuffer * misc)1128 vlVaHandleVAEncMiscParameterTypeMaxFrameSizeHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
1129 {
1130    VAEncMiscParameterBufferMaxFrameSize *ms = (VAEncMiscParameterBufferMaxFrameSize *)misc->data;
1131    context->desc.h265enc.rc[0].max_au_size = ms->max_frame_size;
1132    return VA_STATUS_SUCCESS;
1133 }
1134 
1135 VAStatus
vlVaHandleVAEncMiscParameterTypeHRDHEVC(vlVaContext * context,VAEncMiscParameterBuffer * misc)1136 vlVaHandleVAEncMiscParameterTypeHRDHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
1137 {
1138    VAEncMiscParameterHRD *ms = (VAEncMiscParameterHRD *)misc->data;
1139 
1140    if (ms->buffer_size == 0)
1141       return VA_STATUS_ERROR_INVALID_PARAMETER;
1142 
1143    /* Distinguishes from the default params set for these values in other
1144       functions and app specific params passed down via HRD buffer */
1145    context->desc.h265enc.rc[0].app_requested_hrd_buffer = true;
1146    context->desc.h265enc.rc[0].vbv_buffer_size = ms->buffer_size;
1147    context->desc.h265enc.rc[0].vbv_buf_lv = (ms->initial_buffer_fullness << 6) / ms->buffer_size;
1148    context->desc.h265enc.rc[0].vbv_buf_initial_size = ms->initial_buffer_fullness;
1149 
1150    for (unsigned i = 1; i < context->desc.h265enc.seq.num_temporal_layers; i++) {
1151       context->desc.h265enc.rc[i].vbv_buffer_size =
1152          (float)ms->buffer_size / context->desc.h265enc.rc[0].peak_bitrate *
1153          context->desc.h265enc.rc[i].peak_bitrate;
1154       context->desc.h265enc.rc[i].vbv_buf_lv = context->desc.h265enc.rc[0].vbv_buf_lv;
1155       context->desc.h265enc.rc[i].vbv_buf_initial_size =
1156          (context->desc.h265enc.rc[i].vbv_buffer_size * context->desc.h265enc.rc[i].vbv_buf_lv) >> 6;
1157    }
1158 
1159    return VA_STATUS_SUCCESS;
1160 }
1161 
1162 VAStatus
vlVaHandleVAEncMiscParameterTypeTemporalLayerHEVC(vlVaContext * context,VAEncMiscParameterBuffer * misc)1163 vlVaHandleVAEncMiscParameterTypeTemporalLayerHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
1164 {
1165    VAEncMiscParameterTemporalLayerStructure *tl = (VAEncMiscParameterTemporalLayerStructure *)misc->data;
1166 
1167    context->desc.h265enc.seq.num_temporal_layers = tl->number_of_layers;
1168 
1169    return VA_STATUS_SUCCESS;
1170 }
1171