1/************************************************************************** 2 * 3 * Copyright 2017 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 "radeon_vcn_enc.h" 29 30#include "pipe/p_video_codec.h" 31#include "radeon_video.h" 32#include "radeonsi/si_pipe.h" 33#include "util/u_memory.h" 34#include "util/u_video.h" 35#include "vl/vl_video_buffer.h" 36 37#include <stdio.h> 38 39static const unsigned index_to_shifts[4] = {24, 16, 8, 0}; 40 41static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_picture_desc *picture) 42{ 43 if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { 44 struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; 45 enc->enc_pic.picture_type = pic->picture_type; 46 enc->enc_pic.frame_num = pic->frame_num; 47 enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; 48 enc->enc_pic.pic_order_cnt_type = pic->pic_order_cnt_type; 49 enc->enc_pic.ref_idx_l0 = pic->ref_idx_l0_list[0]; 50 enc->enc_pic.ref_idx_l1 = pic->ref_idx_l1_list[0]; 51 enc->enc_pic.not_referenced = pic->not_referenced; 52 enc->enc_pic.is_idr = (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR); 53 if (pic->pic_ctrl.enc_frame_cropping_flag) { 54 enc->enc_pic.crop_left = pic->pic_ctrl.enc_frame_crop_left_offset; 55 enc->enc_pic.crop_right = pic->pic_ctrl.enc_frame_crop_right_offset; 56 enc->enc_pic.crop_top = pic->pic_ctrl.enc_frame_crop_top_offset; 57 enc->enc_pic.crop_bottom = pic->pic_ctrl.enc_frame_crop_bottom_offset; 58 } else { 59 enc->enc_pic.crop_left = 0; 60 enc->enc_pic.crop_right = (align(enc->base.width, 16) - enc->base.width) / 2; 61 enc->enc_pic.crop_top = 0; 62 enc->enc_pic.crop_bottom = (align(enc->base.height, 16) - enc->base.height) / 2; 63 } 64 enc->enc_pic.num_temporal_layers = pic->num_temporal_layers ? pic->num_temporal_layers : 1; 65 enc->enc_pic.temporal_id = 0; 66 for (int i = 0; i < enc->enc_pic.num_temporal_layers; i++) 67 { 68 enc->enc_pic.rc_layer_init[i].target_bit_rate = pic->rate_ctrl[i].target_bitrate; 69 enc->enc_pic.rc_layer_init[i].peak_bit_rate = pic->rate_ctrl[i].peak_bitrate; 70 enc->enc_pic.rc_layer_init[i].frame_rate_num = pic->rate_ctrl[i].frame_rate_num; 71 enc->enc_pic.rc_layer_init[i].frame_rate_den = pic->rate_ctrl[i].frame_rate_den; 72 enc->enc_pic.rc_layer_init[i].vbv_buffer_size = pic->rate_ctrl[i].vbv_buffer_size; 73 enc->enc_pic.rc_layer_init[i].avg_target_bits_per_picture = pic->rate_ctrl[i].target_bits_picture; 74 enc->enc_pic.rc_layer_init[i].peak_bits_per_picture_integer = 75 pic->rate_ctrl[i].peak_bits_picture_integer; 76 enc->enc_pic.rc_layer_init[i].peak_bits_per_picture_fractional = 77 pic->rate_ctrl[i].peak_bits_picture_fraction; 78 } 79 enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rate_ctrl[0].vbv_buf_lv; 80 enc->enc_pic.rc_per_pic.qp = pic->quant_i_frames; 81 enc->enc_pic.rc_per_pic.min_qp_app = 0; 82 enc->enc_pic.rc_per_pic.max_qp_app = 51; 83 enc->enc_pic.rc_per_pic.max_au_size = 0; 84 enc->enc_pic.rc_per_pic.enabled_filler_data = pic->rate_ctrl[0].fill_data_enable; 85 enc->enc_pic.rc_per_pic.skip_frame_enable = false; 86 enc->enc_pic.rc_per_pic.enforce_hrd = pic->rate_ctrl[0].enforce_hrd; 87 88 switch (pic->rate_ctrl[0].rate_ctrl_method) { 89 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE: 90 enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; 91 break; 92 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP: 93 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT: 94 enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_CBR; 95 break; 96 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP: 97 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE: 98 enc->enc_pic.rc_session_init.rate_control_method = 99 RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR; 100 break; 101 default: 102 enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; 103 } 104 enc->enc_pic.spec_misc.profile_idc = u_get_h264_profile_idc(enc->base.profile); 105 if (enc->enc_pic.spec_misc.profile_idc >= PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN && 106 enc->enc_pic.spec_misc.profile_idc != PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED) 107 enc->enc_pic.spec_misc.cabac_enable = pic->pic_ctrl.enc_cabac_enable; 108 else 109 enc->enc_pic.spec_misc.cabac_enable = false; 110 enc->enc_pic.spec_misc.cabac_init_idc = enc->enc_pic.spec_misc.cabac_enable ? pic->pic_ctrl.enc_cabac_init_idc : 0; 111 112 } else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) { 113 struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; 114 enc->enc_pic.picture_type = pic->picture_type; 115 enc->enc_pic.frame_num = pic->frame_num; 116 enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; 117 enc->enc_pic.pic_order_cnt_type = pic->pic_order_cnt_type; 118 enc->enc_pic.ref_idx_l0 = pic->ref_idx_l0; 119 enc->enc_pic.ref_idx_l1 = pic->ref_idx_l1; 120 enc->enc_pic.not_referenced = pic->not_referenced; 121 enc->enc_pic.is_idr = (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR) || 122 (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_I); 123 124 if (pic->seq.conformance_window_flag) { 125 enc->enc_pic.crop_left = pic->seq.conf_win_left_offset; 126 enc->enc_pic.crop_right = pic->seq.conf_win_right_offset; 127 enc->enc_pic.crop_top = pic->seq.conf_win_top_offset; 128 enc->enc_pic.crop_bottom = pic->seq.conf_win_bottom_offset; 129 } else { 130 enc->enc_pic.crop_left = 0; 131 enc->enc_pic.crop_right = (align(enc->base.width, 16) - enc->base.width) / 2; 132 enc->enc_pic.crop_top = 0; 133 enc->enc_pic.crop_bottom = (align(enc->base.height, 16) - enc->base.height) / 2; 134 } 135 136 enc->enc_pic.general_tier_flag = pic->seq.general_tier_flag; 137 enc->enc_pic.general_profile_idc = pic->seq.general_profile_idc; 138 enc->enc_pic.general_level_idc = pic->seq.general_level_idc; 139 enc->enc_pic.max_poc = MAX2(16, util_next_power_of_two(pic->seq.intra_period)); 140 enc->enc_pic.log2_max_poc = 0; 141 enc->enc_pic.num_temporal_layers = 1; 142 for (int i = enc->enc_pic.max_poc; i != 0; enc->enc_pic.log2_max_poc++) 143 i = (i >> 1); 144 enc->enc_pic.chroma_format_idc = pic->seq.chroma_format_idc; 145 enc->enc_pic.pic_width_in_luma_samples = pic->seq.pic_width_in_luma_samples; 146 enc->enc_pic.pic_height_in_luma_samples = pic->seq.pic_height_in_luma_samples; 147 enc->enc_pic.log2_diff_max_min_luma_coding_block_size = 148 pic->seq.log2_diff_max_min_luma_coding_block_size; 149 enc->enc_pic.log2_min_transform_block_size_minus2 = 150 pic->seq.log2_min_transform_block_size_minus2; 151 enc->enc_pic.log2_diff_max_min_transform_block_size = 152 pic->seq.log2_diff_max_min_transform_block_size; 153 154 /* To fix incorrect hardcoded values set by player 155 * log2_diff_max_min_luma_coding_block_size = log2(64) - (log2_min_luma_coding_block_size_minus3 + 3) 156 * max_transform_hierarchy_depth_inter = log2_diff_max_min_luma_coding_block_size + 1 157 * max_transform_hierarchy_depth_intra = log2_diff_max_min_luma_coding_block_size + 1 158 */ 159 enc->enc_pic.max_transform_hierarchy_depth_inter = 160 6 - (pic->seq.log2_min_luma_coding_block_size_minus3 + 3) + 1; 161 enc->enc_pic.max_transform_hierarchy_depth_intra = 162 enc->enc_pic.max_transform_hierarchy_depth_inter; 163 164 enc->enc_pic.log2_parallel_merge_level_minus2 = pic->pic.log2_parallel_merge_level_minus2; 165 enc->enc_pic.bit_depth_luma_minus8 = pic->seq.bit_depth_luma_minus8; 166 enc->enc_pic.bit_depth_chroma_minus8 = pic->seq.bit_depth_chroma_minus8; 167 enc->enc_pic.nal_unit_type = pic->pic.nal_unit_type; 168 enc->enc_pic.max_num_merge_cand = pic->slice.max_num_merge_cand; 169 enc->enc_pic.sample_adaptive_offset_enabled_flag = 170 pic->seq.sample_adaptive_offset_enabled_flag; 171 enc->enc_pic.pcm_enabled_flag = pic->seq.pcm_enabled_flag; 172 enc->enc_pic.sps_temporal_mvp_enabled_flag = pic->seq.sps_temporal_mvp_enabled_flag; 173 enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled = 174 pic->slice.slice_loop_filter_across_slices_enabled_flag; 175 enc->enc_pic.hevc_deblock.deblocking_filter_disabled = 176 pic->slice.slice_deblocking_filter_disabled_flag; 177 enc->enc_pic.hevc_deblock.beta_offset_div2 = pic->slice.slice_beta_offset_div2; 178 enc->enc_pic.hevc_deblock.tc_offset_div2 = pic->slice.slice_tc_offset_div2; 179 enc->enc_pic.hevc_deblock.cb_qp_offset = pic->slice.slice_cb_qp_offset; 180 enc->enc_pic.hevc_deblock.cr_qp_offset = pic->slice.slice_cr_qp_offset; 181 enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 = 182 pic->seq.log2_min_luma_coding_block_size_minus3; 183 enc->enc_pic.hevc_spec_misc.amp_disabled = !pic->seq.amp_enabled_flag; 184 enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled = 185 pic->seq.strong_intra_smoothing_enabled_flag; 186 enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag = 187 pic->pic.constrained_intra_pred_flag; 188 enc->enc_pic.hevc_spec_misc.cabac_init_flag = pic->slice.cabac_init_flag; 189 enc->enc_pic.hevc_spec_misc.half_pel_enabled = 1; 190 enc->enc_pic.hevc_spec_misc.quarter_pel_enabled = 1; 191 enc->enc_pic.rc_layer_init[0].target_bit_rate = pic->rc.target_bitrate; 192 enc->enc_pic.rc_layer_init[0].peak_bit_rate = pic->rc.peak_bitrate; 193 enc->enc_pic.rc_layer_init[0].frame_rate_num = pic->rc.frame_rate_num; 194 enc->enc_pic.rc_layer_init[0].frame_rate_den = pic->rc.frame_rate_den; 195 enc->enc_pic.rc_layer_init[0].vbv_buffer_size = pic->rc.vbv_buffer_size; 196 enc->enc_pic.rc_layer_init[0].avg_target_bits_per_picture = pic->rc.target_bits_picture; 197 enc->enc_pic.rc_layer_init[0].peak_bits_per_picture_integer = pic->rc.peak_bits_picture_integer; 198 enc->enc_pic.rc_layer_init[0].peak_bits_per_picture_fractional = 199 pic->rc.peak_bits_picture_fraction; 200 enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc.vbv_buf_lv; 201 enc->enc_pic.rc_per_pic.qp = pic->rc.quant_i_frames; 202 enc->enc_pic.rc_per_pic.min_qp_app = 0; 203 enc->enc_pic.rc_per_pic.max_qp_app = 51; 204 enc->enc_pic.rc_per_pic.max_au_size = 0; 205 enc->enc_pic.rc_per_pic.enabled_filler_data = pic->rc.fill_data_enable; 206 enc->enc_pic.rc_per_pic.skip_frame_enable = false; 207 enc->enc_pic.rc_per_pic.enforce_hrd = pic->rc.enforce_hrd; 208 switch (pic->rc.rate_ctrl_method) { 209 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE: 210 enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; 211 break; 212 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP: 213 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT: 214 enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_CBR; 215 break; 216 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP: 217 case PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE: 218 enc->enc_pic.rc_session_init.rate_control_method = 219 RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR; 220 break; 221 default: 222 enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE; 223 } 224 } 225} 226 227static void flush(struct radeon_encoder *enc) 228{ 229 enc->ws->cs_flush(&enc->cs, PIPE_FLUSH_ASYNC, NULL); 230} 231 232static void radeon_enc_flush(struct pipe_video_codec *encoder) 233{ 234 struct radeon_encoder *enc = (struct radeon_encoder *)encoder; 235 flush(enc); 236} 237 238static void radeon_enc_cs_flush(void *ctx, unsigned flags, struct pipe_fence_handle **fence) 239{ 240 // just ignored 241} 242 243static unsigned get_cpb_num(struct radeon_encoder *enc) 244{ 245 unsigned w = align(enc->base.width, 16) / 16; 246 unsigned h = align(enc->base.height, 16) / 16; 247 unsigned dpb; 248 249 switch (enc->base.level) { 250 case 10: 251 dpb = 396; 252 break; 253 case 11: 254 dpb = 900; 255 break; 256 case 12: 257 case 13: 258 case 20: 259 dpb = 2376; 260 break; 261 case 21: 262 dpb = 4752; 263 break; 264 case 22: 265 case 30: 266 dpb = 8100; 267 break; 268 case 31: 269 dpb = 18000; 270 break; 271 case 32: 272 dpb = 20480; 273 break; 274 case 40: 275 case 41: 276 dpb = 32768; 277 break; 278 case 42: 279 dpb = 34816; 280 break; 281 case 50: 282 dpb = 110400; 283 break; 284 default: 285 case 51: 286 case 52: 287 dpb = 184320; 288 break; 289 } 290 291 return MIN2(dpb / (w * h), 16); 292} 293 294static void radeon_enc_begin_frame(struct pipe_video_codec *encoder, 295 struct pipe_video_buffer *source, 296 struct pipe_picture_desc *picture) 297{ 298 struct radeon_encoder *enc = (struct radeon_encoder *)encoder; 299 struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source; 300 bool need_rate_control = false; 301 302 if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) { 303 struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture; 304 need_rate_control = 305 (enc->enc_pic.rc_layer_init[0].target_bit_rate != pic->rate_ctrl[0].target_bitrate) || 306 (enc->enc_pic.rc_layer_init[0].frame_rate_num != pic->rate_ctrl[0].frame_rate_num) || 307 (enc->enc_pic.rc_layer_init[0].frame_rate_den != pic->rate_ctrl[0].frame_rate_den); 308 } else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) { 309 struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture; 310 need_rate_control = enc->enc_pic.rc_layer_init[0].target_bit_rate != pic->rc.target_bitrate; 311 } 312 313 radeon_vcn_enc_get_param(enc, picture); 314 315 enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma); 316 enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma); 317 318 enc->need_feedback = false; 319 320 if (!enc->stream_handle) { 321 struct rvid_buffer fb; 322 enc->stream_handle = si_vid_alloc_stream_handle(); 323 enc->si = CALLOC_STRUCT(rvid_buffer); 324 si_vid_create_buffer(enc->screen, enc->si, 128 * 1024, PIPE_USAGE_STAGING); 325 si_vid_create_buffer(enc->screen, &fb, 4096, PIPE_USAGE_STAGING); 326 enc->fb = &fb; 327 enc->begin(enc); 328 flush(enc); 329 si_vid_destroy_buffer(&fb); 330 } 331 if (need_rate_control) { 332 enc->begin(enc); 333 flush(enc); 334 } 335} 336 337static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder, 338 struct pipe_video_buffer *source, 339 struct pipe_resource *destination, void **fb) 340{ 341 struct radeon_encoder *enc = (struct radeon_encoder *)encoder; 342 enc->get_buffer(destination, &enc->bs_handle, NULL); 343 enc->bs_size = destination->width0; 344 345 *fb = enc->fb = CALLOC_STRUCT(rvid_buffer); 346 347 if (!si_vid_create_buffer(enc->screen, enc->fb, 4096, PIPE_USAGE_STAGING)) { 348 RVID_ERR("Can't create feedback buffer.\n"); 349 return; 350 } 351 352 enc->need_feedback = true; 353 enc->encode(enc); 354} 355 356static void radeon_enc_end_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source, 357 struct pipe_picture_desc *picture) 358{ 359 struct radeon_encoder *enc = (struct radeon_encoder *)encoder; 360 flush(enc); 361} 362 363static void radeon_enc_destroy(struct pipe_video_codec *encoder) 364{ 365 struct radeon_encoder *enc = (struct radeon_encoder *)encoder; 366 367 if (enc->stream_handle) { 368 struct rvid_buffer fb; 369 enc->need_feedback = false; 370 si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING); 371 enc->fb = &fb; 372 enc->destroy(enc); 373 flush(enc); 374 if (enc->si) { 375 si_vid_destroy_buffer(enc->si); 376 FREE(enc->si); 377 enc->si = NULL; 378 } 379 si_vid_destroy_buffer(&fb); 380 } 381 382 si_vid_destroy_buffer(&enc->cpb); 383 enc->ws->cs_destroy(&enc->cs); 384 FREE(enc); 385} 386 387static void radeon_enc_get_feedback(struct pipe_video_codec *encoder, void *feedback, 388 unsigned *size) 389{ 390 struct radeon_encoder *enc = (struct radeon_encoder *)encoder; 391 struct rvid_buffer *fb = feedback; 392 393 if (size) { 394 uint32_t *ptr = enc->ws->buffer_map(enc->ws, fb->res->buf, &enc->cs, 395 PIPE_MAP_READ_WRITE | RADEON_MAP_TEMPORARY); 396 if (ptr[1]) 397 *size = ptr[6]; 398 else 399 *size = 0; 400 enc->ws->buffer_unmap(enc->ws, fb->res->buf); 401 } 402 403 si_vid_destroy_buffer(fb); 404 FREE(fb); 405} 406 407static int setup_dpb(struct radeon_encoder *enc, enum pipe_format buffer_format, 408 enum amd_gfx_level gfx_level) 409{ 410 uint32_t aligned_width = align(enc->base.width, 16); 411 uint32_t aligned_height = align(enc->base.height, 16); 412 uint32_t rec_luma_pitch = align(aligned_width, enc->alignment); 413 414 int luma_size = rec_luma_pitch * align(aligned_height, enc->alignment); 415 if (buffer_format == PIPE_FORMAT_P010) 416 luma_size *= 2; 417 int chroma_size = align(luma_size / 2, enc->alignment); 418 int offset = 0; 419 420 uint32_t num_reconstructed_pictures = enc->base.max_references + 1; 421 assert(num_reconstructed_pictures <= RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES); 422 423 int i; 424 for (i = 0; i < num_reconstructed_pictures; i++) { 425 if (gfx_level >= GFX11) { 426 enc->enc_pic.ctx_buf.reconstructed_pictures_v4_0[i].luma_offset = offset; 427 offset += luma_size; 428 enc->enc_pic.ctx_buf.reconstructed_pictures_v4_0[i].chroma_offset = offset; 429 offset += chroma_size; 430 } else { 431 enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset = offset; 432 offset += luma_size; 433 enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset = offset; 434 offset += chroma_size; 435 } 436 } 437 for (; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { 438 enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset = 0; 439 enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset = 0; 440 } 441 442 enc->enc_pic.ctx_buf.num_reconstructed_pictures = num_reconstructed_pictures; 443 enc->dpb_size = offset; 444 445 return offset; 446} 447 448struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context, 449 const struct pipe_video_codec *templ, 450 struct radeon_winsys *ws, 451 radeon_enc_get_buffer get_buffer) 452{ 453 struct si_screen *sscreen = (struct si_screen *)context->screen; 454 struct si_context *sctx = (struct si_context *)context; 455 struct radeon_encoder *enc; 456 struct pipe_video_buffer *tmp_buf, templat = {}; 457 struct radeon_surf *tmp_surf; 458 unsigned cpb_size; 459 460 enc = CALLOC_STRUCT(radeon_encoder); 461 462 if (!enc) 463 return NULL; 464 465 enc->alignment = 256; 466 enc->base = *templ; 467 enc->base.context = context; 468 enc->base.destroy = radeon_enc_destroy; 469 enc->base.begin_frame = radeon_enc_begin_frame; 470 enc->base.encode_bitstream = radeon_enc_encode_bitstream; 471 enc->base.end_frame = radeon_enc_end_frame; 472 enc->base.flush = radeon_enc_flush; 473 enc->base.get_feedback = radeon_enc_get_feedback; 474 enc->get_buffer = get_buffer; 475 enc->bits_in_shifter = 0; 476 enc->screen = context->screen; 477 enc->ws = ws; 478 479 if (!ws->cs_create(&enc->cs, sctx->ctx, AMD_IP_VCN_ENC, radeon_enc_cs_flush, enc, false)) { 480 RVID_ERR("Can't get command submission context.\n"); 481 goto error; 482 } 483 484 templat.buffer_format = PIPE_FORMAT_NV12; 485 if (enc->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) 486 templat.buffer_format = PIPE_FORMAT_P010; 487 templat.width = enc->base.width; 488 templat.height = enc->base.height; 489 templat.interlaced = false; 490 491 if (!(tmp_buf = context->create_video_buffer(context, &templat))) { 492 RVID_ERR("Can't create video buffer.\n"); 493 goto error; 494 } 495 496 enc->cpb_num = get_cpb_num(enc); 497 498 if (!enc->cpb_num) 499 goto error; 500 501 get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf); 502 503 cpb_size = (sscreen->info.gfx_level < GFX9) 504 ? align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) * 505 align(tmp_surf->u.legacy.level[0].nblk_y, 32) 506 : align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) * 507 align(tmp_surf->u.gfx9.surf_height, 32); 508 509 cpb_size = cpb_size * 3 / 2; 510 cpb_size = cpb_size * enc->cpb_num; 511 tmp_buf->destroy(tmp_buf); 512 513 cpb_size += setup_dpb(enc, templat.buffer_format, sscreen->info.gfx_level); 514 515 if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) { 516 RVID_ERR("Can't create CPB buffer.\n"); 517 goto error; 518 } 519 520 if (sscreen->info.gfx_level >= GFX11) 521 radeon_enc_4_0_init(enc); 522 else if (sscreen->info.family >= CHIP_NAVI21) 523 radeon_enc_3_0_init(enc); 524 else if (sscreen->info.family >= CHIP_RENOIR) 525 radeon_enc_2_0_init(enc); 526 else 527 radeon_enc_1_2_init(enc); 528 529 return &enc->base; 530 531error: 532 enc->ws->cs_destroy(&enc->cs); 533 534 si_vid_destroy_buffer(&enc->cpb); 535 536 FREE(enc); 537 return NULL; 538} 539 540void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer *buf, 541 unsigned usage, enum radeon_bo_domain domain, signed offset) 542{ 543 enc->ws->cs_add_buffer(&enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain); 544 uint64_t addr; 545 addr = enc->ws->buffer_get_virtual_address(buf); 546 addr = addr + offset; 547 RADEON_ENC_CS(addr >> 32); 548 RADEON_ENC_CS(addr); 549} 550 551void radeon_enc_set_emulation_prevention(struct radeon_encoder *enc, bool set) 552{ 553 if (set != enc->emulation_prevention) { 554 enc->emulation_prevention = set; 555 enc->num_zeros = 0; 556 } 557} 558 559void radeon_enc_output_one_byte(struct radeon_encoder *enc, unsigned char byte) 560{ 561 if (enc->byte_index == 0) 562 enc->cs.current.buf[enc->cs.current.cdw] = 0; 563 enc->cs.current.buf[enc->cs.current.cdw] |= 564 ((unsigned int)(byte) << index_to_shifts[enc->byte_index]); 565 enc->byte_index++; 566 567 if (enc->byte_index >= 4) { 568 enc->byte_index = 0; 569 enc->cs.current.cdw++; 570 } 571} 572 573void radeon_enc_emulation_prevention(struct radeon_encoder *enc, unsigned char byte) 574{ 575 if (enc->emulation_prevention) { 576 if ((enc->num_zeros >= 2) && ((byte == 0x00) || (byte == 0x01) || 577 (byte == 0x02) || (byte == 0x03))) { 578 radeon_enc_output_one_byte(enc, 0x03); 579 enc->bits_output += 8; 580 enc->num_zeros = 0; 581 } 582 enc->num_zeros = (byte == 0 ? (enc->num_zeros + 1) : 0); 583 } 584} 585 586void radeon_enc_code_fixed_bits(struct radeon_encoder *enc, unsigned int value, 587 unsigned int num_bits) 588{ 589 unsigned int bits_to_pack = 0; 590 enc->bits_size += num_bits; 591 592 while (num_bits > 0) { 593 unsigned int value_to_pack = value & (0xffffffff >> (32 - num_bits)); 594 bits_to_pack = 595 num_bits > (32 - enc->bits_in_shifter) ? (32 - enc->bits_in_shifter) : num_bits; 596 597 if (bits_to_pack < num_bits) 598 value_to_pack = value_to_pack >> (num_bits - bits_to_pack); 599 600 enc->shifter |= value_to_pack << (32 - enc->bits_in_shifter - bits_to_pack); 601 num_bits -= bits_to_pack; 602 enc->bits_in_shifter += bits_to_pack; 603 604 while (enc->bits_in_shifter >= 8) { 605 unsigned char output_byte = (unsigned char)(enc->shifter >> 24); 606 enc->shifter <<= 8; 607 radeon_enc_emulation_prevention(enc, output_byte); 608 radeon_enc_output_one_byte(enc, output_byte); 609 enc->bits_in_shifter -= 8; 610 enc->bits_output += 8; 611 } 612 } 613} 614 615void radeon_enc_reset(struct radeon_encoder *enc) 616{ 617 enc->emulation_prevention = false; 618 enc->shifter = 0; 619 enc->bits_in_shifter = 0; 620 enc->bits_output = 0; 621 enc->num_zeros = 0; 622 enc->byte_index = 0; 623 enc->bits_size = 0; 624} 625 626void radeon_enc_byte_align(struct radeon_encoder *enc) 627{ 628 unsigned int num_padding_zeros = (32 - enc->bits_in_shifter) % 8; 629 630 if (num_padding_zeros > 0) 631 radeon_enc_code_fixed_bits(enc, 0, num_padding_zeros); 632} 633 634void radeon_enc_flush_headers(struct radeon_encoder *enc) 635{ 636 if (enc->bits_in_shifter != 0) { 637 unsigned char output_byte = (unsigned char)(enc->shifter >> 24); 638 radeon_enc_emulation_prevention(enc, output_byte); 639 radeon_enc_output_one_byte(enc, output_byte); 640 enc->bits_output += enc->bits_in_shifter; 641 enc->shifter = 0; 642 enc->bits_in_shifter = 0; 643 enc->num_zeros = 0; 644 } 645 646 if (enc->byte_index > 0) { 647 enc->cs.current.cdw++; 648 enc->byte_index = 0; 649 } 650} 651 652void radeon_enc_code_ue(struct radeon_encoder *enc, unsigned int value) 653{ 654 int x = -1; 655 unsigned int ue_code = value + 1; 656 value += 1; 657 658 while (value) { 659 value = (value >> 1); 660 x += 1; 661 } 662 663 unsigned int ue_length = (x << 1) + 1; 664 radeon_enc_code_fixed_bits(enc, ue_code, ue_length); 665} 666 667void radeon_enc_code_se(struct radeon_encoder *enc, int value) 668{ 669 unsigned int v = 0; 670 671 if (value != 0) 672 v = (value < 0 ? ((unsigned int)(0 - value) << 1) : (((unsigned int)(value) << 1) - 1)); 673 674 radeon_enc_code_ue(enc, v); 675} 676