summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao, Yakui <yakui.zhao@intel.com>2014-05-26 08:40:15 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2014-06-16 11:53:35 +0800
commit107274f309c6c3a7c59b70d5140b781341c7e9c2 (patch)
tree375b1ae53ffa90401250da01a4f282c50801b307
parentee4b8c3ec1e5b5f126d8bdb7021eb15630de751e (diff)
downloadlibva-intel-driver-107274f309c6c3a7c59b70d5140b781341c7e9c2.tar.gz
H264_Encoding: Add the support of packed slice header to be flexible
Under some encoding scenario, the user hopes to generate the packed slice header data by themself and then the driver can insert the passed slice header packed data into the coded clip. 1.The VA_ENC_PACKED_HEADER_SLICE flag is exported and it is treated as optional. This is to say: if packed slice header data is passed, it will be inserted directly. If no packed slice header data is passed, the driver will help to generate it. 2.Another restriction is that the packed slice header data is inserted after the packed rawdata for one slice. That is to say: If it needs to insert the packed rawdata and slice header data, the packed rawdata will be inserted firstly(This is handled by the driver). Signed-off-by: Zhao, Yakui <yakui.zhao@intel.com> (cherry picked from commit 00111e8a8bfa67b971419b72577eaa1b9f47bc34) Conflicts: src/gen75_mfc.c src/gen8_mfc.c
-rw-r--r--src/gen6_mfc.c28
-rw-r--r--src/gen6_mfc_common.c61
-rw-r--r--src/gen75_mfc.c30
-rw-r--r--src/gen8_mfc.c30
-rwxr-xr-xsrc/i965_drv_video.c32
-rw-r--r--src/i965_drv_video.h3
6 files changed, 90 insertions, 94 deletions
diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c
index c6702e85..f1b29b9d 100644
--- a/src/gen6_mfc.c
+++ b/src/gen6_mfc.c
@@ -788,8 +788,6 @@ gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
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;
@@ -816,14 +814,6 @@ gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
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
- 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);
-
dri_bo_map(vme_context->vme_output.bo , 1);
msg = (unsigned int *)vme_context->vme_output.bo->virtual;
@@ -869,7 +859,6 @@ gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
1, 1, 1, 0, slice_batch);
}
- free(slice_header);
}
@@ -1176,8 +1165,6 @@ gen6_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
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;
@@ -1210,21 +1197,6 @@ gen6_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
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
- 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_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */
used = intel_batchbuffer_used_size(slice_batch);
head_size = (used - old_used) / 16;
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c
index 44e6e957..e500feb8 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -1528,10 +1528,12 @@ void intel_avc_slice_insert_packed_data(VADriverContextP ctx,
VAEncPackedHeaderParameterBuffer *param = NULL;
unsigned int *header_data = NULL;
struct gen6_mfc_context *mfc_context = encoder_context->mfc_context;
+ int slice_header_index;
- /* If the number of packed data for current slice is zero, return */
- if (encode_state->slice_rawdata_count[slice_index] == 0)
- return;
+ if (encode_state->slice_header_index[slice_index] == 0)
+ slice_header_index = -1;
+ else
+ slice_header_index = (encode_state->slice_header_index[slice_index] & SLICE_PACKED_DATA_INDEX_MASK);
count = encode_state->slice_rawdata_count[slice_index];
start_index = (encode_state->slice_rawdata_index[slice_index] & SLICE_PACKED_DATA_INDEX_MASK);
@@ -1543,6 +1545,11 @@ void intel_avc_slice_insert_packed_data(VADriverContextP ctx,
param = (VAEncPackedHeaderParameterBuffer *)
(encode_state->packed_header_params_ext[start_index + i]->buffer);
+
+ /* skip the slice header packed data type as it is lastly inserted */
+ if (param->type == VAEncPackedHeaderSlice)
+ continue;
+
length_in_bits = param->bit_length;
skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits);
@@ -1561,5 +1568,53 @@ void intel_avc_slice_insert_packed_data(VADriverContextP ctx,
!param->has_emulation_bytes,
slice_batch);
}
+
+ if (slice_header_index == -1) {
+ unsigned char *slice_header = NULL;
+ int slice_header_length_in_bits = 0;
+ 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;
+
+ /* No slice header data is passed. And the driver needs to generate it */
+ /* For the Normal H264 */
+ slice_header_length_in_bits = build_avc_slice_header(pSequenceParameter,
+ pPicParameter,
+ pSliceParameter,
+ &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,
+ 5, /* first 5 bytes are start code + nal unit type */
+ 1, 0, 1, slice_batch);
+
+ free(slice_header);
+ } else {
+ 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;
+
+ /* as the slice header is the last header data for one slice,
+ * the last header flag is set to one.
+ */
+ skip_emul_byte_cnt = intel_avc_find_skipemulcnt((unsigned char *)header_data, length_in_bits);
+
+ mfc_context->insert_object(ctx,
+ encoder_context,
+ header_data,
+ ALIGN(length_in_bits, 32) >> 5,
+ length_in_bits & 0x1f,
+ skip_emul_byte_cnt,
+ 1,
+ 0,
+ !param->has_emulation_bytes,
+ slice_batch);
+ }
+
return;
}
diff --git a/src/gen75_mfc.c b/src/gen75_mfc.c
index 18a588f9..1051dd53 100644
--- a/src/gen75_mfc.c
+++ b/src/gen75_mfc.c
@@ -1166,8 +1166,6 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
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;
@@ -1194,16 +1192,6 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
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
- 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);
-
dri_bo_map(vme_context->vme_output.bo , 1);
msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual;
@@ -1516,8 +1504,6 @@ gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
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 slice_type = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
@@ -1547,22 +1533,6 @@ gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
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
- 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_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */
head_offset = intel_batchbuffer_used_size(slice_batch);
diff --git a/src/gen8_mfc.c b/src/gen8_mfc.c
index 2fc1facf..c86cf091 100644
--- a/src/gen8_mfc.c
+++ b/src/gen8_mfc.c
@@ -1029,8 +1029,6 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
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;
@@ -1058,16 +1056,6 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
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
- 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);
-
dri_bo_map(vme_context->vme_output.bo , 1);
msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual;
@@ -1409,8 +1397,6 @@ gen8_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
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;
@@ -1443,22 +1429,6 @@ gen8_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
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
- 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_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */
used = intel_batchbuffer_used_size(slice_batch);
head_size = (used - old_used) / 16;
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index cf42b687..8da5a947 100755
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -659,7 +659,8 @@ i965_GetConfigAttributes(VADriverContextP ctx,
profile == VAProfileH264Main ||
profile == VAProfileH264High ||
profile == VAProfileH264MultiviewHigh) {
- attrib_list[i].value |= VA_ENC_PACKED_HEADER_RAW_DATA;
+ attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
+ VA_ENC_PACKED_HEADER_SLICE);
}
break;
}
@@ -1650,6 +1651,12 @@ i965_destroy_context(struct object_heap *heap, struct object_base *obj)
free(obj_context->codec_state.encode.slice_rawdata_count);
obj_context->codec_state.encode.slice_rawdata_count = NULL;
}
+
+ if (obj_context->codec_state.encode.slice_header_index) {
+ free(obj_context->codec_state.encode.slice_header_index);
+ obj_context->codec_state.encode.slice_header_index = NULL;
+ }
+
for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
free(obj_context->codec_state.encode.packed_header_params_ext);
@@ -1792,6 +1799,9 @@ i965_CreateContext(VADriverContextP ctx,
obj_context->codec_state.encode.slice_rawdata_count =
calloc(obj_context->codec_state.encode.slice_num, sizeof(int));
+ obj_context->codec_state.encode.slice_header_index =
+ calloc(obj_context->codec_state.encode.slice_num, sizeof(int));
+
assert(i965->codec_info->enc_hw_context_init);
obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
} else {
@@ -2229,6 +2239,8 @@ i965_BeginPicture(VADriverContextP ctx,
sizeof(int) * obj_context->codec_state.encode.slice_num);
memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
sizeof(int) * obj_context->codec_state.encode.slice_num);
+ memset(obj_context->codec_state.encode.slice_header_index, 0,
+ sizeof(int) * obj_context->codec_state.encode.slice_num);
for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
@@ -2481,7 +2493,10 @@ i965_encoder_render_picture(VADriverContextP ctx,
encode->slice_num * sizeof(int));
encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
encode->slice_num * sizeof(int));
+ encode->slice_header_index = realloc(encode->slice_header_index,
+ encode->slice_num * sizeof(int));
if ((encode->slice_rawdata_index == NULL) ||
+ (encode->slice_header_index == NULL) ||
(encode->slice_rawdata_count == NULL)) {
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
return vaStatus;
@@ -2495,7 +2510,8 @@ i965_encoder_render_picture(VADriverContextP ctx,
VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
encode->last_packed_header_type = param->type;
- if (param->type == VAEncPackedHeaderRawData) {
+ if ((param->type == VAEncPackedHeaderRawData) ||
+ (param->type == VAEncPackedHeaderSlice)) {
vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
} else {
vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
@@ -2513,7 +2529,8 @@ i965_encoder_render_picture(VADriverContextP ctx,
vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
return vaStatus;
}
- if (encode->last_packed_header_type == VAEncPackedHeaderRawData) {
+ if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
+ encode->last_packed_header_type == VAEncPackedHeaderSlice) {
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 */
@@ -2522,6 +2539,15 @@ i965_encoder_render_picture(VADriverContextP ctx,
SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
}
encode->slice_rawdata_count[encode->num_slice_params_ext]++;
+ if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
+ if (encode->slice_header_index[encode->num_slice_params_ext] == 0) {
+ encode->slice_header_index[encode->num_slice_params_ext] =
+ SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
+ } else {
+ WARN_ONCE("Multi slice header data is passed for"
+ " slice %d!\n", encode->num_slice_params_ext);
+ }
+ }
}
} else {
ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index 98272096..29e550f4 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -165,6 +165,9 @@ struct encode_state
/* This is to store the number of packed data for one slice */
int *slice_rawdata_count;
+ /* This is to store the index of packed slice header for one slice */
+ int *slice_header_index;
+
int last_packed_header_type;
struct buffer_store *misc_param[16];