radeon/uvd: implement HEVC support

add context buffer to fix H265 uvd decode issue.
fix H265 corruption issue caused by incorrect assigned ref_pic_list.

v2: disable interlace for HEVC
    add CZ sps flag workaround
    fix coding style

Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Boyuan Zhang <boyuan.zhang@amd.com>
Reviewed-by: Leo Liu <leo.liu@amd.com>
This commit is contained in:
Boyuan Zhang 2015-07-08 16:54:48 -04:00 committed by Marek Olšák
parent 0654a9ca17
commit 839bf82606
3 changed files with 298 additions and 17 deletions

View file

@ -57,7 +57,7 @@
#define FB_BUFFER_OFFSET 0x1000
#define FB_BUFFER_SIZE 2048
#define IT_SCALING_TABLE_SIZE 224
#define IT_SCALING_TABLE_SIZE 992
/* UVD decoder representation */
struct ruvd_decoder {
@ -86,6 +86,7 @@ struct ruvd_decoder {
struct rvid_buffer dpb;
bool use_legacy;
struct rvid_buffer ctx;
};
/* flush IB to the hardware */
@ -124,6 +125,13 @@ static void send_cmd(struct ruvd_decoder *dec, unsigned cmd,
set_reg(dec, RUVD_GPCOM_VCPU_CMD, cmd << 1);
}
/* do the codec needs an IT buffer ?*/
static bool have_it(struct ruvd_decoder *dec)
{
return dec->stream_type == RUVD_CODEC_H264_PERF ||
dec->stream_type == RUVD_CODEC_H265;
}
/* map the next available message/feedback/itscaling buffer */
static void map_msg_fb_it_buf(struct ruvd_decoder *dec)
{
@ -139,7 +147,7 @@ static void map_msg_fb_it_buf(struct ruvd_decoder *dec)
/* calc buffer offsets */
dec->msg = (struct ruvd_msg *)ptr;
dec->fb = (uint32_t *)(ptr + FB_BUFFER_OFFSET);
if (dec->stream_type == RUVD_CODEC_H264_PERF)
if (have_it(dec))
dec->it = (uint8_t *)(ptr + FB_BUFFER_OFFSET + FB_BUFFER_SIZE);
}
@ -159,8 +167,7 @@ static void send_msg_buf(struct ruvd_decoder *dec)
dec->ws->buffer_unmap(buf->res->cs_buf);
dec->msg = NULL;
dec->fb = NULL;
if (dec->stream_type == RUVD_CODEC_H264_PERF)
dec->it = NULL;
dec->it = NULL;
/* and send it to the hardware */
send_cmd(dec, RUVD_CMD_MSG_BUFFER, buf->res->cs_buf, 0,
@ -191,12 +198,35 @@ static uint32_t profile2stream_type(struct ruvd_decoder *dec, unsigned family)
case PIPE_VIDEO_FORMAT_MPEG4:
return RUVD_CODEC_MPEG4;
case PIPE_VIDEO_FORMAT_HEVC:
return RUVD_CODEC_H265;
default:
assert(0);
return 0;
}
}
static unsigned calc_ctx_size(struct ruvd_decoder *dec)
{
unsigned width_in_mb, height_in_mb, ctx_size;
unsigned width = align(dec->base.width, VL_MACROBLOCK_WIDTH);
unsigned height = align(dec->base.height, VL_MACROBLOCK_HEIGHT);
unsigned max_references = dec->base.max_references + 1;
if (dec->base.width * dec->base.height >= 4096*2000)
max_references = MAX2(max_references, 8);
else
max_references = MAX2(max_references, 17);
width = align (width, 16);
height = align (height, 16);
ctx_size = ((width + 255) / 16)*((height + 255) / 16) * 16 * max_references + 52 * 1024;
return ctx_size;
}
/* calculate size of reference picture buffer */
static unsigned calc_dpb_size(struct ruvd_decoder *dec)
{
@ -270,6 +300,17 @@ static unsigned calc_dpb_size(struct ruvd_decoder *dec)
break;
}
case PIPE_VIDEO_FORMAT_HEVC:
if (dec->base.width * dec->base.height >= 4096*2000)
max_references = MAX2(max_references, 8);
else
max_references = MAX2(max_references, 17);
width = align (width, 16);
height = align (height, 16);
dpb_size = align((width * height * 3) / 2, 256) * max_references;
break;
case PIPE_VIDEO_FORMAT_VC1:
// the firmware seems to allways assume a minimum of ref frames
max_references = MAX2(NUM_VC1_REFS, max_references);
@ -319,6 +360,12 @@ static unsigned calc_dpb_size(struct ruvd_decoder *dec)
return dpb_size;
}
/* free associated data in the video buffer callback */
static void ruvd_destroy_associated_data(void *data)
{
/* NOOP, since we only use an intptr */
}
/* get h264 specific message bits */
static struct ruvd_h264 get_h264_msg(struct ruvd_decoder *dec, struct pipe_h264_picture_desc *pic)
{
@ -392,6 +439,11 @@ static struct ruvd_h264 get_h264_msg(struct ruvd_decoder *dec, struct pipe_h264_
memcpy(result.scaling_list_4x4, pic->pps->ScalingList4x4, 6*16);
memcpy(result.scaling_list_8x8, pic->pps->ScalingList8x8, 2*64);
if (dec->stream_type == RUVD_CODEC_H264_PERF) {
memcpy(dec->it, result.scaling_list_4x4, 6*16);
memcpy((dec->it + 96), result.scaling_list_8x8, 2*64);
}
result.num_ref_frames = pic->num_ref_frames;
result.num_ref_idx_l0_active_minus1 = pic->num_ref_idx_l0_active_minus1;
@ -408,6 +460,151 @@ static struct ruvd_h264 get_h264_msg(struct ruvd_decoder *dec, struct pipe_h264_
return result;
}
/* get h265 specific message bits */
static struct ruvd_h265 get_h265_msg(struct ruvd_decoder *dec, struct pipe_video_buffer *target,
struct pipe_h265_picture_desc *pic)
{
struct ruvd_h265 result;
unsigned i;
memset(&result, 0, sizeof(result));
result.sps_info_flags = 0;
result.sps_info_flags |= pic->pps->sps->scaling_list_enabled_flag << 0;
result.sps_info_flags |= pic->pps->sps->amp_enabled_flag << 1;
result.sps_info_flags |= pic->pps->sps->sample_adaptive_offset_enabled_flag << 2;
result.sps_info_flags |= pic->pps->sps->pcm_enabled_flag << 3;
result.sps_info_flags |= pic->pps->sps->pcm_loop_filter_disabled_flag << 4;
result.sps_info_flags |= pic->pps->sps->long_term_ref_pics_present_flag << 5;
result.sps_info_flags |= pic->pps->sps->sps_temporal_mvp_enabled_flag << 6;
result.sps_info_flags |= pic->pps->sps->strong_intra_smoothing_enabled_flag << 7;
result.sps_info_flags |= pic->pps->sps->separate_colour_plane_flag << 8;
if (((struct r600_common_screen*)dec->screen)->family == CHIP_CARRIZO)
result.sps_info_flags |= 1 << 9;
result.chroma_format = pic->pps->sps->chroma_format_idc;
result.bit_depth_luma_minus8 = pic->pps->sps->bit_depth_luma_minus8;
result.bit_depth_chroma_minus8 = pic->pps->sps->bit_depth_chroma_minus8;
result.log2_max_pic_order_cnt_lsb_minus4 = pic->pps->sps->log2_max_pic_order_cnt_lsb_minus4;
result.sps_max_dec_pic_buffering_minus1 = pic->pps->sps->sps_max_dec_pic_buffering_minus1;
result.log2_min_luma_coding_block_size_minus3 = pic->pps->sps->log2_min_luma_coding_block_size_minus3;
result.log2_diff_max_min_luma_coding_block_size = pic->pps->sps->log2_diff_max_min_luma_coding_block_size;
result.log2_min_transform_block_size_minus2 = pic->pps->sps->log2_min_transform_block_size_minus2;
result.log2_diff_max_min_transform_block_size = pic->pps->sps->log2_diff_max_min_transform_block_size;
result.max_transform_hierarchy_depth_inter = pic->pps->sps->max_transform_hierarchy_depth_inter;
result.max_transform_hierarchy_depth_intra = pic->pps->sps->max_transform_hierarchy_depth_intra;
result.pcm_sample_bit_depth_luma_minus1 = pic->pps->sps->pcm_sample_bit_depth_luma_minus1;
result.pcm_sample_bit_depth_chroma_minus1 = pic->pps->sps->pcm_sample_bit_depth_chroma_minus1;
result.log2_min_pcm_luma_coding_block_size_minus3 = pic->pps->sps->log2_min_pcm_luma_coding_block_size_minus3;
result.log2_diff_max_min_pcm_luma_coding_block_size = pic->pps->sps->log2_diff_max_min_pcm_luma_coding_block_size;
result.num_short_term_ref_pic_sets = pic->pps->sps->num_short_term_ref_pic_sets;
result.pps_info_flags = 0;
result.pps_info_flags |= pic->pps->dependent_slice_segments_enabled_flag << 0;
result.pps_info_flags |= pic->pps->output_flag_present_flag << 1;
result.pps_info_flags |= pic->pps->sign_data_hiding_enabled_flag << 2;
result.pps_info_flags |= pic->pps->cabac_init_present_flag << 3;
result.pps_info_flags |= pic->pps->constrained_intra_pred_flag << 4;
result.pps_info_flags |= pic->pps->transform_skip_enabled_flag << 5;
result.pps_info_flags |= pic->pps->cu_qp_delta_enabled_flag << 6;
result.pps_info_flags |= pic->pps->pps_slice_chroma_qp_offsets_present_flag << 7;
result.pps_info_flags |= pic->pps->weighted_pred_flag << 8;
result.pps_info_flags |= pic->pps->weighted_bipred_flag << 9;
result.pps_info_flags |= pic->pps->transquant_bypass_enabled_flag << 10;
result.pps_info_flags |= pic->pps->tiles_enabled_flag << 11;
result.pps_info_flags |= pic->pps->entropy_coding_sync_enabled_flag << 12;
result.pps_info_flags |= pic->pps->uniform_spacing_flag << 13;
result.pps_info_flags |= pic->pps->loop_filter_across_tiles_enabled_flag << 14;
result.pps_info_flags |= pic->pps->pps_loop_filter_across_slices_enabled_flag << 15;
result.pps_info_flags |= pic->pps->deblocking_filter_override_enabled_flag << 16;
result.pps_info_flags |= pic->pps->pps_deblocking_filter_disabled_flag << 17;
result.pps_info_flags |= pic->pps->lists_modification_present_flag << 18;
result.pps_info_flags |= pic->pps->slice_segment_header_extension_present_flag << 19;
//result.pps_info_flags |= pic->pps->deblocking_filter_control_present_flag; ???
result.num_extra_slice_header_bits = pic->pps->num_extra_slice_header_bits;
result.num_long_term_ref_pic_sps = pic->pps->sps->num_long_term_ref_pics_sps;
result.num_ref_idx_l0_default_active_minus1 = pic->pps->num_ref_idx_l0_default_active_minus1;
result.num_ref_idx_l1_default_active_minus1 = pic->pps->num_ref_idx_l1_default_active_minus1;
result.pps_cb_qp_offset = pic->pps->pps_cb_qp_offset;
result.pps_cr_qp_offset = pic->pps->pps_cr_qp_offset;
result.pps_beta_offset_div2 = pic->pps->pps_beta_offset_div2;
result.pps_tc_offset_div2 = pic->pps->pps_tc_offset_div2;
result.diff_cu_qp_delta_depth = pic->pps->diff_cu_qp_delta_depth;
result.num_tile_columns_minus1 = pic->pps->num_tile_columns_minus1;
result.num_tile_rows_minus1 = pic->pps->num_tile_rows_minus1;
result.log2_parallel_merge_level_minus2 = pic->pps->log2_parallel_merge_level_minus2;
result.init_qp_minus26 = pic->pps->init_qp_minus26;
for (i = 0; i < 19; ++i)
result.column_width_minus1[i] = pic->pps->column_width_minus1[i];
for (i = 0; i < 21; ++i)
result.row_height_minus1[i] = pic->pps->row_height_minus1[i];
result.num_delta_pocs_ref_rps_idx = pic->NumDeltaPocsOfRefRpsIdx;
result.curr_idx = pic->CurrPicOrderCntVal;
result.curr_poc = pic->CurrPicOrderCntVal;
vl_video_buffer_set_associated_data(target, &dec->base,
(void *)(uintptr_t)pic->CurrPicOrderCntVal,
&ruvd_destroy_associated_data);
for (i = 0; i < 16; ++i) {
struct pipe_video_buffer *ref = pic->ref[i];
uintptr_t ref_pic = 0;
result.poc_list[i] = pic->PicOrderCntVal[i];
if (ref)
ref_pic = (uintptr_t)vl_video_buffer_get_associated_data(ref, &dec->base);
else
ref_pic = 0x7F;
result.ref_pic_list[i] = ref_pic;
}
for (i = 0; i < 8; ++i) {
result.ref_pic_set_st_curr_before[i] = 0xFF;
result.ref_pic_set_st_curr_after[i] = 0xFF;
result.ref_pic_set_lt_curr[i] = 0xFF;
}
for (i = 0; i < pic->NumPocStCurrBefore; ++i)
result.ref_pic_set_st_curr_before[i] = pic->RefPicSetStCurrBefore[i];
for (i = 0; i < pic->NumPocStCurrAfter; ++i)
result.ref_pic_set_st_curr_after[i] = pic->RefPicSetStCurrAfter[i];
for (i = 0; i < pic->NumPocLtCurr; ++i)
result.ref_pic_set_lt_curr[i] = pic->RefPicSetLtCurr[i];
for (i = 0; i < 6; ++i)
result.ucScalingListDCCoefSizeID2[i] = pic->pps->sps->ScalingListDCCoeff16x16[i];
for (i = 0; i < 2; ++i)
result.ucScalingListDCCoefSizeID3[i] = pic->pps->sps->ScalingListDCCoeff32x32[i];
memcpy(dec->it, pic->pps->sps->ScalingList4x4, 6 * 16);
memcpy(dec->it + 96, pic->pps->sps->ScalingList8x8, 6 * 64);
memcpy(dec->it + 480, pic->pps->sps->ScalingList16x16, 6 * 64);
memcpy(dec->it + 864, pic->pps->sps->ScalingList32x32, 2 * 64);
/* TODO
result.highestTid;
result.isNonRef;
IDRPicFlag;
RAPPicFlag;
NumPocTotalCurr;
NumShortTermPictureSliceHeaderBits;
NumLongTermPictureSliceHeaderBits;
IsLongTerm[16];
*/
return result;
}
/* get vc1 specific message bits */
static struct ruvd_vc1 get_vc1_msg(struct pipe_vc1_picture_desc *pic)
{
@ -627,16 +824,12 @@ static void ruvd_destroy(struct pipe_video_codec *decoder)
}
rvid_destroy_buffer(&dec->dpb);
if (u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_FORMAT_HEVC)
rvid_destroy_buffer(&dec->ctx);
FREE(dec);
}
/* free associated data in the video buffer callback */
static void ruvd_destroy_associated_data(void *data)
{
/* NOOP, since we only use an intptr */
}
/**
* start decoding of a new frame
*/
@ -759,10 +952,10 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder,
switch (u_reduce_video_profile(picture->profile)) {
case PIPE_VIDEO_FORMAT_MPEG4_AVC:
dec->msg->body.decode.codec.h264 = get_h264_msg(dec, (struct pipe_h264_picture_desc*)picture);
if (dec->stream_type == RUVD_CODEC_H264_PERF) {
memcpy(dec->it, dec->msg->body.decode.codec.h264.scaling_list_4x4, 6*16);
memcpy((dec->it + 96), dec->msg->body.decode.codec.h264.scaling_list_8x8, 2*64);
}
break;
case PIPE_VIDEO_FORMAT_HEVC:
dec->msg->body.decode.codec.h265 = get_h265_msg(dec, target, (struct pipe_h265_picture_desc*)picture);
break;
case PIPE_VIDEO_FORMAT_VC1:
@ -792,13 +985,17 @@ static void ruvd_end_frame(struct pipe_video_codec *decoder,
send_cmd(dec, RUVD_CMD_DPB_BUFFER, dec->dpb.res->cs_buf, 0,
RADEON_USAGE_READWRITE, RADEON_DOMAIN_VRAM);
if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) {
send_cmd(dec, RUVD_CMD_CONTEXT_BUFFER, dec->ctx.res->cs_buf, 0,
RADEON_USAGE_READWRITE, RADEON_DOMAIN_VRAM);
}
send_cmd(dec, RUVD_CMD_BITSTREAM_BUFFER, bs_buf->res->cs_buf,
0, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
send_cmd(dec, RUVD_CMD_DECODING_TARGET_BUFFER, dt, 0,
RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
send_cmd(dec, RUVD_CMD_FEEDBACK_BUFFER, msg_fb_it_buf->res->cs_buf,
FB_BUFFER_OFFSET, RADEON_USAGE_WRITE, RADEON_DOMAIN_GTT);
if (dec->stream_type == RUVD_CODEC_H264_PERF)
if (have_it(dec))
send_cmd(dec, RUVD_CMD_ITSCALING_TABLE_BUFFER, msg_fb_it_buf->res->cs_buf,
FB_BUFFER_OFFSET + FB_BUFFER_SIZE, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
set_reg(dec, RUVD_ENGINE_CNTL, 1);
@ -884,7 +1081,7 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context,
for (i = 0; i < NUM_BUFFERS; ++i) {
unsigned msg_fb_it_size = FB_BUFFER_OFFSET + FB_BUFFER_SIZE;
STATIC_ASSERT(sizeof(struct ruvd_msg) <= FB_BUFFER_OFFSET);
if (dec->stream_type == RUVD_CODEC_H264_PERF)
if (have_it(dec))
msg_fb_it_size += IT_SCALING_TABLE_SIZE;
if (!rvid_create_buffer(dec->screen, &dec->msg_fb_it_buffers[i],
msg_fb_it_size, PIPE_USAGE_STAGING)) {
@ -911,6 +1108,15 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context,
rvid_clear_buffer(context, &dec->dpb);
if (u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_FORMAT_HEVC) {
unsigned ctx_size = calc_ctx_size(dec);
if (!rvid_create_buffer(dec->screen, &dec->ctx, ctx_size, PIPE_USAGE_DEFAULT)) {
RVID_ERR("Can't allocated context buffer.\n");
goto error;
}
rvid_clear_buffer(context, &dec->ctx);
}
map_msg_fb_it_buf(dec);
dec->msg->size = sizeof(*dec->msg);
dec->msg->msg_type = RUVD_MSG_CREATE;
@ -918,7 +1124,7 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context,
dec->msg->body.create.stream_type = dec->stream_type;
dec->msg->body.create.width_in_samples = dec->base.width;
dec->msg->body.create.height_in_samples = dec->base.height;
dec->msg->body.create.dpb_size = dec->dpb.res->buf->size;
dec->msg->body.create.dpb_size = dpb_size;
send_msg_buf(dec);
flush(dec);
next_buffer(dec);
@ -934,6 +1140,8 @@ error:
}
rvid_destroy_buffer(&dec->dpb);
if (u_reduce_video_profile(dec->base.profile) == PIPE_VIDEO_FORMAT_HEVC)
rvid_destroy_buffer(&dec->ctx);
FREE(dec);

View file

@ -63,6 +63,7 @@
#define RUVD_CMD_FEEDBACK_BUFFER 0x00000003
#define RUVD_CMD_BITSTREAM_BUFFER 0x00000100
#define RUVD_CMD_ITSCALING_TABLE_BUFFER 0x00000204
#define RUVD_CMD_CONTEXT_BUFFER 0x00000206
/* UVD message types */
#define RUVD_MSG_CREATE 0
@ -75,6 +76,7 @@
#define RUVD_CODEC_MPEG2 0x00000003
#define RUVD_CODEC_MPEG4 0x00000004
#define RUVD_CODEC_H264_PERF 0x00000007
#define RUVD_CODEC_H265 0x00000010
/* UVD decode target buffer tiling mode */
#define RUVD_TILE_LINEAR 0x00000000
@ -173,6 +175,66 @@ struct ruvd_h264 {
} mvc;
};
struct ruvd_h265 {
uint32_t sps_info_flags;
uint32_t pps_info_flags;
uint8_t chroma_format;
uint8_t bit_depth_luma_minus8;
uint8_t bit_depth_chroma_minus8;
uint8_t log2_max_pic_order_cnt_lsb_minus4;
uint8_t sps_max_dec_pic_buffering_minus1;
uint8_t log2_min_luma_coding_block_size_minus3;
uint8_t log2_diff_max_min_luma_coding_block_size;
uint8_t log2_min_transform_block_size_minus2;
uint8_t log2_diff_max_min_transform_block_size;
uint8_t max_transform_hierarchy_depth_inter;
uint8_t max_transform_hierarchy_depth_intra;
uint8_t pcm_sample_bit_depth_luma_minus1;
uint8_t pcm_sample_bit_depth_chroma_minus1;
uint8_t log2_min_pcm_luma_coding_block_size_minus3;
uint8_t log2_diff_max_min_pcm_luma_coding_block_size;
uint8_t num_extra_slice_header_bits;
uint8_t num_short_term_ref_pic_sets;
uint8_t num_long_term_ref_pic_sps;
uint8_t num_ref_idx_l0_default_active_minus1;
uint8_t num_ref_idx_l1_default_active_minus1;
int8_t pps_cb_qp_offset;
int8_t pps_cr_qp_offset;
int8_t pps_beta_offset_div2;
int8_t pps_tc_offset_div2;
uint8_t diff_cu_qp_delta_depth;
uint8_t num_tile_columns_minus1;
uint8_t num_tile_rows_minus1;
uint8_t log2_parallel_merge_level_minus2;
uint16_t column_width_minus1[19];
uint16_t row_height_minus1[21];
int8_t init_qp_minus26;
uint8_t num_delta_pocs_ref_rps_idx;
uint8_t curr_idx;
uint8_t reserved1;
int32_t curr_poc;
uint8_t ref_pic_list[16];
int32_t poc_list[16];
uint8_t ref_pic_set_st_curr_before[8];
uint8_t ref_pic_set_st_curr_after[8];
uint8_t ref_pic_set_lt_curr[8];
uint8_t ucScalingListDCCoefSizeID2[6];
uint8_t ucScalingListDCCoefSizeID3[2];
uint8_t highestTid;
uint8_t isNonRef;
};
struct ruvd_vc1 {
uint32_t profile;
uint32_t level;
@ -329,6 +391,7 @@ struct ruvd_msg {
union {
struct ruvd_h264 h264;
struct ruvd_h265 h265;
struct ruvd_vc1 vc1;
struct ruvd_mpeg2 mpeg2;
struct ruvd_mpeg4 mpeg4;

View file

@ -264,6 +264,10 @@ int rvid_get_video_param(struct pipe_screen *screen,
/* FIXME: VC-1 simple/main profile is broken */
return profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED &&
entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE;
case PIPE_VIDEO_FORMAT_HEVC:
/* Carrizo only supports HEVC Main */
return rscreen->family >= CHIP_CARRIZO &&
profile == PIPE_VIDEO_PROFILE_HEVC_MAIN;
default:
return false;
}
@ -276,8 +280,12 @@ int rvid_get_video_param(struct pipe_screen *screen,
case PIPE_VIDEO_CAP_PREFERED_FORMAT:
return PIPE_FORMAT_NV12;
case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
if (u_reduce_video_profile(profile) == PIPE_VIDEO_FORMAT_HEVC)
return false; //The hardware doesn't support interlaced HEVC.
return true;
case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
if (u_reduce_video_profile(profile) == PIPE_VIDEO_FORMAT_HEVC)
return false; //The hardware doesn't support interlaced HEVC.
return true;
case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
return true;
@ -302,6 +310,8 @@ int rvid_get_video_param(struct pipe_screen *screen,
case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
return 41;
case PIPE_VIDEO_PROFILE_HEVC_MAIN:
return 186;
default:
return 0;
}