summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPengfei Qu <Pengfei.Qu@intel.com>2016-12-28 13:46:13 +0800
committerSean V Kelley <seanvk@posteo.de>2017-01-10 15:22:26 -0800
commitfc3c465caaac5202e69ebca006c525321475c148 (patch)
tree1e6aab2ce09450e43da8542eeeee3e9d070f3b67
parentf704bff5dd4ea3dc6c899c93506ee52b4d0ef558 (diff)
ENC: add MFX command for AVC encoder
Signed-off-by: Pengfei Qu <Pengfei.Qu@intel.com> Reviewed-by: Sean V Kelley <seanvk@posteo.de>
-rwxr-xr-xsrc/gen9_avc_encoder.c561
1 files changed, 561 insertions, 0 deletions
diff --git a/src/gen9_avc_encoder.c b/src/gen9_avc_encoder.c
index 8b11c5a..ccbd26c 100755
--- a/src/gen9_avc_encoder.c
+++ b/src/gen9_avc_encoder.c
@@ -6024,3 +6024,564 @@ gen9_mfc_avc_fqm_state(VADriverContextP ctx,
gen9_mfc_fqm_state(ctx, MFX_QM_AVC_8x8_INTER_MATRIX, fqm, 32, encoder_context);
}
}
+
+static void
+gen9_mfc_avc_insert_object(VADriverContextP ctx,
+ struct intel_encoder_context *encoder_context,
+ unsigned int *insert_data, int lenght_in_dws, int data_bits_in_last_dw,
+ int skip_emul_byte_count, int is_last_header, int is_end_of_slice, int emulation_flag,
+ int slice_header_indicator)
+{
+ struct intel_batchbuffer *batch = encoder_context->base.batch;
+
+ if (data_bits_in_last_dw == 0)
+ data_bits_in_last_dw = 32;
+
+ BEGIN_BCS_BATCH(batch, lenght_in_dws + 2);
+
+ OUT_BCS_BATCH(batch, MFX_INSERT_OBJECT | (lenght_in_dws));
+ OUT_BCS_BATCH(batch,
+ (0 << 16) | /* always start at offset 0 */
+ (slice_header_indicator << 14) |
+ (data_bits_in_last_dw << 8) |
+ (skip_emul_byte_count << 4) |
+ (!!emulation_flag << 3) |
+ ((!!is_last_header) << 2) |
+ ((!!is_end_of_slice) << 1) |
+ (0 << 0)); /* TODO: check this flag */
+ intel_batchbuffer_data(batch, insert_data, lenght_in_dws * 4);
+
+ ADVANCE_BCS_BATCH(batch);
+}
+
+static void
+gen9_mfc_avc_insert_slice_packed_data(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ int slice_index)
+{
+ VAEncPackedHeaderParameterBuffer *param = NULL;
+ unsigned int length_in_bits;
+ unsigned int *header_data = NULL;
+ int count, i, start_index;
+ int slice_header_index;
+
+ if (encode_state->slice_header_index[slice_index] == 0)
+ slice_header_index = -1;
+ else
+ slice_header_index = (encode_state->slice_header_index[slice_index] & SLICE_PACKED_DATA_INDEX_MASK);
+
+ count = encode_state->slice_rawdata_count[slice_index];
+ start_index = (encode_state->slice_rawdata_index[slice_index] & SLICE_PACKED_DATA_INDEX_MASK);
+
+ for (i = 0; i < count; i++) {
+ unsigned int skip_emul_byte_cnt;
+
+ header_data = (unsigned int *)encode_state->packed_header_data_ext[start_index + i]->buffer;
+
+ param = (VAEncPackedHeaderParameterBuffer *)(encode_state->packed_header_params_ext[start_index + i]->buffer);
+
+ /* skip the slice header packed data type as it is lastly inserted */
+ if (param->type == VAEncPackedHeaderSlice)
+ continue;
+
+ length_in_bits = param->bit_length;
+
+ skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits);
+
+ /* as the slice header is still required, the last header flag is set to
+ * zero.
+ */
+ gen9_mfc_avc_insert_object(ctx,
+ encoder_context,
+ header_data,
+ ALIGN(length_in_bits, 32) >> 5,
+ length_in_bits & 0x1f,
+ skip_emul_byte_cnt,
+ 0,
+ 0,
+ !param->has_emulation_bytes,
+ 0);
+ }
+
+ if (slice_header_index == -1) {
+ VAEncSequenceParameterBufferH264 *seq_param = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
+ VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
+ VAEncSliceParameterBufferH264 *slice_params = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[slice_index]->buffer;
+ unsigned char *slice_header = NULL;
+ int slice_header_length_in_bits = 0;
+
+ /* No slice header data is passed. And the driver needs to generate it */
+ /* For the Normal H264 */
+ slice_header_length_in_bits = build_avc_slice_header(seq_param,
+ pic_param,
+ slice_params,
+ &slice_header);
+ gen9_mfc_avc_insert_object(ctx,
+ encoder_context,
+ (unsigned int *)slice_header,
+ ALIGN(slice_header_length_in_bits, 32) >> 5,
+ slice_header_length_in_bits & 0x1f,
+ 5, /* first 5 bytes are start code + nal unit type */
+ 1, 0, 1,
+ 1);
+
+ free(slice_header);
+ } else {
+ unsigned int skip_emul_byte_cnt;
+
+ header_data = (unsigned int *)encode_state->packed_header_data_ext[slice_header_index]->buffer;
+
+ param = (VAEncPackedHeaderParameterBuffer *)(encode_state->packed_header_params_ext[slice_header_index]->buffer);
+ length_in_bits = param->bit_length;
+
+ /* as the slice header is the last header data for one slice,
+ * the last header flag is set to one.
+ */
+ skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits);
+
+ gen9_mfc_avc_insert_object(ctx,
+ encoder_context,
+ header_data,
+ ALIGN(length_in_bits, 32) >> 5,
+ length_in_bits & 0x1f,
+ skip_emul_byte_cnt,
+ 1,
+ 0,
+ !param->has_emulation_bytes,
+ 1);
+ }
+
+ return;
+}
+
+static void
+gen9_mfc_avc_inset_headers(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ VAEncSliceParameterBufferH264 *slice_param,
+ int slice_index)
+{
+ struct encoder_vme_mfc_context * pak_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
+ struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )pak_context->generic_enc_state;
+ int idx = va_enc_packed_type_to_idx(VAEncPackedHeaderH264_SPS);
+ unsigned int internal_rate_mode = generic_state->internal_rate_mode;
+ unsigned int skip_emul_byte_cnt;
+
+ if (slice_index == 0) {
+ if (encode_state->packed_header_data[idx]) {
+ VAEncPackedHeaderParameterBuffer *param = NULL;
+ unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
+ unsigned int length_in_bits;
+
+ assert(encode_state->packed_header_param[idx]);
+ param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
+ length_in_bits = param->bit_length;
+
+ skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits);
+ gen9_mfc_avc_insert_object(ctx,
+ encoder_context,
+ header_data,
+ ALIGN(length_in_bits, 32) >> 5,
+ length_in_bits & 0x1f,
+ skip_emul_byte_cnt,
+ 0,
+ 0,
+ !param->has_emulation_bytes,
+ 0);
+ }
+
+ idx = va_enc_packed_type_to_idx(VAEncPackedHeaderH264_PPS);
+
+ if (encode_state->packed_header_data[idx]) {
+ VAEncPackedHeaderParameterBuffer *param = NULL;
+ unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
+ unsigned int length_in_bits;
+
+ assert(encode_state->packed_header_param[idx]);
+ param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
+ length_in_bits = param->bit_length;
+
+ skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits);
+
+ gen9_mfc_avc_insert_object(ctx,
+ encoder_context,
+ header_data,
+ ALIGN(length_in_bits, 32) >> 5,
+ length_in_bits & 0x1f,
+ skip_emul_byte_cnt,
+ 0,
+ 0,
+ !param->has_emulation_bytes,
+ 0);
+ }
+
+ idx = va_enc_packed_type_to_idx(VAEncPackedHeaderH264_SEI);
+
+ if (encode_state->packed_header_data[idx]) {
+ VAEncPackedHeaderParameterBuffer *param = NULL;
+ unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[idx]->buffer;
+ unsigned int length_in_bits;
+
+ assert(encode_state->packed_header_param[idx]);
+ param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[idx]->buffer;
+ length_in_bits = param->bit_length;
+
+ skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits);
+ gen9_mfc_avc_insert_object(ctx,
+ encoder_context,
+ header_data,
+ ALIGN(length_in_bits, 32) >> 5,
+ length_in_bits & 0x1f,
+ skip_emul_byte_cnt,
+ 0,
+ 0,
+ !param->has_emulation_bytes,
+ 0);
+ } else if (internal_rate_mode == INTEL_BRC_CBR) {
+ /* TODO: insert others */
+ }
+ }
+
+ gen9_mfc_avc_insert_slice_packed_data(ctx,
+ encode_state,
+ encoder_context,
+ slice_index);
+}
+
+static void
+gen9_mfc_avc_slice_state(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ VAEncPictureParameterBufferH264 *pic_param,
+ VAEncSliceParameterBufferH264 *slice_param,
+ VAEncSliceParameterBufferH264 *next_slice_param)
+{
+ struct encoder_vme_mfc_context * pak_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
+ struct gen9_avc_encoder_context * avc_ctx = (struct gen9_avc_encoder_context * )pak_context->private_enc_ctx;
+ struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )pak_context->generic_enc_state;
+ struct avc_enc_state * avc_state = (struct avc_enc_state * )pak_context->private_enc_state;
+ struct intel_batchbuffer *batch = encoder_context->base.batch;
+ unsigned int luma_log2_weight_denom = slice_param->luma_log2_weight_denom;
+ unsigned int chroma_log2_weight_denom = slice_param->chroma_log2_weight_denom;
+ unsigned char correct[6], grow, shrink;
+ int slice_hor_pos, slice_ver_pos, next_slice_hor_pos, next_slice_ver_pos;
+ int max_qp_n, max_qp_p;
+ int i;
+ int weighted_pred_idc = 0;
+ int num_ref_l0 = 0, num_ref_l1 = 0;
+ int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
+ int slice_qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
+ unsigned int rounding_value = 0;
+ unsigned int rounding_inter_enable = 0;
+
+ //check the inter rounding
+ if(generic_state->frame_type == SLICE_TYPE_P)
+ {
+ if(avc_state->rounding_inter_p == AVC_INVALID_ROUNDING_VALUE)
+ {
+ if(avc_state->adaptive_rounding_inter_enable && !(generic_state->brc_enabled))
+ {
+ if(generic_state->gop_ref_distance == 1)
+ avc_state->rounding_value = gen9_avc_adaptive_inter_rounding_p_without_b[slice_qp];
+ else
+ avc_state->rounding_value = gen9_avc_adaptive_inter_rounding_p[slice_qp];
+ }
+ else
+ {
+ avc_state->rounding_value = gen9_avc_inter_rounding_p[generic_state->preset];
+ }
+
+ }else
+ {
+ avc_state->rounding_value = avc_state->rounding_inter_p;
+ }
+ }else if(generic_state->frame_type == SLICE_TYPE_B)
+ {
+ if(pic_param->pic_fields.bits.reference_pic_flag)
+ {
+ if(avc_state->rounding_inter_b_ref == AVC_INVALID_ROUNDING_VALUE)
+ avc_state->rounding_value = gen9_avc_inter_rounding_b_ref[generic_state->preset];
+ else
+ avc_state->rounding_value = avc_state->rounding_inter_b_ref;
+ }
+ else
+ {
+ if(avc_state->rounding_inter_b == AVC_INVALID_ROUNDING_VALUE)
+ {
+ if(avc_state->adaptive_rounding_inter_enable && !(generic_state->brc_enabled))
+ avc_state->rounding_value = gen9_avc_adaptive_inter_rounding_b[slice_qp];
+ else
+ avc_state->rounding_value = gen9_avc_inter_rounding_b[generic_state->preset];
+ }else
+ {
+ avc_state->rounding_value = avc_state->rounding_inter_b;
+ }
+ }
+ }
+
+ slice_hor_pos = slice_param->macroblock_address % generic_state->frame_width_in_mbs;
+ slice_ver_pos = slice_param->macroblock_address / generic_state->frame_height_in_mbs;
+
+ if (next_slice_param) {
+ next_slice_hor_pos = next_slice_param->macroblock_address % generic_state->frame_width_in_mbs;
+ next_slice_ver_pos = next_slice_param->macroblock_address / generic_state->frame_height_in_mbs;
+ } else {
+ next_slice_hor_pos = 0;
+ next_slice_ver_pos = generic_state->frame_height_in_mbs;
+ }
+
+ if (slice_type == SLICE_TYPE_I) {
+ luma_log2_weight_denom = 0;
+ chroma_log2_weight_denom = 0;
+ } else if (slice_type == SLICE_TYPE_P) {
+ weighted_pred_idc = pic_param->pic_fields.bits.weighted_pred_flag;
+ num_ref_l0 = pic_param->num_ref_idx_l0_active_minus1 + 1;
+ rounding_inter_enable = avc_state->rounding_inter_enable;
+ rounding_value = avc_state->rounding_value;
+
+ if (slice_param->num_ref_idx_active_override_flag)
+ num_ref_l0 = slice_param->num_ref_idx_l0_active_minus1 + 1;
+ } else if (slice_type == SLICE_TYPE_B) {
+ weighted_pred_idc = pic_param->pic_fields.bits.weighted_bipred_idc;
+ num_ref_l0 = pic_param->num_ref_idx_l0_active_minus1 + 1;
+ num_ref_l1 = pic_param->num_ref_idx_l1_active_minus1 + 1;
+ rounding_inter_enable = avc_state->rounding_inter_enable;
+ rounding_value = avc_state->rounding_value;
+
+ if (slice_param->num_ref_idx_active_override_flag) {
+ num_ref_l0 = slice_param->num_ref_idx_l0_active_minus1 + 1;
+ num_ref_l1 = slice_param->num_ref_idx_l1_active_minus1 + 1;
+ }
+
+ if (weighted_pred_idc == 2) {
+ /* 8.4.3 - Derivation process for prediction weights (8-279) */
+ luma_log2_weight_denom = 5;
+ chroma_log2_weight_denom = 5;
+ }
+ }
+
+ max_qp_n = 0; /* TODO: update it */
+ max_qp_p = 0; /* TODO: update it */
+ grow = 0; /* TODO: update it */
+ shrink = 0; /* TODO: update it */
+
+ for (i = 0; i < 6; i++)
+ correct[i] = 0; /* TODO: update it */
+
+ BEGIN_BCS_BATCH(batch, 11);
+
+ OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2) );
+ OUT_BCS_BATCH(batch, slice_type);
+ OUT_BCS_BATCH(batch,
+ (num_ref_l1 << 24) |
+ (num_ref_l0 << 16) |
+ (chroma_log2_weight_denom << 8) |
+ (luma_log2_weight_denom << 0));
+ OUT_BCS_BATCH(batch,
+ (weighted_pred_idc << 30) |
+ (((slice_type == SLICE_TYPE_B)?slice_param->direct_spatial_mv_pred_flag:0) << 29) |
+ (slice_param->disable_deblocking_filter_idc << 27) |
+ (slice_param->cabac_init_idc << 24) |
+ (slice_qp << 16) |
+ ((slice_param->slice_beta_offset_div2 & 0xf) << 8) |
+ ((slice_param->slice_alpha_c0_offset_div2 & 0xf) << 0));
+
+ OUT_BCS_BATCH(batch,
+ slice_ver_pos << 24 |
+ slice_hor_pos << 16 |
+ slice_param->macroblock_address);
+ OUT_BCS_BATCH(batch,
+ next_slice_ver_pos << 16 |
+ next_slice_hor_pos);
+
+ OUT_BCS_BATCH(batch,
+ (0 << 31) | /* TODO: ignore it for VDENC ??? */
+ (1 << 30) | /* ResetRateControlCounter */
+ (2 << 28) | /* Loose Rate Control */
+ (0 << 24) | /* RC Stable Tolerance */
+ (0 << 23) | /* RC Panic Enable */
+ (1 << 22) | /* CBP mode */
+ (0 << 21) | /* MB Type Direct Conversion, 0: Enable, 1: Disable */
+ (0 << 20) | /* MB Type Skip Conversion, 0: Enable, 1: Disable */
+ (!next_slice_param << 19) | /* Is Last Slice */
+ (0 << 18) | /* BitstreamOutputFlag Compressed BitStream Output Disable Flag 0:enable 1:disable */
+ (1 << 17) | /* HeaderPresentFlag */
+ (1 << 16) | /* SliceData PresentFlag */
+ (0 << 15) | /* TailPresentFlag, TODO: check it on VDEnc */
+ (1 << 13) | /* RBSP NAL TYPE */
+ (1 << 12)); /* CabacZeroWordInsertionEnable */
+
+ OUT_BCS_BATCH(batch, avc_ctx->compressed_bitstream.start_offset);
+
+ OUT_BCS_BATCH(batch,
+ (max_qp_n << 24) | /*Target QP - 24 is lowest QP*/
+ (max_qp_p << 16) | /*Target QP + 20 is highest QP*/
+ (shrink << 8) |
+ (grow << 0));
+ OUT_BCS_BATCH(batch,
+ (rounding_inter_enable << 31) |
+ (rounding_value << 28) |
+ (1 << 27) |
+ (5 << 24) |
+ (correct[5] << 20) |
+ (correct[4] << 16) |
+ (correct[3] << 12) |
+ (correct[2] << 8) |
+ (correct[1] << 4) |
+ (correct[0] << 0));
+ OUT_BCS_BATCH(batch, 0);
+
+ ADVANCE_BCS_BATCH(batch);
+}
+
+static uint8_t
+gen9_mfc_avc_get_ref_idx_state(VAPictureH264 *va_pic, unsigned int frame_store_id)
+{
+ unsigned int is_long_term =
+ !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
+ unsigned int is_top_field =
+ !!(va_pic->flags & VA_PICTURE_H264_TOP_FIELD);
+ unsigned int is_bottom_field =
+ !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD);
+
+ return ((is_long_term << 6) |
+ (0 << 5) |
+ (frame_store_id << 1) |
+ ((is_top_field ^ 1) & is_bottom_field));
+}
+
+static void
+gen9_mfc_avc_ref_idx_state(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ VAEncSliceParameterBufferH264 *slice_param)
+{
+ struct encoder_vme_mfc_context * pak_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context;
+ struct avc_enc_state * avc_state = (struct avc_enc_state * )pak_context->private_enc_state;
+ struct intel_batchbuffer *batch = encoder_context->base.batch;
+ VAPictureH264 *ref_pic;
+ int i, slice_type, ref_idx_shift;
+ unsigned int fwd_ref_entry;
+ unsigned int bwd_ref_entry;
+
+ /* max 4 ref frames are allowed for l0 and l1 */
+ fwd_ref_entry = 0x80808080;
+ slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
+
+ if ((slice_type == SLICE_TYPE_P) ||
+ (slice_type == SLICE_TYPE_B)) {
+ for (i = 0; i < avc_state->num_refs[0]; i++) {
+ ref_pic = &slice_param->RefPicList0[i];
+ ref_idx_shift = i * 8;
+
+ fwd_ref_entry &= ~(0xFF << ref_idx_shift);
+ fwd_ref_entry += (gen9_mfc_avc_get_ref_idx_state(ref_pic, avc_state->list_ref_idx[0][i]) << ref_idx_shift);
+ }
+ }
+
+ bwd_ref_entry = 0x80808080;
+ if (slice_type == SLICE_TYPE_B) {
+ for (i = 0; i < avc_state->num_refs[1]; i++) {
+ ref_pic = &slice_param->RefPicList1[i];
+ ref_idx_shift = i * 8;
+
+ bwd_ref_entry &= ~(0xFF << ref_idx_shift);
+ bwd_ref_entry += (gen9_mfc_avc_get_ref_idx_state(ref_pic, avc_state->list_ref_idx[1][i]) << ref_idx_shift);
+ }
+ }
+
+ if ((slice_type == SLICE_TYPE_P) ||
+ (slice_type == SLICE_TYPE_B)) {
+ BEGIN_BCS_BATCH(batch, 10);
+ OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | 8);
+ OUT_BCS_BATCH(batch, 0); // L0
+ OUT_BCS_BATCH(batch, fwd_ref_entry);
+
+ for (i = 0; i < 7; i++) {
+ OUT_BCS_BATCH(batch, 0x80808080);
+ }
+
+ ADVANCE_BCS_BATCH(batch);
+ }
+
+ if (slice_type == SLICE_TYPE_B) {
+ BEGIN_BCS_BATCH(batch, 10);
+ OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | 8);
+ OUT_BCS_BATCH(batch, 1); //Select L1
+ OUT_BCS_BATCH(batch, bwd_ref_entry); //max 4 reference allowed
+ for(i = 0; i < 7; i++) {
+ OUT_BCS_BATCH(batch, 0x80808080);
+ }
+ ADVANCE_BCS_BATCH(batch);
+ }
+}
+
+static void
+gen9_mfc_avc_weightoffset_state(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ VAEncPictureParameterBufferH264 *pic_param,
+ VAEncSliceParameterBufferH264 *slice_param)
+{
+ struct intel_batchbuffer *batch = encoder_context->base.batch;
+ int i, slice_type;
+ short weightoffsets[32 * 6];
+
+ slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
+
+ if (slice_type == SLICE_TYPE_P &&
+ pic_param->pic_fields.bits.weighted_pred_flag == 1) {
+ memset(weightoffsets,0,32*6 * sizeof(short));
+ for (i = 0; i < 32; i++) {
+ weightoffsets[i * 6 + 0] = slice_param->luma_weight_l0[i];
+ weightoffsets[i * 6 + 1] = slice_param->luma_offset_l0[i];
+ weightoffsets[i * 6 + 2] = slice_param->chroma_weight_l0[i][0];
+ weightoffsets[i * 6 + 3] = slice_param->chroma_offset_l0[i][0];
+ weightoffsets[i * 6 + 4] = slice_param->chroma_weight_l0[i][1];
+ weightoffsets[i * 6 + 5] = slice_param->chroma_offset_l0[i][1];
+ }
+
+ BEGIN_BCS_BATCH(batch, 98);
+ OUT_BCS_BATCH(batch, MFX_AVC_WEIGHTOFFSET_STATE | (98 - 2));
+ OUT_BCS_BATCH(batch, 0);
+ intel_batchbuffer_data(batch, weightoffsets, sizeof(weightoffsets));
+
+ ADVANCE_BCS_BATCH(batch);
+ }
+
+ if (slice_type == SLICE_TYPE_B &&
+ (pic_param->pic_fields.bits.weighted_bipred_idc == 1)) {
+ memset(weightoffsets,0,32*6 * sizeof(short));
+ for (i = 0; i < 32; i++) {
+ weightoffsets[i * 6 + 0] = slice_param->luma_weight_l0[i];
+ weightoffsets[i * 6 + 1] = slice_param->luma_offset_l0[i];
+ weightoffsets[i * 6 + 2] = slice_param->chroma_weight_l0[i][0];
+ weightoffsets[i * 6 + 3] = slice_param->chroma_offset_l0[i][0];
+ weightoffsets[i * 6 + 4] = slice_param->chroma_weight_l0[i][1];
+ weightoffsets[i * 6 + 5] = slice_param->chroma_offset_l0[i][1];
+ }
+
+ BEGIN_BCS_BATCH(batch, 98);
+ OUT_BCS_BATCH(batch, MFX_AVC_WEIGHTOFFSET_STATE | (98 - 2));
+ OUT_BCS_BATCH(batch, 0);
+ intel_batchbuffer_data(batch, weightoffsets, sizeof(weightoffsets));
+ ADVANCE_BCS_BATCH(batch);
+
+ memset(weightoffsets,0,32*6 * sizeof(short));
+ for (i = 0; i < 32; i++) {
+ weightoffsets[i * 6 + 0] = slice_param->luma_weight_l1[i];
+ weightoffsets[i * 6 + 1] = slice_param->luma_offset_l1[i];
+ weightoffsets[i * 6 + 2] = slice_param->chroma_weight_l1[i][0];
+ weightoffsets[i * 6 + 3] = slice_param->chroma_offset_l1[i][0];
+ weightoffsets[i * 6 + 4] = slice_param->chroma_weight_l1[i][1];
+ weightoffsets[i * 6 + 5] = slice_param->chroma_offset_l1[i][1];
+ }
+
+ BEGIN_BCS_BATCH(batch, 98);
+ OUT_BCS_BATCH(batch, MFX_AVC_WEIGHTOFFSET_STATE | (98 - 2));
+ OUT_BCS_BATCH(batch, 1);
+ intel_batchbuffer_data(batch, weightoffsets, sizeof(weightoffsets));
+ ADVANCE_BCS_BATCH(batch);
+ }
+}