1 /************************************************************************** 2 * 3 * Copyright 2017 Advanced Micro Devices, Inc. 4 * 5 * SPDX-License-Identifier: MIT 6 * 7 **************************************************************************/ 8 9 #include "pipe/p_video_codec.h" 10 #include "radeon_vcn_enc.h" 11 #include "radeon_video.h" 12 #include "si_pipe.h" 13 #include "util/u_video.h" 14 15 #include <stdio.h> 16 17 #define RENCODE_FW_INTERFACE_MAJOR_VERSION 1 18 #define RENCODE_FW_INTERFACE_MINOR_VERSION 1 19 20 #define RENCODE_IB_PARAM_SESSION_INFO 0x00000001 21 #define RENCODE_IB_PARAM_TASK_INFO 0x00000002 22 #define RENCODE_IB_PARAM_SESSION_INIT 0x00000003 23 #define RENCODE_IB_PARAM_LAYER_CONTROL 0x00000004 24 #define RENCODE_IB_PARAM_LAYER_SELECT 0x00000005 25 #define RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x00000006 26 #define RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x00000007 27 #define RENCODE_IB_PARAM_QUALITY_PARAMS 0x00000009 28 #define RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU 0x0000000a 29 #define RENCODE_IB_PARAM_SLICE_HEADER 0x0000000b 30 #define RENCODE_IB_PARAM_INPUT_FORMAT 0x0000000c 31 #define RENCODE_IB_PARAM_OUTPUT_FORMAT 0x0000000d 32 #define RENCODE_IB_PARAM_ENCODE_PARAMS 0x0000000f 33 #define RENCODE_IB_PARAM_INTRA_REFRESH 0x00000010 34 #define RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x00000011 35 #define RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER 0x00000012 36 #define RENCODE_IB_PARAM_QP_MAP 0x00000014 37 #define RENCODE_IB_PARAM_FEEDBACK_BUFFER 0x00000015 38 #define RENCODE_IB_PARAM_ENCODE_LATENCY 0x00000018 39 #define RENCODE_IB_PARAM_ENCODE_STATISTICS 0x00000019 40 41 #define RENCODE_HEVC_IB_PARAM_SLICE_CONTROL 0x00100001 42 #define RENCODE_HEVC_IB_PARAM_SPEC_MISC 0x00100002 43 #define RENCODE_HEVC_IB_PARAM_LOOP_FILTER 0x00100003 44 45 #define RENCODE_H264_IB_PARAM_SLICE_CONTROL 0x00200001 46 #define RENCODE_H264_IB_PARAM_SPEC_MISC 0x00200002 47 #define RENCODE_H264_IB_PARAM_ENCODE_PARAMS 0x00200003 48 #define RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER 0x00200004 49 radeon_enc_op_preset(struct radeon_encoder * enc)50static void radeon_enc_op_preset(struct radeon_encoder *enc) 51 { 52 uint32_t preset_mode; 53 54 if (enc->enc_pic.quality_modes.preset_mode == RENCODE_PRESET_MODE_SPEED && 55 (!enc->enc_pic.hevc_deblock.disable_sao && 56 (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC))) 57 preset_mode = RENCODE_IB_OP_SET_BALANCE_ENCODING_MODE; 58 else if (enc->enc_pic.quality_modes.preset_mode == RENCODE_PRESET_MODE_QUALITY) 59 preset_mode = RENCODE_IB_OP_SET_QUALITY_ENCODING_MODE; 60 else if (enc->enc_pic.quality_modes.preset_mode == RENCODE_PRESET_MODE_BALANCE) 61 preset_mode = RENCODE_IB_OP_SET_BALANCE_ENCODING_MODE; 62 else 63 preset_mode = RENCODE_IB_OP_SET_SPEED_ENCODING_MODE; 64 65 RADEON_ENC_BEGIN(preset_mode); 66 RADEON_ENC_END(); 67 } 68 radeon_enc_quality_params(struct radeon_encoder * enc)69static void radeon_enc_quality_params(struct radeon_encoder *enc) 70 { 71 RADEON_ENC_BEGIN(enc->cmd.quality_params); 72 RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_mode); 73 RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_sensitivity); 74 RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_min_idr_interval); 75 RADEON_ENC_CS(enc->enc_pic.quality_params.two_pass_search_center_map_mode); 76 RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_strength); 77 RADEON_ENC_END(); 78 } 79 radeon_enc_loop_filter_hevc(struct radeon_encoder * enc)80static void radeon_enc_loop_filter_hevc(struct radeon_encoder *enc) 81 { 82 RADEON_ENC_BEGIN(enc->cmd.deblocking_filter_hevc); 83 RADEON_ENC_CS(enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled); 84 RADEON_ENC_CS(enc->enc_pic.hevc_deblock.deblocking_filter_disabled); 85 RADEON_ENC_CS(enc->enc_pic.hevc_deblock.beta_offset_div2); 86 RADEON_ENC_CS(enc->enc_pic.hevc_deblock.tc_offset_div2); 87 RADEON_ENC_CS(enc->enc_pic.hevc_deblock.cb_qp_offset); 88 RADEON_ENC_CS(enc->enc_pic.hevc_deblock.cr_qp_offset); 89 RADEON_ENC_CS(enc->enc_pic.hevc_deblock.disable_sao); 90 RADEON_ENC_END(); 91 } 92 radeon_enc_input_format(struct radeon_encoder * enc)93static void radeon_enc_input_format(struct radeon_encoder *enc) 94 { 95 RADEON_ENC_BEGIN(enc->cmd.input_format); 96 RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_volume); 97 RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_space); 98 RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_range); 99 RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_chroma_subsampling); 100 RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_chroma_location); 101 RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_bit_depth); 102 RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_packing_format); 103 RADEON_ENC_END(); 104 } 105 radeon_enc_output_format(struct radeon_encoder * enc)106static void radeon_enc_output_format(struct radeon_encoder *enc) 107 { 108 RADEON_ENC_BEGIN(enc->cmd.output_format); 109 RADEON_ENC_CS(enc->enc_pic.enc_output_format.output_color_volume); 110 RADEON_ENC_CS(enc->enc_pic.enc_output_format.output_color_range); 111 RADEON_ENC_CS(enc->enc_pic.enc_output_format.output_chroma_location); 112 RADEON_ENC_CS(enc->enc_pic.enc_output_format.output_color_bit_depth); 113 RADEON_ENC_END(); 114 } 115 radeon_enc_ref_swizzle_mode(struct radeon_encoder * enc)116static uint32_t radeon_enc_ref_swizzle_mode(struct radeon_encoder *enc) 117 { 118 /* return RENCODE_REC_SWIZZLE_MODE_LINEAR; for debugging purpose */ 119 if (enc->enc_pic.bit_depth_luma_minus8 != 0) 120 return RENCODE_REC_SWIZZLE_MODE_8x8_1D_THIN_12_24BPP; 121 else 122 return RENCODE_REC_SWIZZLE_MODE_256B_S; 123 } 124 radeon_enc_ctx(struct radeon_encoder * enc)125static void radeon_enc_ctx(struct radeon_encoder *enc) 126 { 127 enc->enc_pic.ctx_buf.swizzle_mode = radeon_enc_ref_swizzle_mode(enc); 128 enc->enc_pic.ctx_buf.two_pass_search_center_map_offset = 0; 129 130 RADEON_ENC_BEGIN(enc->cmd.ctx); 131 RADEON_ENC_READWRITE(enc->dpb->res->buf, enc->dpb->res->domains, 0); 132 RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode); 133 RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch); 134 RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch); 135 RADEON_ENC_CS(enc->enc_pic.ctx_buf.num_reconstructed_pictures); 136 137 for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { 138 RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset); 139 RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset); 140 } 141 142 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_luma_pitch); 143 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_picture_chroma_pitch); 144 145 for (int i = 0; i < RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES; i++) { 146 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].luma_offset); 147 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_reconstructed_pictures[i].chroma_offset); 148 } 149 150 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.yuv.luma_offset); 151 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.yuv.chroma_offset); 152 RADEON_ENC_CS(enc->enc_pic.ctx_buf.two_pass_search_center_map_offset); 153 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.red_offset); 154 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.green_offset); 155 RADEON_ENC_CS(enc->enc_pic.ctx_buf.pre_encode_input_picture.rgb.blue_offset); 156 157 RADEON_ENC_END(); 158 } 159 radeon_enc_spec_misc_hevc(struct radeon_encoder * enc)160static void radeon_enc_spec_misc_hevc(struct radeon_encoder *enc) 161 { 162 RADEON_ENC_BEGIN(enc->cmd.spec_misc_hevc); 163 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3); 164 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.amp_disabled); 165 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled); 166 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag); 167 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.cabac_init_flag); 168 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.half_pel_enabled); 169 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.quarter_pel_enabled); 170 RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.cu_qp_delta_enabled_flag); 171 RADEON_ENC_END(); 172 } 173 encode(struct radeon_encoder * enc)174static void encode(struct radeon_encoder *enc) 175 { 176 unsigned i; 177 178 enc->before_encode(enc); 179 enc->session_info(enc); 180 enc->total_task_size = 0; 181 enc->task_info(enc, enc->need_feedback); 182 183 if (enc->need_rate_control || enc->need_rc_per_pic) { 184 i = 0; 185 do { 186 enc->enc_pic.layer_sel.temporal_layer_index = i; 187 if (enc->need_rate_control) { 188 enc->layer_select(enc); 189 enc->rc_layer_init(enc); 190 } 191 if (enc->need_rc_per_pic) { 192 enc->layer_select(enc); 193 enc->rc_per_pic(enc); 194 } 195 } while (++i < enc->enc_pic.num_temporal_layers); 196 } 197 198 enc->encode_headers(enc); 199 enc->ctx(enc); 200 enc->ctx_override(enc); 201 enc->bitstream(enc); 202 enc->feedback(enc); 203 enc->metadata(enc); 204 enc->encode_statistics(enc); 205 enc->intra_refresh(enc); 206 enc->qp_map(enc); 207 enc->input_format(enc); 208 enc->output_format(enc); 209 210 enc->op_preset(enc); 211 enc->op_enc(enc); 212 *enc->p_task_size = (enc->total_task_size); 213 } 214 radeon_enc_2_0_init(struct radeon_encoder * enc)215void radeon_enc_2_0_init(struct radeon_encoder *enc) 216 { 217 radeon_enc_1_2_init(enc); 218 enc->encode = encode; 219 enc->input_format = radeon_enc_input_format; 220 enc->output_format = radeon_enc_output_format; 221 enc->ctx = radeon_enc_ctx; 222 enc->op_preset = radeon_enc_op_preset; 223 enc->quality_params = radeon_enc_quality_params; 224 enc->ctx_override = radeon_enc_dummy; 225 enc->metadata = radeon_enc_dummy; 226 227 if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) { 228 enc->deblocking_filter = radeon_enc_loop_filter_hevc; 229 enc->spec_misc = radeon_enc_spec_misc_hevc; 230 } 231 232 enc->cmd.session_info = RENCODE_IB_PARAM_SESSION_INFO; 233 enc->cmd.task_info = RENCODE_IB_PARAM_TASK_INFO; 234 enc->cmd.session_init = RENCODE_IB_PARAM_SESSION_INIT; 235 enc->cmd.layer_control = RENCODE_IB_PARAM_LAYER_CONTROL; 236 enc->cmd.layer_select = RENCODE_IB_PARAM_LAYER_SELECT; 237 enc->cmd.rc_session_init = RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT; 238 enc->cmd.rc_layer_init = RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT; 239 enc->cmd.quality_params = RENCODE_IB_PARAM_QUALITY_PARAMS; 240 enc->cmd.nalu = RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU; 241 enc->cmd.slice_header = RENCODE_IB_PARAM_SLICE_HEADER; 242 enc->cmd.input_format = RENCODE_IB_PARAM_INPUT_FORMAT; 243 enc->cmd.output_format = RENCODE_IB_PARAM_OUTPUT_FORMAT; 244 enc->cmd.enc_params = RENCODE_IB_PARAM_ENCODE_PARAMS; 245 enc->cmd.intra_refresh = RENCODE_IB_PARAM_INTRA_REFRESH; 246 enc->cmd.ctx = RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER; 247 enc->cmd.bitstream = RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER; 248 enc->cmd.feedback = RENCODE_IB_PARAM_FEEDBACK_BUFFER; 249 enc->cmd.slice_control_hevc = RENCODE_HEVC_IB_PARAM_SLICE_CONTROL; 250 enc->cmd.spec_misc_hevc = RENCODE_HEVC_IB_PARAM_SPEC_MISC; 251 enc->cmd.deblocking_filter_hevc = RENCODE_HEVC_IB_PARAM_LOOP_FILTER; 252 enc->cmd.slice_control_h264 = RENCODE_H264_IB_PARAM_SLICE_CONTROL; 253 enc->cmd.spec_misc_h264 = RENCODE_H264_IB_PARAM_SPEC_MISC; 254 enc->cmd.enc_params_h264 = RENCODE_H264_IB_PARAM_ENCODE_PARAMS; 255 enc->cmd.deblocking_filter_h264 = RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER; 256 enc->cmd.enc_statistics = RENCODE_IB_PARAM_ENCODE_STATISTICS; 257 enc->cmd.enc_qp_map = RENCODE_IB_PARAM_QP_MAP; 258 enc->cmd.enc_latency = RENCODE_IB_PARAM_ENCODE_LATENCY; 259 260 enc->enc_pic.session_info.interface_version = 261 ((RENCODE_FW_INTERFACE_MAJOR_VERSION << RENCODE_IF_MAJOR_VERSION_SHIFT) | 262 (RENCODE_FW_INTERFACE_MINOR_VERSION << RENCODE_IF_MINOR_VERSION_SHIFT)); 263 } 264