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 vlVaHandleVAEncPictureParameterBufferTypeH264(vlVaDriver
*drv
, vlVaContext
*context
, vlVaBuffer
*buf
)
35 VAEncPictureParameterBufferH264
*h264
;
36 vlVaBuffer
*coded_buf
;
39 context
->desc
.h264enc
.frame_num
= h264
->frame_num
;
40 context
->desc
.h264enc
.not_referenced
= false;
41 context
->desc
.h264enc
.pic_order_cnt
= h264
->CurrPic
.TopFieldOrderCnt
;
42 if (context
->desc
.h264enc
.gop_cnt
== 0)
43 context
->desc
.h264enc
.i_remain
= context
->gop_coeff
;
44 else if (context
->desc
.h264enc
.frame_num
== 1)
45 context
->desc
.h264enc
.i_remain
--;
47 context
->desc
.h264enc
.p_remain
= context
->desc
.h264enc
.gop_size
- context
->desc
.h264enc
.gop_cnt
- context
->desc
.h264enc
.i_remain
;
49 coded_buf
= handle_table_get(drv
->htab
, h264
->coded_buf
);
50 if (!coded_buf
->derived_surface
.resource
)
51 coded_buf
->derived_surface
.resource
= pipe_buffer_create(drv
->pipe
->screen
, PIPE_BIND_VERTEX_BUFFER
,
52 PIPE_USAGE_STREAM
, coded_buf
->size
);
53 context
->coded_buf
= coded_buf
;
55 _mesa_hash_table_insert(context
->desc
.h264enc
.frame_idx
,
56 UINT_TO_PTR(h264
->CurrPic
.picture_id
),
57 UINT_TO_PTR(h264
->frame_num
));
59 if (h264
->pic_fields
.bits
.idr_pic_flag
== 1)
60 context
->desc
.h264enc
.picture_type
= PIPE_H264_ENC_PICTURE_TYPE_IDR
;
62 context
->desc
.h264enc
.picture_type
= PIPE_H264_ENC_PICTURE_TYPE_P
;
64 context
->desc
.h264enc
.quant_i_frames
= h264
->pic_init_qp
;
65 context
->desc
.h264enc
.quant_b_frames
= h264
->pic_init_qp
;
66 context
->desc
.h264enc
.quant_p_frames
= h264
->pic_init_qp
;
67 context
->desc
.h264enc
.gop_cnt
++;
68 if (context
->desc
.h264enc
.gop_cnt
== context
->desc
.h264enc
.gop_size
)
69 context
->desc
.h264enc
.gop_cnt
= 0;
71 return VA_STATUS_SUCCESS
;
75 vlVaHandleVAEncSliceParameterBufferTypeH264(vlVaDriver
*drv
, vlVaContext
*context
, vlVaBuffer
*buf
)
77 VAEncSliceParameterBufferH264
*h264
;
80 context
->desc
.h264enc
.ref_idx_l0
= VA_INVALID_ID
;
81 context
->desc
.h264enc
.ref_idx_l1
= VA_INVALID_ID
;
83 for (int i
= 0; i
< 32; i
++) {
84 if (h264
->RefPicList0
[i
].picture_id
!= VA_INVALID_ID
) {
85 if (context
->desc
.h264enc
.ref_idx_l0
== VA_INVALID_ID
)
86 context
->desc
.h264enc
.ref_idx_l0
= PTR_TO_UINT(util_hash_table_get(context
->desc
.h264enc
.frame_idx
,
87 UINT_TO_PTR(h264
->RefPicList0
[i
].picture_id
)));
89 if (h264
->RefPicList1
[i
].picture_id
!= VA_INVALID_ID
&& h264
->slice_type
== 1) {
90 if (context
->desc
.h264enc
.ref_idx_l1
== VA_INVALID_ID
)
91 context
->desc
.h264enc
.ref_idx_l1
= PTR_TO_UINT(util_hash_table_get(context
->desc
.h264enc
.frame_idx
,
92 UINT_TO_PTR(h264
->RefPicList1
[i
].picture_id
)));
96 if (h264
->slice_type
== 1)
97 context
->desc
.h264enc
.picture_type
= PIPE_H264_ENC_PICTURE_TYPE_B
;
98 else if (h264
->slice_type
== 0)
99 context
->desc
.h264enc
.picture_type
= PIPE_H264_ENC_PICTURE_TYPE_P
;
100 else if (h264
->slice_type
== 2) {
101 if (context
->desc
.h264enc
.picture_type
== PIPE_H264_ENC_PICTURE_TYPE_IDR
)
102 context
->desc
.h264enc
.idr_pic_id
++;
104 context
->desc
.h264enc
.picture_type
= PIPE_H264_ENC_PICTURE_TYPE_I
;
106 context
->desc
.h264enc
.picture_type
= PIPE_H264_ENC_PICTURE_TYPE_SKIP
;
108 return VA_STATUS_SUCCESS
;
112 vlVaHandleVAEncSequenceParameterBufferTypeH264(vlVaDriver
*drv
, vlVaContext
*context
, vlVaBuffer
*buf
)
114 VAEncSequenceParameterBufferH264
*h264
= (VAEncSequenceParameterBufferH264
*)buf
->data
;
115 if (!context
->decoder
) {
116 context
->templat
.max_references
= h264
->max_num_ref_frames
;
117 context
->templat
.level
= h264
->level_idc
;
118 context
->decoder
= drv
->pipe
->create_video_codec(drv
->pipe
, &context
->templat
);
119 if (!context
->decoder
)
120 return VA_STATUS_ERROR_ALLOCATION_FAILED
;
123 context
->gop_coeff
= ((1024 + h264
->intra_idr_period
- 1) / h264
->intra_idr_period
+ 1) / 2 * 2;
124 if (context
->gop_coeff
> VL_VA_ENC_GOP_COEFF
)
125 context
->gop_coeff
= VL_VA_ENC_GOP_COEFF
;
126 context
->desc
.h264enc
.gop_size
= h264
->intra_idr_period
* context
->gop_coeff
;
127 context
->desc
.h264enc
.rate_ctrl
.frame_rate_num
= h264
->time_scale
/ 2;
128 context
->desc
.h264enc
.rate_ctrl
.frame_rate_den
= h264
->num_units_in_tick
;
129 context
->desc
.h264enc
.pic_order_cnt_type
= h264
->seq_fields
.bits
.pic_order_cnt_type
;
131 if (h264
->frame_cropping_flag
) {
132 context
->desc
.h264enc
.pic_ctrl
.enc_frame_cropping_flag
= h264
->frame_cropping_flag
;
133 context
->desc
.h264enc
.pic_ctrl
.enc_frame_crop_left_offset
= h264
->frame_crop_left_offset
;
134 context
->desc
.h264enc
.pic_ctrl
.enc_frame_crop_right_offset
= h264
->frame_crop_right_offset
;
135 context
->desc
.h264enc
.pic_ctrl
.enc_frame_crop_top_offset
= h264
->frame_crop_top_offset
;
136 context
->desc
.h264enc
.pic_ctrl
.enc_frame_crop_bottom_offset
= h264
->frame_crop_bottom_offset
;
138 return VA_STATUS_SUCCESS
;
142 vlVaHandleVAEncMiscParameterTypeRateControlH264(vlVaContext
*context
, VAEncMiscParameterBuffer
*misc
)
144 VAEncMiscParameterRateControl
*rc
= (VAEncMiscParameterRateControl
*)misc
->data
;
145 if (context
->desc
.h264enc
.rate_ctrl
.rate_ctrl_method
==
146 PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT
)
147 context
->desc
.h264enc
.rate_ctrl
.target_bitrate
= rc
->bits_per_second
;
149 context
->desc
.h264enc
.rate_ctrl
.target_bitrate
= rc
->bits_per_second
* (rc
->target_percentage
/ 100.0);
150 context
->desc
.h264enc
.rate_ctrl
.peak_bitrate
= rc
->bits_per_second
;
151 if (context
->desc
.h264enc
.rate_ctrl
.target_bitrate
< 2000000)
152 context
->desc
.h264enc
.rate_ctrl
.vbv_buffer_size
= MIN2((context
->desc
.h264enc
.rate_ctrl
.target_bitrate
* 2.75), 2000000);
154 context
->desc
.h264enc
.rate_ctrl
.vbv_buffer_size
= context
->desc
.h264enc
.rate_ctrl
.target_bitrate
;
156 return VA_STATUS_SUCCESS
;
160 vlVaHandleVAEncMiscParameterTypeFrameRateH264(vlVaContext
*context
, VAEncMiscParameterBuffer
*misc
)
162 VAEncMiscParameterFrameRate
*fr
= (VAEncMiscParameterFrameRate
*)misc
->data
;
163 if (fr
->framerate
& 0xffff0000) {
164 context
->desc
.h264enc
.rate_ctrl
.frame_rate_num
= fr
->framerate
& 0xffff;
165 context
->desc
.h264enc
.rate_ctrl
.frame_rate_den
= fr
->framerate
>> 16 & 0xffff;
167 context
->desc
.h264enc
.rate_ctrl
.frame_rate_num
= fr
->framerate
;
168 context
->desc
.h264enc
.rate_ctrl
.frame_rate_den
= 1;
170 return VA_STATUS_SUCCESS
;
173 void getEncParamPresetH264(vlVaContext
*context
)
175 //motion estimation preset
176 context
->desc
.h264enc
.motion_est
.motion_est_quarter_pixel
= 0x00000001;
177 context
->desc
.h264enc
.motion_est
.lsmvert
= 0x00000002;
178 context
->desc
.h264enc
.motion_est
.enc_disable_sub_mode
= 0x00000078;
179 context
->desc
.h264enc
.motion_est
.enc_en_ime_overw_dis_subm
= 0x00000001;
180 context
->desc
.h264enc
.motion_est
.enc_ime_overw_dis_subm_no
= 0x00000001;
181 context
->desc
.h264enc
.motion_est
.enc_ime2_search_range_x
= 0x00000004;
182 context
->desc
.h264enc
.motion_est
.enc_ime2_search_range_y
= 0x00000004;
185 context
->desc
.h264enc
.pic_ctrl
.enc_cabac_enable
= 0x00000001;
186 context
->desc
.h264enc
.pic_ctrl
.enc_constraint_set_flags
= 0x00000040;
189 context
->desc
.h264enc
.rate_ctrl
.vbv_buffer_size
= 20000000;
190 context
->desc
.h264enc
.rate_ctrl
.vbv_buf_lv
= 48;
191 context
->desc
.h264enc
.rate_ctrl
.fill_data_enable
= 1;
192 context
->desc
.h264enc
.rate_ctrl
.enforce_hrd
= 1;
193 context
->desc
.h264enc
.enable_vui
= false;
194 if (context
->desc
.h264enc
.rate_ctrl
.frame_rate_num
== 0 ||
195 context
->desc
.h264enc
.rate_ctrl
.frame_rate_den
== 0) {
196 context
->desc
.h264enc
.rate_ctrl
.frame_rate_num
= 30;
197 context
->desc
.h264enc
.rate_ctrl
.frame_rate_den
= 1;
199 context
->desc
.h264enc
.rate_ctrl
.target_bits_picture
=
200 context
->desc
.h264enc
.rate_ctrl
.target_bitrate
*
201 ((float)context
->desc
.h264enc
.rate_ctrl
.frame_rate_den
/
202 context
->desc
.h264enc
.rate_ctrl
.frame_rate_num
);
203 context
->desc
.h264enc
.rate_ctrl
.peak_bits_picture_integer
=
204 context
->desc
.h264enc
.rate_ctrl
.peak_bitrate
*
205 ((float)context
->desc
.h264enc
.rate_ctrl
.frame_rate_den
/
206 context
->desc
.h264enc
.rate_ctrl
.frame_rate_num
);
208 context
->desc
.h264enc
.rate_ctrl
.peak_bits_picture_fraction
= 0;
209 context
->desc
.h264enc
.ref_pic_mode
= 0x00000201;