1 /**************************************************************************
3 * Copyright 2018 Advanced Micro Devices, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #include "util/u_handle_table.h"
29 #include "util/u_video.h"
30 #include "va_private.h"
33 vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver
*drv
, vlVaContext
*context
, vlVaBuffer
*buf
)
35 VAEncPictureParameterBufferHEVC
*h265
;
36 vlVaBuffer
*coded_buf
;
40 context
->desc
.h265enc
.decoded_curr_pic
= h265
->decoded_curr_pic
.picture_id
;
42 for (i
= 0; i
< 15; i
++)
43 context
->desc
.h265enc
.reference_frames
[i
] = h265
->reference_frames
[i
].picture_id
;
45 context
->desc
.h265enc
.pic_order_cnt
= h265
->decoded_curr_pic
.pic_order_cnt
;
46 coded_buf
= handle_table_get(drv
->htab
, h265
->coded_buf
);
48 if (!coded_buf
->derived_surface
.resource
)
49 coded_buf
->derived_surface
.resource
= pipe_buffer_create(drv
->pipe
->screen
, PIPE_BIND_VERTEX_BUFFER
,
50 PIPE_USAGE_STREAM
, coded_buf
->size
);
52 context
->coded_buf
= coded_buf
;
53 context
->desc
.h265enc
.pic
.log2_parallel_merge_level_minus2
= h265
->log2_parallel_merge_level_minus2
;
54 context
->desc
.h265enc
.pic
.nal_unit_type
= h265
->nal_unit_type
;
55 context
->desc
.h265enc
.rc
.quant_i_frames
= h265
->pic_init_qp
;
57 switch(h265
->pic_fields
.bits
.coding_type
) {
59 if (h265
->pic_fields
.bits
.idr_pic_flag
)
60 context
->desc
.h265enc
.picture_type
= PIPE_H265_ENC_PICTURE_TYPE_IDR
;
62 context
->desc
.h265enc
.picture_type
= PIPE_H265_ENC_PICTURE_TYPE_I
;
65 context
->desc
.h265enc
.picture_type
= PIPE_H265_ENC_PICTURE_TYPE_P
;
70 return VA_STATUS_ERROR_UNIMPLEMENTED
; //no b frame support
74 context
->desc
.h265enc
.pic
.constrained_intra_pred_flag
= h265
->pic_fields
.bits
.constrained_intra_pred_flag
;
76 util_hash_table_set(context
->desc
.h265enc
.frame_idx
,
77 UINT_TO_PTR(h265
->decoded_curr_pic
.picture_id
),
78 UINT_TO_PTR(context
->desc
.h265enc
.frame_num
));
80 return VA_STATUS_SUCCESS
;
84 vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver
*drv
, vlVaContext
*context
, vlVaBuffer
*buf
)
86 VAEncSliceParameterBufferHEVC
*h265
;
89 context
->desc
.h265enc
.ref_idx_l0
= VA_INVALID_ID
;
90 context
->desc
.h265enc
.ref_idx_l1
= VA_INVALID_ID
;
92 for (int i
= 0; i
< 15; i
++) {
93 if (h265
->ref_pic_list0
[i
].picture_id
!= VA_INVALID_ID
) {
94 if (context
->desc
.h265enc
.ref_idx_l0
== VA_INVALID_ID
)
95 context
->desc
.h265enc
.ref_idx_l0
= PTR_TO_UINT(util_hash_table_get(context
->desc
.h265enc
.frame_idx
,
96 UINT_TO_PTR(h265
->ref_pic_list0
[i
].picture_id
)));
98 if (h265
->ref_pic_list1
[i
].picture_id
!= VA_INVALID_ID
&& h265
->slice_type
== 1) {
99 if (context
->desc
.h265enc
.ref_idx_l1
== VA_INVALID_ID
)
100 context
->desc
.h265enc
.ref_idx_l1
= PTR_TO_UINT(util_hash_table_get(context
->desc
.h265enc
.frame_idx
,
101 UINT_TO_PTR(h265
->ref_pic_list1
[i
].picture_id
)));
105 context
->desc
.h265enc
.slice
.max_num_merge_cand
= h265
->max_num_merge_cand
;
106 context
->desc
.h265enc
.slice
.slice_cb_qp_offset
= h265
->slice_cb_qp_offset
;
107 context
->desc
.h265enc
.slice
.slice_cr_qp_offset
= h265
->slice_cr_qp_offset
;
108 context
->desc
.h265enc
.slice
.slice_beta_offset_div2
= h265
->slice_beta_offset_div2
;
109 context
->desc
.h265enc
.slice
.slice_tc_offset_div2
= h265
->slice_tc_offset_div2
;
110 context
->desc
.h265enc
.slice
.cabac_init_flag
= h265
->slice_fields
.bits
.cabac_init_flag
;
111 context
->desc
.h265enc
.slice
.slice_deblocking_filter_disabled_flag
= h265
->slice_fields
.bits
.slice_deblocking_filter_disabled_flag
;
112 context
->desc
.h265enc
.slice
.slice_loop_filter_across_slices_enabled_flag
= h265
->slice_fields
.bits
.slice_loop_filter_across_slices_enabled_flag
;
114 return VA_STATUS_SUCCESS
;
118 vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver
*drv
, vlVaContext
*context
, vlVaBuffer
*buf
)
120 VAEncSequenceParameterBufferHEVC
*h265
= (VAEncSequenceParameterBufferHEVC
*)buf
->data
;
122 if (!context
->decoder
) {
123 context
->templat
.level
= h265
->general_level_idc
;
124 context
->decoder
= drv
->pipe
->create_video_codec(drv
->pipe
, &context
->templat
);
126 if (!context
->decoder
)
127 return VA_STATUS_ERROR_ALLOCATION_FAILED
;
130 context
->desc
.h265enc
.seq
.general_profile_idc
= h265
->general_profile_idc
;
131 context
->desc
.h265enc
.seq
.general_level_idc
= h265
->general_level_idc
;
132 context
->desc
.h265enc
.seq
.general_tier_flag
= h265
->general_tier_flag
;
133 context
->desc
.h265enc
.seq
.intra_period
= h265
->intra_period
;
134 context
->desc
.h265enc
.seq
.pic_width_in_luma_samples
= h265
->pic_width_in_luma_samples
;
135 context
->desc
.h265enc
.seq
.pic_height_in_luma_samples
= h265
->pic_height_in_luma_samples
;
136 context
->desc
.h265enc
.seq
.chroma_format_idc
= h265
->seq_fields
.bits
.chroma_format_idc
;
137 context
->desc
.h265enc
.seq
.bit_depth_luma_minus8
= h265
->seq_fields
.bits
.bit_depth_luma_minus8
;
138 context
->desc
.h265enc
.seq
.bit_depth_chroma_minus8
= h265
->seq_fields
.bits
.bit_depth_chroma_minus8
;
139 context
->desc
.h265enc
.seq
.strong_intra_smoothing_enabled_flag
= h265
->seq_fields
.bits
.strong_intra_smoothing_enabled_flag
;
140 context
->desc
.h265enc
.seq
.amp_enabled_flag
= h265
->seq_fields
.bits
.amp_enabled_flag
;
141 context
->desc
.h265enc
.seq
.sample_adaptive_offset_enabled_flag
= h265
->seq_fields
.bits
.sample_adaptive_offset_enabled_flag
;
142 context
->desc
.h265enc
.seq
.pcm_enabled_flag
= h265
->seq_fields
.bits
.pcm_enabled_flag
;
143 context
->desc
.h265enc
.seq
.sps_temporal_mvp_enabled_flag
= h265
->seq_fields
.bits
.sps_temporal_mvp_enabled_flag
;
144 context
->desc
.h265enc
.seq
.log2_min_luma_coding_block_size_minus3
= h265
->log2_min_luma_coding_block_size_minus3
;
145 context
->desc
.h265enc
.seq
.log2_diff_max_min_luma_coding_block_size
= h265
->log2_diff_max_min_luma_coding_block_size
;
146 context
->desc
.h265enc
.seq
.log2_min_transform_block_size_minus2
= h265
->log2_min_transform_block_size_minus2
;
147 context
->desc
.h265enc
.seq
.log2_diff_max_min_transform_block_size
= h265
->log2_diff_max_min_transform_block_size
;
148 context
->desc
.h265enc
.seq
.max_transform_hierarchy_depth_inter
= h265
->max_transform_hierarchy_depth_inter
;
149 context
->desc
.h265enc
.seq
.max_transform_hierarchy_depth_intra
= h265
->max_transform_hierarchy_depth_intra
;
150 context
->desc
.h265enc
.rc
.frame_rate_num
= h265
->vui_time_scale
;
151 context
->desc
.h265enc
.rc
.frame_rate_den
= h265
->vui_num_units_in_tick
;
153 return VA_STATUS_SUCCESS
;
157 vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext
*context
, VAEncMiscParameterBuffer
*misc
)
159 VAEncMiscParameterRateControl
*rc
= (VAEncMiscParameterRateControl
*)misc
->data
;
161 if (context
->desc
.h265enc
.rc
.rate_ctrl_method
==
162 PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT
)
163 context
->desc
.h265enc
.rc
.target_bitrate
= rc
->bits_per_second
;
165 context
->desc
.h265enc
.rc
.target_bitrate
= rc
->bits_per_second
* (rc
->target_percentage
/ 100.0);
166 context
->desc
.h265enc
.rc
.peak_bitrate
= rc
->bits_per_second
;
167 if (context
->desc
.h265enc
.rc
.target_bitrate
< 2000000)
168 context
->desc
.h265enc
.rc
.vbv_buffer_size
= MIN2((context
->desc
.h265enc
.rc
.target_bitrate
* 2.75), 2000000);
170 context
->desc
.h265enc
.rc
.vbv_buffer_size
= context
->desc
.h265enc
.rc
.target_bitrate
;
172 return VA_STATUS_SUCCESS
;
176 vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext
*context
, VAEncMiscParameterBuffer
*misc
)
178 VAEncMiscParameterFrameRate
*fr
= (VAEncMiscParameterFrameRate
*)misc
->data
;
180 if (fr
->framerate
& 0xffff0000) {
181 context
->desc
.h265enc
.rc
.frame_rate_num
= fr
->framerate
& 0xffff;
182 context
->desc
.h265enc
.rc
.frame_rate_den
= fr
->framerate
>> 16 & 0xffff;
184 context
->desc
.h265enc
.rc
.frame_rate_num
= fr
->framerate
;
185 context
->desc
.h265enc
.rc
.frame_rate_den
= 1;
188 return VA_STATUS_SUCCESS
;
191 void getEncParamPresetH265(vlVaContext
*context
)
194 context
->desc
.h265enc
.rc
.vbv_buffer_size
= 20000000;
195 context
->desc
.h265enc
.rc
.vbv_buf_lv
= 48;
196 context
->desc
.h265enc
.rc
.fill_data_enable
= 1;
197 context
->desc
.h265enc
.rc
.enforce_hrd
= 1;
198 if (context
->desc
.h265enc
.rc
.frame_rate_num
== 0 ||
199 context
->desc
.h265enc
.rc
.frame_rate_den
== 0) {
200 context
->desc
.h265enc
.rc
.frame_rate_num
= 30;
201 context
->desc
.h265enc
.rc
.frame_rate_den
= 1;
203 context
->desc
.h265enc
.rc
.target_bits_picture
=
204 context
->desc
.h265enc
.rc
.target_bitrate
*
205 ((float)context
->desc
.h265enc
.rc
.frame_rate_den
/
206 context
->desc
.h265enc
.rc
.frame_rate_num
);
207 context
->desc
.h265enc
.rc
.peak_bits_picture_integer
=
208 context
->desc
.h265enc
.rc
.peak_bitrate
*
209 ((float)context
->desc
.h265enc
.rc
.frame_rate_den
/
210 context
->desc
.h265enc
.rc
.frame_rate_num
);
212 context
->desc
.h265enc
.rc
.peak_bits_picture_fraction
= 0;