3
};
-static const int va_to_gen7_vc1_profile[4] = {
- GEN7_VC1_SIMPLE_PROFILE,
- GEN7_VC1_MAIN_PROFILE,
- GEN7_VC1_RESERVED_PROFILE,
- GEN7_VC1_ADVANCED_PROFILE
+static const int fptype_to_picture_type[8][2] = {
+ {GEN7_VC1_I_PICTURE, GEN7_VC1_I_PICTURE},
+ {GEN7_VC1_I_PICTURE, GEN7_VC1_P_PICTURE},
+ {GEN7_VC1_P_PICTURE, GEN7_VC1_I_PICTURE},
+ {GEN7_VC1_P_PICTURE, GEN7_VC1_P_PICTURE},
+ {GEN7_VC1_B_PICTURE, GEN7_VC1_B_PICTURE},
+ {GEN7_VC1_B_PICTURE, GEN7_VC1_BI_PICTURE},
+ {GEN7_VC1_BI_PICTURE, GEN7_VC1_B_PICTURE},
+ {GEN7_VC1_BI_PICTURE, GEN7_VC1_BI_PICTURE}
};
static void
if (!gen7_vc1_surface)
return;
- dri_bo_unreference(gen7_vc1_surface->dmv);
+ dri_bo_unreference(gen7_vc1_surface->dmv_top);
+ dri_bo_unreference(gen7_vc1_surface->dmv_bottom);
free(gen7_vc1_surface);
*data = NULL;
}
{
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct gen7_vc1_surface *gen7_vc1_surface = obj_surface->private_data;
- int height_in_mbs = ALIGN(pic_param->coded_height, 16) / 16;
+ int height_in_mbs;
+ int picture_type;
+ int is_first_field = 1;
+
+ if (!pic_param->sequence_fields.bits.interlace ||
+ (pic_param->picture_fields.bits.frame_coding_mode < 2)) { /* Progressive or Frame-Interlace */
+ picture_type = pic_param->picture_fields.bits.picture_type;
+ } else {/* Field-Interlace */
+ is_first_field = pic_param->picture_fields.bits.is_first_field;
+ picture_type = fptype_to_picture_type[pic_param->picture_fields.bits.picture_type][!is_first_field];
+ }
obj_surface->free_private_data = gen7_mfd_free_vc1_surface;
obj_surface->private_data = gen7_vc1_surface;
}
- gen7_vc1_surface->picture_type = pic_param->picture_fields.bits.picture_type;
- gen7_vc1_surface->intensity_compensation = 0;
- gen7_vc1_surface->luma_scale = 0;
- gen7_vc1_surface->luma_shift = 0;
+ if (!pic_param->sequence_fields.bits.interlace ||
+ pic_param->picture_fields.bits.frame_coding_mode < 2 || /* Progressive or Frame-Interlace */
+ is_first_field) {
+ gen7_vc1_surface->picture_type_top = 0;
+ gen7_vc1_surface->picture_type_bottom = 0;
+ gen7_vc1_surface->intensity_compensation_top = 0;
+ gen7_vc1_surface->intensity_compensation_bottom = 0;
+ gen7_vc1_surface->luma_scale_top[0] = 0;
+ gen7_vc1_surface->luma_scale_top[1] = 0;
+ gen7_vc1_surface->luma_scale_bottom[0] = 0;
+ gen7_vc1_surface->luma_scale_bottom[1] = 0;
+ gen7_vc1_surface->luma_shift_top[0] = 0;
+ gen7_vc1_surface->luma_shift_top[1] = 0;
+ gen7_vc1_surface->luma_shift_bottom[0] = 0;
+ gen7_vc1_surface->luma_shift_bottom[1] = 0;
+ }
+
+ if (!pic_param->sequence_fields.bits.interlace ||
+ pic_param->picture_fields.bits.frame_coding_mode < 2) { /* Progressive or Frame-Interlace */
+ gen7_vc1_surface->picture_type_top = picture_type;
+ gen7_vc1_surface->picture_type_bottom = picture_type;
+ } else if (pic_param->picture_fields.bits.top_field_first ^ is_first_field)
+ gen7_vc1_surface->picture_type_bottom = picture_type;
+ else
+ gen7_vc1_surface->picture_type_top = picture_type;
+
+ /*
+ * The Direct MV buffer is scalable with frame height, but
+ * does not scale with frame width as the hardware assumes
+ * that frame width is fixed at 128 MBs.
+ */
+
+ if (gen7_vc1_surface->dmv_top == NULL) {
+ height_in_mbs = ALIGN(obj_surface->orig_height, 16) / 16;
+ gen7_vc1_surface->dmv_top = dri_bo_alloc(i965->intel.bufmgr,
+ "direct mv w/r buffer",
+ 128 * height_in_mbs * 64,
+ 0x1000);
+ }
- if (gen7_vc1_surface->dmv == NULL) {
- gen7_vc1_surface->dmv = dri_bo_alloc(i965->intel.bufmgr,
+ if (pic_param->sequence_fields.bits.interlace &&
+ gen7_vc1_surface->dmv_bottom == NULL) {
+ height_in_mbs = ALIGN(obj_surface->orig_height, 32) / 32;
+ gen7_vc1_surface->dmv_bottom = dri_bo_alloc(i965->intel.bufmgr,
"direct mv w/r buffer",
128 * height_in_mbs * 64,
0x1000);
VAPictureParameterBufferVC1 *pic_param;
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_surface *obj_surface;
+ struct gen7_vc1_surface *gen7_vc1_current_surface;
+ struct gen7_vc1_surface *gen7_vc1_forward_surface;
dri_bo *bo;
int width_in_mbs;
int picture_type;
- int intensity_compensation;
+ int is_first_field = 1;
+ int i;
assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
width_in_mbs = ALIGN(pic_param->coded_width, 16) / 16;
- picture_type = pic_param->picture_fields.bits.picture_type;
- intensity_compensation = (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation);
-
- intel_update_vc1_frame_store_index(ctx,
- decode_state,
- pic_param,
- gen7_mfd_context->reference_surface);
- /* Forward reference picture */
- obj_surface = decode_state->reference_objects[0];
- if (pic_param->forward_reference_picture != VA_INVALID_ID &&
- obj_surface &&
- obj_surface->private_data) {
- if (picture_type == 1 && intensity_compensation) { /* P picture */
- struct gen7_vc1_surface *gen7_vc1_surface = obj_surface->private_data;
-
- gen7_vc1_surface->intensity_compensation = intensity_compensation;
- gen7_vc1_surface->luma_scale = pic_param->luma_scale;
- gen7_vc1_surface->luma_shift = pic_param->luma_shift;
- }
+ if (!pic_param->sequence_fields.bits.interlace ||
+ (pic_param->picture_fields.bits.frame_coding_mode < 2)) { /* Progressive or Frame-Interlace */
+ picture_type = pic_param->picture_fields.bits.picture_type;
+ } else {/* Field-Interlace */
+ is_first_field = pic_param->picture_fields.bits.is_first_field;
+ picture_type = fptype_to_picture_type[pic_param->picture_fields.bits.picture_type][!is_first_field];
}
/* Current decoded picture */
dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo);
gen7_mfd_context->post_deblocking_output.bo = obj_surface->bo;
dri_bo_reference(gen7_mfd_context->post_deblocking_output.bo);
- gen7_mfd_context->post_deblocking_output.valid = pic_param->entrypoint_fields.bits.loopfilter;
dri_bo_unreference(gen7_mfd_context->pre_deblocking_output.bo);
gen7_mfd_context->pre_deblocking_output.bo = obj_surface->bo;
dri_bo_reference(gen7_mfd_context->pre_deblocking_output.bo);
- gen7_mfd_context->pre_deblocking_output.valid = !pic_param->entrypoint_fields.bits.loopfilter;
+
+ if (picture_type == GEN7_VC1_SKIPPED_PICTURE) {
+ gen7_mfd_context->post_deblocking_output.valid = 0;
+ gen7_mfd_context->pre_deblocking_output.valid = 1;
+ } else {
+ gen7_mfd_context->post_deblocking_output.valid = pic_param->entrypoint_fields.bits.loopfilter;
+ gen7_mfd_context->pre_deblocking_output.valid = !pic_param->entrypoint_fields.bits.loopfilter;
+ }
+
+ intel_update_vc1_frame_store_index(ctx,
+ decode_state,
+ pic_param,
+ gen7_mfd_context->reference_surface);
+
+ if (picture_type == GEN7_VC1_P_PICTURE) {
+ obj_surface = decode_state->reference_objects[0];
+ gen7_vc1_current_surface = (struct gen7_vc1_surface *)(decode_state->render_object->private_data);
+ if (pic_param->forward_reference_picture != VA_INVALID_ID &&
+ obj_surface)
+ gen7_vc1_forward_surface = (struct gen7_vc1_surface *)(obj_surface->private_data);
+ else
+ gen7_vc1_forward_surface = NULL;
+
+ if (!pic_param->sequence_fields.bits.interlace ||
+ pic_param->picture_fields.bits.frame_coding_mode == 0) { /* Progressive */
+ if (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation) {
+ if (gen7_vc1_forward_surface) {
+ gen7_vc1_forward_surface->intensity_compensation_top = 1;
+ gen7_vc1_forward_surface->intensity_compensation_bottom = 1;
+ gen7_vc1_forward_surface->luma_scale_top[0] = pic_param->luma_scale;
+ gen7_vc1_forward_surface->luma_scale_bottom[0] = pic_param->luma_scale;
+ gen7_vc1_forward_surface->luma_shift_top[0] = pic_param->luma_shift;
+ gen7_vc1_forward_surface->luma_shift_bottom[0] = pic_param->luma_shift;
+ }
+ }
+ } else if (pic_param->sequence_fields.bits.interlace &&
+ pic_param->picture_fields.bits.frame_coding_mode == 1) { /* Frame-Interlace */
+ if (pic_param->picture_fields.bits.intensity_compensation) {
+ if (gen7_vc1_forward_surface) {
+ gen7_vc1_forward_surface->intensity_compensation_top = 1;
+ gen7_vc1_forward_surface->intensity_compensation_bottom = 1;
+ gen7_vc1_forward_surface->luma_scale_top[0] = pic_param->luma_scale;
+ gen7_vc1_forward_surface->luma_scale_bottom[0] = pic_param->luma_scale;
+ gen7_vc1_forward_surface->luma_shift_top[0] = pic_param->luma_shift;
+ gen7_vc1_forward_surface->luma_shift_bottom[0] = pic_param->luma_shift;
+ }
+ }
+ } else if (pic_param->sequence_fields.bits.interlace &&
+ pic_param->picture_fields.bits.frame_coding_mode == 2) { /* Field-Interlace */
+ if (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation) {
+ if (pic_param->intensity_compensation_field == 1 || /* Top field */
+ pic_param->intensity_compensation_field == 0) { /* Both fields */
+ if (is_first_field) {
+ if ((!pic_param->reference_fields.bits.num_reference_pictures &&
+ (pic_param->reference_fields.bits.reference_field_pic_indicator ==
+ pic_param->picture_fields.bits.top_field_first)) ||
+ pic_param->reference_fields.bits.num_reference_pictures) {
+ if (gen7_vc1_forward_surface) {
+ i = gen7_vc1_forward_surface->intensity_compensation_top++;
+ gen7_vc1_forward_surface->luma_scale_top[i] = pic_param->luma_scale;
+ gen7_vc1_forward_surface->luma_shift_top[i] = pic_param->luma_shift;
+ }
+ }
+ } else { /* Second field */
+ if (pic_param->picture_fields.bits.top_field_first) {
+ if ((!pic_param->reference_fields.bits.num_reference_pictures &&
+ !pic_param->reference_fields.bits.reference_field_pic_indicator) ||
+ pic_param->reference_fields.bits.num_reference_pictures) {
+ i = gen7_vc1_current_surface->intensity_compensation_top++;
+ gen7_vc1_current_surface->luma_scale_top[i] = pic_param->luma_scale;
+ gen7_vc1_current_surface->luma_shift_top[i] = pic_param->luma_shift;
+ }
+ } else {
+ if ((!pic_param->reference_fields.bits.num_reference_pictures &&
+ pic_param->reference_fields.bits.reference_field_pic_indicator) ||
+ pic_param->reference_fields.bits.num_reference_pictures) {
+ if (gen7_vc1_forward_surface) {
+ i = gen7_vc1_forward_surface->intensity_compensation_top++;
+ gen7_vc1_forward_surface->luma_scale_top[i] = pic_param->luma_scale;
+ gen7_vc1_forward_surface->luma_shift_top[i] = pic_param->luma_shift;
+ }
+ }
+ }
+ }
+ }
+ if (pic_param->intensity_compensation_field == 2 || /* Bottom field */
+ pic_param->intensity_compensation_field == 0) { /* Both fields */
+ if (is_first_field) {
+ if ((!pic_param->reference_fields.bits.num_reference_pictures &&
+ (pic_param->reference_fields.bits.reference_field_pic_indicator ^
+ pic_param->picture_fields.bits.top_field_first)) ||
+ pic_param->reference_fields.bits.num_reference_pictures) {
+ if (gen7_vc1_forward_surface) {
+ i = gen7_vc1_forward_surface->intensity_compensation_bottom++;
+ if (pic_param->intensity_compensation_field == 2) { /* Bottom field */
+ gen7_vc1_forward_surface->luma_scale_bottom[i] = pic_param->luma_scale;
+ gen7_vc1_forward_surface->luma_shift_bottom[i] = pic_param->luma_shift;
+ } else { /* Both fields */
+ gen7_vc1_forward_surface->luma_scale_bottom[i] = pic_param->luma_scale2;
+ gen7_vc1_forward_surface->luma_shift_bottom[i] = pic_param->luma_shift2;
+ }
+ }
+ }
+ } else { /* Second field */
+ if (pic_param->picture_fields.bits.top_field_first) {
+ if ((!pic_param->reference_fields.bits.num_reference_pictures &&
+ pic_param->reference_fields.bits.reference_field_pic_indicator) ||
+ pic_param->reference_fields.bits.num_reference_pictures) {
+ if (gen7_vc1_forward_surface) {
+ i = gen7_vc1_forward_surface->intensity_compensation_bottom++;
+ if (pic_param->intensity_compensation_field == 2) { /* Bottom field */
+ gen7_vc1_forward_surface->luma_scale_bottom[i] = pic_param->luma_scale;
+ gen7_vc1_forward_surface->luma_shift_bottom[i] = pic_param->luma_shift;
+ } else { /* Both fields */
+ gen7_vc1_forward_surface->luma_scale_bottom[i] = pic_param->luma_scale2;
+ gen7_vc1_forward_surface->luma_shift_bottom[i] = pic_param->luma_shift2;
+ }
+ }
+ }
+ } else {
+ if ((!pic_param->reference_fields.bits.num_reference_pictures &&
+ !pic_param->reference_fields.bits.reference_field_pic_indicator) ||
+ pic_param->reference_fields.bits.num_reference_pictures) {
+ i = gen7_vc1_current_surface->intensity_compensation_bottom++;
+ if (pic_param->intensity_compensation_field == 2) { /* Bottom field */
+ gen7_vc1_current_surface->luma_scale_bottom[i] = pic_param->luma_scale;
+ gen7_vc1_current_surface->luma_shift_bottom[i] = pic_param->luma_shift;
+ } else { /* Both fields */
+ gen7_vc1_current_surface->luma_scale_bottom[i] = pic_param->luma_scale2;
+ gen7_vc1_current_surface->luma_shift_bottom[i] = pic_param->luma_shift2;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
dri_bo_unreference(gen7_mfd_context->intra_row_store_scratch_buffer.bo);
bo = dri_bo_alloc(i965->intel.bufmgr,
if (gen7_mfd_context->bitplane_read_buffer.valid) {
int width_in_mbs = ALIGN(pic_param->coded_width, 16) / 16;
- int height_in_mbs = ALIGN(pic_param->coded_height, 16) / 16;
+ int height_in_mbs;
int bitplane_width = ALIGN(width_in_mbs, 2) / 2;
int src_w, src_h;
uint8_t *src = NULL, *dst = NULL;
+ if (!pic_param->sequence_fields.bits.interlace ||
+ (pic_param->picture_fields.bits.frame_coding_mode < 2)) /* Progressive or Frame-Interlace */
+ height_in_mbs = ALIGN(pic_param->coded_height, 16) / 16;
+ else /* Field-Interlace */
+ height_in_mbs = ALIGN(pic_param->coded_height, 32) / 32;
+
bo = dri_bo_alloc(i965->intel.bufmgr,
"VC-1 Bitplane",
bitplane_width * height_in_mbs,
struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
VAPictureParameterBufferVC1 *pic_param;
struct object_surface *obj_surface;
+ struct gen7_vc1_surface *gen7_vc1_current_surface;
+ struct gen7_vc1_surface *gen7_vc1_reference_surface;
int alt_pquant_config = 0, alt_pquant_edge_mask = 0, alt_pq;
int dquant, dquantfrm, dqprofile, dqdbedge, dqsbedge, dqbilevel;
- int unified_mv_mode;
+ int unified_mv_mode = 0;
int ref_field_pic_polarity = 0;
int scale_factor = 0;
int trans_ac_y = 0;
int dmv_surface_valid = 0;
+ int frfd = 0;
int brfd = 0;
int fcm = 0;
int picture_type;
int ptype;
- int profile;
int overlap = 0;
int interpolation_mode = 0;
+ int height_in_mbs;
+ int is_first_field = 1;
+ int loopfilter = 0;
+ int bitplane_present;
+ int range_reduction = 0;
+ int range_reduction_scale = 0;
+ int forward_mb = 0, mv_type_mb = 0, skip_mb = 0, direct_mb = 0;
+ int overflags = 0, ac_pred = 0, field_tx = 0;
assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
- picture_type = pic_param->picture_fields.bits.picture_type;
+ if (!pic_param->sequence_fields.bits.interlace ||
+ (pic_param->picture_fields.bits.frame_coding_mode < 2)) { /* Progressive or Frame-Interlace */
+ picture_type = pic_param->picture_fields.bits.picture_type;
+ height_in_mbs = ALIGN(pic_param->coded_height, 16) / 16;
+ } else {/* Field-Interlace */
+ is_first_field = pic_param->picture_fields.bits.is_first_field;
+ picture_type = fptype_to_picture_type[pic_param->picture_fields.bits.picture_type][!is_first_field];
+ height_in_mbs = ALIGN(pic_param->coded_height, 32) / 32;
+ }
- profile = va_to_gen7_vc1_profile[pic_param->sequence_fields.bits.profile];
dquant = pic_param->pic_quantizer_fields.bits.dquant;
dquantfrm = pic_param->pic_quantizer_fields.bits.dq_frame;
dqprofile = pic_param->pic_quantizer_fields.bits.dq_profile;
}
}
- if (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation) {
- assert(pic_param->mv_fields.bits.mv_mode2 < 4);
- unified_mv_mode = va_to_gen7_vc1_mv[pic_param->mv_fields.bits.mv_mode2];
- } else {
- assert(pic_param->mv_fields.bits.mv_mode < 4);
- unified_mv_mode = va_to_gen7_vc1_mv[pic_param->mv_fields.bits.mv_mode];
+ if (pic_param->sequence_fields.bits.profile == 1 && /* Main Profile */
+ pic_param->sequence_fields.bits.rangered) {
+ obj_surface = decode_state->reference_objects[0];
+
+ gen7_vc1_current_surface = (struct gen7_vc1_surface *)(decode_state->render_object->private_data);
+
+ if (pic_param->forward_reference_picture != VA_INVALID_ID &&
+ obj_surface)
+ gen7_vc1_reference_surface = (struct gen7_vc1_surface *)(obj_surface->private_data);
+ else
+ gen7_vc1_reference_surface = NULL;
+
+ if (picture_type == GEN7_VC1_SKIPPED_PICTURE)
+ if (gen7_vc1_reference_surface)
+ gen7_vc1_current_surface->range_reduction_frame = gen7_vc1_reference_surface->range_reduction_frame;
+ else
+ gen7_vc1_current_surface->range_reduction_frame = 0;
+ else
+ gen7_vc1_current_surface->range_reduction_frame = pic_param->range_reduction_frame;
+
+ if (gen7_vc1_reference_surface) {
+ if (gen7_vc1_current_surface->range_reduction_frame &&
+ !gen7_vc1_reference_surface->range_reduction_frame) {
+ range_reduction = 1;
+ range_reduction_scale = 0;
+ } else if (!gen7_vc1_current_surface->range_reduction_frame &&
+ gen7_vc1_reference_surface->range_reduction_frame) {
+ range_reduction = 1;
+ range_reduction_scale = 1;
+ }
+ }
}
- if (pic_param->sequence_fields.bits.interlace == 1 &&
- pic_param->picture_fields.bits.frame_coding_mode != 0) { /* frame-interlace or field-interlace */
- /* FIXME: calculate reference field picture polarity */
- assert(0);
- ref_field_pic_polarity = 0;
+ if ((!pic_param->sequence_fields.bits.interlace ||
+ pic_param->picture_fields.bits.frame_coding_mode != 1) && /* Progressive or Field-Interlace */
+ (picture_type == GEN7_VC1_P_PICTURE ||
+ picture_type == GEN7_VC1_B_PICTURE)) {
+ if (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation) {
+ assert(pic_param->mv_fields.bits.mv_mode2 < 4);
+ unified_mv_mode = va_to_gen7_vc1_mv[pic_param->mv_fields.bits.mv_mode2];
+ } else {
+ assert(pic_param->mv_fields.bits.mv_mode < 4);
+ unified_mv_mode = va_to_gen7_vc1_mv[pic_param->mv_fields.bits.mv_mode];
+ }
+ }
+
+ if (pic_param->sequence_fields.bits.interlace &&
+ pic_param->picture_fields.bits.frame_coding_mode == 2 && /* Field-Interlace */
+ picture_type == GEN7_VC1_P_PICTURE &&
+ !pic_param->reference_fields.bits.num_reference_pictures) {
+ if (pic_param->reference_fields.bits.reference_field_pic_indicator == 0) {
+ ref_field_pic_polarity = is_first_field ?
+ pic_param->picture_fields.bits.top_field_first :
+ !pic_param->picture_fields.bits.top_field_first;
+ } else {
+ ref_field_pic_polarity = is_first_field ?
+ !pic_param->picture_fields.bits.top_field_first :
+ pic_param->picture_fields.bits.top_field_first;
+ }
}
if (pic_param->b_picture_fraction < 21)
scale_factor = b_picture_scale_factor[pic_param->b_picture_fraction];
- if (picture_type == GEN7_VC1_SKIPPED_PICTURE)
+ if (picture_type == GEN7_VC1_SKIPPED_PICTURE) {
ptype = GEN7_VC1_P_PICTURE;
- else
+ bitplane_present = 1;
+ } else {
ptype = pic_param->picture_fields.bits.picture_type;
-
- if (profile == GEN7_VC1_ADVANCED_PROFILE &&
- picture_type == GEN7_VC1_I_PICTURE)
- picture_type = GEN7_VC1_BI_PICTURE;
+ bitplane_present = !!(pic_param->bitplane_present.value & 0x7f);
+ forward_mb = pic_param->raw_coding.flags.forward_mb;
+ mv_type_mb = pic_param->raw_coding.flags.mv_type_mb;
+ skip_mb = pic_param->raw_coding.flags.skip_mb;
+ direct_mb = pic_param->raw_coding.flags.direct_mb;
+ overflags = pic_param->raw_coding.flags.overflags;
+ ac_pred = pic_param->raw_coding.flags.ac_pred;
+ field_tx = pic_param->raw_coding.flags.field_tx;
+ loopfilter = pic_param->entrypoint_fields.bits.loopfilter;
+ }
if (picture_type == GEN7_VC1_I_PICTURE || picture_type == GEN7_VC1_BI_PICTURE) /* I picture */
trans_ac_y = pic_param->transform_fields.bits.transform_ac_codingset_idx2;
}
}
-
if (picture_type == GEN7_VC1_B_PICTURE) {
- struct gen7_vc1_surface *gen7_vc1_surface = NULL;
-
obj_surface = decode_state->reference_objects[1];
- if (obj_surface)
- gen7_vc1_surface = obj_surface->private_data;
-
- if (!gen7_vc1_surface ||
- (gen7_vc1_surface->picture_type == GEN7_VC1_I_PICTURE ||
- gen7_vc1_surface->picture_type == GEN7_VC1_BI_PICTURE))
- dmv_surface_valid = 0;
+ if (pic_param->backward_reference_picture != VA_INVALID_ID &&
+ obj_surface)
+ gen7_vc1_reference_surface = (struct gen7_vc1_surface *)(obj_surface->private_data);
else
- dmv_surface_valid = 1;
+ gen7_vc1_reference_surface = NULL;
+
+ if (gen7_vc1_reference_surface) {
+ if (pic_param->sequence_fields.bits.interlace &&
+ pic_param->picture_fields.bits.frame_coding_mode == 2 && /* Field-Interlace */
+ pic_param->picture_fields.bits.top_field_first ^ is_first_field) {
+ if (gen7_vc1_reference_surface->picture_type_bottom == GEN7_VC1_P_PICTURE)
+ dmv_surface_valid = 1;
+ } else if (gen7_vc1_reference_surface->picture_type_top == GEN7_VC1_P_PICTURE)
+ dmv_surface_valid = 1;
+ }
}
assert(pic_param->picture_fields.bits.frame_coding_mode < 3);
- if (pic_param->picture_fields.bits.frame_coding_mode < 2)
- fcm = pic_param->picture_fields.bits.frame_coding_mode;
- else {
- if (pic_param->picture_fields.bits.top_field_first)
- fcm = 2;
+ if (pic_param->sequence_fields.bits.interlace) {
+ if (pic_param->picture_fields.bits.frame_coding_mode < 2)
+ fcm = pic_param->picture_fields.bits.frame_coding_mode;
+ else if (!pic_param->picture_fields.bits.top_field_first)
+ fcm = 3; /* Field with bottom field first */
else
- fcm = 3;
+ fcm = 2; /* Field with top field first */
}
- if (picture_type == GEN7_VC1_B_PICTURE) { /* B picture */
- brfd = pic_param->reference_fields.bits.reference_distance;
- brfd = (scale_factor * brfd) >> 8;
- brfd = pic_param->reference_fields.bits.reference_distance - brfd - 1;
+ if (pic_param->sequence_fields.bits.interlace &&
+ pic_param->picture_fields.bits.frame_coding_mode == 2) { /* Field-Interlace */
+ if (picture_type == GEN7_VC1_I_PICTURE ||
+ picture_type == GEN7_VC1_P_PICTURE) {
+ gen7_vc1_current_surface = (struct gen7_vc1_surface *)(decode_state->render_object->private_data);
+
+ if (is_first_field)
+ gen7_vc1_current_surface->reference_distance = pic_param->reference_fields.bits.reference_distance;
+
+ frfd = gen7_vc1_current_surface->reference_distance;
+ } else if (picture_type == GEN7_VC1_B_PICTURE) {
+ obj_surface = decode_state->reference_objects[1];
- if (brfd < 0)
- brfd = 0;
+ if (pic_param->backward_reference_picture != VA_INVALID_ID &&
+ obj_surface)
+ gen7_vc1_reference_surface = (struct gen7_vc1_surface *)(obj_surface->private_data);
+ else
+ gen7_vc1_reference_surface = NULL;
+
+ if (gen7_vc1_reference_surface) {
+ frfd = (scale_factor * gen7_vc1_reference_surface->reference_distance) >> 8;
+
+ brfd = gen7_vc1_reference_surface->reference_distance - frfd - 1;
+ if (brfd < 0)
+ brfd = 0;
+ }
+ }
}
if (pic_param->sequence_fields.bits.overlap) {
- if (profile == GEN7_VC1_ADVANCED_PROFILE) {
+ if (pic_param->sequence_fields.bits.profile == 3) { /* Advanced Profile */
if (picture_type == GEN7_VC1_P_PICTURE &&
pic_param->pic_quantizer_fields.bits.pic_quantizer_scale >= 9) {
overlap = 1;
}
}
- assert(pic_param->conditional_overlap_flag < 3);
- assert(pic_param->mv_fields.bits.mv_table < 4); /* FIXME: interlace mode */
-
if (pic_param->mv_fields.bits.mv_mode == VAMvMode1MvHalfPelBilinear ||
(pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation &&
pic_param->mv_fields.bits.mv_mode2 == VAMvMode1MvHalfPelBilinear))
- interpolation_mode = 9; /* Half-pel bilinear */
- else if (pic_param->mv_fields.bits.mv_mode == VAMvMode1MvHalfPel ||
- (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation &&
- pic_param->mv_fields.bits.mv_mode2 == VAMvMode1MvHalfPel))
- interpolation_mode = 1; /* Half-pel bicubic */
+ interpolation_mode = 8 | pic_param->fast_uvmc_flag;
else
- interpolation_mode = 0; /* Quarter-pel bicubic */
+ interpolation_mode = 0 | pic_param->fast_uvmc_flag;
BEGIN_BCS_BATCH(batch, 6);
OUT_BCS_BATCH(batch, MFD_VC1_LONG_PIC_STATE | (6 - 2));
OUT_BCS_BATCH(batch,
- (((ALIGN(pic_param->coded_height, 16) / 16) - 1) << 16) |
+ ((height_in_mbs - 1) << 16) |
((ALIGN(pic_param->coded_width, 16) / 16) - 1));
OUT_BCS_BATCH(batch,
((ALIGN(pic_param->coded_width, 16) / 16 + 1) / 2 - 1) << 24 |
pic_param->rounding_control << 13 |
pic_param->sequence_fields.bits.syncmarker << 12 |
interpolation_mode << 8 |
- 0 << 7 | /* FIXME: scale up or down ??? */
- pic_param->range_reduction_frame << 6 |
- pic_param->entrypoint_fields.bits.loopfilter << 5 |
+ range_reduction_scale << 7 |
+ range_reduction << 6 |
+ loopfilter << 5 |
overlap << 4 |
- !pic_param->picture_fields.bits.is_first_field << 3 |
- (pic_param->sequence_fields.bits.profile == 3) << 0);
+ !is_first_field << 3 |
+ (pic_param->sequence_fields.bits.profile == 3) << 0); /* Advanced Profile */
OUT_BCS_BATCH(batch,
va_to_gen7_vc1_condover[pic_param->conditional_overlap_flag] << 29 |
ptype << 26 |
pic_param->fast_uvmc_flag << 26 |
ref_field_pic_polarity << 25 |
pic_param->reference_fields.bits.num_reference_pictures << 24 |
- pic_param->reference_fields.bits.reference_distance << 20 |
- pic_param->reference_fields.bits.reference_distance << 16 | /* FIXME: ??? */
+ brfd << 20 |
+ frfd << 16 |
pic_param->mv_fields.bits.extended_dmv_range << 10 |
pic_param->mv_fields.bits.extended_mv_range << 8 |
alt_pquant_edge_mask << 4 |
pic_param->pic_quantizer_fields.bits.half_qp << 1 |
pic_param->pic_quantizer_fields.bits.pic_quantizer_type << 0);
OUT_BCS_BATCH(batch,
- !!(pic_param->bitplane_present.value & 0x7f) << 31 |
- pic_param->raw_coding.flags.forward_mb << 30 |
- pic_param->raw_coding.flags.mv_type_mb << 29 |
- pic_param->raw_coding.flags.skip_mb << 28 |
- pic_param->raw_coding.flags.direct_mb << 27 |
- pic_param->raw_coding.flags.overflags << 26 |
- pic_param->raw_coding.flags.ac_pred << 25 |
- pic_param->raw_coding.flags.field_tx << 24 |
+ bitplane_present << 31 |
+ forward_mb << 30 |
+ mv_type_mb << 29 |
+ skip_mb << 28 |
+ direct_mb << 27 |
+ overflags << 26 |
+ ac_pred << 25 |
+ field_tx << 24 |
pic_param->mv_fields.bits.mv_table << 20 |
pic_param->mv_fields.bits.four_mv_block_pattern_table << 18 |
pic_param->mv_fields.bits.two_mv_block_pattern_table << 16 |
{
struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
VAPictureParameterBufferVC1 *pic_param;
+ struct gen7_vc1_surface *gen7_vc1_top_surface;
+ struct gen7_vc1_surface *gen7_vc1_bottom_surface;
int picture_type;
+ int is_first_field = 1;
int intensitycomp_single_fwd = 0;
- int luma_scale1 = 0;
- int luma_shift1 = 0;
+ int intensitycomp_single_bwd = 0;
+ int intensitycomp_double_fwd = 0;
+ int lumscale1_single_fwd = 0;
+ int lumscale2_single_fwd = 0;
+ int lumshift1_single_fwd = 0;
+ int lumshift2_single_fwd = 0;
+ int lumscale1_single_bwd = 0;
+ int lumscale2_single_bwd = 0;
+ int lumshift1_single_bwd = 0;
+ int lumshift2_single_bwd = 0;
+ int lumscale1_double_fwd = 0;
+ int lumscale2_double_fwd = 0;
+ int lumshift1_double_fwd = 0;
+ int lumshift2_double_fwd = 0;
+ int replication_mode = 0;
assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
- picture_type = pic_param->picture_fields.bits.picture_type;
-
- if (gen7_mfd_context->reference_surface[0].surface_id != VA_INVALID_ID) {
- if (picture_type == 1 || picture_type == 2) { /* P/B picture */
- struct gen7_vc1_surface *gen7_vc1_surface = gen7_mfd_context->reference_surface[0].obj_surface->private_data;
- if (gen7_vc1_surface) {
- intensitycomp_single_fwd = gen7_vc1_surface->intensity_compensation;
- luma_scale1 = gen7_vc1_surface->luma_scale;
- luma_shift1 = gen7_vc1_surface->luma_shift;
+
+ if (!pic_param->sequence_fields.bits.interlace ||
+ (pic_param->picture_fields.bits.frame_coding_mode < 2)) { /* Progressive or Frame-Interlace */
+ picture_type = pic_param->picture_fields.bits.picture_type;
+ } else {/* Field-Interlace */
+ is_first_field = pic_param->picture_fields.bits.is_first_field;
+ picture_type = fptype_to_picture_type[pic_param->picture_fields.bits.picture_type][!is_first_field];
+ }
+
+ if (picture_type == GEN7_VC1_P_PICTURE ||
+ picture_type == GEN7_VC1_B_PICTURE) {
+ if (gen7_mfd_context->reference_surface[0].surface_id != VA_INVALID_ID)
+ gen7_vc1_top_surface = (struct gen7_vc1_surface *)(gen7_mfd_context->reference_surface[0].obj_surface->private_data);
+ else
+ gen7_vc1_top_surface = NULL;
+
+ if (gen7_vc1_top_surface) {
+ intensitycomp_single_fwd = !!gen7_vc1_top_surface->intensity_compensation_top;
+ lumscale1_single_fwd = gen7_vc1_top_surface->luma_scale_top[0];
+ lumshift1_single_fwd = gen7_vc1_top_surface->luma_shift_top[0];
+ if (gen7_vc1_top_surface->intensity_compensation_top == 2) {
+ intensitycomp_double_fwd = 1;
+ lumscale1_double_fwd = gen7_vc1_top_surface->luma_scale_top[1];
+ lumshift1_double_fwd = gen7_vc1_top_surface->luma_shift_top[1];
+ }
+ }
+
+ if (pic_param->sequence_fields.bits.interlace &&
+ pic_param->picture_fields.bits.frame_coding_mode > 0) { /* Frame-Interlace or Field-Interlace */
+ if (gen7_mfd_context->reference_surface[2].surface_id != VA_INVALID_ID)
+ gen7_vc1_bottom_surface = (struct gen7_vc1_surface *)(gen7_mfd_context->reference_surface[2].obj_surface->private_data);
+ else
+ gen7_vc1_bottom_surface = NULL;
+
+ if (gen7_vc1_bottom_surface) {
+ intensitycomp_single_fwd |= !!gen7_vc1_bottom_surface->intensity_compensation_bottom << 1;
+ lumscale2_single_fwd = gen7_vc1_bottom_surface->luma_scale_bottom[0];
+ lumshift2_single_fwd = gen7_vc1_bottom_surface->luma_shift_bottom[0];
+ if (gen7_vc1_bottom_surface->intensity_compensation_bottom == 2) {
+ intensitycomp_double_fwd |= 2;
+ lumscale2_double_fwd = gen7_vc1_bottom_surface->luma_scale_bottom[1];
+ lumshift2_double_fwd = gen7_vc1_bottom_surface->luma_shift_bottom[1];
+ }
+ }
+ }
+ }
+
+ if (picture_type == GEN7_VC1_B_PICTURE) {
+ if (gen7_mfd_context->reference_surface[1].surface_id != VA_INVALID_ID)
+ gen7_vc1_top_surface = (struct gen7_vc1_surface *)(gen7_mfd_context->reference_surface[1].obj_surface->private_data);
+ else
+ gen7_vc1_top_surface = NULL;
+
+ if (gen7_vc1_top_surface) {
+ intensitycomp_single_bwd = !!gen7_vc1_top_surface->intensity_compensation_top;
+ lumscale1_single_bwd = gen7_vc1_top_surface->luma_scale_top[0];
+ lumshift1_single_bwd = gen7_vc1_top_surface->luma_shift_top[0];
+ }
+
+ if (pic_param->sequence_fields.bits.interlace &&
+ pic_param->picture_fields.bits.frame_coding_mode > 0) { /* Frame-Interlace or Field-Interlace */
+ if (gen7_mfd_context->reference_surface[3].surface_id != VA_INVALID_ID)
+ gen7_vc1_bottom_surface = (struct gen7_vc1_surface *)(gen7_mfd_context->reference_surface[3].obj_surface->private_data);
+ else
+ gen7_vc1_bottom_surface = NULL;
+
+ if (gen7_vc1_bottom_surface) {
+ intensitycomp_single_bwd |= !!gen7_vc1_bottom_surface->intensity_compensation_bottom << 1;
+ lumscale2_single_bwd = gen7_vc1_bottom_surface->luma_scale_bottom[0];
+ lumshift2_single_bwd = gen7_vc1_bottom_surface->luma_shift_bottom[0];
}
}
}
+ if (pic_param->sequence_fields.bits.interlace &&
+ pic_param->picture_fields.bits.frame_coding_mode > 0) { /* Frame-Interlace or Field-Interlace */
+ if (picture_type == GEN7_VC1_P_PICTURE)
+ replication_mode = 0x5;
+ else if (picture_type == GEN7_VC1_B_PICTURE)
+ replication_mode = 0xf;
+ }
+
BEGIN_BCS_BATCH(batch, 6);
OUT_BCS_BATCH(batch, MFX_VC1_PRED_PIPE_STATE | (6 - 2));
OUT_BCS_BATCH(batch,
- 0 << 14 | /* FIXME: double ??? */
+ intensitycomp_double_fwd << 14 |
0 << 12 |
intensitycomp_single_fwd << 10 |
- 0 << 8 |
- 0 << 4 | /* FIXME: interlace mode */
+ intensitycomp_single_bwd << 8 |
+ replication_mode << 4 |
0);
OUT_BCS_BATCH(batch,
- luma_shift1 << 16 |
- luma_scale1 << 0);
- OUT_BCS_BATCH(batch, 0);
- OUT_BCS_BATCH(batch, 0);
- OUT_BCS_BATCH(batch, 0);
+ lumshift2_single_fwd << 24 |
+ lumshift1_single_fwd << 16 |
+ lumscale2_single_fwd << 8 |
+ lumscale1_single_fwd << 0);
+ OUT_BCS_BATCH(batch,
+ lumshift2_double_fwd << 24 |
+ lumshift1_double_fwd << 16 |
+ lumscale2_double_fwd << 8 |
+ lumscale1_double_fwd << 0);
+ OUT_BCS_BATCH(batch,
+ lumshift2_single_bwd << 24 |
+ lumshift1_single_bwd << 16 |
+ lumscale2_single_bwd << 8 |
+ lumscale1_single_bwd << 0);
+ OUT_BCS_BATCH(batch,
+ 0 << 24 |
+ 0 << 16 |
+ 0 << 8 |
+ 0 << 0);
ADVANCE_BCS_BATCH(batch);
}
struct gen7_mfd_context *gen7_mfd_context)
{
struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
+ VAPictureParameterBufferVC1 *pic_param;
struct object_surface *obj_surface;
dri_bo *dmv_read_buffer = NULL, *dmv_write_buffer = NULL;
+ int picture_type;
+ int is_first_field = 1;
- obj_surface = decode_state->render_object;
+ pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
- if (obj_surface && obj_surface->private_data) {
- dmv_write_buffer = ((struct gen7_vc1_surface *)(obj_surface->private_data))->dmv;
+ if (!pic_param->sequence_fields.bits.interlace ||
+ (pic_param->picture_fields.bits.frame_coding_mode < 2)) { /* Progressive or Frame-Interlace */
+ picture_type = pic_param->picture_fields.bits.picture_type;
+ } else {/* Field-Interlace */
+ is_first_field = pic_param->picture_fields.bits.is_first_field;
+ picture_type = fptype_to_picture_type[pic_param->picture_fields.bits.picture_type][!is_first_field];
}
- obj_surface = decode_state->reference_objects[1];
+ if (picture_type == GEN7_VC1_P_PICTURE ||
+ picture_type == GEN7_VC1_SKIPPED_PICTURE) {
+ obj_surface = decode_state->render_object;
- if (obj_surface && obj_surface->private_data) {
- dmv_read_buffer = ((struct gen7_vc1_surface *)(obj_surface->private_data))->dmv;
+ if (pic_param->sequence_fields.bits.interlace &&
+ (pic_param->picture_fields.bits.frame_coding_mode == 2) && /* Field-Interlace */
+ (pic_param->picture_fields.bits.top_field_first ^ is_first_field))
+ dmv_write_buffer = ((struct gen7_vc1_surface *)(obj_surface->private_data))->dmv_bottom;
+ else
+ dmv_write_buffer = ((struct gen7_vc1_surface *)(obj_surface->private_data))->dmv_top;
+ }
+
+ if (picture_type == GEN7_VC1_B_PICTURE) {
+ obj_surface = decode_state->reference_objects[1];
+ if (pic_param->backward_reference_picture != VA_INVALID_ID &&
+ obj_surface &&
+ obj_surface->private_data) {
+
+ if (pic_param->sequence_fields.bits.interlace &&
+ (pic_param->picture_fields.bits.frame_coding_mode == 2) && /* Field-Interlace */
+ (pic_param->picture_fields.bits.top_field_first ^ is_first_field))
+ dmv_read_buffer = ((struct gen7_vc1_surface *)(obj_surface->private_data))->dmv_bottom;
+ else
+ dmv_read_buffer = ((struct gen7_vc1_surface *)(obj_surface->private_data))->dmv_top;
+ }
}
BEGIN_BCS_BATCH(batch, 3);
int slice_header_size = in_slice_data_bit_offset / 8;
int i, j;
- if (profile != 3)
- out_slice_data_bit_offset = in_slice_data_bit_offset;
- else {
- for (i = 0, j = 0; i < slice_header_size; i++, j++) {
- if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4) {
- if (i < slice_header_size - 1)
+ if (profile == 3 && slice_header_size) { /* Advanced Profile */
+ for (i = 0, j = 0; i < slice_header_size - 1; i++, j++)
+ if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4)
i++, j += 2;
- else {
- buf[j + 2] = buf[j + 1];
- j++;
- }
+
+ if (i == slice_header_size - 1) {
+ if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3 && buf[j + 3] < 4) {
+ buf[j + 2] = 0;
+ j++;
}
+
+ j++;
}
out_slice_data_bit_offset = 8 * j + in_slice_data_bit_offset % 8;
- }
+ } else /* Simple or Main Profile */
+ out_slice_data_bit_offset = in_slice_data_bit_offset;
return out_slice_data_bit_offset;
}
if (next_slice_param)
next_slice_start_vert_pos = next_slice_param->slice_vertical_position;
- else
+ else if (!pic_param->sequence_fields.bits.interlace ||
+ pic_param->picture_fields.bits.frame_coding_mode < 2) /* Progressive or Frame-Interlace */
next_slice_start_vert_pos = ALIGN(pic_param->coded_height, 16) / 16;
+ else /* Field-Interlace */
+ next_slice_start_vert_pos = ALIGN(pic_param->coded_height, 32) / 32;
BEGIN_BCS_BATCH(batch, 5);
OUT_BCS_BATCH(batch, MFD_VC1_BSD_OBJECT | (5 - 2));