gallium: rename 'state tracker' to 'frontend'
[mesa.git] / src / gallium / frontends / va / picture_hevc_enc.c
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 VAStatus
33 vlVaHandleVAEncPictureParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
34 {
35 VAEncPictureParameterBufferHEVC *h265;
36 vlVaBuffer *coded_buf;
37 int i;
38
39 h265 = buf->data;
40 context->desc.h265enc.decoded_curr_pic = h265->decoded_curr_pic.picture_id;
41
42 for (i = 0; i < 15; i++)
43 context->desc.h265enc.reference_frames[i] = h265->reference_frames[i].picture_id;
44
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);
47
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);
51
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;
56
57 switch(h265->pic_fields.bits.coding_type) {
58 case 1:
59 if (h265->pic_fields.bits.idr_pic_flag)
60 context->desc.h265enc.picture_type = PIPE_H265_ENC_PICTURE_TYPE_IDR;
61 else
62 context->desc.h265enc.picture_type = PIPE_H265_ENC_PICTURE_TYPE_I;
63 break;
64 case 2:
65 context->desc.h265enc.picture_type = PIPE_H265_ENC_PICTURE_TYPE_P;
66 break;
67 case 3:
68 case 4:
69 case 5:
70 return VA_STATUS_ERROR_UNIMPLEMENTED; //no b frame support
71 break;
72 }
73
74 context->desc.h265enc.pic.constrained_intra_pred_flag = h265->pic_fields.bits.constrained_intra_pred_flag;
75
76 _mesa_hash_table_insert(context->desc.h265enc.frame_idx,
77 UINT_TO_PTR(h265->decoded_curr_pic.picture_id),
78 UINT_TO_PTR(context->desc.h265enc.frame_num));
79
80 return VA_STATUS_SUCCESS;
81 }
82
83 VAStatus
84 vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
85 {
86 VAEncSliceParameterBufferHEVC *h265;
87
88 h265 = buf->data;
89 context->desc.h265enc.ref_idx_l0 = VA_INVALID_ID;
90 context->desc.h265enc.ref_idx_l1 = VA_INVALID_ID;
91
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)));
97 }
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)));
102 }
103 }
104
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;
113
114 return VA_STATUS_SUCCESS;
115 }
116
117 VAStatus
118 vlVaHandleVAEncSequenceParameterBufferTypeHEVC(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf)
119 {
120 VAEncSequenceParameterBufferHEVC *h265 = (VAEncSequenceParameterBufferHEVC *)buf->data;
121
122 if (!context->decoder) {
123 context->templat.level = h265->general_level_idc;
124 context->decoder = drv->pipe->create_video_codec(drv->pipe, &context->templat);
125
126 if (!context->decoder)
127 return VA_STATUS_ERROR_ALLOCATION_FAILED;
128 }
129
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;
152
153 return VA_STATUS_SUCCESS;
154 }
155
156 VAStatus
157 vlVaHandleVAEncMiscParameterTypeRateControlHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
158 {
159 VAEncMiscParameterRateControl *rc = (VAEncMiscParameterRateControl *)misc->data;
160
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;
164 else
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);
169 else
170 context->desc.h265enc.rc.vbv_buffer_size = context->desc.h265enc.rc.target_bitrate;
171
172 return VA_STATUS_SUCCESS;
173 }
174
175 VAStatus
176 vlVaHandleVAEncMiscParameterTypeFrameRateHEVC(vlVaContext *context, VAEncMiscParameterBuffer *misc)
177 {
178 VAEncMiscParameterFrameRate *fr = (VAEncMiscParameterFrameRate *)misc->data;
179
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;
183 } else {
184 context->desc.h265enc.rc.frame_rate_num = fr->framerate;
185 context->desc.h265enc.rc.frame_rate_den = 1;
186 }
187
188 return VA_STATUS_SUCCESS;
189 }
190
191 void getEncParamPresetH265(vlVaContext *context)
192 {
193 //rate control
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;
202 }
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);
211
212 context->desc.h265enc.rc.peak_bits_picture_fraction = 0;
213 }