summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao, Yakui <yakui.zhao@intel.com>2014-05-26 08:40:15 +0800
committerZhao Yakui <yakui.zhao@intel.com>2014-05-26 08:40:15 +0800
commit974597ef64dc9a283d4787e1484a75d1610414f4 (patch)
treec8e9bf0803866604a79a6ced776ae6147eb4dd67
parent65727b1868f01d836659396724b83d2992656242 (diff)
H264_encoding: Add the support of inserting the packed raw data passed from user
Under some encoding scenario, the user-space application hopes that the driver can insert the passed packed rawdata into the coded clip. This is to allow the insertion of packed rawdata passed from user. As the position of packed rawdata is related with the slice. So the following restrictions are added: 1. the packed rawdata header type/data should be paired. 2. the packed rawdata data is inserted by following the passed order 3. the packed rawdata header type/data is split by using VAEncSliceParameterBuffer. That is to say: The packed rawdata for slice 0 should be passed before the first VAEncSliceParameterBuffer. After one VAEncSliceParameterBuffer is parsed, the subseuquent packed rawdata is for another new slice. The subsequent packed rawdata after the last VAEncSliceParameterBuffer is ignored. 4. it does not change the rule for the packed data of SPS/PPS/MISC type. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
-rw-r--r--src/gen6_mfc.c4
-rw-r--r--src/gen6_mfc.h7
-rw-r--r--src/gen6_mfc_common.c48
-rw-r--r--src/gen75_mfc.c25
-rw-r--r--src/gen8_mfc.c25
-rwxr-xr-xsrc/i965_drv_video.c62
6 files changed, 124 insertions, 47 deletions
diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c
index 21db0a7..c6702e8 100644
--- a/src/gen6_mfc.c
+++ b/src/gen6_mfc.c
@@ -814,6 +814,8 @@ gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
if ( slice_index == 0)
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);
+
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header);
// slice hander
@@ -1206,6 +1208,8 @@ gen6_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
if (slice_index == 0)
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);
+
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header);
// slice hander
diff --git a/src/gen6_mfc.h b/src/gen6_mfc.h
index 6df8093..f39432a 100644
--- a/src/gen6_mfc.h
+++ b/src/gen6_mfc.h
@@ -265,4 +265,11 @@ intel_mfc_avc_ref_idx_state(VADriverContextP ctx,
extern
Bool gen8_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
+extern void
+intel_avc_slice_insert_packed_data(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ int slice_index,
+ struct intel_batchbuffer *slice_batch);
+
#endif /* _GEN6_MFC_BCS_H_ */
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index 7d52fc6..b93cb47 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -1468,3 +1468,51 @@ intel_avc_vme_reference_state(VADriverContextP ctx,
vme_context->ref_index_in_mb[list_index] = 0;
}
}
+
+void intel_avc_slice_insert_packed_data(VADriverContextP ctx,
+ struct encode_state *encode_state,
+ struct intel_encoder_context *encoder_context,
+ int slice_index,
+ struct intel_batchbuffer *slice_batch)
+{
+ int count, i, start_index;
+ unsigned int length_in_bits;
+ VAEncPackedHeaderParameterBuffer *param = NULL;
+ unsigned int *header_data = NULL;
+ struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
+
+ /* If the number of packed data for current slice is zero, return */
+ if (encode_state->slice_rawdata_count[slice_index] == 0)
+ return;
+
+ 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);
+ 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.
+ */
+ mfc_context->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,
+ slice_batch);
+ }
+ return;
+}
+
diff --git a/src/gen75_mfc.c b/src/gen75_mfc.c
index 9ab010a..7b75e2b 100644
--- a/src/gen75_mfc.c
+++ b/src/gen75_mfc.c
@@ -1209,17 +1209,8 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
1, 0, 1, slice_batch);
} else {
- /* generate one mvc prefix nal */
- slice_header_length_in_bits = build_avc_mvc_prefix_nal_unit(mvc_seq_param,
- mvc_pic_param,
- mvc_slice_param,
- &slice_header);
- 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,
- 8, /* first 8 bytes are start code + nal unit type + svc ext flag + mvc nal extension */
- 0, 0, 1, slice_batch);
- free(slice_header);
+ intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
/* generate one common H264 slice header */
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter,
pPicParameter,
@@ -1242,6 +1233,8 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
if ( slice_index == 0)
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);
+
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header);
// slice hander
@@ -1614,16 +1607,7 @@ gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
1, 0, 1, slice_batch);
} else {
- /* generate one mvc prefix nal */
- slice_header_length_in_bits = build_avc_mvc_prefix_nal_unit(mvc_seq_param,
- mvc_pic_param,
- slice_param,
- &slice_header);
- 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,
- 8, /* first 8 bytes are start code + nal unit type + svc ext flag + mvc nal extension */
- 0, 0, 1, slice_batch);
- free(slice_header);
+ intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
/* generate common H264 slice header */
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter,
@@ -1637,6 +1621,7 @@ gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
}
} else {
+ intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header);
diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c
index ad92a6b..cb6e6a4 100644
--- a/src/gen8_mfc.c
+++ b/src/gen8_mfc.c
@@ -1073,16 +1073,7 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
1, 0, 1, slice_batch);
} else {
- /* generate one mvc prefix nal */
- slice_header_length_in_bits = build_avc_mvc_prefix_nal_unit(mvc_seq_param,
- mvc_pic_param,
- mvc_slice_param,
- &slice_header);
- 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,
- 8, /* first 8 bytes are start code + nal unit type + svc ext flag + mvc nal extension */
- 0, 0, 1, slice_batch);
- free(slice_header);
+ intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
/* generate one common H264 slice header */
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter,
@@ -1106,6 +1097,8 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
if ( slice_index == 0)
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);
+
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header);
// slice hander
@@ -1510,16 +1503,7 @@ gen8_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
1, 0, 1, slice_batch);
} else {
- /* generate one mvc prefix nal */
- slice_header_length_in_bits = build_avc_mvc_prefix_nal_unit(mvc_seq_param,
- mvc_pic_param,
- slice_param,
- &slice_header);
- 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,
- 8, /* first 8 bytes are start code + nal unit type + svc ext flag + mvc nal extension */
- 0, 0, 1, slice_batch);
- free(slice_header);
+ intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
/* generate common H264 slice header */
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter,
@@ -1533,6 +1517,7 @@ gen8_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
}
} else {
+ intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter, pPicParameter, pSliceParameter, &slice_header);
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index de643b8..954b377 100755
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -417,6 +417,12 @@ i965_GetConfigAttributes(VADriverContextP ctx,
case VAConfigAttribEncPackedHeaders:
if (entrypoint == VAEntrypointEncSlice) {
attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
+ if (profile == VAProfileH264ConstrainedBaseline ||
+ profile == VAProfileH264Main ||
+ profile == VAProfileH264High ||
+ profile == VAProfileH264MultiviewHigh) {
+ attrib_list[i].value |= VA_ENC_PACKED_HEADER_RAW_DATA;
+ }
break;
}
@@ -2172,6 +2178,9 @@ DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
// DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
+DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_params_ext, packed_header_params_ext)
+DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_data_ext, packed_header_data_ext)
+
static VAStatus
i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
struct object_context *obj_context,
@@ -2235,10 +2244,12 @@ i965_encoder_render_picture(VADriverContextP ctx,
struct i965_driver_data *i965 = i965_driver_data(ctx);
struct object_context *obj_context = CONTEXT(context);
VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+ struct encode_state *encode;
int i;
ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
+ encode = &obj_context->codec_state.encode;
for (i = 0; i < num_buffers; i++) {
struct object_buffer *obj_buffer = BUFFER(buffers[i]);
@@ -2264,35 +2275,67 @@ i965_encoder_render_picture(VADriverContextP ctx,
case VAEncSliceParameterBufferType:
vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
+ if (vaStatus == VA_STATUS_SUCCESS) {
+ /* When the max number of slices is updated, it also needs
+ * to reallocate the arrays that is used to store
+ * the packed data index/count for the slice
+ */
+ if (encode->max_slice_params_ext > encode->slice_num) {
+ encode->slice_num = encode->max_slice_params_ext;
+ encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
+ encode->slice_num * sizeof(int));
+ encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
+ encode->slice_num * sizeof(int));
+ if ((encode->slice_rawdata_index == NULL) ||
+ (encode->slice_rawdata_count == NULL)) {
+ vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
+ return vaStatus;
+ }
+ }
+ }
break;
case VAEncPackedHeaderParameterBufferType:
{
- struct encode_state *encode = &obj_context->codec_state.encode;
VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
encode->last_packed_header_type = param->type;
- vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
+ if (param->type == VAEncPackedHeaderRawData) {
+ vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
+ } else {
+ vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
obj_context,
obj_buffer,
va_enc_packed_type_to_idx(encode->last_packed_header_type));
+ }
break;
}
case VAEncPackedHeaderDataBufferType:
{
- struct encode_state *encode = &obj_context->codec_state.encode;
- ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
- encode->last_packed_header_type == VAEncPackedHeaderPicture ||
- encode->last_packed_header_type == VAEncPackedHeaderSlice ||
+ if (encode->last_packed_header_type == VAEncPackedHeaderRawData) {
+ vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
+ if (vaStatus == VA_STATUS_SUCCESS) {
+ /* store the first index of the packed header data for current slice */
+ if (encode->slice_rawdata_index[encode->num_slice_params_ext] == 0) {
+ encode->slice_rawdata_index[encode->num_slice_params_ext] =
+ SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
+ }
+ encode->slice_rawdata_count[encode->num_slice_params_ext]++;
+ }
+ } else {
+ ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
+ encode->last_packed_header_type == VAEncPackedHeaderPicture ||
+ encode->last_packed_header_type == VAEncPackedHeaderSlice ||
(((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
VA_STATUS_ERROR_ENCODING_ERROR);
- vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
+ vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
obj_context,
obj_buffer,
va_enc_packed_type_to_idx(encode->last_packed_header_type));
+ }
break;
}
@@ -2396,6 +2439,11 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
} else if (obj_context->codec_type == CODEC_ENC) {
ASSERT_RET(VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
+ if (obj_context->codec_state.encode.num_packed_header_params_ext !=
+ obj_context->codec_state.encode.num_packed_header_data_ext) {
+ WARN_ONCE("the packed header/data is not paired for encoding!\n");
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+ }
if (!(obj_context->codec_state.encode.pic_param ||
obj_context->codec_state.encode.pic_param_ext)) {
return VA_STATUS_ERROR_INVALID_PARAMETER;