[Libva] [Libva-intel-driver PATCH 17/27] HEVC: gen9_hcpd_slice_state()
Xiang, Haihao
haihao.xiang at intel.com
Wed Nov 19 07:05:32 PST 2014
Set slice parameters in HCP_SLICE_STATE
Signed-off-by: Xiang, Haihao <haihao.xiang at intel.com>
---
src/gen9_mfd.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 153 insertions(+), 1 deletion(-)
diff --git a/src/gen9_mfd.c b/src/gen9_mfd.c
index 58a677c..09e19de 100644
--- a/src/gen9_mfd.c
+++ b/src/gen9_mfd.c
@@ -681,6 +681,147 @@ gen9_hcpd_weightoffset_state(VADriverContextP ctx,
gen9_hcpd_weightoffset_state_1(batch, 1, slice_param);
}
+static int
+gen9_hcpd_get_collocated_ref_idx(VADriverContextP ctx,
+ VAPictureParameterBufferHEVC *pic_param,
+ VASliceParameterBufferHEVC *slice_param,
+ struct gen9_hcpd_context *gen9_hcpd_context)
+{
+ uint8_t *ref_list;
+ VAPictureHEVC *ref_pic;
+
+ if (slice_param->collocated_ref_idx > 14)
+ return 0;
+
+ if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_I)
+ return 0;
+
+ if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P ||
+ (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_B &&
+ slice_param->LongSliceFlags.fields.collocated_from_l0_flag))
+ ref_list = slice_param->RefPicList[0];
+ else {
+ assert(slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_B);
+ ref_list = slice_param->RefPicList[1];
+ }
+
+ ref_pic = &pic_param->ReferenceFrames[ref_list[slice_param->collocated_ref_idx]];
+
+ return gen9_hcpd_get_reference_picture_frame_id(ref_pic, gen9_hcpd_context->reference_surfaces);
+}
+
+static int
+gen9_hcpd_is_list_low_delay(uint8_t ref_list_count,
+ uint8_t ref_list[15],
+ VAPictureHEVC *curr_pic,
+ VAPictureHEVC ref_surfaces[15])
+{
+ int i;
+
+ for (i = 0; i < MIN(ref_list_count, 15); i++) {
+ VAPictureHEVC *ref_pic;
+
+ if (ref_list[i] > 14)
+ continue;
+
+ ref_pic = &ref_surfaces[ref_list[i]];
+
+ if (ref_pic->pic_order_cnt > curr_pic->pic_order_cnt)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+gen9_hcpd_is_low_delay(VADriverContextP ctx,
+ VAPictureParameterBufferHEVC *pic_param,
+ VASliceParameterBufferHEVC *slice_param)
+{
+ if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_I)
+ return 0;
+ else if (slice_param->LongSliceFlags.fields.slice_type == HEVC_SLICE_P)
+ return gen9_hcpd_is_list_low_delay(slice_param->num_ref_idx_l0_active_minus1 + 1,
+ slice_param->RefPicList[0],
+ &pic_param->CurrPic,
+ pic_param->ReferenceFrames);
+ else
+ return gen9_hcpd_is_list_low_delay(slice_param->num_ref_idx_l0_active_minus1 + 1,
+ slice_param->RefPicList[0],
+ &pic_param->CurrPic,
+ pic_param->ReferenceFrames) &&
+ gen9_hcpd_is_list_low_delay(slice_param->num_ref_idx_l1_active_minus1 + 1,
+ slice_param->RefPicList[1],
+ &pic_param->CurrPic,
+ pic_param->ReferenceFrames);
+}
+
+static void
+gen9_hcpd_slice_state(VADriverContextP ctx,
+ VAPictureParameterBufferHEVC *pic_param,
+ VASliceParameterBufferHEVC *slice_param,
+ VASliceParameterBufferHEVC *next_slice_param,
+ struct gen9_hcpd_context *gen9_hcpd_context)
+{
+ struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
+ int slice_hor_pos, slice_ver_pos, next_slice_hor_pos, next_slice_ver_pos;
+
+ slice_hor_pos = slice_param->slice_segment_address % gen9_hcpd_context->picture_width_in_ctbs;
+ slice_ver_pos = slice_param->slice_segment_address / gen9_hcpd_context->picture_width_in_ctbs;
+
+ if (next_slice_param) {
+ next_slice_hor_pos = next_slice_param->slice_segment_address % gen9_hcpd_context->picture_width_in_ctbs;
+ next_slice_ver_pos = next_slice_param->slice_segment_address / gen9_hcpd_context->picture_width_in_ctbs;
+ } else {
+ next_slice_hor_pos = 0;
+ next_slice_ver_pos = 0;
+ }
+
+ BEGIN_BCS_BATCH(batch, 9);
+
+ OUT_BCS_BATCH(batch, HCP_SLICE_STATE | (9 - 2));
+
+ OUT_BCS_BATCH(batch,
+ slice_ver_pos << 16 |
+ slice_hor_pos);
+ OUT_BCS_BATCH(batch,
+ next_slice_ver_pos << 16 |
+ next_slice_hor_pos);
+ OUT_BCS_BATCH(batch,
+ (slice_param->slice_cr_qp_offset & 0x1f) << 17 |
+ (slice_param->slice_cb_qp_offset & 0x1f) << 12 |
+ (pic_param->init_qp_minus26 + 26 + slice_param->slice_qp_delta) << 6 |
+ slice_param->LongSliceFlags.fields.slice_temporal_mvp_enabled_flag << 5 |
+ slice_param->LongSliceFlags.fields.dependent_slice_segment_flag << 4 |
+ !next_slice_param << 2 |
+ slice_param->LongSliceFlags.fields.slice_type);
+ OUT_BCS_BATCH(batch,
+ gen9_hcpd_get_collocated_ref_idx(ctx, pic_param, slice_param, gen9_hcpd_context) << 26 |
+ (5 - slice_param->five_minus_max_num_merge_cand - 1) << 23 |
+ slice_param->LongSliceFlags.fields.cabac_init_flag << 22 |
+ slice_param->luma_log2_weight_denom << 19 |
+ (slice_param->luma_log2_weight_denom + slice_param->delta_chroma_log2_weight_denom) << 16 |
+ slice_param->LongSliceFlags.fields.collocated_from_l0_flag << 15 |
+ gen9_hcpd_is_low_delay(ctx, pic_param, slice_param) << 14 |
+ slice_param->LongSliceFlags.fields.mvd_l1_zero_flag << 13 |
+ slice_param->LongSliceFlags.fields.slice_sao_luma_flag << 12 |
+ slice_param->LongSliceFlags.fields.slice_sao_chroma_flag << 11 |
+ slice_param->LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag << 10 |
+ (slice_param->slice_beta_offset_div2 & 0xf) << 5 |
+ (slice_param->slice_tc_offset_div2 & 0xf) << 1 |
+ slice_param->LongSliceFlags.fields.slice_deblocking_filter_disabled_flag);
+ OUT_BCS_BATCH(batch,
+ slice_param->slice_data_byte_offset); /* DW 5 */
+ OUT_BCS_BATCH(batch,
+ 0 << 26 |
+ 0 << 20 |
+ 0);
+ OUT_BCS_BATCH(batch, 0); /* Ignored for decoding */
+ OUT_BCS_BATCH(batch, 0); /* Ignored for decoding */
+
+ ADVANCE_BCS_BATCH(batch);
+}
+
static VAStatus
gen9_hcpd_hevc_decode_picture(VADriverContextP ctx,
struct decode_state *decode_state,
@@ -689,7 +830,7 @@ gen9_hcpd_hevc_decode_picture(VADriverContextP ctx,
VAStatus vaStatus;
struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch;
VAPictureParameterBufferHEVC *pic_param;
- VASliceParameterBufferHEVC *slice_param;
+ VASliceParameterBufferHEVC *slice_param, *next_slice_param, *next_slice_group_param;
dri_bo *slice_data_bo;
int i, j;
@@ -719,7 +860,18 @@ gen9_hcpd_hevc_decode_picture(VADriverContextP ctx,
gen9_hcpd_ind_obj_base_addr_state(ctx, slice_data_bo, gen9_hcpd_context);
+ if (j == decode_state->num_slice_params - 1)
+ next_slice_group_param = NULL;
+ else
+ next_slice_group_param = (VASliceParameterBufferHEVC *)decode_state->slice_params[j + 1]->buffer;
+
for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
+ if (i < decode_state->slice_params[j]->num_elements - 1)
+ next_slice_param = slice_param + 1;
+ else
+ next_slice_param = next_slice_group_param;
+
+ gen9_hcpd_slice_state(ctx, pic_param, slice_param, next_slice_param, gen9_hcpd_context);
gen9_hcpd_ref_idx_state(ctx, pic_param, slice_param, gen9_hcpd_context);
gen9_hcpd_weightoffset_state(ctx, slice_param, gen9_hcpd_context);
slice_param++;
--
1.9.1
More information about the Libva
mailing list