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 **************************************************************************/
31 #include "pipe/p_video_codec.h"
33 #include "util/u_memory.h"
34 #include "util/u_video.h"
36 #include "vl/vl_mpeg12_decoder.h"
38 #include "r600_pipe_common.h"
39 #include "radeon_video.h"
40 #include "radeon_vcn_dec.h"
42 #define FB_BUFFER_OFFSET 0x1000
43 #define FB_BUFFER_SIZE 2048
44 #define IT_SCALING_TABLE_SIZE 992
45 #define RDECODE_SESSION_CONTEXT_SIZE (128 * 1024)
47 #define RDECODE_GPCOM_VCPU_CMD 0x2070c
48 #define RDECODE_GPCOM_VCPU_DATA0 0x20710
49 #define RDECODE_GPCOM_VCPU_DATA1 0x20714
50 #define RDECODE_ENGINE_CNTL 0x20718
53 #define NUM_MPEG2_REFS 6
54 #define NUM_H264_REFS 17
55 #define NUM_VC1_REFS 5
57 struct radeon_decoder
{
58 struct pipe_video_codec base
;
60 unsigned stream_handle
;
62 unsigned frame_number
;
64 struct pipe_screen
*screen
;
65 struct radeon_winsys
*ws
;
66 struct radeon_winsys_cs
*cs
;
73 struct rvid_buffer msg_fb_it_buffers
[NUM_BUFFERS
];
74 struct rvid_buffer bs_buffers
[NUM_BUFFERS
];
75 struct rvid_buffer dpb
;
76 struct rvid_buffer ctx
;
77 struct rvid_buffer sessionctx
;
83 static rvcn_dec_message_avc_t
get_h264_msg(struct radeon_decoder
*dec
,
84 struct pipe_h264_picture_desc
*pic
)
86 rvcn_dec_message_avc_t result
;
88 memset(&result
, 0, sizeof(result
));
89 switch (pic
->base
.profile
) {
90 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE
:
91 result
.profile
= RDECODE_H264_PROFILE_BASELINE
;
94 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN
:
95 result
.profile
= RDECODE_H264_PROFILE_MAIN
;
98 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH
:
99 result
.profile
= RDECODE_H264_PROFILE_HIGH
;
107 result
.level
= dec
->base
.level
;
109 result
.sps_info_flags
= 0;
110 result
.sps_info_flags
|= pic
->pps
->sps
->direct_8x8_inference_flag
<< 0;
111 result
.sps_info_flags
|= pic
->pps
->sps
->mb_adaptive_frame_field_flag
<< 1;
112 result
.sps_info_flags
|= pic
->pps
->sps
->frame_mbs_only_flag
<< 2;
113 result
.sps_info_flags
|= pic
->pps
->sps
->delta_pic_order_always_zero_flag
<< 3;
115 result
.bit_depth_luma_minus8
= pic
->pps
->sps
->bit_depth_luma_minus8
;
116 result
.bit_depth_chroma_minus8
= pic
->pps
->sps
->bit_depth_chroma_minus8
;
117 result
.log2_max_frame_num_minus4
= pic
->pps
->sps
->log2_max_frame_num_minus4
;
118 result
.pic_order_cnt_type
= pic
->pps
->sps
->pic_order_cnt_type
;
119 result
.log2_max_pic_order_cnt_lsb_minus4
=
120 pic
->pps
->sps
->log2_max_pic_order_cnt_lsb_minus4
;
122 switch (dec
->base
.chroma_format
) {
123 case PIPE_VIDEO_CHROMA_FORMAT_NONE
:
125 case PIPE_VIDEO_CHROMA_FORMAT_400
:
126 result
.chroma_format
= 0;
128 case PIPE_VIDEO_CHROMA_FORMAT_420
:
129 result
.chroma_format
= 1;
131 case PIPE_VIDEO_CHROMA_FORMAT_422
:
132 result
.chroma_format
= 2;
134 case PIPE_VIDEO_CHROMA_FORMAT_444
:
135 result
.chroma_format
= 3;
139 result
.pps_info_flags
= 0;
140 result
.pps_info_flags
|= pic
->pps
->transform_8x8_mode_flag
<< 0;
141 result
.pps_info_flags
|= pic
->pps
->redundant_pic_cnt_present_flag
<< 1;
142 result
.pps_info_flags
|= pic
->pps
->constrained_intra_pred_flag
<< 2;
143 result
.pps_info_flags
|= pic
->pps
->deblocking_filter_control_present_flag
<< 3;
144 result
.pps_info_flags
|= pic
->pps
->weighted_bipred_idc
<< 4;
145 result
.pps_info_flags
|= pic
->pps
->weighted_pred_flag
<< 6;
146 result
.pps_info_flags
|= pic
->pps
->bottom_field_pic_order_in_frame_present_flag
<< 7;
147 result
.pps_info_flags
|= pic
->pps
->entropy_coding_mode_flag
<< 8;
149 result
.num_slice_groups_minus1
= pic
->pps
->num_slice_groups_minus1
;
150 result
.slice_group_map_type
= pic
->pps
->slice_group_map_type
;
151 result
.slice_group_change_rate_minus1
= pic
->pps
->slice_group_change_rate_minus1
;
152 result
.pic_init_qp_minus26
= pic
->pps
->pic_init_qp_minus26
;
153 result
.chroma_qp_index_offset
= pic
->pps
->chroma_qp_index_offset
;
154 result
.second_chroma_qp_index_offset
= pic
->pps
->second_chroma_qp_index_offset
;
156 memcpy(result
.scaling_list_4x4
, pic
->pps
->ScalingList4x4
, 6*16);
157 memcpy(result
.scaling_list_8x8
, pic
->pps
->ScalingList8x8
, 2*64);
159 memcpy(dec
->it
, result
.scaling_list_4x4
, 6*16);
160 memcpy((dec
->it
+ 96), result
.scaling_list_8x8
, 2*64);
162 result
.num_ref_frames
= pic
->num_ref_frames
;
164 result
.num_ref_idx_l0_active_minus1
= pic
->num_ref_idx_l0_active_minus1
;
165 result
.num_ref_idx_l1_active_minus1
= pic
->num_ref_idx_l1_active_minus1
;
167 result
.frame_num
= pic
->frame_num
;
168 memcpy(result
.frame_num_list
, pic
->frame_num_list
, 4*16);
169 result
.curr_field_order_cnt_list
[0] = pic
->field_order_cnt
[0];
170 result
.curr_field_order_cnt_list
[1] = pic
->field_order_cnt
[1];
171 memcpy(result
.field_order_cnt_list
, pic
->field_order_cnt_list
, 4*16*2);
173 result
.decoded_pic_idx
= pic
->frame_num
;
178 static void radeon_dec_destroy_associated_data(void *data
)
180 /* NOOP, since we only use an intptr */
183 static rvcn_dec_message_hevc_t
get_h265_msg(struct radeon_decoder
*dec
,
184 struct pipe_video_buffer
*target
,
185 struct pipe_h265_picture_desc
*pic
)
187 rvcn_dec_message_hevc_t result
;
190 memset(&result
, 0, sizeof(result
));
191 result
.sps_info_flags
= 0;
192 result
.sps_info_flags
|= pic
->pps
->sps
->scaling_list_enabled_flag
<< 0;
193 result
.sps_info_flags
|= pic
->pps
->sps
->amp_enabled_flag
<< 1;
194 result
.sps_info_flags
|= pic
->pps
->sps
->sample_adaptive_offset_enabled_flag
<< 2;
195 result
.sps_info_flags
|= pic
->pps
->sps
->pcm_enabled_flag
<< 3;
196 result
.sps_info_flags
|= pic
->pps
->sps
->pcm_loop_filter_disabled_flag
<< 4;
197 result
.sps_info_flags
|= pic
->pps
->sps
->long_term_ref_pics_present_flag
<< 5;
198 result
.sps_info_flags
|= pic
->pps
->sps
->sps_temporal_mvp_enabled_flag
<< 6;
199 result
.sps_info_flags
|= pic
->pps
->sps
->strong_intra_smoothing_enabled_flag
<< 7;
200 result
.sps_info_flags
|= pic
->pps
->sps
->separate_colour_plane_flag
<< 8;
201 if (((struct r600_common_screen
*)dec
->screen
)->family
== CHIP_CARRIZO
)
202 result
.sps_info_flags
|= 1 << 9;
203 if (pic
->UseRefPicList
== true)
204 result
.sps_info_flags
|= 1 << 10;
206 result
.chroma_format
= pic
->pps
->sps
->chroma_format_idc
;
207 result
.bit_depth_luma_minus8
= pic
->pps
->sps
->bit_depth_luma_minus8
;
208 result
.bit_depth_chroma_minus8
= pic
->pps
->sps
->bit_depth_chroma_minus8
;
209 result
.log2_max_pic_order_cnt_lsb_minus4
= pic
->pps
->sps
->log2_max_pic_order_cnt_lsb_minus4
;
210 result
.sps_max_dec_pic_buffering_minus1
= pic
->pps
->sps
->sps_max_dec_pic_buffering_minus1
;
211 result
.log2_min_luma_coding_block_size_minus3
=
212 pic
->pps
->sps
->log2_min_luma_coding_block_size_minus3
;
213 result
.log2_diff_max_min_luma_coding_block_size
=
214 pic
->pps
->sps
->log2_diff_max_min_luma_coding_block_size
;
215 result
.log2_min_transform_block_size_minus2
=
216 pic
->pps
->sps
->log2_min_transform_block_size_minus2
;
217 result
.log2_diff_max_min_transform_block_size
=
218 pic
->pps
->sps
->log2_diff_max_min_transform_block_size
;
219 result
.max_transform_hierarchy_depth_inter
=
220 pic
->pps
->sps
->max_transform_hierarchy_depth_inter
;
221 result
.max_transform_hierarchy_depth_intra
=
222 pic
->pps
->sps
->max_transform_hierarchy_depth_intra
;
223 result
.pcm_sample_bit_depth_luma_minus1
= pic
->pps
->sps
->pcm_sample_bit_depth_luma_minus1
;
224 result
.pcm_sample_bit_depth_chroma_minus1
=
225 pic
->pps
->sps
->pcm_sample_bit_depth_chroma_minus1
;
226 result
.log2_min_pcm_luma_coding_block_size_minus3
=
227 pic
->pps
->sps
->log2_min_pcm_luma_coding_block_size_minus3
;
228 result
.log2_diff_max_min_pcm_luma_coding_block_size
=
229 pic
->pps
->sps
->log2_diff_max_min_pcm_luma_coding_block_size
;
230 result
.num_short_term_ref_pic_sets
= pic
->pps
->sps
->num_short_term_ref_pic_sets
;
232 result
.pps_info_flags
= 0;
233 result
.pps_info_flags
|= pic
->pps
->dependent_slice_segments_enabled_flag
<< 0;
234 result
.pps_info_flags
|= pic
->pps
->output_flag_present_flag
<< 1;
235 result
.pps_info_flags
|= pic
->pps
->sign_data_hiding_enabled_flag
<< 2;
236 result
.pps_info_flags
|= pic
->pps
->cabac_init_present_flag
<< 3;
237 result
.pps_info_flags
|= pic
->pps
->constrained_intra_pred_flag
<< 4;
238 result
.pps_info_flags
|= pic
->pps
->transform_skip_enabled_flag
<< 5;
239 result
.pps_info_flags
|= pic
->pps
->cu_qp_delta_enabled_flag
<< 6;
240 result
.pps_info_flags
|= pic
->pps
->pps_slice_chroma_qp_offsets_present_flag
<< 7;
241 result
.pps_info_flags
|= pic
->pps
->weighted_pred_flag
<< 8;
242 result
.pps_info_flags
|= pic
->pps
->weighted_bipred_flag
<< 9;
243 result
.pps_info_flags
|= pic
->pps
->transquant_bypass_enabled_flag
<< 10;
244 result
.pps_info_flags
|= pic
->pps
->tiles_enabled_flag
<< 11;
245 result
.pps_info_flags
|= pic
->pps
->entropy_coding_sync_enabled_flag
<< 12;
246 result
.pps_info_flags
|= pic
->pps
->uniform_spacing_flag
<< 13;
247 result
.pps_info_flags
|= pic
->pps
->loop_filter_across_tiles_enabled_flag
<< 14;
248 result
.pps_info_flags
|= pic
->pps
->pps_loop_filter_across_slices_enabled_flag
<< 15;
249 result
.pps_info_flags
|= pic
->pps
->deblocking_filter_override_enabled_flag
<< 16;
250 result
.pps_info_flags
|= pic
->pps
->pps_deblocking_filter_disabled_flag
<< 17;
251 result
.pps_info_flags
|= pic
->pps
->lists_modification_present_flag
<< 18;
252 result
.pps_info_flags
|= pic
->pps
->slice_segment_header_extension_present_flag
<< 19;
254 result
.num_extra_slice_header_bits
= pic
->pps
->num_extra_slice_header_bits
;
255 result
.num_long_term_ref_pic_sps
= pic
->pps
->sps
->num_long_term_ref_pics_sps
;
256 result
.num_ref_idx_l0_default_active_minus1
= pic
->pps
->num_ref_idx_l0_default_active_minus1
;
257 result
.num_ref_idx_l1_default_active_minus1
= pic
->pps
->num_ref_idx_l1_default_active_minus1
;
258 result
.pps_cb_qp_offset
= pic
->pps
->pps_cb_qp_offset
;
259 result
.pps_cr_qp_offset
= pic
->pps
->pps_cr_qp_offset
;
260 result
.pps_beta_offset_div2
= pic
->pps
->pps_beta_offset_div2
;
261 result
.pps_tc_offset_div2
= pic
->pps
->pps_tc_offset_div2
;
262 result
.diff_cu_qp_delta_depth
= pic
->pps
->diff_cu_qp_delta_depth
;
263 result
.num_tile_columns_minus1
= pic
->pps
->num_tile_columns_minus1
;
264 result
.num_tile_rows_minus1
= pic
->pps
->num_tile_rows_minus1
;
265 result
.log2_parallel_merge_level_minus2
= pic
->pps
->log2_parallel_merge_level_minus2
;
266 result
.init_qp_minus26
= pic
->pps
->init_qp_minus26
;
268 for (i
= 0; i
< 19; ++i
)
269 result
.column_width_minus1
[i
] = pic
->pps
->column_width_minus1
[i
];
271 for (i
= 0; i
< 21; ++i
)
272 result
.row_height_minus1
[i
] = pic
->pps
->row_height_minus1
[i
];
274 result
.num_delta_pocs_ref_rps_idx
= pic
->NumDeltaPocsOfRefRpsIdx
;
275 result
.curr_idx
= pic
->CurrPicOrderCntVal
;
276 result
.curr_poc
= pic
->CurrPicOrderCntVal
;
278 vl_video_buffer_set_associated_data(target
, &dec
->base
,
279 (void *)(uintptr_t)pic
->CurrPicOrderCntVal
,
280 &radeon_dec_destroy_associated_data
);
282 for (i
= 0; i
< 16; ++i
) {
283 struct pipe_video_buffer
*ref
= pic
->ref
[i
];
284 uintptr_t ref_pic
= 0;
286 result
.poc_list
[i
] = pic
->PicOrderCntVal
[i
];
289 ref_pic
= (uintptr_t)vl_video_buffer_get_associated_data(ref
, &dec
->base
);
292 result
.ref_pic_list
[i
] = ref_pic
;
295 for (i
= 0; i
< 8; ++i
) {
296 result
.ref_pic_set_st_curr_before
[i
] = 0xFF;
297 result
.ref_pic_set_st_curr_after
[i
] = 0xFF;
298 result
.ref_pic_set_lt_curr
[i
] = 0xFF;
301 for (i
= 0; i
< pic
->NumPocStCurrBefore
; ++i
)
302 result
.ref_pic_set_st_curr_before
[i
] = pic
->RefPicSetStCurrBefore
[i
];
304 for (i
= 0; i
< pic
->NumPocStCurrAfter
; ++i
)
305 result
.ref_pic_set_st_curr_after
[i
] = pic
->RefPicSetStCurrAfter
[i
];
307 for (i
= 0; i
< pic
->NumPocLtCurr
; ++i
)
308 result
.ref_pic_set_lt_curr
[i
] = pic
->RefPicSetLtCurr
[i
];
310 for (i
= 0; i
< 6; ++i
)
311 result
.ucScalingListDCCoefSizeID2
[i
] = pic
->pps
->sps
->ScalingListDCCoeff16x16
[i
];
313 for (i
= 0; i
< 2; ++i
)
314 result
.ucScalingListDCCoefSizeID3
[i
] = pic
->pps
->sps
->ScalingListDCCoeff32x32
[i
];
316 memcpy(dec
->it
, pic
->pps
->sps
->ScalingList4x4
, 6 * 16);
317 memcpy(dec
->it
+ 96, pic
->pps
->sps
->ScalingList8x8
, 6 * 64);
318 memcpy(dec
->it
+ 480, pic
->pps
->sps
->ScalingList16x16
, 6 * 64);
319 memcpy(dec
->it
+ 864, pic
->pps
->sps
->ScalingList32x32
, 2 * 64);
321 for (i
= 0 ; i
< 2 ; i
++) {
322 for (int j
= 0 ; j
< 15 ; j
++)
323 result
.direct_reflist
[i
][j
] = pic
->RefPicList
[i
][j
];
326 if ((pic
->base
.profile
== PIPE_VIDEO_PROFILE_HEVC_MAIN_10
) &&
327 (target
->buffer_format
== PIPE_FORMAT_NV12
)) {
328 result
.p010_mode
= 0;
329 result
.luma_10to8
= 5;
330 result
.chroma_10to8
= 5;
331 result
.hevc_reserved
[0] = 4; /* sclr_luma10to8 */
332 result
.hevc_reserved
[1] = 4; /* sclr_chroma10to8 */
338 static unsigned calc_ctx_size_h265_main(struct radeon_decoder
*dec
)
340 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
341 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
343 unsigned max_references
= dec
->base
.max_references
+ 1;
345 if (dec
->base
.width
* dec
->base
.height
>= 4096*2000)
346 max_references
= MAX2(max_references
, 8);
348 max_references
= MAX2(max_references
, 17);
350 width
= align (width
, 16);
351 height
= align (height
, 16);
352 return ((width
+ 255) / 16) * ((height
+ 255) / 16) * 16 * max_references
+ 52 * 1024;
355 static unsigned calc_ctx_size_h265_main10(struct radeon_decoder
*dec
, struct pipe_h265_picture_desc
*pic
)
357 unsigned block_size
, log2_ctb_size
, width_in_ctb
, height_in_ctb
, num_16x16_block_per_ctb
;
358 unsigned context_buffer_size_per_ctb_row
, cm_buffer_size
, max_mb_address
, db_left_tile_pxl_size
;
359 unsigned db_left_tile_ctx_size
= 4096 / 16 * (32 + 16 * 4);
361 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
362 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
363 unsigned coeff_10bit
= (pic
->pps
->sps
->bit_depth_luma_minus8
||
364 pic
->pps
->sps
->bit_depth_chroma_minus8
) ? 2 : 1;
366 unsigned max_references
= dec
->base
.max_references
+ 1;
368 if (dec
->base
.width
* dec
->base
.height
>= 4096*2000)
369 max_references
= MAX2(max_references
, 8);
371 max_references
= MAX2(max_references
, 17);
373 block_size
= (1 << (pic
->pps
->sps
->log2_min_luma_coding_block_size_minus3
+ 3));
374 log2_ctb_size
= block_size
+ pic
->pps
->sps
->log2_diff_max_min_luma_coding_block_size
;
376 width_in_ctb
= (width
+ ((1 << log2_ctb_size
) - 1)) >> log2_ctb_size
;
377 height_in_ctb
= (height
+ ((1 << log2_ctb_size
) - 1)) >> log2_ctb_size
;
379 num_16x16_block_per_ctb
= ((1 << log2_ctb_size
) >> 4) * ((1 << log2_ctb_size
) >> 4);
380 context_buffer_size_per_ctb_row
= align(width_in_ctb
* num_16x16_block_per_ctb
* 16, 256);
381 max_mb_address
= (unsigned) ceil(height
* 8 / 2048.0);
383 cm_buffer_size
= max_references
* context_buffer_size_per_ctb_row
* height_in_ctb
;
384 db_left_tile_pxl_size
= coeff_10bit
* (max_mb_address
* 2 * 2048 + 1024);
386 return cm_buffer_size
+ db_left_tile_ctx_size
+ db_left_tile_pxl_size
;
389 static void rvcn_dec_message_create(struct radeon_decoder
*dec
)
391 rvcn_dec_message_header_t
*header
= dec
->msg
;
392 rvcn_dec_message_create_t
*create
= dec
->msg
+ sizeof(rvcn_dec_message_header_t
);
393 unsigned sizes
= sizeof(rvcn_dec_message_header_t
) + sizeof(rvcn_dec_message_create_t
);
395 memset(dec
->msg
, 0, sizes
);
396 header
->header_size
= sizeof(rvcn_dec_message_header_t
);
397 header
->total_size
= sizes
;
398 header
->num_buffers
= 1;
399 header
->msg_type
= RDECODE_MSG_CREATE
;
400 header
->stream_handle
= dec
->stream_handle
;
401 header
->status_report_feedback_number
= 0;
403 header
->index
[0].message_id
= RDECODE_MESSAGE_CREATE
;
404 header
->index
[0].offset
= sizeof(rvcn_dec_message_header_t
);
405 header
->index
[0].size
= sizeof(rvcn_dec_message_create_t
);
406 header
->index
[0].filled
= 0;
408 create
->stream_type
= dec
->stream_type
;
409 create
->session_flags
= 0;
410 create
->width_in_samples
= dec
->base
.width
;
411 create
->height_in_samples
= dec
->base
.height
;
414 static struct pb_buffer
*rvcn_dec_message_decode(struct radeon_decoder
*dec
,
415 struct pipe_video_buffer
*target
,
416 struct pipe_picture_desc
*picture
)
418 struct r600_texture
*luma
= (struct r600_texture
*)
419 ((struct vl_video_buffer
*)target
)->resources
[0];
420 struct r600_texture
*chroma
= (struct r600_texture
*)
421 ((struct vl_video_buffer
*)target
)->resources
[1];
422 rvcn_dec_message_header_t
*header
;
423 rvcn_dec_message_index_t
*index
;
424 rvcn_dec_message_decode_t
*decode
;
425 unsigned sizes
= 0, offset_decode
, offset_codec
;
429 sizes
+= sizeof(rvcn_dec_message_header_t
);
430 index
= (void*)header
+ sizeof(rvcn_dec_message_header_t
);
431 sizes
+= sizeof(rvcn_dec_message_index_t
);
432 offset_decode
= sizes
;
433 decode
= (void*)index
+ sizeof(rvcn_dec_message_index_t
);
434 sizes
+= sizeof(rvcn_dec_message_decode_t
);
435 offset_codec
= sizes
;
436 codec
= (void*)decode
+ sizeof(rvcn_dec_message_decode_t
);
438 memset(dec
->msg
, 0, sizes
);
439 header
->header_size
= sizeof(rvcn_dec_message_header_t
);
440 header
->total_size
= sizes
;
441 header
->num_buffers
= 2;
442 header
->msg_type
= RDECODE_MSG_DECODE
;
443 header
->stream_handle
= dec
->stream_handle
;
444 header
->status_report_feedback_number
= dec
->frame_number
;
446 header
->index
[0].message_id
= RDECODE_MESSAGE_DECODE
;
447 header
->index
[0].offset
= offset_decode
;
448 header
->index
[0].size
= sizeof(rvcn_dec_message_decode_t
);
449 header
->index
[0].filled
= 0;
451 index
->offset
= offset_codec
;
452 index
->size
= sizeof(rvcn_dec_message_avc_t
);
455 decode
->stream_type
= dec
->stream_type
;;
456 decode
->decode_flags
= 0x1;
457 decode
->width_in_samples
= dec
->base
.width
;;
458 decode
->height_in_samples
= dec
->base
.height
;;
460 decode
->bsd_size
= align(dec
->bs_size
, 128);
461 decode
->dpb_size
= dec
->dpb
.res
->buf
->size
;
463 ((struct r600_resource
*)((struct vl_video_buffer
*)target
)->resources
[0])->buf
->size
+
464 ((struct r600_resource
*)((struct vl_video_buffer
*)target
)->resources
[1])->buf
->size
;
466 decode
->sct_size
= 0;
467 decode
->sc_coeff_size
= 0;
469 decode
->sw_ctxt_size
= RDECODE_SESSION_CONTEXT_SIZE
;
470 decode
->db_pitch
= align(dec
->base
.width
, 32);
471 decode
->db_surf_tile_config
= 0;
473 decode
->dt_pitch
= luma
->surface
.u
.gfx9
.surf_pitch
* luma
->surface
.bpe
;;
474 decode
->dt_uv_pitch
= decode
->dt_pitch
/ 2;
476 decode
->dt_tiling_mode
= 0;
477 decode
->dt_swizzle_mode
= RDECODE_SW_MODE_LINEAR
;
478 decode
->dt_array_mode
= RDECODE_ARRAY_MODE_LINEAR
;
479 decode
->dt_field_mode
= ((struct vl_video_buffer
*)target
)->base
.interlaced
;
480 decode
->dt_surf_tile_config
= 0;
481 decode
->dt_uv_surf_tile_config
= 0;
483 decode
->dt_luma_top_offset
= luma
->surface
.u
.gfx9
.surf_offset
;
484 decode
->dt_chroma_top_offset
= chroma
->surface
.u
.gfx9
.surf_offset
;
485 if (decode
->dt_field_mode
) {
486 decode
->dt_luma_bottom_offset
= luma
->surface
.u
.gfx9
.surf_offset
+
487 luma
->surface
.u
.gfx9
.surf_slice_size
;
488 decode
->dt_chroma_bottom_offset
= chroma
->surface
.u
.gfx9
.surf_offset
+
489 chroma
->surface
.u
.gfx9
.surf_slice_size
;
491 decode
->dt_luma_bottom_offset
= decode
->dt_luma_top_offset
;
492 decode
->dt_chroma_bottom_offset
= decode
->dt_chroma_top_offset
;
495 switch (u_reduce_video_profile(picture
->profile
)) {
496 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
497 rvcn_dec_message_avc_t avc
=
498 get_h264_msg(dec
, (struct pipe_h264_picture_desc
*)picture
);
499 memcpy(codec
, (void*)&avc
, sizeof(rvcn_dec_message_avc_t
));
500 index
->message_id
= RDECODE_MESSAGE_AVC
;
503 case PIPE_VIDEO_FORMAT_HEVC
: {
504 rvcn_dec_message_hevc_t hevc
=
505 get_h265_msg(dec
, target
, (struct pipe_h265_picture_desc
*)picture
);
507 memcpy(codec
, (void*)&hevc
, sizeof(rvcn_dec_message_hevc_t
));
508 index
->message_id
= RDECODE_MESSAGE_HEVC
;
509 if (dec
->ctx
.res
== NULL
) {
511 if (dec
->base
.profile
== PIPE_VIDEO_PROFILE_HEVC_MAIN_10
)
512 ctx_size
= calc_ctx_size_h265_main10(dec
,
513 (struct pipe_h265_picture_desc
*)picture
);
515 ctx_size
= calc_ctx_size_h265_main(dec
);
516 if (!rvid_create_buffer(dec
->screen
, &dec
->ctx
, ctx_size
, PIPE_USAGE_DEFAULT
))
517 RVID_ERR("Can't allocated context buffer.\n");
518 rvid_clear_buffer(dec
->base
.context
, &dec
->ctx
);
528 decode
->hw_ctxt_size
= dec
->ctx
.res
->buf
->size
;
530 return luma
->resource
.buf
;
533 static void rvcn_dec_message_destroy(struct radeon_decoder
*dec
)
535 rvcn_dec_message_header_t
*header
= dec
->msg
;
537 memset(dec
->msg
, 0, sizeof(rvcn_dec_message_header_t
));
538 header
->header_size
= sizeof(rvcn_dec_message_header_t
);
539 header
->total_size
= sizeof(rvcn_dec_message_header_t
) -
540 sizeof(rvcn_dec_message_index_t
);
541 header
->num_buffers
= 0;
542 header
->msg_type
= RDECODE_MSG_DESTROY
;
543 header
->stream_handle
= dec
->stream_handle
;
544 header
->status_report_feedback_number
= 0;
547 static void rvcn_dec_message_feedback(struct radeon_decoder
*dec
)
549 rvcn_dec_feedback_header_t
*header
= (void*)dec
->fb
;
551 header
->header_size
= sizeof(rvcn_dec_feedback_header_t
);
552 header
->total_size
= sizeof(rvcn_dec_feedback_header_t
);
553 header
->num_buffers
= 0;
556 /* flush IB to the hardware */
557 static int flush(struct radeon_decoder
*dec
, unsigned flags
)
559 return dec
->ws
->cs_flush(dec
->cs
, flags
, NULL
);
562 /* add a new set register command to the IB */
563 static void set_reg(struct radeon_decoder
*dec
, unsigned reg
, uint32_t val
)
565 radeon_emit(dec
->cs
, RDECODE_PKT0(reg
>> 2, 0));
566 radeon_emit(dec
->cs
, val
);
569 /* send a command to the VCPU through the GPCOM registers */
570 static void send_cmd(struct radeon_decoder
*dec
, unsigned cmd
,
571 struct pb_buffer
* buf
, uint32_t off
,
572 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
576 dec
->ws
->cs_add_buffer(dec
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
,
577 domain
, RADEON_PRIO_UVD
);
578 addr
= dec
->ws
->buffer_get_virtual_address(buf
);
581 set_reg(dec
, RDECODE_GPCOM_VCPU_DATA0
, addr
);
582 set_reg(dec
, RDECODE_GPCOM_VCPU_DATA1
, addr
>> 32);
583 set_reg(dec
, RDECODE_GPCOM_VCPU_CMD
, cmd
<< 1);
586 /* do the codec needs an IT buffer ?*/
587 static bool have_it(struct radeon_decoder
*dec
)
589 return dec
->stream_type
== RDECODE_CODEC_H264_PERF
||
590 dec
->stream_type
== RDECODE_CODEC_H265
;
593 /* map the next available message/feedback/itscaling buffer */
594 static void map_msg_fb_it_buf(struct radeon_decoder
*dec
)
596 struct rvid_buffer
* buf
;
599 /* grab the current message/feedback buffer */
600 buf
= &dec
->msg_fb_it_buffers
[dec
->cur_buffer
];
602 /* and map it for CPU access */
603 ptr
= dec
->ws
->buffer_map(buf
->res
->buf
, dec
->cs
, PIPE_TRANSFER_WRITE
);
605 /* calc buffer offsets */
608 dec
->fb
= (uint32_t *)(ptr
+ FB_BUFFER_OFFSET
);
610 dec
->it
= (uint8_t *)(ptr
+ FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
);
613 /* unmap and send a message command to the VCPU */
614 static void send_msg_buf(struct radeon_decoder
*dec
)
616 struct rvid_buffer
* buf
;
618 /* ignore the request if message/feedback buffer isn't mapped */
619 if (!dec
->msg
|| !dec
->fb
)
622 /* grab the current message buffer */
623 buf
= &dec
->msg_fb_it_buffers
[dec
->cur_buffer
];
625 /* unmap the buffer */
626 dec
->ws
->buffer_unmap(buf
->res
->buf
);
631 if (dec
->sessionctx
.res
)
632 send_cmd(dec
, RDECODE_CMD_SESSION_CONTEXT_BUFFER
,
633 dec
->sessionctx
.res
->buf
, 0, RADEON_USAGE_READWRITE
,
636 /* and send it to the hardware */
637 send_cmd(dec
, RDECODE_CMD_MSG_BUFFER
, buf
->res
->buf
, 0,
638 RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
641 /* cycle to the next set of buffers */
642 static void next_buffer(struct radeon_decoder
*dec
)
645 dec
->cur_buffer
%= NUM_BUFFERS
;
648 static unsigned calc_ctx_size_h264_perf(struct radeon_decoder
*dec
)
650 unsigned width_in_mb
, height_in_mb
, ctx_size
;
651 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
652 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
654 unsigned max_references
= dec
->base
.max_references
+ 1;
656 // picture width & height in 16 pixel units
657 width_in_mb
= width
/ VL_MACROBLOCK_WIDTH
;
658 height_in_mb
= align(height
/ VL_MACROBLOCK_HEIGHT
, 2);
660 unsigned fs_in_mb
= width_in_mb
* height_in_mb
;
661 unsigned num_dpb_buffer
;
662 switch(dec
->base
.level
) {
664 num_dpb_buffer
= 8100 / fs_in_mb
;
667 num_dpb_buffer
= 18000 / fs_in_mb
;
670 num_dpb_buffer
= 20480 / fs_in_mb
;
673 num_dpb_buffer
= 32768 / fs_in_mb
;
676 num_dpb_buffer
= 34816 / fs_in_mb
;
679 num_dpb_buffer
= 110400 / fs_in_mb
;
682 num_dpb_buffer
= 184320 / fs_in_mb
;
685 num_dpb_buffer
= 184320 / fs_in_mb
;
689 max_references
= MAX2(MIN2(NUM_H264_REFS
, num_dpb_buffer
), max_references
);
690 ctx_size
= max_references
* align(width_in_mb
* height_in_mb
* 192, 256);
695 /* calculate size of reference picture buffer */
696 static unsigned calc_dpb_size(struct radeon_decoder
*dec
)
698 unsigned width_in_mb
, height_in_mb
, image_size
, dpb_size
;
700 // always align them to MB size for dpb calculation
701 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
702 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
704 // always one more for currently decoded picture
705 unsigned max_references
= dec
->base
.max_references
+ 1;
707 // aligned size of a single frame
708 image_size
= align(width
, 32) * height
;
709 image_size
+= image_size
/ 2;
710 image_size
= align(image_size
, 1024);
712 // picture width & height in 16 pixel units
713 width_in_mb
= width
/ VL_MACROBLOCK_WIDTH
;
714 height_in_mb
= align(height
/ VL_MACROBLOCK_HEIGHT
, 2);
716 switch (u_reduce_video_profile(dec
->base
.profile
)) {
717 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
718 unsigned fs_in_mb
= width_in_mb
* height_in_mb
;
719 unsigned num_dpb_buffer
;
721 switch(dec
->base
.level
) {
723 num_dpb_buffer
= 8100 / fs_in_mb
;
726 num_dpb_buffer
= 18000 / fs_in_mb
;
729 num_dpb_buffer
= 20480 / fs_in_mb
;
732 num_dpb_buffer
= 32768 / fs_in_mb
;
735 num_dpb_buffer
= 34816 / fs_in_mb
;
738 num_dpb_buffer
= 110400 / fs_in_mb
;
741 num_dpb_buffer
= 184320 / fs_in_mb
;
744 num_dpb_buffer
= 184320 / fs_in_mb
;
748 max_references
= MAX2(MIN2(NUM_H264_REFS
, num_dpb_buffer
), max_references
);
749 dpb_size
= image_size
* max_references
;
753 case PIPE_VIDEO_FORMAT_HEVC
:
754 if (dec
->base
.width
* dec
->base
.height
>= 4096*2000)
755 max_references
= MAX2(max_references
, 8);
757 max_references
= MAX2(max_references
, 17);
759 width
= align (width
, 16);
760 height
= align (height
, 16);
761 if (dec
->base
.profile
== PIPE_VIDEO_PROFILE_HEVC_MAIN_10
)
762 dpb_size
= align((align(width
, 32) * height
* 9) / 4, 256) * max_references
;
764 dpb_size
= align((align(width
, 32) * height
* 3) / 2, 256) * max_references
;
767 case PIPE_VIDEO_FORMAT_VC1
:
768 // the firmware seems to allways assume a minimum of ref frames
769 max_references
= MAX2(NUM_VC1_REFS
, max_references
);
771 // reference picture buffer
772 dpb_size
= image_size
* max_references
;
775 dpb_size
+= width_in_mb
* height_in_mb
* 128;
778 dpb_size
+= width_in_mb
* 64;
781 dpb_size
+= width_in_mb
* 128;
784 dpb_size
+= align(MAX2(width_in_mb
, height_in_mb
) * 7 * 16, 64);
787 case PIPE_VIDEO_FORMAT_MPEG12
:
788 // reference picture buffer, must be big enough for all frames
789 dpb_size
= image_size
* NUM_MPEG2_REFS
;
792 case PIPE_VIDEO_FORMAT_MPEG4
:
793 // reference picture buffer
794 dpb_size
= image_size
* max_references
;
797 dpb_size
+= width_in_mb
* height_in_mb
* 64;
800 dpb_size
+= align(width_in_mb
* height_in_mb
* 32, 64);
802 dpb_size
= MAX2(dpb_size
, 30 * 1024 * 1024);
806 // something is missing here
809 // at least use a sane default value
810 dpb_size
= 32 * 1024 * 1024;
817 * destroy this video decoder
819 static void radeon_dec_destroy(struct pipe_video_codec
*decoder
)
821 struct radeon_decoder
*dec
= (struct radeon_decoder
*)decoder
;
826 map_msg_fb_it_buf(dec
);
827 rvcn_dec_message_destroy(dec
);
832 dec
->ws
->cs_destroy(dec
->cs
);
834 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
835 rvid_destroy_buffer(&dec
->msg_fb_it_buffers
[i
]);
836 rvid_destroy_buffer(&dec
->bs_buffers
[i
]);
839 rvid_destroy_buffer(&dec
->dpb
);
840 rvid_destroy_buffer(&dec
->ctx
);
841 rvid_destroy_buffer(&dec
->sessionctx
);
847 * start decoding of a new frame
849 static void radeon_dec_begin_frame(struct pipe_video_codec
*decoder
,
850 struct pipe_video_buffer
*target
,
851 struct pipe_picture_desc
*picture
)
853 struct radeon_decoder
*dec
= (struct radeon_decoder
*)decoder
;
858 frame
= ++dec
->frame_number
;
859 vl_video_buffer_set_associated_data(target
, decoder
, (void *)frame
,
860 &radeon_dec_destroy_associated_data
);
863 dec
->bs_ptr
= dec
->ws
->buffer_map(
864 dec
->bs_buffers
[dec
->cur_buffer
].res
->buf
,
865 dec
->cs
, PIPE_TRANSFER_WRITE
);
869 * decode a macroblock
871 static void radeon_dec_decode_macroblock(struct pipe_video_codec
*decoder
,
872 struct pipe_video_buffer
*target
,
873 struct pipe_picture_desc
*picture
,
874 const struct pipe_macroblock
*macroblocks
,
875 unsigned num_macroblocks
)
877 /* not supported (yet) */
884 static void radeon_dec_decode_bitstream(struct pipe_video_codec
*decoder
,
885 struct pipe_video_buffer
*target
,
886 struct pipe_picture_desc
*picture
,
887 unsigned num_buffers
,
888 const void * const *buffers
,
889 const unsigned *sizes
)
891 struct radeon_decoder
*dec
= (struct radeon_decoder
*)decoder
;
899 for (i
= 0; i
< num_buffers
; ++i
) {
900 struct rvid_buffer
*buf
= &dec
->bs_buffers
[dec
->cur_buffer
];
901 unsigned new_size
= dec
->bs_size
+ sizes
[i
];
903 if (new_size
> buf
->res
->buf
->size
) {
904 dec
->ws
->buffer_unmap(buf
->res
->buf
);
905 if (!rvid_resize_buffer(dec
->screen
, dec
->cs
, buf
, new_size
)) {
906 RVID_ERR("Can't resize bitstream buffer!");
910 dec
->bs_ptr
= dec
->ws
->buffer_map(buf
->res
->buf
, dec
->cs
,
911 PIPE_TRANSFER_WRITE
);
915 dec
->bs_ptr
+= dec
->bs_size
;
918 memcpy(dec
->bs_ptr
, buffers
[i
], sizes
[i
]);
919 dec
->bs_size
+= sizes
[i
];
920 dec
->bs_ptr
+= sizes
[i
];
925 * end decoding of the current frame
927 static void radeon_dec_end_frame(struct pipe_video_codec
*decoder
,
928 struct pipe_video_buffer
*target
,
929 struct pipe_picture_desc
*picture
)
931 struct radeon_decoder
*dec
= (struct radeon_decoder
*)decoder
;
932 struct pb_buffer
*dt
;
933 struct rvid_buffer
*msg_fb_it_buf
, *bs_buf
;
940 msg_fb_it_buf
= &dec
->msg_fb_it_buffers
[dec
->cur_buffer
];
941 bs_buf
= &dec
->bs_buffers
[dec
->cur_buffer
];
943 memset(dec
->bs_ptr
, 0, align(dec
->bs_size
, 128) - dec
->bs_size
);
944 dec
->ws
->buffer_unmap(bs_buf
->res
->buf
);
946 map_msg_fb_it_buf(dec
);
947 dt
= rvcn_dec_message_decode(dec
, target
, picture
);
948 rvcn_dec_message_feedback(dec
);
951 send_cmd(dec
, RDECODE_CMD_DPB_BUFFER
, dec
->dpb
.res
->buf
, 0,
952 RADEON_USAGE_READWRITE
, RADEON_DOMAIN_VRAM
);
954 send_cmd(dec
, RDECODE_CMD_CONTEXT_BUFFER
, dec
->ctx
.res
->buf
, 0,
955 RADEON_USAGE_READWRITE
, RADEON_DOMAIN_VRAM
);
956 send_cmd(dec
, RDECODE_CMD_BITSTREAM_BUFFER
, bs_buf
->res
->buf
,
957 0, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
958 send_cmd(dec
, RDECODE_CMD_DECODING_TARGET_BUFFER
, dt
, 0,
959 RADEON_USAGE_WRITE
, RADEON_DOMAIN_VRAM
);
960 send_cmd(dec
, RDECODE_CMD_FEEDBACK_BUFFER
, msg_fb_it_buf
->res
->buf
,
961 FB_BUFFER_OFFSET
, RADEON_USAGE_WRITE
, RADEON_DOMAIN_GTT
);
963 send_cmd(dec
, RDECODE_CMD_IT_SCALING_TABLE_BUFFER
, msg_fb_it_buf
->res
->buf
,
964 FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
965 set_reg(dec
, RDECODE_ENGINE_CNTL
, 1);
967 flush(dec
, RADEON_FLUSH_ASYNC
);
972 * flush any outstanding command buffers to the hardware
974 static void radeon_dec_flush(struct pipe_video_codec
*decoder
)
979 * create and HW decoder
981 struct pipe_video_codec
*radeon_create_decoder(struct pipe_context
*context
,
982 const struct pipe_video_codec
*templ
)
984 struct radeon_winsys
* ws
= ((struct r600_common_context
*)context
)->ws
;
985 struct r600_common_context
*rctx
= (struct r600_common_context
*)context
;
986 unsigned width
= templ
->width
, height
= templ
->height
;
987 unsigned dpb_size
, bs_buf_size
, stream_type
= 0;
988 struct radeon_decoder
*dec
;
991 switch(u_reduce_video_profile(templ
->profile
)) {
992 case PIPE_VIDEO_FORMAT_MPEG12
:
993 if (templ
->entrypoint
> PIPE_VIDEO_ENTRYPOINT_BITSTREAM
)
994 return vl_create_mpeg12_decoder(context
, templ
);
995 stream_type
= RDECODE_CODEC_MPEG2_VLD
;
997 case PIPE_VIDEO_FORMAT_MPEG4
:
998 width
= align(width
, VL_MACROBLOCK_WIDTH
);
999 height
= align(height
, VL_MACROBLOCK_HEIGHT
);
1000 stream_type
= RDECODE_CODEC_MPEG4
;
1002 case PIPE_VIDEO_FORMAT_VC1
:
1003 stream_type
= RDECODE_CODEC_VC1
;
1005 case PIPE_VIDEO_FORMAT_MPEG4_AVC
:
1006 width
= align(width
, VL_MACROBLOCK_WIDTH
);
1007 height
= align(height
, VL_MACROBLOCK_HEIGHT
);
1008 stream_type
= RDECODE_CODEC_H264_PERF
;
1010 case PIPE_VIDEO_FORMAT_HEVC
:
1011 stream_type
= RDECODE_CODEC_H265
;
1018 dec
= CALLOC_STRUCT(radeon_decoder
);
1024 dec
->base
.context
= context
;
1025 dec
->base
.width
= width
;
1026 dec
->base
.height
= height
;
1028 dec
->base
.destroy
= radeon_dec_destroy
;
1029 dec
->base
.begin_frame
= radeon_dec_begin_frame
;
1030 dec
->base
.decode_macroblock
= radeon_dec_decode_macroblock
;
1031 dec
->base
.decode_bitstream
= radeon_dec_decode_bitstream
;
1032 dec
->base
.end_frame
= radeon_dec_end_frame
;
1033 dec
->base
.flush
= radeon_dec_flush
;
1035 dec
->stream_type
= stream_type
;
1036 dec
->stream_handle
= rvid_alloc_stream_handle();
1037 dec
->screen
= context
->screen
;
1039 dec
->cs
= ws
->cs_create(rctx
->ctx
, RING_VCN_DEC
, NULL
, NULL
);
1041 RVID_ERR("Can't get command submission context.\n");
1045 bs_buf_size
= width
* height
* (512 / (16 * 16));
1046 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
1047 unsigned msg_fb_it_size
= FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
;
1049 msg_fb_it_size
+= IT_SCALING_TABLE_SIZE
;
1050 if (!rvid_create_buffer(dec
->screen
, &dec
->msg_fb_it_buffers
[i
],
1051 msg_fb_it_size
, PIPE_USAGE_STAGING
)) {
1052 RVID_ERR("Can't allocated message buffers.\n");
1056 if (!rvid_create_buffer(dec
->screen
, &dec
->bs_buffers
[i
],
1057 bs_buf_size
, PIPE_USAGE_STAGING
)) {
1058 RVID_ERR("Can't allocated bitstream buffers.\n");
1062 rvid_clear_buffer(context
, &dec
->msg_fb_it_buffers
[i
]);
1063 rvid_clear_buffer(context
, &dec
->bs_buffers
[i
]);
1066 dpb_size
= calc_dpb_size(dec
);
1068 if (!rvid_create_buffer(dec
->screen
, &dec
->dpb
, dpb_size
, PIPE_USAGE_DEFAULT
)) {
1069 RVID_ERR("Can't allocated dpb.\n");
1073 rvid_clear_buffer(context
, &dec
->dpb
);
1075 if (dec
->stream_type
== RDECODE_CODEC_H264_PERF
) {
1076 unsigned ctx_size
= calc_ctx_size_h264_perf(dec
);
1077 if (!rvid_create_buffer(dec
->screen
, &dec
->ctx
, ctx_size
, PIPE_USAGE_DEFAULT
)) {
1078 RVID_ERR("Can't allocated context buffer.\n");
1081 rvid_clear_buffer(context
, &dec
->ctx
);
1084 if (!rvid_create_buffer(dec
->screen
, &dec
->sessionctx
,
1085 RDECODE_SESSION_CONTEXT_SIZE
,
1086 PIPE_USAGE_DEFAULT
)) {
1087 RVID_ERR("Can't allocated session ctx.\n");
1090 rvid_clear_buffer(context
, &dec
->sessionctx
);
1092 map_msg_fb_it_buf(dec
);
1093 rvcn_dec_message_create(dec
);
1104 if (dec
->cs
) dec
->ws
->cs_destroy(dec
->cs
);
1106 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
1107 rvid_destroy_buffer(&dec
->msg_fb_it_buffers
[i
]);
1108 rvid_destroy_buffer(&dec
->bs_buffers
[i
]);
1111 rvid_destroy_buffer(&dec
->dpb
);
1112 rvid_destroy_buffer(&dec
->ctx
);
1113 rvid_destroy_buffer(&dec
->sessionctx
);