-----Original Message-----
From: Zhao, Yakui 
Sent: Tuesday, January 17, 2017 10:47 AM
To: Qu, Pengfei <pengfei...@intel.com>
Cc: libva@lists.freedesktop.org
Subject: Re: [Libva] [PATCH v1 8/9] ENC: add MFX pipeline for AVC encoder

On 01/13/2017 05:24 PM, Pengfei Qu wrote:
> MFX pipeline:
> add MFX command for AVC encoder
> add MFX Picture slice level command init for AVC
> add MFX pipeline init prepare run for AVC encode
> add VME/MFX context init for AVC encoder
>

Please see the inline comment.

> Reviewed-by: Sean V Kelley<sea...@posteo.de>
> Signed-off-by: Pengfei Qu<pengfei...@intel.com>
> ---
>   src/gen9_avc_encoder.c | 1887 
> +++++++++++++++++++++++++++++++++++++++++++++++-
>   1 file changed, 1886 insertions(+), 1 deletion(-)
>
> diff --git a/src/gen9_avc_encoder.c b/src/gen9_avc_encoder.c
> index 5caa9f4..a7545f1 100755
> --- a/src/gen9_avc_encoder.c
> +++ b/src/gen9_avc_encoder.c
> @@ -5742,4 +5742,1889 @@ gen9_avc_kernel_init(VADriverContextP ctx,
>       generic_ctx->pfn_send_brc_mb_update_surface = 
> gen9_avc_send_surface_brc_mb_update;
>       generic_ctx->pfn_send_sfd_surface = gen9_avc_send_surface_sfd;
>       generic_ctx->pfn_send_wp_surface = gen9_avc_send_surface_wp;
> -}
> \ No newline at end of file
> +}
> +
> +/*
> +PAK pipeline related function
> +*/
> +extern int
> +intel_avc_enc_slice_type_fixup(int slice_type);
> +
> +static void
> +gen9_mfc_avc_pipe_mode_select(VADriverContextP ctx,
> +                              struct encode_state *encode_state,
> +                              struct intel_encoder_context *encoder_context)
> +{
> +    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 intel_batchbuffer *batch = encoder_context->base.batch;
> +
> +    BEGIN_BCS_BATCH(batch, 5);
> +
> +    OUT_BCS_BATCH(batch, MFX_PIPE_MODE_SELECT | (5 - 2));
> +    OUT_BCS_BATCH(batch,
> +                  (0<<  29) |
> +                  (MFX_LONG_MODE<<  17) |       /* Must be long format for 
> encoder */
> +                  (MFD_MODE_VLD<<  15) |
> +                  (0<<  13) |                   /* VDEnc mode  is 1*/
> +                  ((generic_state->curr_pak_pass != 
> (generic_state->num_pak_passes -1))<<  10) |                   /* Stream-Out 
> Enable */
> +                  ((!!avc_ctx->res_post_deblocking_output.bo)<<  9)  |    /* 
> Post Deblocking Output */
> +                  ((!!avc_ctx->res_pre_deblocking_output.bo)<<  8)  |     /* 
> Pre Deblocking Output */
> +                  (0<<  7)  |                   /* Scaled surface enable */
> +                  (0<<  6)  |                   /* Frame statistics stream 
> out enable, always '1' in VDEnc mode */
> +                  (0<<  5)  |                   /* not in stitch mode */
> +                  (1<<  4)  |                   /* encoding mode */
> +                  (MFX_FORMAT_AVC<<  0));
> +    OUT_BCS_BATCH(batch,
> +                  (0<<  7)  | /* expand NOA bus flag */
> +                  (0<<  6)  | /* disable slice-level clock gating */
> +                  (0<<  5)  | /* disable clock gating for NOA */
> +                  (0<<  4)  | /* terminate if AVC motion and POC table error 
> occurs */
> +                  (0<<  3)  | /* terminate if AVC mbdata error occurs */
> +                  (0<<  2)  | /* terminate if AVC CABAC/CAVLC decode error 
> occurs */
> +                  (0<<  1)  |
> +                  (0<<  0));
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen9_mfc_avc_surface_state(VADriverContextP ctx,
> +                           struct intel_encoder_context *encoder_context,
> +                           struct i965_gpe_resource *gpe_resource,
> +                           int id)
> +{
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +
> +    BEGIN_BCS_BATCH(batch, 6);
> +
> +    OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2));
> +    OUT_BCS_BATCH(batch, id);
> +    OUT_BCS_BATCH(batch,
> +                  ((gpe_resource->height - 1)<<  18) |
> +                  ((gpe_resource->width - 1)<<  4));
> +    OUT_BCS_BATCH(batch,
> +                  (MFX_SURFACE_PLANAR_420_8<<  28) |    /* 420 planar YUV 
> surface */
> +                  (1<<  27) |                           /* must be 1 for 
> interleave U/V, hardware requirement */
> +                  ((gpe_resource->pitch - 1)<<  3) |    /* pitch */
> +                  (0<<  2)  |                           /* must be 0 for 
> interleave U/V */
> +                  (1<<  1)  |                           /* must be tiled */
> +                  (I965_TILEWALK_YMAJOR<<  0));         /* tile walk, 
> TILEWALK_YMAJOR */
> +    OUT_BCS_BATCH(batch,
> +                  (0<<  16) |                                /* must be 0 
> for interleave U/V */
> +                  (gpe_resource->y_cb_offset));         /* y offset for 
> U(cb) */
> +    OUT_BCS_BATCH(batch,
> +                  (0<<  16) |                                /* must be 0 
> for interleave U/V */
> +                  (gpe_resource->y_cb_offset));         /* y offset for 
> U(cb) */
> +
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen9_mfc_avc_pipe_buf_addr_state(VADriverContextP ctx, struct 
> intel_encoder_context *encoder_context)
> +{
> +    struct encoder_vme_mfc_context * pak_context = (struct 
> encoder_vme_mfc_context *)encoder_context->vme_context;
> +    struct generic_encoder_context * generic_ctx = (struct 
> generic_encoder_context * )pak_context->generic_enc_ctx;
> +    struct gen9_avc_encoder_context * avc_ctx = (struct 
> gen9_avc_encoder_context * )pak_context->private_enc_ctx;
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +    int i;
> +
> +    BEGIN_BCS_BATCH(batch, 65);
> +
> +    OUT_BCS_BATCH(batch, MFX_PIPE_BUF_ADDR_STATE | (65 - 2));
> +
> +    /* the DW1-3 is for pre_deblocking */
> +    OUT_BUFFER_3DW(batch, avc_ctx->res_pre_deblocking_output.bo, 1, 0, 0);
> +
> +    /* the DW4-6 is for the post_deblocking */
> +    OUT_BUFFER_3DW(batch, avc_ctx->res_post_deblocking_output.bo, 1, 0, 0);
> +
> +    /* the DW7-9 is for the uncompressed_picture */
> +    OUT_BUFFER_3DW(batch, generic_ctx->res_uncompressed_input_surface.bo, 1, 
> 0, 0);
> +
> +    /* the DW10-12 is for PAK information (write) */
> +    OUT_BUFFER_3DW(batch, avc_ctx->res_pak_mb_status_buffer.bo, 1, 0, 0);//?
> +
> +    /* the DW13-15 is for the intra_row_store_scratch */
> +    OUT_BUFFER_3DW(batch, avc_ctx->res_intra_row_store_scratch_buffer.bo, 1, 
> 0, 0);
> +
> +    /* the DW16-18 is for the deblocking filter */
> +    OUT_BUFFER_3DW(batch, 
> avc_ctx->res_deblocking_filter_row_store_scratch_buffer.bo, 1, 0, 0);
> +
> +    /* the DW 19-50 is for Reference pictures*/
> +    for (i = 0; i<  ARRAY_ELEMS(avc_ctx->list_reference_res); i++) {
> +        OUT_BUFFER_2DW(batch, avc_ctx->list_reference_res[i].bo, 1, 0);
> +    }
> +
> +    /* DW 51, reference picture attributes */
> +    OUT_BCS_BATCH(batch, 0);
> +
> +    /* The DW 52-54 is for PAK information (read) */
> +    OUT_BUFFER_3DW(batch, avc_ctx->res_pak_mb_status_buffer.bo, 1, 0, 0);
> +
> +    /* the DW 55-57 is the ILDB buffer */
> +    OUT_BUFFER_3DW(batch, NULL, 0, 0, 0);
> +
> +    /* the DW 58-60 is the second ILDB buffer */
> +    OUT_BUFFER_3DW(batch, NULL, 0, 0, 0);
> +
> +    /* DW 61, memory compress enable&  mode */
> +    OUT_BCS_BATCH(batch, 0);
> +
> +    /* the DW 62-64 is the buffer */
> +    OUT_BUFFER_3DW(batch, NULL, 0, 0, 0);
> +
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen9_mfc_avc_ind_obj_base_addr_state(VADriverContextP ctx,
> +                                     struct encode_state *encode_state,
> +                                     struct intel_encoder_context 
> *encoder_context)
> +{
> +    struct encoder_vme_mfc_context * pak_context = (struct 
> encoder_vme_mfc_context *)encoder_context->vme_context;
> +    struct generic_encoder_context * generic_ctx = (struct 
> generic_encoder_context * )pak_context->generic_enc_ctx;
> +    struct generic_enc_codec_state * generic_state = (struct 
> generic_enc_codec_state * )pak_context->generic_enc_state;
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +    struct object_surface *obj_surface;
> +    struct gen9_surface_avc *avc_priv_surface;
> +    unsigned int size = 0;
> +    unsigned int w_mb = generic_state->frame_width_in_mbs;
> +    unsigned int h_mb = generic_state->frame_height_in_mbs;
> +
> +    obj_surface = encode_state->reconstructed_object;
> +
> +    if (!obj_surface || !obj_surface->private_data)
> +        return;
> +    avc_priv_surface = obj_surface->private_data;
> +
> +    BEGIN_BCS_BATCH(batch, 26);
> +
> +    OUT_BCS_BATCH(batch, MFX_IND_OBJ_BASE_ADDR_STATE | (26 - 2));
> +    /* The DW1-5 is for the MFX indirect bistream offset, ignore for VDEnc 
> mode */
> +    OUT_BUFFER_3DW(batch, NULL, 0, 0, 0);
> +    OUT_BUFFER_2DW(batch, NULL, 0, 0);
> +
> +    /* the DW6-10 is for MFX Indirect MV Object Base Address, ignore for 
> VDEnc mode */
> +    size = w_mb * h_mb * 32 * 4;
> +    OUT_BUFFER_3DW(batch,
> +                   avc_priv_surface->res_mv_data_surface.bo,
> +                   1,
> +                   0,
> +                   0);
> +    OUT_BUFFER_2DW(batch,
> +                   avc_priv_surface->res_mv_data_surface.bo,
> +                   1,
> +                   ALIGN(size,0x1000));
> +
> +    /* The DW11-15 is for MFX IT-COFF. Not used on encoder */
> +    OUT_BUFFER_3DW(batch, NULL, 0, 0, 0);
> +    OUT_BUFFER_2DW(batch, NULL, 0, 0);
> +
> +    /* The DW16-20 is for MFX indirect DBLK. Not used on encoder */
> +    OUT_BUFFER_3DW(batch, NULL, 0, 0, 0);
> +    OUT_BUFFER_2DW(batch, NULL, 0, 0);
> +
> +    /* The DW21-25 is for MFC Indirect PAK-BSE Object Base Address for 
> Encoder
> +     * Note: an offset is specified in MFX_AVC_SLICE_STATE
> +     */
> +    OUT_BUFFER_3DW(batch,
> +                   generic_ctx->compressed_bitstream.res.bo,
> +                   1,
> +                   0,
> +                   0);
> +    OUT_BUFFER_2DW(batch,
> +                   generic_ctx->compressed_bitstream.res.bo,
> +                   1,
> +                   generic_ctx->compressed_bitstream.end_offset);
> +
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen9_mfc_avc_bsp_buf_base_addr_state(VADriverContextP ctx, struct 
> intel_encoder_context *encoder_context)
> +{
> +    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 intel_batchbuffer *batch = encoder_context->base.batch;
> +
> +    BEGIN_BCS_BATCH(batch, 10);
> +
> +    OUT_BCS_BATCH(batch, MFX_BSP_BUF_BASE_ADDR_STATE | (10 - 2));
> +
> +    /* The DW1-3 is for bsd/mpc row store scratch buffer */
> +    OUT_BUFFER_3DW(batch, avc_ctx->res_bsd_mpc_row_store_scratch_buffer.bo, 
> 1, 0, 0);
> +
> +    /* The DW4-6 is for MPR Row Store Scratch Buffer Base Address, ignore 
> for encoder */
> +    OUT_BUFFER_3DW(batch, NULL, 0, 0, 0);
> +
> +    /* The DW7-9 is for Bitplane Read Buffer Base Address, ignore for 
> encoder */
> +    OUT_BUFFER_3DW(batch, NULL, 0, 0, 0);
> +
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen9_mfc_avc_directmode_state(VADriverContextP ctx,
> +                              struct intel_encoder_context *encoder_context)
> +{
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +    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 avc_enc_state * avc_state = (struct avc_enc_state * 
> )pak_context->private_enc_state;
> +
> +    int i;
> +
> +    BEGIN_BCS_BATCH(batch, 71);
> +
> +    OUT_BCS_BATCH(batch, MFX_AVC_DIRECTMODE_STATE | (71 - 2));
> +
> +    /* Reference frames and Current frames */
> +    /* the DW1-32 is for the direct MV for reference */
> +    for(i = 0; i<  NUM_MFC_AVC_DMV_BUFFERS - 2; i += 2) {
> +        if ( avc_ctx->res_direct_mv_buffersr[i].bo != NULL) {
> +            OUT_BCS_RELOC64(batch, avc_ctx->res_direct_mv_buffersr[i].bo,
> +                          I915_GEM_DOMAIN_INSTRUCTION, 0,
> +                          0);
> +        } else {
> +            OUT_BCS_BATCH(batch, 0);
> +            OUT_BCS_BATCH(batch, 0);
> +        }
> +    }
> +
> +    OUT_BCS_BATCH(batch, 0);
> +
> +    /* the DW34-36 is the MV for the current reference */
> +    OUT_BCS_RELOC64(batch, 
> avc_ctx->res_direct_mv_buffersr[NUM_MFC_AVC_DMV_BUFFERS - 2].bo,
> +                  I915_GEM_DOMAIN_INSTRUCTION, 0,
> +                  0);
> +
> +    OUT_BCS_BATCH(batch, 0);
> +
> +    /* POL list */
> +    for(i = 0; i<  32; i++) {
> +        OUT_BCS_BATCH(batch, avc_state->top_field_poc[i]);
> +    }
> +    OUT_BCS_BATCH(batch, avc_state->top_field_poc[NUM_MFC_AVC_DMV_BUFFERS - 
> 2]);
> +    OUT_BCS_BATCH(batch, avc_state->top_field_poc[NUM_MFC_AVC_DMV_BUFFERS - 
> 1]);
> +
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen9_mfc_qm_state(VADriverContextP ctx,
> +                  int qm_type,
> +                  const unsigned int *qm,
> +                  int qm_length,
> +                  struct intel_encoder_context *encoder_context)
> +{
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +    unsigned int qm_buffer[16];
> +
> +    assert(qm_length<= 16);
> +    assert(sizeof(*qm) == 4);
> +    memset(qm_buffer,0,16*4);
> +    memcpy(qm_buffer, qm, qm_length * 4);
> +
> +    BEGIN_BCS_BATCH(batch, 18);
> +    OUT_BCS_BATCH(batch, MFX_QM_STATE | (18 - 2));
> +    OUT_BCS_BATCH(batch, qm_type<<  0);
> +    intel_batchbuffer_data(batch, qm_buffer, 16 * 4);
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen9_mfc_avc_qm_state(VADriverContextP ctx,
> +                      struct encode_state *encode_state,
> +                      struct intel_encoder_context *encoder_context)
> +{
> +    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;
> +    VAEncSequenceParameterBufferH264  *seq_param = avc_state->seq_param;
> +    VAEncPictureParameterBufferH264  *pic_param = avc_state->pic_param;
> +
> +    /* TODO: add support for non flat matrix */
> +    const unsigned int *qm_4x4_intra;
> +    const unsigned int *qm_4x4_inter;
> +    const unsigned int *qm_8x8_intra;
> +    const unsigned int *qm_8x8_inter;
> +
> +    if (!seq_param->seq_fields.bits.seq_scaling_matrix_present_flag
> +&&  !pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
> +        qm_4x4_intra = qm_4x4_inter = qm_8x8_intra = qm_8x8_inter = qm_flat;
> +    } else {
> +        VAIQMatrixBufferH264 *qm;
> +        assert(encode_state->q_matrix&&  encode_state->q_matrix->buffer);
> +        qm = (VAIQMatrixBufferH264 *)encode_state->q_matrix->buffer;
> +        qm_4x4_intra = (unsigned int *)qm->ScalingList4x4[0];
> +        qm_4x4_inter = (unsigned int *)qm->ScalingList4x4[3];
> +        qm_8x8_intra = (unsigned int *)qm->ScalingList8x8[0];
> +        qm_8x8_inter = (unsigned int *)qm->ScalingList8x8[1];
> +    }
> +
> +    gen9_mfc_qm_state(ctx, MFX_QM_AVC_4X4_INTRA_MATRIX, qm_4x4_intra, 12, 
> encoder_context);
> +    gen9_mfc_qm_state(ctx, MFX_QM_AVC_4X4_INTER_MATRIX, qm_4x4_inter, 12, 
> encoder_context);
> +    gen9_mfc_qm_state(ctx, MFX_QM_AVC_8x8_INTRA_MATRIX, qm_8x8_intra, 16, 
> encoder_context);
> +    gen9_mfc_qm_state(ctx, MFX_QM_AVC_8x8_INTER_MATRIX, qm_8x8_inter, 16, 
> encoder_context);
> +}
> +
> +static void
> +gen9_mfc_fqm_state(VADriverContextP ctx,
> +                   int fqm_type,
> +                   const unsigned int *fqm,
> +                   int fqm_length,
> +                   struct intel_encoder_context *encoder_context)
> +{
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +    unsigned int fqm_buffer[32];
> +
> +    assert(fqm_length<= 32);
> +    assert(sizeof(*fqm) == 4);
> +    memset(fqm_buffer,0,32*4);
> +    memcpy(fqm_buffer, fqm, fqm_length * 4);
> +
> +    BEGIN_BCS_BATCH(batch, 34);
> +    OUT_BCS_BATCH(batch, MFX_FQM_STATE | (34 - 2));
> +    OUT_BCS_BATCH(batch, fqm_type<<  0);
> +    intel_batchbuffer_data(batch, fqm_buffer, 32 * 4);
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen9_mfc_fill_fqm(uint8_t *qm, uint16_t *fqm, int len)
> +{
> +    int i, j;
> +    for (i = 0; i<  len; i++)
> +       for (j = 0; j<  len; j++)
> +           fqm[i * len + j] = (1<<  16) / qm[j * len + i];
> +}
> +
> +static void
> +gen9_mfc_avc_fqm_state(VADriverContextP ctx,
> +                      struct encode_state *encode_state,
> +                      struct intel_encoder_context *encoder_context)
> +{
> +    /* TODO: add support for non flat matrix */
> +    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;
> +    VAEncSequenceParameterBufferH264  *seq_param = avc_state->seq_param;
> +    VAEncPictureParameterBufferH264  *pic_param = avc_state->pic_param;
> +
> +    if (!seq_param->seq_fields.bits.seq_scaling_matrix_present_flag
> +&&  !pic_param->pic_fields.bits.pic_scaling_matrix_present_flag) {
> +        gen9_mfc_fqm_state(ctx, MFX_QM_AVC_4X4_INTRA_MATRIX, fqm_flat, 24, 
> encoder_context);
> +        gen9_mfc_fqm_state(ctx, MFX_QM_AVC_4X4_INTER_MATRIX, fqm_flat, 24, 
> encoder_context);
> +        gen9_mfc_fqm_state(ctx, MFX_QM_AVC_8x8_INTRA_MATRIX, fqm_flat, 32, 
> encoder_context);
> +        gen9_mfc_fqm_state(ctx, MFX_QM_AVC_8x8_INTER_MATRIX, fqm_flat, 32, 
> encoder_context);
> +    } else {
> +        int i;
> +        uint32_t fqm[32];
> +        VAIQMatrixBufferH264 *qm;
> +        assert(encode_state->q_matrix&&  encode_state->q_matrix->buffer);
> +        qm = (VAIQMatrixBufferH264 *)encode_state->q_matrix->buffer;
> +
> +        for (i = 0; i<  3; i++)
> +            gen9_mfc_fill_fqm(qm->ScalingList4x4[i], (uint16_t *)fqm + 16 * 
> i, 4);
> +        gen9_mfc_fqm_state(ctx, MFX_QM_AVC_4X4_INTRA_MATRIX, fqm, 24, 
> encoder_context);
> +
> +        for (i = 3; i<  6; i++)
> +            gen9_mfc_fill_fqm(qm->ScalingList4x4[i], (uint16_t *)fqm + 16 * 
> (i - 3), 4);
> +        gen9_mfc_fqm_state(ctx, MFX_QM_AVC_4X4_INTER_MATRIX, fqm, 24, 
> encoder_context);
> +
> +        gen9_mfc_fill_fqm(qm->ScalingList8x8[0], (uint16_t *)fqm, 8);
> +        gen9_mfc_fqm_state(ctx, MFX_QM_AVC_8x8_INTRA_MATRIX, fqm, 32, 
> encoder_context);
> +
> +        gen9_mfc_fill_fqm(qm->ScalingList8x8[1], (uint16_t *)fqm, 8);
> +        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)
> +{
> +    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,
> +                                      struct intel_batchbuffer *batch)
> +{
> +    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,
> +                                   batch);
> +    }
> +
> +    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,
> +                                   batch);
> +
> +        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,
> +                                   batch);
> +    }
> +
> +    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 intel_batchbuffer *batch)
> +{
> +    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,
> +                                       batch);
> +        }
> +
> +        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,
> +                                       batch);
> +        }
> +
> +        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,
> +                                       batch);
> +        } else if (internal_rate_mode == VA_RC_CBR) {
> +            /* TODO: insert others */
> +        }
> +    }
> +
> +    gen9_mfc_avc_insert_slice_packed_data(ctx,
> +                                          encode_state,
> +                                          encoder_context,
> +                                          slice_index,
> +                                          batch);
> +}
> +
> +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 intel_batchbuffer *batch)
> +{
> +    struct encoder_vme_mfc_context * pak_context = (struct 
> encoder_vme_mfc_context *)encoder_context->vme_context;
> +    struct generic_encoder_context * generic_ctx = (struct 
> generic_encoder_context * )pak_context->generic_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;
> +    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 rc_panic_enable = 0;
> +    unsigned int rate_control_counter_enable = 0;
> +    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 */
> +
> +    rate_control_counter_enable = (generic_state->brc_enabled&&  
> (generic_state->curr_pak_pass != 0));
> +    rc_panic_enable = (avc_state->rc_panic_enable&&
> +                      (!avc_state->min_max_qp_enable)&&
> +                      (encoder_context->rate_control_mode != VA_RC_CQP)&&
> +                      (generic_state->curr_pak_pass == 
> (generic_state->num_pak_passes - 1)));
> +
> +    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,
> +                  (rate_control_counter_enable<<  31) |           /* TODO: 
> ignore it for VDENC ??? */
> +                  (1<<  30) |           /* ResetRateControlCounter */
> +                  (2<<  28) |           /* Loose Rate Control */
> +                  (0<<  24) |           /* RC Stable Tolerance */
> +                  (rc_panic_enable<<  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, generic_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 intel_batchbuffer *batch)
> +{
> +    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;
> +    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)
> +{
> +    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);
> +    }
> +}
> +
> +static void
> +gen9_mfc_avc_single_slice(VADriverContextP ctx,
> +                          struct encode_state *encode_state,
> +                          struct intel_encoder_context *encoder_context,
> +                          VAEncSliceParameterBufferH264 *slice_param,
> +                          VAEncSliceParameterBufferH264 *next_slice_param,
> +                          int slice_index)
> +{
> +    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;
> +    struct intel_batchbuffer *slice_batch = 
> avc_ctx->pres_slice_batch_buffer_2nd_level;
> +    VAEncPictureParameterBufferH264 *pic_param = 
> (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
> +    struct gpe_mi_batch_buffer_start_parameter second_level_batch;
> +    struct object_surface *obj_surface;
> +    struct gen9_surface_avc *avc_priv_surface;
> +
> +    unsigned int slice_offset = 0;
> +
> +    if(generic_state->curr_pak_pass == 0)
> +    {
> +        slice_offset = intel_batchbuffer_used_size(slice_batch);
> +        avc_state->slice_batch_offset[slice_index] = slice_offset;
> +        gen9_mfc_avc_ref_idx_state(ctx, encode_state, encoder_context, 
> slice_param,slice_batch);
> +        gen9_mfc_avc_weightoffset_state(ctx,
> +                                        encode_state,
> +                                        encoder_context,
> +                                        pic_param,
> +                                        slice_param,
> +                                        slice_batch);
> +        gen9_mfc_avc_slice_state(ctx,
> +                                 encode_state,
> +                                 encoder_context,
> +                                 pic_param,
> +                                 slice_param,
> +                                 next_slice_param,
> +                                 slice_batch);
> +        gen9_mfc_avc_inset_headers(ctx,
> +                                   encode_state,
> +                                   encoder_context,
> +                                   slice_param,
> +                                   slice_index,
> +                                   slice_batch);
> +
> +        BEGIN_BCS_BATCH(slice_batch, 2);
> +        OUT_BCS_BATCH(slice_batch, 0);
> +        OUT_BCS_BATCH(slice_batch, MI_BATCH_BUFFER_END);
> +        ADVANCE_BCS_BATCH(slice_batch);
> +
> +    }else
> +    {
> +        slice_offset = avc_state->slice_batch_offset[slice_index];
> +    }
> +    /* insert slice as second levle.*/
> +    memset(&second_level_batch, 0, sizeof(second_level_batch));
> +    second_level_batch.is_second_level = 1; /* Must be the second level 
> batch buffer */
> +    second_level_batch.offset = slice_offset;
> +    second_level_batch.bo = slice_batch->buffer;
> +    gen8_gpe_mi_batch_buffer_start(ctx, batch,&second_level_batch);
> +
> +    /* insert mb code as second levle.*/
> +    obj_surface = encode_state->reconstructed_object;
> +    assert(obj_surface->private_data);
> +    avc_priv_surface = (struct gen9_surface_avc *)obj_surface->private_data;
> +
> +    memset(&second_level_batch, 0, sizeof(second_level_batch));
> +    second_level_batch.is_second_level = 1; /* Must be the second level 
> batch buffer */
> +    second_level_batch.offset = slice_param->macroblock_address * 16 * 4;
> +    second_level_batch.bo = avc_priv_surface->res_mb_code_surface.bo;
> +    gen8_gpe_mi_batch_buffer_start(ctx, batch,&second_level_batch);
> +
> +}
> +
> +static void
> +gen9_avc_pak_slice_level(VADriverContextP ctx,
> +                         struct encode_state *encode_state,
> +                         struct intel_encoder_context *encoder_context)
> +{
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +    struct gpe_mi_flush_dw_parameter mi_flush_dw_params;
> +    VAEncSliceParameterBufferH264 *slice_param, *next_slice_param, 
> *next_slice_group_param;
> +    int i, j;
> +    int slice_index = 0;
> +    int is_frame_level = 1;       /* TODO: check it for SKL,now single slice 
> per frame */
> +    int has_tail = 0;             /* TODO: check it later */
> +
> +    for (j = 0; j<  encode_state->num_slice_params_ext; j++) {
> +        slice_param = (VAEncSliceParameterBufferH264 
> *)encode_state->slice_params_ext[j]->buffer;
> +
> +        if (j == encode_state->num_slice_params_ext - 1)
> +            next_slice_group_param = NULL;
> +        else
> +            next_slice_group_param = (VAEncSliceParameterBufferH264 
> *)encode_state->slice_params_ext[j + 1]->buffer;
> +
> +        for (i = 0; i<  encode_state->slice_params_ext[j]->num_elements; 
> i++) {
> +            if (i<  encode_state->slice_params_ext[j]->num_elements - 1)
> +                next_slice_param = slice_param + 1;
> +            else
> +                next_slice_param = next_slice_group_param;
> +
> +            gen9_mfc_avc_single_slice(ctx,
> +                                      encode_state,
> +                                      encoder_context,
> +                                      slice_param,
> +                                      next_slice_param,
> +                                      slice_index);
> +            slice_param++;
> +            slice_index++;
> +
> +            if (is_frame_level)
> +                break;
> +            else {
> +                /* TODO: remove assert(0) and add other commands here */
> +                assert(0);
> +            }
> +        }
> +
> +        if (is_frame_level)
> +            break;
> +    }
> +
> +    if (has_tail) {
> +        /* TODO: insert a tail if required */
> +    }
> +
> +    memset(&mi_flush_dw_params, 0, sizeof(mi_flush_dw_params));
> +    mi_flush_dw_params.video_pipeline_cache_invalidate = 1;
> +    gen8_gpe_mi_flush_dw(ctx, batch,&mi_flush_dw_params);
> +}
> +static void
> +gen9_avc_pak_picture_level(VADriverContextP ctx,
> +                           struct encode_state *encode_state,
> +                           struct intel_encoder_context *encoder_context)
> +{
> +    struct encoder_vme_mfc_context * pak_context = (struct 
> encoder_vme_mfc_context *)encoder_context->vme_context;
> +    struct generic_encoder_context * generic_ctx = (struct 
> generic_encoder_context * )pak_context->generic_enc_ctx;
> +    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 gpe_mi_batch_buffer_start_parameter second_level_batch;
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +
> +    if (generic_state->brc_enabled&&
> +        generic_state->curr_pak_pass) {
> +        struct gpe_mi_conditional_batch_buffer_end_parameter 
> mi_conditional_batch_buffer_end_params;
> +        struct encoder_status_buffer_internal *status_buffer;
> +        status_buffer =&(avc_ctx->status_buffer);
> +
> +        memset(&mi_conditional_batch_buffer_end_params, 0, 
> sizeof(mi_conditional_batch_buffer_end_params));
> +        mi_conditional_batch_buffer_end_params.offset = 
> status_buffer->image_status_mask_offset;
> +        mi_conditional_batch_buffer_end_params.bo = status_buffer->bo;
> +        mi_conditional_batch_buffer_end_params.compare_data = 0;
> +        mi_conditional_batch_buffer_end_params.compare_mask_mode_disabled = 
> 0;
> +        gen9_gpe_mi_conditional_batch_buffer_end(ctx, 
> batch,&mi_conditional_batch_buffer_end_params);
> +    }
> +
> +    gen9_mfc_avc_pipe_mode_select(ctx,encode_state,encoder_context);
> +    
> gen9_mfc_avc_surface_state(ctx,encoder_context,&(generic_ctx->res_reconstructed_surface),0);
> +    
> gen9_mfc_avc_surface_state(ctx,encoder_context,&(generic_ctx->res_uncompressed_input_surface),4);
> +    gen9_mfc_avc_pipe_buf_addr_state(ctx,encoder_context);
> +    gen9_mfc_avc_ind_obj_base_addr_state(ctx,encode_state,encoder_context);
> +    gen9_mfc_avc_bsp_buf_base_addr_state(ctx,encoder_context);
> +
> +    if(generic_state->brc_enabled)
> +    {
> +        memset(&second_level_batch, 0, sizeof(second_level_batch));
> +        if (generic_state->curr_pak_pass == 0) {
> +            second_level_batch.offset = 0;
> +        } else {
> +            second_level_batch.offset = generic_state->curr_pak_pass * 
> INTEL_AVC_IMAGE_STATE_CMD_SIZE;
> +        }
> +        second_level_batch.is_second_level = 1;
> +        second_level_batch.bo = avc_ctx->res_brc_image_state_read_buffer.bo;
> +        gen8_gpe_mi_batch_buffer_start(ctx, batch,&second_level_batch);
> +    }else
> +    {
> +        /*generate a new image state */
> +        
> gen9_avc_set_image_state_non_brc(ctx,encode_state,encoder_context,&(avc_ctx->res_image_state_batch_buffer_2nd_level));
> +        memset(&second_level_batch, 0, sizeof(second_level_batch));
> +        second_level_batch.offset = 0;
> +        second_level_batch.is_second_level = 1;
> +        second_level_batch.bo = 
> avc_ctx->res_image_state_batch_buffer_2nd_level.bo;
> +        gen8_gpe_mi_batch_buffer_start(ctx, batch,&second_level_batch);
> +    }
> +
> +    gen9_mfc_avc_qm_state(ctx,encode_state,encoder_context);
> +    gen9_mfc_avc_fqm_state(ctx,encode_state,encoder_context);
> +    gen9_mfc_avc_directmode_state(ctx,encoder_context);
> +
> +}
> +
> +static void
> +gen9_avc_read_mfc_status(VADriverContextP ctx, struct intel_encoder_context 
> *encoder_context)
> +{
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +    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 gpe_mi_store_register_mem_parameter mi_store_reg_mem_param;
> +    struct gpe_mi_store_data_imm_parameter mi_store_data_imm_param;
> +    struct gpe_mi_flush_dw_parameter mi_flush_dw_param;
> +    struct encoder_status_buffer_internal *status_buffer;
> +
> +    status_buffer =&(avc_ctx->status_buffer);
> +
> +    memset(&mi_flush_dw_param, 0, sizeof(mi_flush_dw_param));
> +    gen8_gpe_mi_flush_dw(ctx, batch,&mi_flush_dw_param);
> +
> +    /* read register and store into status_buffer and pak_statitistic info */
> +    memset(&mi_store_reg_mem_param, 0, sizeof(mi_store_reg_mem_param));
> +    mi_store_reg_mem_param.bo = status_buffer->bo;
> +    mi_store_reg_mem_param.offset = 
> status_buffer->bs_byte_count_frame_offset;
> +    mi_store_reg_mem_param.mmio_offset = 
> status_buffer->bs_byte_count_frame_reg_offset;
> +    gen8_gpe_mi_store_register_mem(ctx, batch,&mi_store_reg_mem_param);
> +
> +    memset(&mi_store_reg_mem_param, 0, sizeof(mi_store_reg_mem_param));
> +    mi_store_reg_mem_param.bo = status_buffer->bo;
> +    mi_store_reg_mem_param.offset = 
> status_buffer->bs_byte_count_frame_nh_offset;
> +    mi_store_reg_mem_param.mmio_offset = 
> status_buffer->bs_byte_count_frame_nh_reg_offset;
> +    gen8_gpe_mi_store_register_mem(ctx, batch,&mi_store_reg_mem_param);
> +
> +    memset(&mi_store_reg_mem_param, 0, sizeof(mi_store_reg_mem_param));
> +    mi_store_reg_mem_param.bo = status_buffer->bo;
> +    mi_store_reg_mem_param.offset = 
> status_buffer->mfc_qp_status_count_offset;
> +    mi_store_reg_mem_param.mmio_offset = 
> status_buffer->mfc_qp_status_count_reg_offset;
> +    gen8_gpe_mi_store_register_mem(ctx, batch,&mi_store_reg_mem_param);
> +
> +    mi_store_reg_mem_param.bo = status_buffer->bo;
> +    mi_store_reg_mem_param.offset = status_buffer->image_status_mask_offset;
> +    mi_store_reg_mem_param.mmio_offset = 
> status_buffer->image_status_mask_reg_offset;
> +    gen8_gpe_mi_store_register_mem(ctx, batch,&mi_store_reg_mem_param);
> +
> +    /*update the status in the pak_statistic_surface */
> +    mi_store_reg_mem_param.bo = 
> avc_ctx->res_brc_pre_pak_statistics_output_buffer.bo;
> +    mi_store_reg_mem_param.offset = 0;
> +    mi_store_reg_mem_param.mmio_offset = 
> status_buffer->bs_byte_count_frame_reg_offset;
> +    gen8_gpe_mi_store_register_mem(ctx, batch,&mi_store_reg_mem_param);
> +
> +    mi_store_reg_mem_param.bo = 
> avc_ctx->res_brc_pre_pak_statistics_output_buffer.bo;
> +    mi_store_reg_mem_param.offset = 4;
> +    mi_store_reg_mem_param.mmio_offset = 
> status_buffer->bs_byte_count_frame_nh_reg_offset;
> +    gen8_gpe_mi_store_register_mem(ctx, batch,&mi_store_reg_mem_param);
> +
> +    memset(&mi_store_data_imm_param, 0, sizeof(mi_store_data_imm_param));
> +    mi_store_data_imm_param.bo = 
> avc_ctx->res_brc_pre_pak_statistics_output_buffer.bo;
> +    mi_store_data_imm_param.offset = sizeof(unsigned int) * 2;
> +    mi_store_data_imm_param.dw0 = (generic_state->curr_pak_pass + 1);
> +    gen8_gpe_mi_store_data_imm(ctx, batch,&mi_store_data_imm_param);
> +
> +    mi_store_reg_mem_param.bo = 
> avc_ctx->res_brc_pre_pak_statistics_output_buffer.bo;
> +    mi_store_reg_mem_param.offset = sizeof(unsigned int) * (4 + 
> generic_state->curr_pak_pass) ;
> +    mi_store_reg_mem_param.mmio_offset = 
> status_buffer->image_status_ctrl_reg_offset;
> +    gen8_gpe_mi_store_register_mem(ctx, batch,&mi_store_reg_mem_param);
> +
> +    memset(&mi_flush_dw_param, 0, sizeof(mi_flush_dw_param));
> +    gen8_gpe_mi_flush_dw(ctx, batch,&mi_flush_dw_param);
> +
> +    return;
> +}
> +
> +static void
> +gen9_avc_pak_brc_prepare(struct encode_state *encode_state,
> +                          struct intel_encoder_context *encoder_context)
> +{
> +    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;
> +    unsigned int rate_control_mode = encoder_context->rate_control_mode;
> +
> +    switch (rate_control_mode&  0x7f) {
> +    case VA_RC_CBR:
> +        generic_state->internal_rate_mode = VA_RC_CBR;
> +        break;
> +
> +    case VA_RC_VBR:
> +        generic_state->internal_rate_mode = VA_RC_VBR;//AVBR
> +        break;
> +
> +    case VA_RC_CQP:
> +    default:
> +        generic_state->internal_rate_mode = VA_RC_CQP;
> +        break;
> +    }
> +
> +}
> +
> +static VAStatus
> +gen9_avc_pak_pipeline_prepare(VADriverContextP ctx,
> +                     struct encode_state *encode_state,
> +                     struct intel_encoder_context *encoder_context)
> +{
> +    VAStatus va_status;
> +    struct i965_driver_data *i965 = i965_driver_data(ctx);
> +    struct encoder_vme_mfc_context * pak_context = (struct 
> encoder_vme_mfc_context *)encoder_context->vme_context;
> +    struct generic_encoder_context * generic_ctx = (struct 
> generic_encoder_context * )pak_context->generic_enc_ctx;
> +    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 object_surface *obj_surface;
> +    VAEncPictureParameterBufferH264  *pic_param = avc_state->pic_param;
> +    VAEncSliceParameterBufferH264 *slice_param = avc_state->slice_param[0];
> +
> +    struct gen9_surface_avc *avc_priv_surface;
> +    int i, j, enable_avc_ildb = 0;
> +    unsigned int allocate_flag = 1;
> +    unsigned int size;
> +    unsigned int w_mb = generic_state->frame_width_in_mbs;
> +    unsigned int h_mb = generic_state->frame_height_in_mbs;
> +    struct avc_surface_param surface_param;
> +
> +    /* update the parameter and check slice parameter */
> +    for (j = 0; j<  encode_state->num_slice_params_ext&&  enable_avc_ildb == 
> 0; j++) {
> +        assert(encode_state->slice_params_ext&&  
> encode_state->slice_params_ext[j]->buffer);
> +        slice_param = (VAEncSliceParameterBufferH264 
> *)encode_state->slice_params_ext[j]->buffer;
> +
> +        for (i = 0; i<  encode_state->slice_params_ext[j]->num_elements; 
> i++) {
> +            assert((slice_param->slice_type == SLICE_TYPE_I) ||
> +                   (slice_param->slice_type == SLICE_TYPE_SI) ||
> +                   (slice_param->slice_type == SLICE_TYPE_P) ||
> +                   (slice_param->slice_type == SLICE_TYPE_SP) ||
> +                   (slice_param->slice_type == SLICE_TYPE_B));
> +
> +            if (slice_param->disable_deblocking_filter_idc != 1) {
> +                enable_avc_ildb = 1;
> +                break;
> +            }
> +
> +            slice_param++;
> +        }
> +    }
> +    avc_state->enable_avc_ildb = enable_avc_ildb;
> +
> +    /* setup the all surface and buffer for PAK */
> +    /* Setup current reconstruct frame */
> +    obj_surface = encode_state->reconstructed_object;
> +    va_status = i965_check_alloc_surface_bo(ctx, obj_surface, 1, 
> VA_FOURCC_NV12, SUBSAMPLE_YUV420);
> +
> +    if (va_status != VA_STATUS_SUCCESS)
> +        return va_status;
> +    memset(&surface_param,0,sizeof(surface_param));
> +    surface_param.frame_width = generic_state->frame_width_in_pixel;
> +    surface_param.frame_height = generic_state->frame_height_in_pixel;
> +    va_status = gen9_avc_init_check_surfaces(ctx,
> +                                             obj_surface,encoder_context,
> +&surface_param);
> +    if (va_status != VA_STATUS_SUCCESS)
> +        return va_status;
> +    /* init the member of avc_priv_surface,frame_store_id,qp_value */
> +    {
> +       avc_priv_surface = (struct gen9_surface_avc 
> *)obj_surface->private_data;
> +       avc_state->top_field_poc[NUM_MFC_AVC_DMV_BUFFERS-2] = 0;
> +       avc_state->top_field_poc[NUM_MFC_AVC_DMV_BUFFERS-1] = 0;
> +       
> i965_free_gpe_resource(&avc_ctx->res_direct_mv_buffersr[NUM_MFC_AVC_DMV_BUFFERS-2]);
> +       
> i965_free_gpe_resource(&avc_ctx->res_direct_mv_buffersr[NUM_MFC_AVC_DMV_BUFFERS-1]);
> +       
> i965_dri_object_to_buffer_gpe_resource(&avc_ctx->res_direct_mv_buffersr[NUM_MFC_AVC_DMV_BUFFERS-2],avc_priv_surface->dmv_top);
> +       
> i965_dri_object_to_buffer_gpe_resource(&avc_ctx->res_direct_mv_buffersr[NUM_MFC_AVC_DMV_BUFFERS-1],avc_priv_surface->dmv_bottom);
> +       dri_bo_reference(avc_priv_surface->dmv_top);
> +       dri_bo_reference(avc_priv_surface->dmv_bottom);
> +       avc_priv_surface->qp_value = pic_param->pic_init_qp + 
> slice_param->slice_qp_delta;
> +       avc_priv_surface->frame_store_id = 0;
> +       avc_priv_surface->frame_idx = pic_param->CurrPic.frame_idx;
> +       avc_priv_surface->top_field_order_cnt = 
> pic_param->CurrPic.TopFieldOrderCnt;
> +       avc_priv_surface->is_as_ref = 
> pic_param->pic_fields.bits.reference_pic_flag;
> +       avc_state->top_field_poc[NUM_MFC_AVC_DMV_BUFFERS-2] = 
> avc_priv_surface->top_field_order_cnt;
> +       avc_state->top_field_poc[NUM_MFC_AVC_DMV_BUFFERS-1] = 
> avc_priv_surface->top_field_order_cnt + 1;
> +    }
> +    i965_free_gpe_resource(&generic_ctx->res_reconstructed_surface);
> +    i965_free_gpe_resource(&avc_ctx->res_post_deblocking_output);
> +    i965_free_gpe_resource(&avc_ctx->res_pre_deblocking_output);
> +    
> i965_object_surface_to_2d_gpe_resource_with_align(&generic_ctx->res_reconstructed_surface,
>  obj_surface);
> +
> +
> +    if (avc_state->enable_avc_ildb) {
> +        
> i965_object_surface_to_2d_gpe_resource_with_align(&avc_ctx->res_post_deblocking_output,
>  obj_surface);
> +    } else {
> +        
> i965_object_surface_to_2d_gpe_resource_with_align(&avc_ctx->res_pre_deblocking_output,
>  obj_surface);
> +    }
> +    /* input YUV surface */
> +    obj_surface = encode_state->input_yuv_object;
> +    va_status = i965_check_alloc_surface_bo(ctx, obj_surface, 1, 
> VA_FOURCC_NV12, SUBSAMPLE_YUV420);
> +
> +    if (va_status != VA_STATUS_SUCCESS)
> +        return va_status;
> +    i965_free_gpe_resource(&generic_ctx->res_uncompressed_input_surface);
> +    
> i965_object_surface_to_2d_gpe_resource_with_align(&generic_ctx->res_uncompressed_input_surface,
>  obj_surface);
> +
> +    /* Reference surfaces */
> +    for (i = 0; i<  ARRAY_ELEMS(avc_ctx->list_reference_res); i++) {
> +        i965_free_gpe_resource(&avc_ctx->list_reference_res[i]);
> +        i965_free_gpe_resource(&avc_ctx->res_direct_mv_buffersr[i*2]);
> +        i965_free_gpe_resource(&avc_ctx->res_direct_mv_buffersr[i*2 + 1]);
> +        obj_surface = encode_state->reference_objects[i];
> +        avc_state->top_field_poc[2*i] = 0;
> +        avc_state->top_field_poc[2*i+1] = 0;
> +
> +        if (obj_surface&&  obj_surface->bo) {
> +            
> i965_object_surface_to_2d_gpe_resource_with_align(&avc_ctx->list_reference_res[i],
>  obj_surface);
> +
> +            /* actually it should be handled when it is reconstructed 
> surface */
> +            va_status = gen9_avc_init_check_surfaces(ctx,
> +                obj_surface,encoder_context,
> +&surface_param);
> +            if (va_status != VA_STATUS_SUCCESS)
> +                return va_status;
> +            avc_priv_surface = (struct gen9_surface_avc 
> *)obj_surface->private_data;
> +            
> i965_dri_object_to_buffer_gpe_resource(&avc_ctx->res_direct_mv_buffersr[i*2],avc_priv_surface->dmv_top);
> +            
> i965_dri_object_to_buffer_gpe_resource(&avc_ctx->res_direct_mv_buffersr[i*2 + 
> 1],avc_priv_surface->dmv_bottom);
> +            dri_bo_reference(avc_priv_surface->dmv_top);
> +            dri_bo_reference(avc_priv_surface->dmv_bottom);
> +            avc_priv_surface->frame_store_id = i;
> +            avc_state->top_field_poc[2*i] = 
> avc_priv_surface->top_field_order_cnt;
> +            avc_state->top_field_poc[2*i+1] = 
> avc_priv_surface->top_field_order_cnt+1;
> +        }else
> +        {
> +            break;
> +        }
> +    }
> +
> +    if (avc_ctx->pres_slice_batch_buffer_2nd_level)
> +        intel_batchbuffer_free(avc_ctx->pres_slice_batch_buffer_2nd_level);
> +
> +    avc_ctx->pres_slice_batch_buffer_2nd_level =
> +        intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD,
> +                              4096 *
> +                              encode_state->num_slice_params_ext);
> +    if (!avc_ctx->pres_slice_batch_buffer_2nd_level)
> +        return VA_STATUS_ERROR_ALLOCATION_FAILED;
> +
> +    for (i = 0;i<  MAX_AVC_SLICE_NUM;i++) {
> +        avc_state->slice_batch_offset[i] = 0;
> +    }
> +
> +
> +    size = w_mb * 64;
> +    i965_free_gpe_resource(&avc_ctx->res_intra_row_store_scratch_buffer);
> +    allocate_flag = i965_allocate_gpe_resource(i965->intel.bufmgr,
> +&avc_ctx->res_intra_row_store_scratch_buffer,
> +                                 size,
> +                                "PAK Intra row store scratch buffer");
> +    if (!allocate_flag)
> +        goto failed_allocation;
> +
> +    size = w_mb * 4 * 64;
> +    
> i965_free_gpe_resource(&avc_ctx->res_deblocking_filter_row_store_scratch_buffer);
> +    allocate_flag = i965_allocate_gpe_resource(i965->intel.bufmgr,
> +&avc_ctx->res_deblocking_filter_row_store_scratch_buffer,
> +                                 size,
> +                                "PAK Deblocking filter row store scratch 
> buffer");
> +    if (!allocate_flag)
> +        goto failed_allocation;
> +
> +    size = w_mb * 2 * 64;
> +    i965_free_gpe_resource(&avc_ctx->res_bsd_mpc_row_store_scratch_buffer);
> +    allocate_flag = i965_allocate_gpe_resource(i965->intel.bufmgr,
> +&avc_ctx->res_bsd_mpc_row_store_scratch_buffer,
> +                                 size,
> +                                "PAK BSD/MPC row store scratch buffer");
> +    if (!allocate_flag)
> +        goto failed_allocation;
> +
> +    size = w_mb * h_mb * 16;
> +    i965_free_gpe_resource(&avc_ctx->res_pak_mb_status_buffer);
> +    allocate_flag = i965_allocate_gpe_resource(i965->intel.bufmgr,
> +&avc_ctx->res_pak_mb_status_buffer,
> +                                 size,
> +                                "PAK MB status buffer");
> +    if (!allocate_flag)
> +        goto failed_allocation;
> +
> +    return VA_STATUS_SUCCESS;
> +
> +failed_allocation:
> +    return VA_STATUS_ERROR_ALLOCATION_FAILED;
> +}
> +
> +static VAStatus
> +gen9_avc_encode_picture(VADriverContextP ctx,
> +                        VAProfile profile,
> +                        struct encode_state *encode_state,
> +                        struct intel_encoder_context *encoder_context)
> +{
> +    VAStatus va_status;
> +    struct i965_driver_data *i965 = i965_driver_data(ctx);
> +    struct encoder_vme_mfc_context * vme_context = (struct 
> encoder_vme_mfc_context *)encoder_context->vme_context;
> +    struct gen9_avc_encoder_context * avc_ctx = (struct 
> gen9_avc_encoder_context * )vme_context->private_enc_ctx;
> +    struct generic_enc_codec_state * generic_state = (struct 
> generic_enc_codec_state * )vme_context->generic_enc_state;
> +    struct intel_batchbuffer *batch = encoder_context->base.batch;
> +
> +    va_status = gen9_avc_pak_pipeline_prepare(ctx, encode_state, 
> encoder_context);
> +
> +    if (va_status != VA_STATUS_SUCCESS)
> +        return va_status;
> +

Please check whether the below logic is correct.
It seems that it uses the GPU command of conditional end for the 
subsequent pass. In such case all the commands should be put into one 
batch buffer and it is submitted only once.
But the current logic causes that it is submitted multiple times.
[Pengfei] good comments. It will be fixed.

> +    for (generic_state->curr_pak_pass = 0;
> +         generic_state->curr_pak_pass<  generic_state->num_pak_passes;
> +         generic_state->curr_pak_pass++) {
> +
> +         if (i965->intel.has_bsd2)
> +             intel_batchbuffer_start_atomic_bcs_override(batch, 0x1000, 
> BSD_RING0);
> +         else
> +             intel_batchbuffer_start_atomic_bcs(batch, 0x1000);
> +         intel_batchbuffer_emit_mi_flush(batch);
> +
> +         if (generic_state->curr_pak_pass == 0) {
> +             /* Initialize the avc Image Ctrl reg for the first pass,write 0 
> to staturs/control register, is it needed in AVC? */
> +             struct gpe_mi_load_register_imm_parameter mi_load_reg_imm;
> +             struct encoder_status_buffer_internal *status_buffer;
> +
> +             status_buffer =&(avc_ctx->status_buffer);
> +             memset(&mi_load_reg_imm, 0, sizeof(mi_load_reg_imm));
> +             mi_load_reg_imm.mmio_offset = 
> status_buffer->image_status_ctrl_reg_offset;
> +             mi_load_reg_imm.data = 0;
> +             gen8_gpe_mi_load_register_imm(ctx, batch,&mi_load_reg_imm);
> +         }
> +         gen9_avc_pak_picture_level(ctx, encode_state, encoder_context);
> +         gen9_avc_pak_slice_level(ctx, encode_state, encoder_context);
> +         intel_batchbuffer_emit_mi_flush(batch);
> +
> +         gen9_avc_read_mfc_status(ctx, encoder_context);
> +         intel_batchbuffer_end_atomic(batch);
> +         intel_batchbuffer_flush(batch);
> +
> +    }
> +
> +    generic_state->seq_frame_number++;
> +    generic_state->total_frame_number++;
> +    generic_state->first_frame = 0;
> +    return VA_STATUS_SUCCESS;
> +}
> +
> +static VAStatus
> +gen9_avc_pak_pipeline(VADriverContextP ctx,
> +                      VAProfile profile,
> +                      struct encode_state *encode_state,
> +                      struct intel_encoder_context *encoder_context)
> +{
> +    VAStatus vaStatus;
> +
> +    switch (profile) {
> +    case VAProfileH264ConstrainedBaseline:
> +    case VAProfileH264Main:
> +    case VAProfileH264High:
> +        vaStatus = gen9_avc_encode_picture(ctx, profile, encode_state, 
> encoder_context);
> +        break;
> +
> +    default:
> +        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
> +        break;
> +    }
> +
> +    return vaStatus;
> +}
> +
> +static void
> +gen9_avc_pak_context_destroy(void * context)
> +{
> +    struct encoder_vme_mfc_context * pak_context = (struct 
> encoder_vme_mfc_context *)context;
> +    struct generic_encoder_context * generic_ctx = (struct 
> generic_encoder_context * )pak_context->generic_enc_ctx;
> +    struct gen9_avc_encoder_context * avc_ctx = (struct 
> gen9_avc_encoder_context * )pak_context->private_enc_ctx;
> +
> +    int i = 0;
> +
> +    if (!pak_context)
> +        return;
> +
> +    // other things
> +    i965_free_gpe_resource(&generic_ctx->res_reconstructed_surface);
> +    i965_free_gpe_resource(&avc_ctx->res_post_deblocking_output);
> +    i965_free_gpe_resource(&avc_ctx->res_pre_deblocking_output);
> +    i965_free_gpe_resource(&generic_ctx->res_uncompressed_input_surface);
> +
> +    i965_free_gpe_resource(&generic_ctx->compressed_bitstream.res);
> +    i965_free_gpe_resource(&avc_ctx->res_intra_row_store_scratch_buffer);
> +    
> i965_free_gpe_resource(&avc_ctx->res_deblocking_filter_row_store_scratch_buffer);
> +    i965_free_gpe_resource(&avc_ctx->res_bsd_mpc_row_store_scratch_buffer);
> +    i965_free_gpe_resource(&avc_ctx->res_pak_mb_status_buffer);
> +
> +    for(i = 0 ; i<  MAX_MFC_AVC_REFERENCE_SURFACES; i++)
> +    {
> +        i965_free_gpe_resource(&avc_ctx->list_reference_res[i]);
> +    }
> +
> +    for(i = 0 ; i<  NUM_MFC_AVC_DMV_BUFFERS; i++)
> +    {
> +        i965_free_gpe_resource(&avc_ctx->res_direct_mv_buffersr[i]);
> +    }
> +
> +    if (avc_ctx->pres_slice_batch_buffer_2nd_level)
> +    {
> +        intel_batchbuffer_free(avc_ctx->pres_slice_batch_buffer_2nd_level);
> +        avc_ctx->pres_slice_batch_buffer_2nd_level = NULL;
> +    }
> +
> +}
> +
> +static VAStatus
> +gen9_avc_get_coded_status(VADriverContextP ctx,
> +                          struct intel_encoder_context *encoder_context,
> +                          struct i965_coded_buffer_segment *coded_buf_seg)
> +{
> +    struct encoder_status *avc_encode_status;
> +
> +    if (!encoder_context || !coded_buf_seg)
> +        return VA_STATUS_ERROR_INVALID_BUFFER;
> +
> +    avc_encode_status = (struct encoder_status 
> *)coded_buf_seg->codec_private_data;
> +    coded_buf_seg->base.size = avc_encode_status->bs_byte_count_frame;
> +
> +    return VA_STATUS_SUCCESS;
> +}
> +

It will be better that this function is defined in Patch_07.
      > Add VME pipeline for H264 encoder
[Pengfei] it wll be moved to Patch_07.

> +Bool
> +gen9_avc_vme_context_init(VADriverContextP ctx, struct intel_encoder_context 
> *encoder_context)
> +{
> +    /* VME&  PAK share the same context */
> +    struct i965_driver_data *i965 = i965_driver_data(ctx);
> +    struct encoder_vme_mfc_context * vme_context = NULL;
> +    struct generic_encoder_context * generic_ctx = NULL;
> +    struct gen9_avc_encoder_context * avc_ctx = NULL;
> +    struct generic_enc_codec_state * generic_state = NULL;
> +    struct avc_enc_state * avc_state = NULL;
> +    struct encoder_status_buffer_internal *status_buffer;
> +    uint32_t base_offset = offsetof(struct i965_coded_buffer_segment, 
> codec_private_data);
> +
> +    vme_context = calloc(1, sizeof(struct encoder_vme_mfc_context));
> +    generic_ctx = calloc(1, sizeof(struct generic_encoder_context));
> +    avc_ctx = calloc(1, sizeof(struct gen9_avc_encoder_context));
> +    generic_state = calloc(1, sizeof(struct generic_enc_codec_state));
> +    avc_state = calloc(1, sizeof(struct avc_enc_state));
> +
> +    if(!vme_context || !generic_ctx || !avc_ctx || !generic_state || 
> !avc_state)
> +        goto allocate_structure_failed;
> +
> +    memset(vme_context,0,sizeof(struct encoder_vme_mfc_context));
> +    memset(generic_ctx,0,sizeof(struct generic_encoder_context));
> +    memset(avc_ctx,0,sizeof(struct gen9_avc_encoder_context));
> +    memset(generic_state,0,sizeof(struct generic_enc_codec_state));
> +    memset(avc_state,0,sizeof(struct avc_enc_state));
> +
> +    encoder_context->vme_context = vme_context;
> +    vme_context->generic_enc_ctx = generic_ctx;
> +    vme_context->private_enc_ctx = avc_ctx;
> +    vme_context->generic_enc_state = generic_state;
> +    vme_context->private_enc_state = avc_state;
> +
> +    if (IS_SKL(i965->intel.device_info)) {
> +        generic_ctx->enc_kernel_ptr = (void *)skl_avc_encoder_kernels;
> +        generic_ctx->enc_kernel_size = sizeof(skl_avc_encoder_kernels);
> +    }
> +    else
> +        goto allocate_structure_failed;
> +
> +    /* initialize misc ? */
> +    avc_ctx->ctx = ctx;
> +    generic_ctx->use_hw_scoreboard = 1;
> +    generic_ctx->use_hw_non_stalling_scoreboard = 1;
> +
> +    /* initialize generic state */
> +
> +    generic_state->kernel_mode = INTEL_ENC_KERNEL_NORMAL;
> +    generic_state->preset = INTEL_PRESET_RT_SPEED;
> +    generic_state->seq_frame_number = 0;
> +    generic_state->total_frame_number = 0;
> +    generic_state->frame_type = 0;
> +    generic_state->first_frame = 1;
> +
> +    generic_state->frame_width_in_pixel = 0;
> +    generic_state->frame_height_in_pixel = 0;
> +    generic_state->frame_width_in_mbs = 0;
> +    generic_state->frame_height_in_mbs = 0;
> +    generic_state->frame_width_4x = 0;
> +    generic_state->frame_height_4x = 0;
> +    generic_state->frame_width_16x = 0;
> +    generic_state->frame_height_16x = 0;
> +    generic_state->frame_width_32x = 0;
> +    generic_state->downscaled_width_4x_in_mb = 0;
> +    generic_state->downscaled_height_4x_in_mb = 0;
> +    generic_state->downscaled_width_16x_in_mb = 0;
> +    generic_state->downscaled_height_16x_in_mb = 0;
> +    generic_state->downscaled_width_32x_in_mb = 0;
> +    generic_state->downscaled_height_32x_in_mb = 0;
> +
> +    generic_state->hme_supported = 1;
> +    generic_state->b16xme_supported = 1;
> +    generic_state->b32xme_supported = 0;
> +    generic_state->hme_enabled = 0;
> +    generic_state->b16xme_enabled = 0;
> +    generic_state->b32xme_enabled = 0;
> +    generic_state->brc_distortion_buffer_supported = 1;
> +    generic_state->brc_constant_buffer_supported = 0;
> +
> +
> +    generic_state->frame_rate = 30;
> +    generic_state->brc_allocated = 0;
> +    generic_state->brc_inited = 0;
> +    generic_state->brc_need_reset = 0;
> +    generic_state->is_low_delay = 0;
> +    generic_state->brc_enabled = 0;//default
> +    generic_state->internal_rate_mode = 0;
> +    generic_state->curr_pak_pass = 0;
> +    generic_state->num_pak_passes = MAX_AVC_PAK_PASS_NUM;
> +    generic_state->is_first_pass = 1;
> +    generic_state->is_last_pass = 0;
> +    generic_state->mb_brc_enabled = 0; // enable mb brc
> +    generic_state->brc_roi_enable = 0;
> +    generic_state->brc_dirty_roi_enable = 0;
> +    generic_state->skip_frame_enbale = 0;
> +
> +    generic_state->target_bit_rate = 0;
> +    generic_state->max_bit_rate = 0;
> +    generic_state->min_bit_rate = 0;
> +    generic_state->init_vbv_buffer_fullness_in_bit = 0;
> +    generic_state->vbv_buffer_size_in_bit = 0;
> +    generic_state->frames_per_100s = 0;
> +    generic_state->gop_size = 0;
> +    generic_state->gop_ref_distance = 0;
> +    generic_state->brc_target_size = 0;
> +    generic_state->brc_mode = 0;
> +    generic_state->brc_init_current_target_buf_full_in_bits = 0.0;
> +    generic_state->brc_init_reset_input_bits_per_frame = 0.0;
> +    generic_state->brc_init_reset_buf_size_in_bits = 0;
> +    generic_state->brc_init_previous_target_buf_full_in_bits = 0;
> +    generic_state->window_size = 0;//default
> +    generic_state->target_percentage = 0;
> +
> +    generic_state->avbr_curracy = 0;
> +    generic_state->avbr_convergence = 0;
> +
> +    generic_state->num_skip_frames = 0;
> +    generic_state->size_skip_frames = 0;
> +
> +    generic_state->num_roi = 0;
> +    generic_state->max_delta_qp = 0;
> +    generic_state->min_delta_qp = 0;
> +
> +    if (encoder_context->rate_control_mode != VA_RC_NONE&&
> +        encoder_context->rate_control_mode != VA_RC_CQP) {
> +        generic_state->brc_enabled = 1;
> +        generic_state->brc_distortion_buffer_supported = 1;
> +        generic_state->brc_constant_buffer_supported = 1;
> +        generic_state->num_pak_passes = MAX_AVC_PAK_PASS_NUM;
> +    }
> +    /*avc state initialization */
> +    avc_state->mad_enable = 0;
> +    avc_state->mb_disable_skip_map_enable = 0;
> +    avc_state->sfd_enable = 1;//default
> +    avc_state->sfd_mb_enable = 1;//set it true
> +    avc_state->adaptive_search_window_enable = 1;//default
> +    avc_state->mb_qp_data_enable = 0;
> +    avc_state->intra_refresh_i_enable = 0;
> +    avc_state->min_max_qp_enable = 0;
> +    avc_state->skip_bias_adjustment_enable = 0;//default,same as   
> skip_bias_adjustment_supporte? no
> +
> +    //external input
> +    avc_state->non_ftq_skip_threshold_lut_input_enable = 0;
> +    avc_state->ftq_skip_threshold_lut_input_enable = 0;
> +    avc_state->ftq_override = 0;
> +
> +    avc_state->direct_bias_adjustment_enable = 0;
> +    avc_state->global_motion_bias_adjustment_enable = 0;
> +    avc_state->disable_sub_mb_partion = 0;
> +    avc_state->arbitrary_num_mbs_in_slice = 0;
> +    avc_state->adaptive_transform_decision_enable = 0;//default
> +    avc_state->skip_check_disable = 0;
> +    avc_state->tq_enable = 0;
> +    avc_state->enable_avc_ildb = 0;
> +    avc_state->mbaff_flag = 0;
> +    avc_state->enable_force_skip = 1;//default
> +    avc_state->rc_panic_enable = 1;//default
> +    avc_state->suppress_recon_enable = 1;//default
> +
> +    avc_state->ref_pic_select_list_supported = 1;
> +    avc_state->mb_brc_supported = 1;//?,default
> +    avc_state->multi_pre_enable = 1;//default
> +    avc_state->ftq_enable = 1;//default
> +    avc_state->caf_supported = 1; //default
> +    avc_state->caf_enable = 0;
> +    avc_state->caf_disable_hd = 1;//default
> +    avc_state->skip_bias_adjustment_supported = 1;//default
> +
> +    avc_state->adaptive_intra_scaling_enable = 1;//default
> +    avc_state->old_mode_cost_enable = 0;//default
> +    avc_state->multi_ref_qp_enable = 1;//default
> +    avc_state->weighted_ref_l0_enable = 1;//default
> +    avc_state->weighted_ref_l1_enable = 1;//default
> +    avc_state->weighted_prediction_supported = 0;
> +    avc_state->brc_split_enable = 0;
> +    avc_state->slice_level_report_supported = 0;
> +
> +    avc_state->fbr_bypass_enable = 1;//default
> +    avc_state->field_scaling_output_interleaved = 0;
> +    avc_state->mb_variance_output_enable = 0;
> +    avc_state->mb_pixel_average_output_enable = 0;
> +    avc_state->rolling_intra_refresh_enable = 0;// same as 
> intra_refresh_i_enable?
> +    avc_state->mbenc_curbe_set_in_brc_update = 0;
> +    avc_state->rounding_inter_enable = 1; //default
> +    avc_state->adaptive_rounding_inter_enable = 1;//default
> +
> +    avc_state->mbenc_i_frame_dist_in_use = 0;
> +    avc_state->mb_status_supported = 1; //set in intialization for gen9
> +    avc_state->mb_status_enable = 0;
> +    avc_state->mb_vproc_stats_enable = 0;
> +    avc_state->flatness_check_enable = 0;
> +    avc_state->flatness_check_supported = 1;//default
> +    avc_state->block_based_skip_enable = 0;
> +    avc_state->use_widi_mbenc_kernel = 0;
> +    avc_state->kernel_trellis_enable = 0;
> +    avc_state->generic_reserved = 0;
> +
> +    avc_state->rounding_value = 0;
> +    avc_state->rounding_inter_p = 255;//default
> +    avc_state->rounding_inter_b = 255; //default
> +    avc_state->rounding_inter_b_ref = 255; //default
> +    avc_state->min_qp_i = INTEL_AVC_MIN_QP;
> +    avc_state->min_qp_p = INTEL_AVC_MIN_QP;
> +    avc_state->min_qp_b = INTEL_AVC_MIN_QP;
> +    avc_state->max_qp_i = INTEL_AVC_MAX_QP;
> +    avc_state->max_qp_p = INTEL_AVC_MAX_QP;
> +    avc_state->max_qp_b = INTEL_AVC_MAX_QP;
> +
> +    memset(avc_state->non_ftq_skip_threshold_lut,0,52*sizeof(uint8_t));
> +    memset(avc_state->ftq_skip_threshold_lut,0,52*sizeof(uint8_t));
> +    memset(avc_state->lamda_value_lut,0,52*2*sizeof(uint8_t));
> +
> +    avc_state->intra_refresh_qp_threshold = 0;
> +    avc_state->trellis_flag = 0;
> +    avc_state->hme_mv_cost_scaling_factor = 0;
> +    avc_state->slice_height = 1;
> +    avc_state->slice_num = 1;
> +    memset(avc_state->dist_scale_factor_list0,0,32*sizeof(uint32_t));
> +    avc_state->bi_weight = 0;
> +    avc_state->brc_const_data_surface_width = 64;
> +    avc_state->brc_const_data_surface_height = 44;
> +
> +    avc_state->num_refs[0] = 0;
> +    avc_state->num_refs[1] = 0;
> +    memset(avc_state->list_ref_idx,0,32*2*sizeof(uint32_t));
> +    
> memset(avc_state->top_field_poc,0,NUM_MFC_AVC_DMV_BUFFERS*sizeof(int32_t));
> +    avc_state->tq_rounding = 0;
> +    avc_state->zero_mv_threshold = 0;
> +    avc_state->slice_second_levle_batch_buffer_in_use = 0;
> +
> +    //1. seq/pic/slice
> +
> +    /* the definition of status buffer offset for Encoder */
> +
> +    status_buffer =&avc_ctx->status_buffer;
> +    memset(status_buffer, 0,sizeof(struct encoder_status_buffer_internal));
> +
> +    status_buffer->base_offset = base_offset;
> +    status_buffer->bs_byte_count_frame_offset = base_offset + 
> offsetof(struct encoder_status, bs_byte_count_frame);
> +    status_buffer->bs_byte_count_frame_nh_offset = base_offset + 
> offsetof(struct encoder_status, bs_byte_count_frame_nh);
> +    status_buffer->image_status_mask_offset = base_offset + offsetof(struct 
> encoder_status, image_status_mask);
> +    status_buffer->image_status_ctrl_offset = base_offset + offsetof(struct 
> encoder_status, image_status_ctrl);
> +    status_buffer->mfc_qp_status_count_offset = base_offset + 
> offsetof(struct encoder_status, mfc_qp_status_count);
> +    status_buffer->media_index_offset       = base_offset + offsetof(struct 
> encoder_status, media_index);
> +
> +    status_buffer->status_buffer_size = sizeof(struct encoder_status);
> +    status_buffer->bs_byte_count_frame_reg_offset = 
> MFC_BITSTREAM_BYTECOUNT_FRAME_REG;
> +    status_buffer->bs_byte_count_frame_nh_reg_offset = 
> MFC_BITSTREAM_BYTECOUNT_SLICE_REG;
> +    status_buffer->image_status_mask_reg_offset = MFC_IMAGE_STATUS_MASK_REG;
> +    status_buffer->image_status_ctrl_reg_offset = MFC_IMAGE_STATUS_CTRL_REG;
> +    status_buffer->mfc_qp_status_count_reg_offset = MFC_QP_STATUS_COUNT_REG;
> +
> +    gen9_avc_kernel_init(ctx,encoder_context);
> +    encoder_context->vme_context = vme_context;
> +    encoder_context->vme_pipeline = gen9_avc_vme_pipeline;
> +    encoder_context->vme_context_destroy = gen9_avc_vme_context_destroy;
> +
> +    return true;
> +
> +allocate_structure_failed:
> +
> +    if(vme_context)
> +        free(vme_context);
> +
> +    if(generic_ctx)
> +        free(generic_ctx);
> +
> +    if(avc_ctx)
> +        free(avc_ctx);
> +
> +    if(generic_state)
> +        free(generic_state);
> +
> +    if(avc_state)
> +        free(avc_state);
> +
> +    return false;
> +}
> +
> +Bool
> +gen9_avc_pak_context_init(VADriverContextP ctx, struct intel_encoder_context 
> *encoder_context)
> +{
> +    /* VME&  PAK share the same context */
> +    struct encoder_vme_mfc_context * pak_context = (struct 
> encoder_vme_mfc_context *)encoder_context->vme_context;
> +
> +    if (!pak_context)
> +        return false;
> +
> +    encoder_context->mfc_context = pak_context;
> +    encoder_context->mfc_context_destroy = gen9_avc_pak_context_destroy;
> +    encoder_context->mfc_pipeline = gen9_avc_pak_pipeline;
> +    encoder_context->mfc_brc_prepare = gen9_avc_pak_brc_prepare;
> +    encoder_context->get_status = gen9_avc_get_coded_status;
> +    return true;
> +}

_______________________________________________
Libva mailing list
Libva@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libva

Reply via email to