1 /**************************************************************************
3 * Copyright 2017 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 "radeon_vcn_enc.h"
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"
39 static const unsigned index_to_shifts
[4] = {24, 16, 8, 0};
41 static void radeon_vcn_enc_get_param(struct radeon_encoder
*enc
, struct pipe_picture_desc
*picture
)
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
;
50 enc
->enc_pic
.ref_idx_l1
= pic
->ref_idx_l1
;
51 enc
->enc_pic
.not_referenced
= pic
->not_referenced
;
52 enc
->enc_pic
.is_idr
= (pic
->picture_type
== PIPE_H264_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
;
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;
64 enc
->enc_pic
.rc_layer_init
.target_bit_rate
= pic
->rate_ctrl
.target_bitrate
;
65 enc
->enc_pic
.rc_layer_init
.peak_bit_rate
= pic
->rate_ctrl
.peak_bitrate
;
66 enc
->enc_pic
.rc_layer_init
.frame_rate_num
= pic
->rate_ctrl
.frame_rate_num
;
67 enc
->enc_pic
.rc_layer_init
.frame_rate_den
= pic
->rate_ctrl
.frame_rate_den
;
68 enc
->enc_pic
.rc_layer_init
.vbv_buffer_size
= pic
->rate_ctrl
.vbv_buffer_size
;
69 enc
->enc_pic
.rc_layer_init
.avg_target_bits_per_picture
= pic
->rate_ctrl
.target_bits_picture
;
70 enc
->enc_pic
.rc_layer_init
.peak_bits_per_picture_integer
=
71 pic
->rate_ctrl
.peak_bits_picture_integer
;
72 enc
->enc_pic
.rc_layer_init
.peak_bits_per_picture_fractional
=
73 pic
->rate_ctrl
.peak_bits_picture_fraction
;
74 enc
->enc_pic
.rc_session_init
.vbv_buffer_level
= pic
->rate_ctrl
.vbv_buf_lv
;
75 enc
->enc_pic
.rc_per_pic
.qp
= pic
->quant_i_frames
;
76 enc
->enc_pic
.rc_per_pic
.min_qp_app
= 0;
77 enc
->enc_pic
.rc_per_pic
.max_qp_app
= 51;
78 enc
->enc_pic
.rc_per_pic
.max_au_size
= 0;
79 enc
->enc_pic
.rc_per_pic
.enabled_filler_data
= pic
->rate_ctrl
.fill_data_enable
;
80 enc
->enc_pic
.rc_per_pic
.skip_frame_enable
= false;
81 enc
->enc_pic
.rc_per_pic
.enforce_hrd
= pic
->rate_ctrl
.enforce_hrd
;
82 switch (pic
->rate_ctrl
.rate_ctrl_method
) {
83 case PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE
:
84 enc
->enc_pic
.rc_session_init
.rate_control_method
= RENCODE_RATE_CONTROL_METHOD_NONE
;
86 case PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP
:
87 case PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT
:
88 enc
->enc_pic
.rc_session_init
.rate_control_method
= RENCODE_RATE_CONTROL_METHOD_CBR
;
90 case PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP
:
91 case PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE
:
92 enc
->enc_pic
.rc_session_init
.rate_control_method
=
93 RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR
;
96 enc
->enc_pic
.rc_session_init
.rate_control_method
= RENCODE_RATE_CONTROL_METHOD_NONE
;
98 } else if (u_reduce_video_profile(picture
->profile
) == PIPE_VIDEO_FORMAT_HEVC
) {
99 struct pipe_h265_enc_picture_desc
*pic
= (struct pipe_h265_enc_picture_desc
*)picture
;
100 enc
->enc_pic
.picture_type
= pic
->picture_type
;
101 enc
->enc_pic
.frame_num
= pic
->frame_num
;
102 enc
->enc_pic
.pic_order_cnt
= pic
->pic_order_cnt
;
103 enc
->enc_pic
.pic_order_cnt_type
= pic
->pic_order_cnt_type
;
104 enc
->enc_pic
.ref_idx_l0
= pic
->ref_idx_l0
;
105 enc
->enc_pic
.ref_idx_l1
= pic
->ref_idx_l1
;
106 enc
->enc_pic
.not_referenced
= pic
->not_referenced
;
107 enc
->enc_pic
.is_idr
= (pic
->picture_type
== PIPE_H265_ENC_PICTURE_TYPE_IDR
) ||
108 (pic
->picture_type
== PIPE_H265_ENC_PICTURE_TYPE_I
);
109 enc
->enc_pic
.crop_left
= 0;
110 enc
->enc_pic
.crop_right
= (align(enc
->base
.width
, 16) - enc
->base
.width
) / 2;
111 enc
->enc_pic
.crop_top
= 0;
112 enc
->enc_pic
.crop_bottom
= (align(enc
->base
.height
, 16) - enc
->base
.height
) / 2;
113 enc
->enc_pic
.general_tier_flag
= pic
->seq
.general_tier_flag
;
114 enc
->enc_pic
.general_profile_idc
= pic
->seq
.general_profile_idc
;
115 enc
->enc_pic
.general_level_idc
= pic
->seq
.general_level_idc
;
116 enc
->enc_pic
.max_poc
= MAX2(16, util_next_power_of_two(pic
->seq
.intra_period
));
117 enc
->enc_pic
.log2_max_poc
= 0;
118 for (int i
= enc
->enc_pic
.max_poc
; i
!= 0; enc
->enc_pic
.log2_max_poc
++)
120 enc
->enc_pic
.chroma_format_idc
= pic
->seq
.chroma_format_idc
;
121 enc
->enc_pic
.pic_width_in_luma_samples
= pic
->seq
.pic_width_in_luma_samples
;
122 enc
->enc_pic
.pic_height_in_luma_samples
= pic
->seq
.pic_height_in_luma_samples
;
123 enc
->enc_pic
.log2_diff_max_min_luma_coding_block_size
=
124 pic
->seq
.log2_diff_max_min_luma_coding_block_size
;
125 enc
->enc_pic
.log2_min_transform_block_size_minus2
=
126 pic
->seq
.log2_min_transform_block_size_minus2
;
127 enc
->enc_pic
.log2_diff_max_min_transform_block_size
=
128 pic
->seq
.log2_diff_max_min_transform_block_size
;
129 enc
->enc_pic
.max_transform_hierarchy_depth_inter
=
130 pic
->seq
.max_transform_hierarchy_depth_inter
;
131 enc
->enc_pic
.max_transform_hierarchy_depth_intra
=
132 pic
->seq
.max_transform_hierarchy_depth_intra
;
133 enc
->enc_pic
.log2_parallel_merge_level_minus2
= pic
->pic
.log2_parallel_merge_level_minus2
;
134 enc
->enc_pic
.bit_depth_luma_minus8
= pic
->seq
.bit_depth_luma_minus8
;
135 enc
->enc_pic
.bit_depth_chroma_minus8
= pic
->seq
.bit_depth_chroma_minus8
;
136 enc
->enc_pic
.nal_unit_type
= pic
->pic
.nal_unit_type
;
137 enc
->enc_pic
.max_num_merge_cand
= pic
->slice
.max_num_merge_cand
;
138 enc
->enc_pic
.sample_adaptive_offset_enabled_flag
=
139 pic
->seq
.sample_adaptive_offset_enabled_flag
;
140 enc
->enc_pic
.pcm_enabled_flag
= pic
->seq
.pcm_enabled_flag
;
141 enc
->enc_pic
.sps_temporal_mvp_enabled_flag
= pic
->seq
.sps_temporal_mvp_enabled_flag
;
142 enc
->enc_pic
.hevc_deblock
.loop_filter_across_slices_enabled
=
143 pic
->slice
.slice_loop_filter_across_slices_enabled_flag
;
144 enc
->enc_pic
.hevc_deblock
.deblocking_filter_disabled
=
145 pic
->slice
.slice_deblocking_filter_disabled_flag
;
146 enc
->enc_pic
.hevc_deblock
.beta_offset_div2
= pic
->slice
.slice_beta_offset_div2
;
147 enc
->enc_pic
.hevc_deblock
.tc_offset_div2
= pic
->slice
.slice_tc_offset_div2
;
148 enc
->enc_pic
.hevc_deblock
.cb_qp_offset
= pic
->slice
.slice_cb_qp_offset
;
149 enc
->enc_pic
.hevc_deblock
.cr_qp_offset
= pic
->slice
.slice_cr_qp_offset
;
150 enc
->enc_pic
.hevc_spec_misc
.log2_min_luma_coding_block_size_minus3
=
151 pic
->seq
.log2_min_luma_coding_block_size_minus3
;
152 enc
->enc_pic
.hevc_spec_misc
.amp_disabled
= !pic
->seq
.amp_enabled_flag
;
153 enc
->enc_pic
.hevc_spec_misc
.strong_intra_smoothing_enabled
=
154 pic
->seq
.strong_intra_smoothing_enabled_flag
;
155 enc
->enc_pic
.hevc_spec_misc
.constrained_intra_pred_flag
=
156 pic
->pic
.constrained_intra_pred_flag
;
157 enc
->enc_pic
.hevc_spec_misc
.cabac_init_flag
= pic
->slice
.cabac_init_flag
;
158 enc
->enc_pic
.hevc_spec_misc
.half_pel_enabled
= 1;
159 enc
->enc_pic
.hevc_spec_misc
.quarter_pel_enabled
= 1;
160 enc
->enc_pic
.rc_layer_init
.target_bit_rate
= pic
->rc
.target_bitrate
;
161 enc
->enc_pic
.rc_layer_init
.peak_bit_rate
= pic
->rc
.peak_bitrate
;
162 enc
->enc_pic
.rc_layer_init
.frame_rate_num
= pic
->rc
.frame_rate_num
;
163 enc
->enc_pic
.rc_layer_init
.frame_rate_den
= pic
->rc
.frame_rate_den
;
164 enc
->enc_pic
.rc_layer_init
.vbv_buffer_size
= pic
->rc
.vbv_buffer_size
;
165 enc
->enc_pic
.rc_layer_init
.avg_target_bits_per_picture
= pic
->rc
.target_bits_picture
;
166 enc
->enc_pic
.rc_layer_init
.peak_bits_per_picture_integer
= pic
->rc
.peak_bits_picture_integer
;
167 enc
->enc_pic
.rc_layer_init
.peak_bits_per_picture_fractional
=
168 pic
->rc
.peak_bits_picture_fraction
;
169 enc
->enc_pic
.rc_session_init
.vbv_buffer_level
= pic
->rc
.vbv_buf_lv
;
170 enc
->enc_pic
.rc_per_pic
.qp
= pic
->rc
.quant_i_frames
;
171 enc
->enc_pic
.rc_per_pic
.min_qp_app
= 0;
172 enc
->enc_pic
.rc_per_pic
.max_qp_app
= 51;
173 enc
->enc_pic
.rc_per_pic
.max_au_size
= 0;
174 enc
->enc_pic
.rc_per_pic
.enabled_filler_data
= pic
->rc
.fill_data_enable
;
175 enc
->enc_pic
.rc_per_pic
.skip_frame_enable
= false;
176 enc
->enc_pic
.rc_per_pic
.enforce_hrd
= pic
->rc
.enforce_hrd
;
177 switch (pic
->rc
.rate_ctrl_method
) {
178 case PIPE_H265_ENC_RATE_CONTROL_METHOD_DISABLE
:
179 enc
->enc_pic
.rc_session_init
.rate_control_method
= RENCODE_RATE_CONTROL_METHOD_NONE
;
181 case PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP
:
182 case PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT
:
183 enc
->enc_pic
.rc_session_init
.rate_control_method
= RENCODE_RATE_CONTROL_METHOD_CBR
;
185 case PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP
:
186 case PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE
:
187 enc
->enc_pic
.rc_session_init
.rate_control_method
=
188 RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR
;
191 enc
->enc_pic
.rc_session_init
.rate_control_method
= RENCODE_RATE_CONTROL_METHOD_NONE
;
196 static void flush(struct radeon_encoder
*enc
)
198 enc
->ws
->cs_flush(enc
->cs
, PIPE_FLUSH_ASYNC
, NULL
);
201 static void radeon_enc_flush(struct pipe_video_codec
*encoder
)
203 struct radeon_encoder
*enc
= (struct radeon_encoder
*)encoder
;
207 static void radeon_enc_cs_flush(void *ctx
, unsigned flags
, struct pipe_fence_handle
**fence
)
212 static unsigned get_cpb_num(struct radeon_encoder
*enc
)
214 unsigned w
= align(enc
->base
.width
, 16) / 16;
215 unsigned h
= align(enc
->base
.height
, 16) / 16;
218 switch (enc
->base
.level
) {
260 return MIN2(dpb
/ (w
* h
), 16);
263 static void radeon_enc_begin_frame(struct pipe_video_codec
*encoder
,
264 struct pipe_video_buffer
*source
,
265 struct pipe_picture_desc
*picture
)
267 struct radeon_encoder
*enc
= (struct radeon_encoder
*)encoder
;
268 struct vl_video_buffer
*vid_buf
= (struct vl_video_buffer
*)source
;
269 bool need_rate_control
= false;
271 if (u_reduce_video_profile(enc
->base
.profile
) == PIPE_VIDEO_FORMAT_MPEG4_AVC
) {
272 struct pipe_h264_enc_picture_desc
*pic
= (struct pipe_h264_enc_picture_desc
*)picture
;
274 enc
->enc_pic
.rc_layer_init
.target_bit_rate
!= pic
->rate_ctrl
.target_bitrate
;
275 } else if (u_reduce_video_profile(picture
->profile
) == PIPE_VIDEO_FORMAT_HEVC
) {
276 struct pipe_h265_enc_picture_desc
*pic
= (struct pipe_h265_enc_picture_desc
*)picture
;
277 need_rate_control
= enc
->enc_pic
.rc_layer_init
.target_bit_rate
!= pic
->rc
.target_bitrate
;
280 radeon_vcn_enc_get_param(enc
, picture
);
282 enc
->get_buffer(vid_buf
->resources
[0], &enc
->handle
, &enc
->luma
);
283 enc
->get_buffer(vid_buf
->resources
[1], NULL
, &enc
->chroma
);
285 enc
->need_feedback
= false;
287 if (!enc
->stream_handle
) {
288 struct rvid_buffer fb
;
289 enc
->stream_handle
= si_vid_alloc_stream_handle();
290 enc
->si
= CALLOC_STRUCT(rvid_buffer
);
291 si_vid_create_buffer(enc
->screen
, enc
->si
, 128 * 1024, PIPE_USAGE_STAGING
);
292 si_vid_create_buffer(enc
->screen
, &fb
, 4096, PIPE_USAGE_STAGING
);
296 si_vid_destroy_buffer(&fb
);
298 if (need_rate_control
) {
304 static void radeon_enc_encode_bitstream(struct pipe_video_codec
*encoder
,
305 struct pipe_video_buffer
*source
,
306 struct pipe_resource
*destination
, void **fb
)
308 struct radeon_encoder
*enc
= (struct radeon_encoder
*)encoder
;
309 enc
->get_buffer(destination
, &enc
->bs_handle
, NULL
);
310 enc
->bs_size
= destination
->width0
;
312 *fb
= enc
->fb
= CALLOC_STRUCT(rvid_buffer
);
314 if (!si_vid_create_buffer(enc
->screen
, enc
->fb
, 4096, PIPE_USAGE_STAGING
)) {
315 RVID_ERR("Can't create feedback buffer.\n");
319 enc
->need_feedback
= true;
323 static void radeon_enc_end_frame(struct pipe_video_codec
*encoder
, struct pipe_video_buffer
*source
,
324 struct pipe_picture_desc
*picture
)
326 struct radeon_encoder
*enc
= (struct radeon_encoder
*)encoder
;
330 static void radeon_enc_destroy(struct pipe_video_codec
*encoder
)
332 struct radeon_encoder
*enc
= (struct radeon_encoder
*)encoder
;
334 if (enc
->stream_handle
) {
335 struct rvid_buffer fb
;
336 enc
->need_feedback
= false;
337 si_vid_create_buffer(enc
->screen
, &fb
, 512, PIPE_USAGE_STAGING
);
341 si_vid_destroy_buffer(&fb
);
344 si_vid_destroy_buffer(&enc
->cpb
);
345 enc
->ws
->cs_destroy(enc
->cs
);
349 static void radeon_enc_get_feedback(struct pipe_video_codec
*encoder
, void *feedback
,
352 struct radeon_encoder
*enc
= (struct radeon_encoder
*)encoder
;
353 struct rvid_buffer
*fb
= feedback
;
356 uint32_t *ptr
= enc
->ws
->buffer_map(fb
->res
->buf
, enc
->cs
,
357 PIPE_TRANSFER_READ_WRITE
| RADEON_TRANSFER_TEMPORARY
);
362 enc
->ws
->buffer_unmap(fb
->res
->buf
);
365 si_vid_destroy_buffer(fb
);
369 struct pipe_video_codec
*radeon_create_encoder(struct pipe_context
*context
,
370 const struct pipe_video_codec
*templ
,
371 struct radeon_winsys
*ws
,
372 radeon_enc_get_buffer get_buffer
)
374 struct si_screen
*sscreen
= (struct si_screen
*)context
->screen
;
375 struct si_context
*sctx
= (struct si_context
*)context
;
376 struct radeon_encoder
*enc
;
377 struct pipe_video_buffer
*tmp_buf
, templat
= {};
378 struct radeon_surf
*tmp_surf
;
381 enc
= CALLOC_STRUCT(radeon_encoder
);
386 enc
->alignment
= 256;
388 enc
->base
.context
= context
;
389 enc
->base
.destroy
= radeon_enc_destroy
;
390 enc
->base
.begin_frame
= radeon_enc_begin_frame
;
391 enc
->base
.encode_bitstream
= radeon_enc_encode_bitstream
;
392 enc
->base
.end_frame
= radeon_enc_end_frame
;
393 enc
->base
.flush
= radeon_enc_flush
;
394 enc
->base
.get_feedback
= radeon_enc_get_feedback
;
395 enc
->get_buffer
= get_buffer
;
396 enc
->bits_in_shifter
= 0;
397 enc
->screen
= context
->screen
;
399 enc
->cs
= ws
->cs_create(sctx
->ctx
, RING_VCN_ENC
, radeon_enc_cs_flush
, enc
, false);
402 RVID_ERR("Can't get command submission context.\n");
406 struct rvid_buffer si
;
407 si_vid_create_buffer(enc
->screen
, &si
, 128 * 1024, PIPE_USAGE_STAGING
);
410 templat
.buffer_format
= PIPE_FORMAT_NV12
;
411 if (enc
->base
.profile
== PIPE_VIDEO_PROFILE_HEVC_MAIN_10
)
412 templat
.buffer_format
= PIPE_FORMAT_P010
;
413 templat
.width
= enc
->base
.width
;
414 templat
.height
= enc
->base
.height
;
415 templat
.interlaced
= false;
417 if (!(tmp_buf
= context
->create_video_buffer(context
, &templat
))) {
418 RVID_ERR("Can't create video buffer.\n");
422 enc
->cpb_num
= get_cpb_num(enc
);
427 get_buffer(((struct vl_video_buffer
*)tmp_buf
)->resources
[0], NULL
, &tmp_surf
);
429 cpb_size
= (sscreen
->info
.chip_class
< GFX9
)
430 ? align(tmp_surf
->u
.legacy
.level
[0].nblk_x
* tmp_surf
->bpe
, 128) *
431 align(tmp_surf
->u
.legacy
.level
[0].nblk_y
, 32)
432 : align(tmp_surf
->u
.gfx9
.surf_pitch
* tmp_surf
->bpe
, 256) *
433 align(tmp_surf
->u
.gfx9
.surf_height
, 32);
435 cpb_size
= cpb_size
* 3 / 2;
436 cpb_size
= cpb_size
* enc
->cpb_num
;
437 tmp_buf
->destroy(tmp_buf
);
439 if (!si_vid_create_buffer(enc
->screen
, &enc
->cpb
, cpb_size
, PIPE_USAGE_DEFAULT
)) {
440 RVID_ERR("Can't create CPB buffer.\n");
444 if (sscreen
->info
.family
>= CHIP_SIENNA_CICHLID
)
445 radeon_enc_3_0_init(enc
);
446 else if (sscreen
->info
.family
>= CHIP_RENOIR
)
447 radeon_enc_2_0_init(enc
);
449 radeon_enc_1_2_init(enc
);
455 enc
->ws
->cs_destroy(enc
->cs
);
457 si_vid_destroy_buffer(&enc
->cpb
);
463 void radeon_enc_add_buffer(struct radeon_encoder
*enc
, struct pb_buffer
*buf
,
464 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
, signed offset
)
466 enc
->ws
->cs_add_buffer(enc
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
, domain
, 0);
468 addr
= enc
->ws
->buffer_get_virtual_address(buf
);
469 addr
= addr
+ offset
;
470 RADEON_ENC_CS(addr
>> 32);
474 void radeon_enc_set_emulation_prevention(struct radeon_encoder
*enc
, bool set
)
476 if (set
!= enc
->emulation_prevention
) {
477 enc
->emulation_prevention
= set
;
482 void radeon_enc_output_one_byte(struct radeon_encoder
*enc
, unsigned char byte
)
484 if (enc
->byte_index
== 0)
485 enc
->cs
->current
.buf
[enc
->cs
->current
.cdw
] = 0;
486 enc
->cs
->current
.buf
[enc
->cs
->current
.cdw
] |=
487 ((unsigned int)(byte
) << index_to_shifts
[enc
->byte_index
]);
490 if (enc
->byte_index
>= 4) {
492 enc
->cs
->current
.cdw
++;
496 void radeon_enc_emulation_prevention(struct radeon_encoder
*enc
, unsigned char byte
)
498 if (enc
->emulation_prevention
) {
499 if ((enc
->num_zeros
>= 2) && ((byte
== 0x00) || (byte
== 0x01) || (byte
== 0x03))) {
500 radeon_enc_output_one_byte(enc
, 0x03);
501 enc
->bits_output
+= 8;
504 enc
->num_zeros
= (byte
== 0 ? (enc
->num_zeros
+ 1) : 0);
508 void radeon_enc_code_fixed_bits(struct radeon_encoder
*enc
, unsigned int value
,
509 unsigned int num_bits
)
511 unsigned int bits_to_pack
= 0;
513 while (num_bits
> 0) {
514 unsigned int value_to_pack
= value
& (0xffffffff >> (32 - num_bits
));
516 num_bits
> (32 - enc
->bits_in_shifter
) ? (32 - enc
->bits_in_shifter
) : num_bits
;
518 if (bits_to_pack
< num_bits
)
519 value_to_pack
= value_to_pack
>> (num_bits
- bits_to_pack
);
521 enc
->shifter
|= value_to_pack
<< (32 - enc
->bits_in_shifter
- bits_to_pack
);
522 num_bits
-= bits_to_pack
;
523 enc
->bits_in_shifter
+= bits_to_pack
;
525 while (enc
->bits_in_shifter
>= 8) {
526 unsigned char output_byte
= (unsigned char)(enc
->shifter
>> 24);
528 radeon_enc_emulation_prevention(enc
, output_byte
);
529 radeon_enc_output_one_byte(enc
, output_byte
);
530 enc
->bits_in_shifter
-= 8;
531 enc
->bits_output
+= 8;
536 void radeon_enc_reset(struct radeon_encoder
*enc
)
538 enc
->emulation_prevention
= false;
540 enc
->bits_in_shifter
= 0;
541 enc
->bits_output
= 0;
546 void radeon_enc_byte_align(struct radeon_encoder
*enc
)
548 unsigned int num_padding_zeros
= (32 - enc
->bits_in_shifter
) % 8;
550 if (num_padding_zeros
> 0)
551 radeon_enc_code_fixed_bits(enc
, 0, num_padding_zeros
);
554 void radeon_enc_flush_headers(struct radeon_encoder
*enc
)
556 if (enc
->bits_in_shifter
!= 0) {
557 unsigned char output_byte
= (unsigned char)(enc
->shifter
>> 24);
558 radeon_enc_emulation_prevention(enc
, output_byte
);
559 radeon_enc_output_one_byte(enc
, output_byte
);
560 enc
->bits_output
+= enc
->bits_in_shifter
;
562 enc
->bits_in_shifter
= 0;
566 if (enc
->byte_index
> 0) {
567 enc
->cs
->current
.cdw
++;
572 void radeon_enc_code_ue(struct radeon_encoder
*enc
, unsigned int value
)
575 unsigned int ue_code
= value
+ 1;
579 value
= (value
>> 1);
583 unsigned int ue_length
= (x
<< 1) + 1;
584 radeon_enc_code_fixed_bits(enc
, ue_code
, ue_length
);
587 void radeon_enc_code_se(struct radeon_encoder
*enc
, int value
)
592 v
= (value
< 0 ? ((unsigned int)(0 - value
) << 1) : (((unsigned int)(value
) << 1) - 1));
594 radeon_enc_code_ue(enc
, v
);