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 **************************************************************************/
30 #include "pipe/p_video_codec.h"
32 #include "util/u_video.h"
33 #include "util/u_memory.h"
35 #include "vl/vl_video_buffer.h"
37 #include "radeonsi/si_pipe.h"
38 #include "radeon_video.h"
39 #include "radeon_uvd_enc.h"
41 #define UVD_HEVC_LEVEL_1 30
42 #define UVD_HEVC_LEVEL_2 60
43 #define UVD_HEVC_LEVEL_2_1 63
44 #define UVD_HEVC_LEVEL_3 90
45 #define UVD_HEVC_LEVEL_3_1 93
46 #define UVD_HEVC_LEVEL_4 120
47 #define UVD_HEVC_LEVEL_4_1 123
48 #define UVD_HEVC_LEVEL_5 150
49 #define UVD_HEVC_LEVEL_5_1 153
50 #define UVD_HEVC_LEVEL_5_2 156
51 #define UVD_HEVC_LEVEL_6 180
52 #define UVD_HEVC_LEVEL_6_1 183
53 #define UVD_HEVC_LEVEL_6_2 186
56 radeon_uvd_enc_get_param(struct radeon_uvd_encoder
*enc
,
57 struct pipe_h265_enc_picture_desc
*pic
)
59 enc
->enc_pic
.picture_type
= pic
->picture_type
;
60 enc
->enc_pic
.frame_num
= pic
->frame_num
;
61 enc
->enc_pic
.pic_order_cnt
= pic
->pic_order_cnt
;
62 enc
->enc_pic
.pic_order_cnt_type
= pic
->pic_order_cnt_type
;
63 enc
->enc_pic
.not_referenced
= pic
->not_referenced
;
64 enc
->enc_pic
.is_iframe
=
65 (pic
->picture_type
== PIPE_H265_ENC_PICTURE_TYPE_IDR
)
66 || (pic
->picture_type
== PIPE_H265_ENC_PICTURE_TYPE_I
);
67 enc
->enc_pic
.crop_left
= 0;
68 enc
->enc_pic
.crop_right
=
69 (align(enc
->base
.width
, 16) - enc
->base
.width
) / 2;
70 enc
->enc_pic
.crop_top
= 0;
71 enc
->enc_pic
.crop_bottom
=
72 (align(enc
->base
.height
, 16) - enc
->base
.height
) / 2;
73 enc
->enc_pic
.general_tier_flag
= pic
->seq
.general_tier_flag
;
74 enc
->enc_pic
.general_profile_idc
= pic
->seq
.general_profile_idc
;
75 enc
->enc_pic
.general_level_idc
= pic
->seq
.general_level_idc
;
76 enc
->enc_pic
.max_poc
=
77 MAX2(16, util_next_power_of_two(pic
->seq
.intra_period
));
78 enc
->enc_pic
.log2_max_poc
= 0;
79 for (int i
= enc
->enc_pic
.max_poc
; i
!= 0; enc
->enc_pic
.log2_max_poc
++)
81 enc
->enc_pic
.chroma_format_idc
= pic
->seq
.chroma_format_idc
;
82 enc
->enc_pic
.pic_width_in_luma_samples
=
83 pic
->seq
.pic_width_in_luma_samples
;
84 enc
->enc_pic
.pic_height_in_luma_samples
=
85 pic
->seq
.pic_height_in_luma_samples
;
86 enc
->enc_pic
.log2_diff_max_min_luma_coding_block_size
=
87 pic
->seq
.log2_diff_max_min_luma_coding_block_size
;
88 enc
->enc_pic
.log2_min_transform_block_size_minus2
=
89 pic
->seq
.log2_min_transform_block_size_minus2
;
90 enc
->enc_pic
.log2_diff_max_min_transform_block_size
=
91 pic
->seq
.log2_diff_max_min_transform_block_size
;
92 enc
->enc_pic
.max_transform_hierarchy_depth_inter
=
93 pic
->seq
.max_transform_hierarchy_depth_inter
;
94 enc
->enc_pic
.max_transform_hierarchy_depth_intra
=
95 pic
->seq
.max_transform_hierarchy_depth_intra
;
96 enc
->enc_pic
.log2_parallel_merge_level_minus2
=
97 pic
->pic
.log2_parallel_merge_level_minus2
;
98 enc
->enc_pic
.bit_depth_luma_minus8
= pic
->seq
.bit_depth_luma_minus8
;
99 enc
->enc_pic
.bit_depth_chroma_minus8
= pic
->seq
.bit_depth_chroma_minus8
;
100 enc
->enc_pic
.nal_unit_type
= pic
->pic
.nal_unit_type
;
101 enc
->enc_pic
.max_num_merge_cand
= pic
->slice
.max_num_merge_cand
;
102 enc
->enc_pic
.sample_adaptive_offset_enabled_flag
=
103 pic
->seq
.sample_adaptive_offset_enabled_flag
;
104 enc
->enc_pic
.pcm_enabled_flag
= 0; /*HW not support PCM */
105 enc
->enc_pic
.sps_temporal_mvp_enabled_flag
=
106 pic
->seq
.sps_temporal_mvp_enabled_flag
;
110 flush(struct radeon_uvd_encoder
*enc
)
112 enc
->ws
->cs_flush(enc
->cs
, PIPE_FLUSH_ASYNC
, NULL
);
116 radeon_uvd_enc_flush(struct pipe_video_codec
*encoder
)
118 struct radeon_uvd_encoder
*enc
= (struct radeon_uvd_encoder
*) encoder
;
123 radeon_uvd_enc_cs_flush(void *ctx
, unsigned flags
,
124 struct pipe_fence_handle
**fence
)
130 get_cpb_num(struct radeon_uvd_encoder
*enc
)
132 unsigned w
= align(enc
->base
.width
, 16) / 16;
133 unsigned h
= align(enc
->base
.height
, 16) / 16;
136 switch (enc
->base
.level
) {
137 case UVD_HEVC_LEVEL_1
:
141 case UVD_HEVC_LEVEL_2
:
145 case UVD_HEVC_LEVEL_2_1
:
149 case UVD_HEVC_LEVEL_3
:
153 case UVD_HEVC_LEVEL_3_1
:
157 case UVD_HEVC_LEVEL_4
:
158 case UVD_HEVC_LEVEL_4_1
:
162 case UVD_HEVC_LEVEL_5
:
163 case UVD_HEVC_LEVEL_5_1
:
164 case UVD_HEVC_LEVEL_5_2
:
168 case UVD_HEVC_LEVEL_6
:
169 case UVD_HEVC_LEVEL_6_1
:
170 case UVD_HEVC_LEVEL_6_2
:
176 return MIN2(dpb
/ (w
* h
), 16);
180 radeon_uvd_enc_begin_frame(struct pipe_video_codec
*encoder
,
181 struct pipe_video_buffer
*source
,
182 struct pipe_picture_desc
*picture
)
184 struct radeon_uvd_encoder
*enc
= (struct radeon_uvd_encoder
*) encoder
;
185 struct vl_video_buffer
*vid_buf
= (struct vl_video_buffer
*) source
;
187 radeon_uvd_enc_get_param(enc
,
188 (struct pipe_h265_enc_picture_desc
*) picture
);
190 enc
->get_buffer(vid_buf
->resources
[0], &enc
->handle
, &enc
->luma
);
191 enc
->get_buffer(vid_buf
->resources
[1], NULL
, &enc
->chroma
);
193 enc
->need_feedback
= false;
195 if (!enc
->stream_handle
) {
196 struct rvid_buffer fb
;
197 enc
->stream_handle
= si_vid_alloc_stream_handle();
198 enc
->si
= CALLOC_STRUCT(rvid_buffer
);
199 si_vid_create_buffer(enc
->screen
, enc
->si
, 128 * 1024,
201 si_vid_create_buffer(enc
->screen
, &fb
, 4096, PIPE_USAGE_STAGING
);
203 enc
->begin(enc
, picture
);
205 si_vid_destroy_buffer(&fb
);
210 radeon_uvd_enc_encode_bitstream(struct pipe_video_codec
*encoder
,
211 struct pipe_video_buffer
*source
,
212 struct pipe_resource
*destination
, void **fb
)
214 struct radeon_uvd_encoder
*enc
= (struct radeon_uvd_encoder
*) encoder
;
215 enc
->get_buffer(destination
, &enc
->bs_handle
, NULL
);
216 enc
->bs_size
= destination
->width0
;
218 *fb
= enc
->fb
= CALLOC_STRUCT(rvid_buffer
);
220 if (!si_vid_create_buffer(enc
->screen
, enc
->fb
, 4096, PIPE_USAGE_STAGING
)) {
221 RVID_ERR("Can't create feedback buffer.\n");
225 enc
->need_feedback
= true;
230 radeon_uvd_enc_end_frame(struct pipe_video_codec
*encoder
,
231 struct pipe_video_buffer
*source
,
232 struct pipe_picture_desc
*picture
)
234 struct radeon_uvd_encoder
*enc
= (struct radeon_uvd_encoder
*) encoder
;
239 radeon_uvd_enc_destroy(struct pipe_video_codec
*encoder
)
241 struct radeon_uvd_encoder
*enc
= (struct radeon_uvd_encoder
*) encoder
;
243 if (enc
->stream_handle
) {
244 struct rvid_buffer fb
;
245 enc
->need_feedback
= false;
246 si_vid_create_buffer(enc
->screen
, &fb
, 512, PIPE_USAGE_STAGING
);
250 si_vid_destroy_buffer(&fb
);
253 si_vid_destroy_buffer(&enc
->cpb
);
254 enc
->ws
->cs_destroy(enc
->cs
);
259 radeon_uvd_enc_get_feedback(struct pipe_video_codec
*encoder
,
260 void *feedback
, unsigned *size
)
262 struct radeon_uvd_encoder
*enc
= (struct radeon_uvd_encoder
*) encoder
;
263 struct rvid_buffer
*fb
= feedback
;
266 radeon_uvd_enc_feedback_t
*fb_data
=
267 (radeon_uvd_enc_feedback_t
*) enc
->ws
->buffer_map(
268 fb
->res
->buf
, enc
->cs
,
269 PIPE_TRANSFER_READ_WRITE
| RADEON_TRANSFER_TEMPORARY
);
271 if (!fb_data
->status
)
272 *size
= fb_data
->bitstream_size
;
275 enc
->ws
->buffer_unmap(fb
->res
->buf
);
278 si_vid_destroy_buffer(fb
);
282 struct pipe_video_codec
*
283 radeon_uvd_create_encoder(struct pipe_context
*context
,
284 const struct pipe_video_codec
*templ
,
285 struct radeon_winsys
*ws
,
286 radeon_uvd_enc_get_buffer get_buffer
)
288 struct si_screen
*sscreen
= (struct si_screen
*) context
->screen
;
289 struct si_context
*sctx
= (struct si_context
*) context
;
290 struct radeon_uvd_encoder
*enc
;
291 struct pipe_video_buffer
*tmp_buf
, templat
= { };
292 struct radeon_surf
*tmp_surf
;
295 if (!si_radeon_uvd_enc_supported(sscreen
)) {
296 RVID_ERR("Unsupported UVD ENC fw version loaded!\n");
300 enc
= CALLOC_STRUCT(radeon_uvd_encoder
);
306 enc
->base
.context
= context
;
307 enc
->base
.destroy
= radeon_uvd_enc_destroy
;
308 enc
->base
.begin_frame
= radeon_uvd_enc_begin_frame
;
309 enc
->base
.encode_bitstream
= radeon_uvd_enc_encode_bitstream
;
310 enc
->base
.end_frame
= radeon_uvd_enc_end_frame
;
311 enc
->base
.flush
= radeon_uvd_enc_flush
;
312 enc
->base
.get_feedback
= radeon_uvd_enc_get_feedback
;
313 enc
->get_buffer
= get_buffer
;
314 enc
->bits_in_shifter
= 0;
315 enc
->screen
= context
->screen
;
318 ws
->cs_create(sctx
->ctx
, RING_UVD_ENC
, radeon_uvd_enc_cs_flush
, enc
, false);
321 RVID_ERR("Can't get command submission context.\n");
325 struct rvid_buffer si
;
326 si_vid_create_buffer(enc
->screen
, &si
, 128 * 1024, PIPE_USAGE_STAGING
);
329 templat
.buffer_format
= PIPE_FORMAT_NV12
;
330 templat
.chroma_format
= PIPE_VIDEO_CHROMA_FORMAT_420
;
331 templat
.width
= enc
->base
.width
;
332 templat
.height
= enc
->base
.height
;
333 templat
.interlaced
= false;
335 if (!(tmp_buf
= context
->create_video_buffer(context
, &templat
))) {
336 RVID_ERR("Can't create video buffer.\n");
340 enc
->cpb_num
= get_cpb_num(enc
);
345 get_buffer(((struct vl_video_buffer
*) tmp_buf
)->resources
[0], NULL
,
348 cpb_size
= (sscreen
->info
.chip_class
< GFX9
) ?
349 align(tmp_surf
->u
.legacy
.level
[0].nblk_x
* tmp_surf
->bpe
, 128) *
350 align(tmp_surf
->u
.legacy
.level
[0].nblk_y
, 32) :
351 align(tmp_surf
->u
.gfx9
.surf_pitch
* tmp_surf
->bpe
, 256) *
352 align(tmp_surf
->u
.gfx9
.surf_height
, 32);
354 cpb_size
= cpb_size
* 3 / 2;
355 cpb_size
= cpb_size
* enc
->cpb_num
;
356 tmp_buf
->destroy(tmp_buf
);
358 if (!si_vid_create_buffer
359 (enc
->screen
, &enc
->cpb
, cpb_size
, PIPE_USAGE_DEFAULT
)) {
360 RVID_ERR("Can't create CPB buffer.\n");
364 radeon_uvd_enc_1_1_init(enc
);
370 enc
->ws
->cs_destroy(enc
->cs
);
372 si_vid_destroy_buffer(&enc
->cpb
);
379 si_radeon_uvd_enc_supported(struct si_screen
* sscreen
)
381 return (sscreen
->info
.uvd_enc_supported
);