#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <math.h>
#include "intel_batchbuffer.h"
#include "i965_defines.h"
#include "i965_encoder_utils.h"
#include "gen6_mfc.h"
#include "gen6_vme.h"
+#include "intel_media.h"
-#define CMD_LEN_IN_OWORD 4
+#define SURFACE_STATE_PADDED_SIZE MAX(SURFACE_STATE_PADDED_SIZE_GEN6, SURFACE_STATE_PADDED_SIZE_GEN7)
+#define SURFACE_STATE_OFFSET(index) (SURFACE_STATE_PADDED_SIZE * index)
+#define BINDING_TABLE_OFFSET(index) (SURFACE_STATE_OFFSET(MAX_MEDIA_SURFACES_GEN6) + sizeof(unsigned int) * index)
static const uint32_t gen6_mfc_batchbuffer_avc_intra[][4] = {
#include "shaders/utils/mfc_batchbuffer_avc_intra.g6b"
ADVANCE_BCS_BATCH(batch);
}
-static void
+void
gen6_mfc_pipe_buf_addr_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
{
struct intel_batchbuffer *batch = encoder_context->base.batch;
ADVANCE_BCS_BATCH(batch);
}
-static void
+void
gen6_mfc_bsp_buf_base_addr_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
{
struct intel_batchbuffer *batch = encoder_context->base.batch;
int beginy = beginmb / width_in_mbs;
int nextx = endmb % width_in_mbs;
int nexty = endmb / width_in_mbs;
- int slice_type = slice_param->slice_type;
+ int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
int last_slice = (endmb == (width_in_mbs * height_in_mbs));
- int bit_rate_control_target, maxQpN, maxQpP;
+ int maxQpN, maxQpP;
unsigned char correct[6], grow, shrink;
int i;
int weighted_pred_idc = 0;
unsigned int luma_log2_weight_denom = slice_param->luma_log2_weight_denom;
unsigned int chroma_log2_weight_denom = slice_param->chroma_log2_weight_denom;
+ int num_ref_l0 = 0, num_ref_l1 = 0;
if (batch == NULL)
batch = encoder_context->base.batch;
- if (slice_type == SLICE_TYPE_I)
- bit_rate_control_target = 0;
- else
- bit_rate_control_target = 1;
-
- if (slice_type == SLICE_TYPE_P) {
+ 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;
+
+ 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;
+
+ 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) */
}
}
- maxQpN = mfc_context->bit_rate_control_context[bit_rate_control_target].MaxQpNegModifier;
- maxQpP = mfc_context->bit_rate_control_context[bit_rate_control_target].MaxQpPosModifier;
+ maxQpN = mfc_context->bit_rate_control_context[slice_type].MaxQpNegModifier;
+ maxQpP = mfc_context->bit_rate_control_context[slice_type].MaxQpPosModifier;
for (i = 0; i < 6; i++)
- correct[i] = mfc_context->bit_rate_control_context[bit_rate_control_target].Correct[i];
+ correct[i] = mfc_context->bit_rate_control_context[slice_type].Correct[i];
- grow = mfc_context->bit_rate_control_context[bit_rate_control_target].GrowInit +
- (mfc_context->bit_rate_control_context[bit_rate_control_target].GrowResistance << 4);
- shrink = mfc_context->bit_rate_control_context[bit_rate_control_target].ShrinkInit +
- (mfc_context->bit_rate_control_context[bit_rate_control_target].ShrinkResistance << 4);
+ grow = mfc_context->bit_rate_control_context[slice_type].GrowInit +
+ (mfc_context->bit_rate_control_context[slice_type].GrowResistance << 4);
+ shrink = mfc_context->bit_rate_control_context[slice_type].ShrinkInit +
+ (mfc_context->bit_rate_control_context[slice_type].ShrinkResistance << 4);
BEGIN_BCS_BATCH(batch, 11);;
OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2) );
OUT_BCS_BATCH(batch, slice_type); /*Slice Type: I:P:B Slice*/
- if (slice_type == SLICE_TYPE_I) {
- OUT_BCS_BATCH(batch, 0); /*no reference frames and pred_weight_table*/
- } else {
- OUT_BCS_BATCH(batch,
- (1 << 16) | /*1 reference frame*/
- (chroma_log2_weight_denom << 8) |
- (luma_log2_weight_denom << 0));
- }
+ OUT_BCS_BATCH(batch,
+ (num_ref_l0 << 16) |
+ (num_ref_l1 << 24) |
+ (chroma_log2_weight_denom << 8) |
+ (luma_log2_weight_denom << 0));
OUT_BCS_BATCH(batch,
(weighted_pred_idc << 30) |
slice_param->macroblock_address );
OUT_BCS_BATCH(batch, (nexty << 16) | nextx); /*Next slice first MB X&Y*/
OUT_BCS_BATCH(batch,
- (rate_control_enable << 31) | /*in CBR mode RateControlCounterEnable = enable*/
+ (0/*rate_control_enable*/ << 31) | /*in CBR mode RateControlCounterEnable = enable*/
(1 << 30) | /*ResetRateControlCounter*/
(0 << 28) | /*RC Triggle Mode = Always Rate Control*/
(4 << 24) | /*RC Stable Tolerance, middle level*/
- (rate_control_enable << 23) | /*RC Panic Enable*/
+ (0/*rate_control_enable*/ << 23) | /*RC Panic Enable*/
(0 << 22) | /*QP mode, don't modfiy CBP*/
(0 << 21) | /*MB Type Direct Conversion Enabled*/
(0 << 20) | /*MB Type Skip Conversion Enabled*/
}
static void
-gen6_mfc_avc_ref_idx_state(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
-{
- struct intel_batchbuffer *batch = encoder_context->base.batch;
- int i;
-
- BEGIN_BCS_BATCH(batch, 10);
- OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | 8);
- OUT_BCS_BATCH(batch, 0); //Select L0
- OUT_BCS_BATCH(batch, 0x80808020); //Only 1 reference
- for(i = 0; i < 7; i++) {
- OUT_BCS_BATCH(batch, 0x80808080);
- }
- ADVANCE_BCS_BATCH(batch);
-
- 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, 0x80808022); //Only 1 reference
- for(i = 0; i < 7; i++) {
- OUT_BCS_BATCH(batch, 0x80808080);
- }
- ADVANCE_BCS_BATCH(batch);
-}
-
-static void
gen6_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,
ADVANCE_BCS_BATCH(batch);
}
-static void gen6_mfc_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context)
+void
+gen6_mfc_init(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
dri_bo *bo;
int i;
+ int width_in_mbs = 0;
+ int height_in_mbs = 0;
+ int slice_batchbuffer_size;
+
+ if (encoder_context->codec == CODEC_H264) {
+ VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
+ width_in_mbs = pSequenceParameter->picture_width_in_mbs;
+ height_in_mbs = pSequenceParameter->picture_height_in_mbs;
+ } else {
+ VAEncSequenceParameterBufferMPEG2 *pSequenceParameter = (VAEncSequenceParameterBufferMPEG2 *)encode_state->seq_param_ext->buffer;
+
+ assert(encoder_context->codec == CODEC_MPEG2);
+
+ width_in_mbs = ALIGN(pSequenceParameter->picture_width, 16) / 16;
+ height_in_mbs = ALIGN(pSequenceParameter->picture_height, 16) / 16;
+ }
+
+ slice_batchbuffer_size = 64 * width_in_mbs * height_in_mbs + 4096 +
+ (SLICE_HEADER + SLICE_TAIL) * encode_state->num_slice_params_ext;
/*Encode common setup for MFC*/
dri_bo_unreference(mfc_context->post_deblocking_output.bo);
dri_bo_unreference(mfc_context->intra_row_store_scratch_buffer.bo);
bo = dri_bo_alloc(i965->intel.bufmgr,
"Buffer",
- 128 * 64,
+ width_in_mbs * 64,
64);
assert(bo);
mfc_context->intra_row_store_scratch_buffer.bo = bo;
dri_bo_unreference(mfc_context->macroblock_status_buffer.bo);
bo = dri_bo_alloc(i965->intel.bufmgr,
"Buffer",
- 128*128*16,
+ width_in_mbs * height_in_mbs * 16,
64);
assert(bo);
mfc_context->macroblock_status_buffer.bo = bo;
dri_bo_unreference(mfc_context->deblocking_filter_row_store_scratch_buffer.bo);
bo = dri_bo_alloc(i965->intel.bufmgr,
"Buffer",
- 49152, /* 6 * 128 * 64 */
+ 4 * width_in_mbs * 64, /* 4 * width_in_mbs * 64 */
64);
assert(bo);
mfc_context->deblocking_filter_row_store_scratch_buffer.bo = bo;
dri_bo_unreference(mfc_context->bsd_mpc_row_store_scratch_buffer.bo);
bo = dri_bo_alloc(i965->intel.bufmgr,
"Buffer",
- 12288, /* 1.5 * 128 * 64 */
+ 128 * width_in_mbs, /* 2 * widht_in_mbs * 64 */
0x1000);
assert(bo);
mfc_context->bsd_mpc_row_store_scratch_buffer.bo = bo;
if (mfc_context->aux_batchbuffer)
intel_batchbuffer_free(mfc_context->aux_batchbuffer);
- mfc_context->aux_batchbuffer = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD);
+ mfc_context->aux_batchbuffer = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD,
+ slice_batchbuffer_size);
mfc_context->aux_batchbuffer_surface.bo = mfc_context->aux_batchbuffer->buffer;
dri_bo_reference(mfc_context->aux_batchbuffer_surface.bo);
mfc_context->aux_batchbuffer_surface.pitch = 16;
i965_gpe_context_init(ctx, &mfc_context->gpe_context);
}
-static void gen6_mfc_avc_pipeline_header_programing(VADriverContextP ctx,
- struct encode_state *encode_state,
- struct intel_encoder_context *encoder_context,
- struct intel_batchbuffer *slice_batch)
-{
- struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
- static int count = 0;
- unsigned int rate_control_mode = encoder_context->rate_control_mode;
-
- if (encode_state->packed_header_data[VAEncPackedHeaderH264_SPS]) {
- VAEncPackedHeaderParameterBuffer *param = NULL;
- unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[VAEncPackedHeaderH264_SPS]->buffer;
- unsigned int length_in_bits;
-
- assert(encode_state->packed_header_param[VAEncPackedHeaderH264_SPS]);
- param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[VAEncPackedHeaderH264_SPS]->buffer;
- length_in_bits = param->bit_length;
-
- mfc_context->insert_object(ctx,
- encoder_context,
- header_data,
- ALIGN(length_in_bits, 32) >> 5,
- length_in_bits & 0x1f,
- 5, /* FIXME: check it */
- 0,
- 0,
- !param->has_emulation_bytes,
- slice_batch);
- }
-
- if (encode_state->packed_header_data[VAEncPackedHeaderH264_PPS]) {
- VAEncPackedHeaderParameterBuffer *param = NULL;
- unsigned int *header_data = (unsigned int *)encode_state->packed_header_data[VAEncPackedHeaderH264_PPS]->buffer;
- unsigned int length_in_bits;
-
- assert(encode_state->packed_header_param[VAEncPackedHeaderH264_PPS]);
- param = (VAEncPackedHeaderParameterBuffer *)encode_state->packed_header_param[VAEncPackedHeaderH264_PPS]->buffer;
- length_in_bits = param->bit_length;
-
- mfc_context->insert_object(ctx,
- encoder_context,
- header_data,
- ALIGN(length_in_bits, 32) >> 5,
- length_in_bits & 0x1f,
- 5, /* FIXME: check it */
- 0,
- 0,
- !param->has_emulation_bytes,
- slice_batch);
- }
-
- if ( (rate_control_mode == VA_RC_CBR) && encode_state->packed_header_data[VAEncPackedHeaderH264_SPS]) { // this is frist AU
- struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
-
- unsigned char *sei_data = NULL;
- int length_in_bits = build_avc_sei_buffering_period(mfc_context->vui_hrd.i_initial_cpb_removal_delay_length,
- mfc_context->vui_hrd.i_initial_cpb_removal_delay, 0, &sei_data);
- mfc_context->insert_object(ctx,
- encoder_context,
- (unsigned int *)sei_data,
- ALIGN(length_in_bits, 32) >> 5,
- length_in_bits & 0x1f,
- 4,
- 0,
- 0,
- 1,
- slice_batch);
- free(sei_data);
- }
-
- // SEI pic_timing header
- if (rate_control_mode == VA_RC_CBR) {
- struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
- unsigned char *sei_data = NULL;
- int length_in_bits = build_avc_sei_pic_timing( mfc_context->vui_hrd.i_cpb_removal_delay_length,
- mfc_context->vui_hrd.i_cpb_removal_delay * mfc_context->vui_hrd.i_frame_number,
- mfc_context->vui_hrd.i_dpb_output_delay_length,
- 0, &sei_data);
- mfc_context->insert_object(ctx,
- encoder_context,
- (unsigned int *)sei_data,
- ALIGN(length_in_bits, 32) >> 5,
- length_in_bits & 0x1f,
- 4,
- 0,
- 0,
- 1,
- slice_batch);
- free(sei_data);
- }
-
- count++;
-}
-
static void gen6_mfc_avc_pipeline_picture_programing( VADriverContextP ctx,
- struct encode_state *encode_state,
- struct intel_encoder_context *encoder_context)
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
{
struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
mfc_context->avc_qm_state(ctx, encoder_context);
mfc_context->avc_fqm_state(ctx, encoder_context);
gen6_mfc_avc_directmode_state(ctx, encoder_context);
- gen6_mfc_avc_ref_idx_state(ctx, encoder_context);
-}
-
-static void
-gen6_mfc_free_avc_surface(void **data)
-{
- struct gen6_mfc_avc_surface_aux *avc_surface = *data;
-
- if (!avc_surface)
- return;
-
- dri_bo_unreference(avc_surface->dmv_top);
- avc_surface->dmv_top = NULL;
- dri_bo_unreference(avc_surface->dmv_bottom);
- avc_surface->dmv_bottom = NULL;
-
- free(avc_surface);
- *data = NULL;
+ intel_mfc_avc_ref_idx_state(ctx, encode_state, encoder_context);
}
-static void
-gen6_mfc_bit_rate_control_context_init(struct encode_state *encode_state,
- struct gen6_mfc_context *mfc_context)
-{
- VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
-
- int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
- int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
- float fps = pSequenceParameter->time_scale * 0.5 / pSequenceParameter->num_units_in_tick ;
- int inter_mb_size = pSequenceParameter->bits_per_second * 1.0 / (fps+4.0) / width_in_mbs / height_in_mbs;
- int intra_mb_size = inter_mb_size * 5.0;
- int i;
-
- mfc_context->bit_rate_control_context[0].target_mb_size = intra_mb_size;
- mfc_context->bit_rate_control_context[0].target_frame_size = intra_mb_size * width_in_mbs * height_in_mbs;
- mfc_context->bit_rate_control_context[1].target_mb_size = inter_mb_size;
- mfc_context->bit_rate_control_context[1].target_frame_size = inter_mb_size * width_in_mbs * height_in_mbs;
-
- for(i = 0 ; i < 2; i++) {
- mfc_context->bit_rate_control_context[i].QpPrimeY = 26;
- mfc_context->bit_rate_control_context[i].MaxQpNegModifier = 6;
- mfc_context->bit_rate_control_context[i].MaxQpPosModifier = 6;
- mfc_context->bit_rate_control_context[i].GrowInit = 6;
- mfc_context->bit_rate_control_context[i].GrowResistance = 4;
- mfc_context->bit_rate_control_context[i].ShrinkInit = 6;
- mfc_context->bit_rate_control_context[i].ShrinkResistance = 4;
-
- mfc_context->bit_rate_control_context[i].Correct[0] = 8;
- mfc_context->bit_rate_control_context[i].Correct[1] = 4;
- mfc_context->bit_rate_control_context[i].Correct[2] = 2;
- mfc_context->bit_rate_control_context[i].Correct[3] = 2;
- mfc_context->bit_rate_control_context[i].Correct[4] = 4;
- mfc_context->bit_rate_control_context[i].Correct[5] = 8;
- }
-
- mfc_context->bit_rate_control_context[0].TargetSizeInWord = (intra_mb_size + 16)/ 16;
- mfc_context->bit_rate_control_context[1].TargetSizeInWord = (inter_mb_size + 16)/ 16;
-
- mfc_context->bit_rate_control_context[0].MaxSizeInWord = mfc_context->bit_rate_control_context[0].TargetSizeInWord * 1.5;
- mfc_context->bit_rate_control_context[1].MaxSizeInWord = mfc_context->bit_rate_control_context[1].TargetSizeInWord * 1.5;
-}
-static int gen6_mfc_bit_rate_control_context_update(struct encode_state *encode_state,
- struct gen6_mfc_context *mfc_context,
- int current_frame_size)
-{
- VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
- int control_index = 1 - (pSliceParameter->slice_type == SLICE_TYPE_I);
- int oldQp = mfc_context->bit_rate_control_context[control_index].QpPrimeY;
-
- /*
- printf("conrol_index = %d, start_qp = %d, result = %d, target = %d\n", control_index,
- mfc_context->bit_rate_control_context[control_index].QpPrimeY, current_frame_size,
- mfc_context->bit_rate_control_context[control_index].target_frame_size );
- */
-
- if ( current_frame_size > mfc_context->bit_rate_control_context[control_index].target_frame_size * 4.0 ) {
- mfc_context->bit_rate_control_context[control_index].QpPrimeY += 4;
- } else if ( current_frame_size > mfc_context->bit_rate_control_context[control_index].target_frame_size * 2.0 ) {
- mfc_context->bit_rate_control_context[control_index].QpPrimeY += 3;
- } else if ( current_frame_size > mfc_context->bit_rate_control_context[control_index].target_frame_size * 1.50 ) {
- mfc_context->bit_rate_control_context[control_index].QpPrimeY += 2;
- } else if ( current_frame_size > mfc_context->bit_rate_control_context[control_index].target_frame_size * 1.20 ) {
- mfc_context->bit_rate_control_context[control_index].QpPrimeY ++;
- } else if (current_frame_size < mfc_context->bit_rate_control_context[control_index].target_frame_size * 0.30 ) {
- mfc_context->bit_rate_control_context[control_index].QpPrimeY -= 3;
- } else if (current_frame_size < mfc_context->bit_rate_control_context[control_index].target_frame_size * 0.50 ) {
- mfc_context->bit_rate_control_context[control_index].QpPrimeY -= 2;
- } else if (current_frame_size < mfc_context->bit_rate_control_context[control_index].target_frame_size * 0.80 ) {
- mfc_context->bit_rate_control_context[control_index].QpPrimeY --;
- }
-
- if ( mfc_context->bit_rate_control_context[control_index].QpPrimeY > 51)
- mfc_context->bit_rate_control_context[control_index].QpPrimeY = 51;
- if ( mfc_context->bit_rate_control_context[control_index].QpPrimeY < 1)
- mfc_context->bit_rate_control_context[control_index].QpPrimeY = 1;
-
- if ( mfc_context->bit_rate_control_context[control_index].QpPrimeY != oldQp)
- return 0;
-
- return 1;
-}
-
-static void
-gen6_mfc_hrd_context_init(struct encode_state *encode_state,
- struct intel_encoder_context *encoder_context)
-{
- struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
- VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
- unsigned int rate_control_mode = encoder_context->rate_control_mode;
- int target_bit_rate = pSequenceParameter->bits_per_second;
-
- // current we only support CBR mode.
- if (rate_control_mode == VA_RC_CBR) {
- mfc_context->vui_hrd.i_bit_rate_value = target_bit_rate >> 10;
- mfc_context->vui_hrd.i_cpb_size_value = (target_bit_rate * 8) >> 10;
- mfc_context->vui_hrd.i_initial_cpb_removal_delay = mfc_context->vui_hrd.i_cpb_size_value * 0.5 * 1024 / target_bit_rate * 90000;
- mfc_context->vui_hrd.i_cpb_removal_delay = 2;
- mfc_context->vui_hrd.i_frame_number = 0;
-
- mfc_context->vui_hrd.i_initial_cpb_removal_delay_length = 24;
- mfc_context->vui_hrd.i_cpb_removal_delay_length = 24;
- mfc_context->vui_hrd.i_dpb_output_delay_length = 24;
- }
-
-}
-
-static void
-gen6_mfc_hrd_context_update(struct encode_state *encode_state,
- struct gen6_mfc_context *mfc_context)
-{
- mfc_context->vui_hrd.i_frame_number++;
-}
-
-static VAStatus gen6_mfc_avc_prepare(VADriverContextP ctx,
- struct encode_state *encode_state,
- struct intel_encoder_context *encoder_context)
-{
- struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
- struct object_surface *obj_surface;
- struct object_buffer *obj_buffer;
- struct gen6_mfc_avc_surface_aux* gen6_avc_surface;
- dri_bo *bo;
- VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
- unsigned int rate_control_mode = encoder_context->rate_control_mode;
- VAStatus vaStatus = VA_STATUS_SUCCESS;
- int i, j, enable_avc_ildb = 0;
- VAEncSliceParameterBufferH264 *slice_param;
-
- 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++;
- }
- }
-
- /*Setup all the input&output object*/
-
- /* Setup current frame and current direct mv buffer*/
- obj_surface = SURFACE(pPicParameter->CurrPic.picture_id);
- assert(obj_surface);
- i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
-
- if ( obj_surface->private_data == NULL) {
- gen6_avc_surface = calloc(sizeof(struct gen6_mfc_avc_surface_aux), 1);
- gen6_avc_surface->dmv_top =
- dri_bo_alloc(i965->intel.bufmgr,
- "Buffer",
- 68*8192,
- 64);
- gen6_avc_surface->dmv_bottom =
- dri_bo_alloc(i965->intel.bufmgr,
- "Buffer",
- 68*8192,
- 64);
- assert(gen6_avc_surface->dmv_top);
- assert(gen6_avc_surface->dmv_bottom);
- obj_surface->private_data = (void *)gen6_avc_surface;
- obj_surface->free_private_data = (void *)gen6_mfc_free_avc_surface;
- }
- gen6_avc_surface = (struct gen6_mfc_avc_surface_aux*) obj_surface->private_data;
- mfc_context->direct_mv_buffers[NUM_MFC_DMV_BUFFERS - 2].bo = gen6_avc_surface->dmv_top;
- mfc_context->direct_mv_buffers[NUM_MFC_DMV_BUFFERS - 1].bo = gen6_avc_surface->dmv_bottom;
- dri_bo_reference(gen6_avc_surface->dmv_top);
- dri_bo_reference(gen6_avc_surface->dmv_bottom);
-
- if (enable_avc_ildb) {
- mfc_context->post_deblocking_output.bo = obj_surface->bo;
- dri_bo_reference(mfc_context->post_deblocking_output.bo);
- } else {
- mfc_context->pre_deblocking_output.bo = obj_surface->bo;
- dri_bo_reference(mfc_context->pre_deblocking_output.bo);
- }
-
- mfc_context->surface_state.width = obj_surface->orig_width;
- mfc_context->surface_state.height = obj_surface->orig_height;
- mfc_context->surface_state.w_pitch = obj_surface->width;
- mfc_context->surface_state.h_pitch = obj_surface->height;
-
- /* Setup reference frames and direct mv buffers*/
- for(i = 0; i < MAX_MFC_REFERENCE_SURFACES; i++) {
- if ( pPicParameter->ReferenceFrames[i].picture_id != VA_INVALID_ID ) {
- obj_surface = SURFACE(pPicParameter->ReferenceFrames[i].picture_id);
- assert(obj_surface);
- if (obj_surface->bo != NULL) {
- mfc_context->reference_surfaces[i].bo = obj_surface->bo;
- dri_bo_reference(obj_surface->bo);
- }
- /* Check DMV buffer */
- if ( obj_surface->private_data == NULL) {
-
- gen6_avc_surface = calloc(sizeof(struct gen6_mfc_avc_surface_aux), 1);
- gen6_avc_surface->dmv_top =
- dri_bo_alloc(i965->intel.bufmgr,
- "Buffer",
- 68*8192,
- 64);
- gen6_avc_surface->dmv_bottom =
- dri_bo_alloc(i965->intel.bufmgr,
- "Buffer",
- 68*8192,
- 64);
- assert(gen6_avc_surface->dmv_top);
- assert(gen6_avc_surface->dmv_bottom);
- obj_surface->private_data = gen6_avc_surface;
- obj_surface->free_private_data = gen6_mfc_free_avc_surface;
- }
-
- gen6_avc_surface = (struct gen6_mfc_avc_surface_aux*) obj_surface->private_data;
- /* Setup DMV buffer */
- mfc_context->direct_mv_buffers[i*2].bo = gen6_avc_surface->dmv_top;
- mfc_context->direct_mv_buffers[i*2+1].bo = gen6_avc_surface->dmv_bottom;
- dri_bo_reference(gen6_avc_surface->dmv_top);
- dri_bo_reference(gen6_avc_surface->dmv_bottom);
- } else {
- break;
- }
- }
-
- obj_surface = SURFACE(encoder_context->input_yuv_surface);
- assert(obj_surface && obj_surface->bo);
- mfc_context->uncompressed_picture_source.bo = obj_surface->bo;
- dri_bo_reference(mfc_context->uncompressed_picture_source.bo);
-
- obj_buffer = BUFFER (pPicParameter->coded_buf); /* FIXME: fix this later */
- bo = obj_buffer->buffer_store->bo;
- assert(bo);
- mfc_context->mfc_indirect_pak_bse_object.bo = bo;
- mfc_context->mfc_indirect_pak_bse_object.offset = ALIGN(sizeof(VACodedBufferSegment), 64);
- mfc_context->mfc_indirect_pak_bse_object.end_offset = ALIGN (obj_buffer->size_element - 0x1000, 0x1000);
- dri_bo_reference(mfc_context->mfc_indirect_pak_bse_object.bo);
-
- /*Programing bit rate control */
- if ( mfc_context->bit_rate_control_context[0].MaxSizeInWord == 0 )
- gen6_mfc_bit_rate_control_context_init(encode_state, mfc_context);
-
- /*Programing HRD control */
- if ( (rate_control_mode == VA_RC_CBR) && (mfc_context->vui_hrd.i_cpb_size_value == 0) )
- gen6_mfc_hrd_context_init(encode_state, encoder_context);
-
- return vaStatus;
-}
-
-static VAStatus gen6_mfc_run(VADriverContextP ctx,
- struct encode_state *encode_state,
- struct intel_encoder_context *encoder_context)
+VAStatus
+gen6_mfc_run(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
{
struct intel_batchbuffer *batch = encoder_context->base.batch;
return VA_STATUS_SUCCESS;
}
-static VAStatus
+VAStatus
gen6_mfc_stop(VADriverContextP ctx,
struct encode_state *encode_state,
struct intel_encoder_context *encoder_context,
int *encoded_bits_size)
{
- struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
- unsigned int *status_mem;
- unsigned int buffer_size_bits = 0;
- int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
- int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
- int i;
-
- dri_bo_map(mfc_context->macroblock_status_buffer.bo, 1);
- status_mem = (unsigned int *)mfc_context->macroblock_status_buffer.bo->virtual;
- //Detecting encoder buffer size and bit rate control result
- for(i = 0; i < width_in_mbs * height_in_mbs; i++) {
- unsigned short current_mb = status_mem[1] >> 16;
- buffer_size_bits += current_mb;
- status_mem += 4;
- }
- dri_bo_unmap(mfc_context->macroblock_status_buffer.bo);
-
- *encoded_bits_size = buffer_size_bits;
- if ( buffer_size_bits == 0) { // FIXME: we can't get info in IVB.
- struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct object_buffer *obj_buffer;
- VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
- obj_buffer = BUFFER (pPicParameter->coded_buf);
- dri_bo_map(obj_buffer->buffer_store->bo, 1);
- unsigned char *coded_mem = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + ALIGN(sizeof(VACodedBufferSegment), 64);
- for(i = 0; i < obj_buffer->size_element - ALIGN(sizeof(VACodedBufferSegment), 64) - 3 - 0x1000; i++) {
- if (!coded_mem[i] &&
- !coded_mem[i + 1] &&
- !coded_mem[i + 2] &&
- !coded_mem[i + 3] &&
- !coded_mem[i + 4])
- break;
- }
- dri_bo_unmap(obj_buffer->buffer_store->bo);
- *encoded_bits_size = i*8;
- }
+ VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+ VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
+ VACodedBufferSegment *coded_buffer_segment;
+
+ vaStatus = i965_MapBuffer(ctx, pPicParameter->coded_buf, (void **)&coded_buffer_segment);
+ assert(vaStatus == VA_STATUS_SUCCESS);
+ *encoded_bits_size = coded_buffer_segment->size * 8;
+ i965_UnmapBuffer(ctx, pPicParameter->coded_buf);
return VA_STATUS_SUCCESS;
}
unsigned char target_mb_size,unsigned char max_mb_size, int slice_type,
struct intel_batchbuffer *batch)
{
+ struct gen6_vme_context *vme_context = encoder_context->vme_context;
int len_in_dwords = 11;
if (batch == NULL)
/*Stuff for Inter MB*/
OUT_BCS_BATCH(batch, msg[1]);
- OUT_BCS_BATCH(batch, 0x0);
- OUT_BCS_BATCH(batch, 0x0);
+ OUT_BCS_BATCH(batch, vme_context->ref_index_in_mb[0]);
+ OUT_BCS_BATCH(batch, vme_context->ref_index_in_mb[1]);
/*MaxSizeInWord and TargetSzieInWord*/
OUT_BCS_BATCH(batch, (max_mb_size << 24) |
VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[slice_index]->buffer;
unsigned int *msg = NULL, offset = 0;
- int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I;
int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
int last_slice = (pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks) == (width_in_mbs * height_in_mbs);
int i,x,y;
int qp = pPicParameter->pic_init_qp + pSliceParameter->slice_qp_delta;
unsigned int rate_control_mode = encoder_context->rate_control_mode;
- unsigned char *slice_header = NULL;
- int slice_header_length_in_bits = 0;
unsigned int tail_data[] = { 0x0, 0x0 };
+ int slice_type = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
+ int is_intra = slice_type == SLICE_TYPE_I;
+ int qp_slice;
+
+ qp_slice = qp;
+ if (rate_control_mode == VA_RC_CBR) {
+ qp = mfc_context->bit_rate_control_context[slice_type].QpPrimeY;
+ if (encode_state->slice_header_index[slice_index] == 0) {
+ pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
+ qp_slice = qp;
+ }
+ }
+
+ /* only support for 8-bit pixel bit-depth */
+ assert(pSequenceParameter->bit_depth_luma_minus8 == 0);
+ assert(pSequenceParameter->bit_depth_chroma_minus8 == 0);
+ assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52);
+ assert(qp >= 0 && qp < 52);
gen6_mfc_avc_slice_state(ctx,
pPicParameter,
pSliceParameter,
encode_state, encoder_context,
- (rate_control_mode == VA_RC_CBR), qp, slice_batch);
+ (rate_control_mode == VA_RC_CBR), qp_slice, slice_batch);
if ( slice_index == 0)
- gen6_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
+ intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
- slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header);
-
- // slice hander
- mfc_context->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, slice_batch);
-
- if ( rate_control_mode == VA_RC_CBR) {
- qp = mfc_context->bit_rate_control_context[1-is_intra].QpPrimeY;
- }
+ intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
dri_bo_map(vme_context->vme_output.bo , 1);
msg = (unsigned int *)vme_context->vme_output.bo->virtual;
if (msg[0] & INTRA_MB_FLAG_MASK) {
gen6_mfc_avc_pak_object_intra(ctx, x, y, last_mb, qp, msg, encoder_context, 0, 0, slice_batch);
} else {
- gen6_mfc_avc_pak_object_inter(ctx, x, y, last_mb, qp, msg, offset, encoder_context, 0, 0, pSliceParameter->slice_type, slice_batch);
+ gen6_mfc_avc_pak_object_inter(ctx, x, y, last_mb, qp, msg, offset, encoder_context, 0, 0, slice_type, slice_batch);
}
msg += INTER_VME_OUTPUT_IN_DWS;
1, 1, 1, 0, slice_batch);
}
- free(slice_header);
}
struct intel_encoder_context *encoder_context)
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
- struct intel_batchbuffer *batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_BSD);
- dri_bo *batch_bo = batch->buffer;
+ struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
+ struct intel_batchbuffer *batch;;
+ dri_bo *batch_bo;
int i;
+ batch = mfc_context->aux_batchbuffer;
+ batch_bo = batch->buffer;
+
for (i = 0; i < encode_state->num_slice_params_ext; i++) {
gen6_mfc_avc_pipeline_slice_programing(ctx, encode_state, encoder_context, i, batch);
}
ADVANCE_BCS_BATCH(batch);
dri_bo_reference(batch_bo);
+
intel_batchbuffer_free(batch);
+ mfc_context->aux_batchbuffer = NULL;
return batch_bo;
}
int mb_x,
int mb_y,
int width_in_mbs,
- int qp)
+ int qp,
+ unsigned int ref_index[2])
{
- BEGIN_BATCH(batch, 12);
+ BEGIN_BATCH(batch, 14);
- OUT_BATCH(batch, CMD_MEDIA_OBJECT | (12 - 2));
+ OUT_BATCH(batch, CMD_MEDIA_OBJECT | (14 - 2));
OUT_BATCH(batch, index);
OUT_BATCH(batch, 0);
OUT_BATCH(batch, 0);
OUT_BATCH(batch,
qp << 16 |
width_in_mbs);
+ OUT_BATCH(batch, ref_index[0]);
+ OUT_BATCH(batch, ref_index[1]);
ADVANCE_BATCH(batch);
}
{
struct intel_batchbuffer *batch = encoder_context->base.batch;
struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
+ struct gen6_vme_context *vme_context = encoder_context->vme_context;
int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
int total_mbs = slice_param->num_macroblocks;
int number_mb_cmds = 128;
mb_x,
mb_y,
width_in_mbs,
- qp);
+ qp,
+ vme_context->ref_index_in_mb);
if (first_object) {
head_offset += head_size;
mb_x,
mb_y,
width_in_mbs,
- qp);
+ qp,
+ vme_context->ref_index_in_mb);
}
}
VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
VAEncPictureParameterBufferH264 *pPicParameter = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
VAEncSliceParameterBufferH264 *pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[slice_index]->buffer;
- int is_intra = pSliceParameter->slice_type == SLICE_TYPE_I;
int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
int last_slice = (pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks) == (width_in_mbs * height_in_mbs);
int qp = pPicParameter->pic_init_qp + pSliceParameter->slice_qp_delta;
unsigned int rate_control_mode = encoder_context->rate_control_mode;
- unsigned char *slice_header = NULL;
- int slice_header_length_in_bits = 0;
unsigned int tail_data[] = { 0x0, 0x0 };
long head_offset;
int old_used = intel_batchbuffer_used_size(slice_batch), used;
unsigned short head_size, tail_size;
+ int slice_type = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
+ int qp_slice;
+
+ qp_slice = qp;
+ if (rate_control_mode == VA_RC_CBR) {
+ qp = mfc_context->bit_rate_control_context[slice_type].QpPrimeY;
+ if (encode_state->slice_header_index[slice_index] == 0) {
+ pSliceParameter->slice_qp_delta = qp - pPicParameter->pic_init_qp;
+ /* Use the adjusted qp when slice_header is generated by driver */
+ qp_slice = qp;
+ }
+ }
+
+ /* only support for 8-bit pixel bit-depth */
+ assert(pSequenceParameter->bit_depth_luma_minus8 == 0);
+ assert(pSequenceParameter->bit_depth_chroma_minus8 == 0);
+ assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52);
+ assert(qp >= 0 && qp < 52);
head_offset = old_used / 16;
gen6_mfc_avc_slice_state(ctx,
encode_state,
encoder_context,
(rate_control_mode == VA_RC_CBR),
- qp,
+ qp_slice,
slice_batch);
if (slice_index == 0)
- gen6_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
-
- slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header);
-
- // slice hander
- mfc_context->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,
- slice_batch);
- free(slice_header);
+ intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
+
+ intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
intel_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */
used = intel_batchbuffer_used_size(slice_batch);
head_size = (used - old_used) / 16;
old_used = used;
- if (rate_control_mode == VA_RC_CBR) {
- qp = mfc_context->bit_rate_control_context[1 - is_intra].QpPrimeY;
- }
-
/* tail */
if (last_slice) {
mfc_context->insert_object(ctx,
#endif
-int interlace_check(VADriverContextP ctx,
- struct encode_state *encode_state,
- struct intel_encoder_context *encoder_context) {
- struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
- VAEncSliceParameterBufferH264 *pSliceParameter;
- int i;
- int mbCount = 0;
- int width_in_mbs = (mfc_context->surface_state.width + 15) / 16;
- int height_in_mbs = (mfc_context->surface_state.height + 15) / 16;
-
- for (i = 0; i < encode_state->num_slice_params_ext; i++) {
- pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[i]->buffer;
- mbCount += pSliceParameter->num_macroblocks;
- }
-
- if ( mbCount == ( width_in_mbs * height_in_mbs ) )
- return 0;
-
- return 1;
-}
-
static void
gen6_mfc_avc_pipeline_programing(VADriverContextP ctx,
struct intel_batchbuffer *batch = encoder_context->base.batch;
dri_bo *slice_batch_bo;
- if ( interlace_check(ctx, encode_state, encoder_context) ) {
+ if ( intel_mfc_interlace_check(ctx, encode_state, encoder_context) ) {
fprintf(stderr, "Current VA driver don't support interlace mode!\n");
assert(0);
return;
dri_bo_unreference(slice_batch_bo);
}
-static VAStatus
+VAStatus
gen6_mfc_avc_encode_picture(VADriverContextP ctx,
struct encode_state *encode_state,
struct intel_encoder_context *encoder_context)
{
struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
unsigned int rate_control_mode = encoder_context->rate_control_mode;
- int MAX_CBR_INTERATE = 4;
int current_frame_bits_size;
- int i;
+ int sts;
- for(i = 0; i < MAX_CBR_INTERATE; i++) {
- gen6_mfc_init(ctx, encoder_context);
- gen6_mfc_avc_prepare(ctx, encode_state, encoder_context);
+ for (;;) {
+ gen6_mfc_init(ctx, encode_state, encoder_context);
+ intel_mfc_avc_prepare(ctx, encode_state, encoder_context);
/*Programing bcs pipeline*/
gen6_mfc_avc_pipeline_programing(ctx, encode_state, encoder_context); //filling the pipeline
gen6_mfc_run(ctx, encode_state, encoder_context);
- if ( rate_control_mode == VA_RC_CBR) {
+ if (rate_control_mode == VA_RC_CBR /*|| rate_control_mode == VA_RC_VBR*/) {
gen6_mfc_stop(ctx, encode_state, encoder_context, ¤t_frame_bits_size);
- //gen6_mfc_hrd_context_check(encode_state, mfc_context);
- if ( gen6_mfc_bit_rate_control_context_update( encode_state, mfc_context, current_frame_bits_size) ) {
- gen6_mfc_hrd_context_update(encode_state, mfc_context);
+ sts = intel_mfc_brc_postpack(encode_state, mfc_context, current_frame_bits_size);
+ if (sts == BRC_NO_HRD_VIOLATION) {
+ intel_mfc_hrd_context_update(encode_state, mfc_context);
break;
}
+ else if (sts == BRC_OVERFLOW_WITH_MIN_QP || sts == BRC_UNDERFLOW_WITH_MAX_QP) {
+ if (!mfc_context->hrd.violation_noted) {
+ fprintf(stderr, "Unrepairable %s!\n", (sts == BRC_OVERFLOW_WITH_MIN_QP)? "overflow": "underflow");
+ mfc_context->hrd.violation_noted = 1;
+ }
+ return VA_STATUS_SUCCESS;
+ }
} else {
break;
}
VAStatus vaStatus;
switch (profile) {
- case VAProfileH264Baseline:
+ case VAProfileH264ConstrainedBaseline:
case VAProfileH264Main:
case VAProfileH264High:
vaStatus = gen6_mfc_avc_encode_picture(ctx, encode_state, encoder_context);
{
struct gen6_mfc_context *mfc_context = calloc(1, sizeof(struct gen6_mfc_context));
+ if (!mfc_context)
+ return False;
+
mfc_context->gpe_context.surface_state_binding_table.length = (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_MEDIA_SURFACES_GEN6;
mfc_context->gpe_context.idrt.max_entries = MAX_GPE_KERNELS;
encoder_context->mfc_context = mfc_context;
encoder_context->mfc_context_destroy = gen6_mfc_context_destroy;
encoder_context->mfc_pipeline = gen6_mfc_pipeline;
+ encoder_context->mfc_brc_prepare = intel_mfc_brc_prepare;
return True;
}