[Libva] [PATCH 06/13] Encoding: Add one ROI flag and ROI buffer
Pengfei Qu
Pengfei.Qu at intel.com
Thu Jul 7 09:17:57 UTC 2016
From: Zhao Yakui <yakui.zhao at intel.com>
v1:
Add one flag to indicate whether ROI is supported in one encode context
Allocate one ROI buffer to hold qp per mb dynamically
Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
Signed-off-by: pjl <cecilia.peng at intel.com>
Signed-off-by: Pengfei Qu <Pengfei.Qu at intel.com>
---
src/gen6_mfc_common.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/gen6_vme.h | 13 +++++++++
src/i965_encoder.c | 7 +++--
src/i965_encoder.h | 1 +
4 files changed, 93 insertions(+), 2 deletions(-)
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index baa8ec4..c7d406f 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -1753,6 +1753,80 @@ intel_h264_setup_cost_surface(VADriverContextP ctx,
surface_state_offset);
}
+extern void
+intel_h264_enc_roi_config(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context)
+{
+ char *qp_ptr;
+ int i, j;
+ VAEncMiscParameterBuffer* pMiscParamROI;
+ VAEncMiscParameterBufferROI *pParamROI;
+ VAEncROI *region_roi;
+ struct gen6_vme_context *vme_context = encoder_context->vme_context;
+ struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
+ VAEncSequenceParameterBufferH264 *pSequenceParameter = (VAEncSequenceParameterBufferH264 *)encode_state->seq_param_ext->buffer;
+ int width_in_mbs = pSequenceParameter->picture_width_in_mbs;
+ int height_in_mbs = pSequenceParameter->picture_height_in_mbs;
+
+ vme_context->roi_enabled = 0;
+ /* Restriction: Disable ROI when multi-slice is enabled */
+ if (!encoder_context->context_roi || (encode_state->num_slice_params_ext > 1))
+ return;
+
+ if (encode_state->misc_param[VAEncMiscParameterTypeROI] == NULL) {
+ return;
+ }
+
+ pMiscParamROI = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeROI]->buffer;
+ pParamROI = (VAEncMiscParameterBufferROI *)pMiscParamROI->data;
+
+ /* check whether number of ROI is correct */
+ /* currently one region is supported */
+ if (pParamROI->num_roi != 1) {
+ return;
+ }
+
+ vme_context->roi_enabled = 1;
+
+ if ((vme_context->saved_width_mbs != width_in_mbs) ||
+ (vme_context->saved_height_mbs != height_in_mbs)) {
+ if (vme_context->qp_per_mb)
+ free(vme_context->qp_per_mb);
+ vme_context->qp_per_mb = calloc(1, width_in_mbs * height_in_mbs);
+
+ vme_context->saved_width_mbs = width_in_mbs;
+ vme_context->saved_height_mbs = height_in_mbs;
+ assert(vme_context->qp_per_mb);
+ }
+ if (encoder_context->rate_control_mode == VA_RC_CBR) {
+ /*
+ * TODO: More complex Qp adjust needs to be added.
+ * Currently it is initialized to slice_qp.
+ */
+ VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
+ VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
+ int qp;
+ int slice_type = intel_avc_enc_slice_type_fixup(slice_param->slice_type);
+
+ qp = mfc_context->bit_rate_control_context[slice_type].QpPrimeY;
+ memset(vme_context->qp_per_mb, qp, width_in_mbs * height_in_mbs);
+ } else if (encoder_context->rate_control_mode == VA_RC_CQP){
+ VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
+ VAEncSliceParameterBufferH264 *slice_param = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[0]->buffer;
+ int qp;
+
+ qp = pic_param->pic_init_qp + slice_param->slice_qp_delta;
+ memset(vme_context->qp_per_mb, qp, width_in_mbs * height_in_mbs);
+ } else {
+ /*
+ * TODO: Disable it for non CBR-CQP.
+ */
+ vme_context->roi_enabled = 0;
+ }
+ return;
+}
+
/* HEVC */
static int
hevc_temporal_find_surface(VAPictureHEVC *curr_pic,
diff --git a/src/gen6_vme.h b/src/gen6_vme.h
index 7059831..002fe0e 100644
--- a/src/gen6_vme.h
+++ b/src/gen6_vme.h
@@ -98,6 +98,13 @@ struct gen6_vme_context
dri_bo *p_qp_cost_table;
dri_bo *b_qp_cost_table;
int cost_table_size;
+
+ /* one buffer define qp per mb. one byte for every mb.
+ * If it needs to be accessed by GPU, it will be changed to dri_bo.
+ */
+ bool roi_enabled;
+ char *qp_per_mb;
+ int saved_width_mbs, saved_height_mbs;
};
#define MPEG2_PIC_WIDTH_HEIGHT 30
@@ -219,4 +226,10 @@ intel_h264_setup_cost_surface(VADriverContextP ctx,
struct intel_encoder_context *encoder_context,
unsigned long binding_table_offset,
unsigned long surface_state_offset);
+
+extern void
+intel_h264_enc_roi_config(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context);
+
#endif /* _GEN6_VME_H_ */
diff --git a/src/i965_encoder.c b/src/i965_encoder.c
index 1088f08..dac0bcb 100644
--- a/src/i965_encoder.c
+++ b/src/i965_encoder.c
@@ -828,6 +828,7 @@ intel_enc_hw_context_init(VADriverContextP ctx,
break;
}
+ encoder_context->context_roi = 0;
for (i = 0; i < obj_config->num_attribs; i++) {
if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
@@ -837,8 +838,10 @@ intel_enc_hw_context_init(VADriverContextP ctx,
WARN_ONCE("Don't support CBR for MPEG-2 encoding\n");
encoder_context->rate_control_mode &= ~VA_RC_CBR;
}
-
- break;
+ }
+ if (obj_config->attrib_list[i].type == VAConfigAttribEncROI) {
+ if (encoder_context->codec == CODEC_H264)
+ encoder_context->context_roi = 1;
}
}
diff --git a/src/i965_encoder.h b/src/i965_encoder.h
index 94d84b5..db7e698 100644
--- a/src/i965_encoder.h
+++ b/src/i965_encoder.h
@@ -66,6 +66,7 @@ struct intel_encoder_context
unsigned int is_tmp_id:1;
unsigned int low_power_mode:1;
unsigned int soft_batch_force:1;
+ unsigned int context_roi:1;
void (*vme_context_destroy)(void *vme_context);
VAStatus (*vme_pipeline)(VADriverContextP ctx,
--
2.7.4
More information about the Libva
mailing list