[Libva] [PATCH Libva-intel-driver 2/2] Encoding: Use the different delimeter to pass packed_rawdata/slice_header based on VAConfigAttribEncPackedHeaders attribute
Zhao, Yakui
yakui.zhao at intel.com
Wed Jun 4 21:54:05 PDT 2014
From: "Zhao, Yakui" <yakui.zhao at intel.com>
Currently the packed_slice_header is optional. And it uses the VAEncSliceParameterBuffer
as the delimeter to decide how to insert the packed rawdata/slice_header
for one slice. This is not convenient under some scenario. For example: When
the user is responsible for generating the packed slice_header, it hopes to
use the packed slice_header as the delimeter to determine how to insert the
packed rawdata/slice_header for the given slice.
So the VAConfigAttribEncPackedHeaders attriburte of encoding_context is
used to decide which kind of delimeter.
a. When the VAEncPackedSlice is set when calling vaCreateConfig, it will use
the packed slice_header as delimeter. Of course the packed rawdata should be
parsed before the packed slice_header for one given slice. For exmaple:
for the slice 0: the packed rawdata should be parsed before paring the first
packed slice_header. After one packed slice_header is parsed, it will start
to parse the corresponding data for a new slice.
b. When the VAEncPackedSlice is not set when calling vaCreateConfig, it will
use the VAEncSliceParameterBuffer as delimeter.
Signed-off-by: Zhao, Yakui <yakui.zhao at intel.com>
---
src/i965_drv_video.c | 122 ++++++++++++++++++++++++++++++++++++++++-----------
src/i965_drv_video.h | 10 ++++-
2 files changed, 105 insertions(+), 27 deletions(-)
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index fcbab79..bae70d5 100755
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -1764,6 +1764,7 @@ i965_CreateContext(VADriverContextP ctx,
assert(i965->codec_info->proc_hw_context_init);
obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
} else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
+ VAConfigAttrib *packed_attrib;
obj_context->codec_type = CODEC_ENC;
memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
@@ -1780,15 +1781,28 @@ i965_CreateContext(VADriverContextP ctx,
calloc(obj_context->codec_state.encode.max_packed_header_data_ext,
sizeof(struct buffer_store *));
- obj_context->codec_state.encode.slice_num = NUM_SLICES;
+ obj_context->codec_state.encode.max_slice_num = NUM_SLICES;
obj_context->codec_state.encode.slice_rawdata_index =
- calloc(obj_context->codec_state.encode.slice_num, sizeof(int));
+ calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
obj_context->codec_state.encode.slice_rawdata_count =
- calloc(obj_context->codec_state.encode.slice_num, sizeof(int));
+ calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
obj_context->codec_state.encode.slice_header_index =
- calloc(obj_context->codec_state.encode.slice_num, sizeof(int));
-
+ calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
+
+ obj_context->codec_state.encode.slice_index = 0;
+ packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
+ if (packed_attrib)
+ obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
+ else {
+ /* use the default value. SPS/PPS/RAWDATA is passed from user
+ * while Slice_header data is generated by driver.
+ */
+ obj_context->codec_state.encode.packed_header_flag =
+ VA_ENC_PACKED_HEADER_SEQUENCE |
+ VA_ENC_PACKED_HEADER_PICTURE |
+ VA_ENC_PACKED_HEADER_RAW_DATA;
+ }
assert(i965->codec_info->enc_hw_context_init);
obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
} else {
@@ -2215,11 +2229,11 @@ i965_BeginPicture(VADriverContextP ctx,
obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/
obj_context->codec_state.encode.last_packed_header_type = 0;
memset(obj_context->codec_state.encode.slice_rawdata_index, 0,
- sizeof(int) * obj_context->codec_state.encode.slice_num);
+ sizeof(int) * obj_context->codec_state.encode.max_slice_num);
memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
- sizeof(int) * obj_context->codec_state.encode.slice_num);
+ sizeof(int) * obj_context->codec_state.encode.max_slice_num);
memset(obj_context->codec_state.encode.slice_header_index, 0,
- sizeof(int) * obj_context->codec_state.encode.slice_num);
+ sizeof(int) * obj_context->codec_state.encode.max_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]);
@@ -2227,6 +2241,7 @@ i965_BeginPicture(VADriverContextP ctx,
i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
obj_context->codec_state.encode.num_packed_header_params_ext = 0;
obj_context->codec_state.encode.num_packed_header_data_ext = 0;
+ obj_context->codec_state.encode.slice_index = 0;
} else {
obj_context->codec_state.decode.current_render_target = render_target;
i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
@@ -2466,21 +2481,25 @@ i965_encoder_render_picture(VADriverContextP ctx,
* 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) {
- int slice_num = encode->slice_num;
- encode->slice_num = encode->max_slice_params_ext;
+ if (!(encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE)) {
+ encode->slice_index++;
+ }
+ if (encode->slice_index == encode->max_slice_num) {
+ int slice_num = encode->max_slice_num;
encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
- encode->slice_num * sizeof(int));
+ (slice_num + NUM_SLICES) * sizeof(int));
encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
- encode->slice_num * sizeof(int));
+ (slice_num + NUM_SLICES) * sizeof(int));
encode->slice_header_index = realloc(encode->slice_header_index,
- encode->slice_num * sizeof(int));
+ (slice_num + NUM_SLICES) * sizeof(int));
memset(encode->slice_rawdata_index + slice_num, 0,
sizeof(int) * NUM_SLICES);
memset(encode->slice_rawdata_count + slice_num, 0,
sizeof(int) * NUM_SLICES);
memset(encode->slice_header_index + slice_num, 0,
sizeof(int) * NUM_SLICES);
+
+ encode->max_slice_num += NUM_SLICES;
if ((encode->slice_rawdata_index == NULL) ||
(encode->slice_header_index == NULL) ||
(encode->slice_rawdata_count == NULL)) {
@@ -2518,22 +2537,66 @@ i965_encoder_render_picture(VADriverContextP ctx,
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 */
- 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);
+
+ /* When the PACKED_SLICE_HEADER flag is passed, it will use
+ * the packed_slice_header as the delimeter to decide how
+ * the packed rawdata is inserted for the given slice.
+ * Otherwise it will use the VAEncSequenceParameterBuffer
+ * as the delimeter
+ */
+ if (encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) {
+ /* store the first index of the packed header data for current slice */
+ if (encode->slice_rawdata_index[encode->slice_index] == 0) {
+ encode->slice_rawdata_index[encode->slice_index] =
+ SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
}
- encode->slice_rawdata_count[encode->num_slice_params_ext]++;
+ encode->slice_rawdata_count[encode->slice_index]++;
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);
+ /* find one packed slice_header delimeter. And the following
+ * packed data is for the next slice
+ */
+ encode->slice_header_index[encode->slice_index] =
+ SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
+ encode->slice_index++;
+ /* Reallocate the buffer to record the index/count of
+ * packed_data for one slice.
+ */
+ if (encode->slice_index == encode->max_slice_num) {
+ int slice_num = encode->max_slice_num;
+
+ encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
+ (slice_num + NUM_SLICES) * sizeof(int));
+ encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
+ (slice_num + NUM_SLICES) * sizeof(int));
+ encode->slice_header_index = realloc(encode->slice_header_index,
+ (slice_num + NUM_SLICES) * sizeof(int));
+ memset(encode->slice_rawdata_index + slice_num, 0,
+ sizeof(int) * NUM_SLICES);
+ memset(encode->slice_rawdata_count + slice_num, 0,
+ sizeof(int) * NUM_SLICES);
+ memset(encode->slice_header_index + slice_num, 0,
+ sizeof(int) * NUM_SLICES);
+ encode->max_slice_num += NUM_SLICES;
}
}
+ } else {
+ if (vaStatus == VA_STATUS_SUCCESS) {
+ /* store the first index of the packed header data for current slice */
+ if (encode->slice_rawdata_index[encode->slice_index] == 0) {
+ encode->slice_rawdata_index[encode->slice_index] =
+ SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
+ }
+ encode->slice_rawdata_count[encode->slice_index]++;
+ if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
+ if (encode->slice_header_index[encode->slice_index] == 0) {
+ encode->slice_header_index[encode->slice_index] =
+ 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->slice_index);
+ }
+ }
+ }
}
} else {
ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
@@ -2668,6 +2731,13 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
(obj_context->codec_state.encode.num_slice_params_ext <=0)) {
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
+
+ if ((obj_context->codec_state.encode.packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) &&
+ (obj_context->codec_state.encode.num_slice_params_ext !=
+ obj_context->codec_state.encode.slice_index)) {
+ WARN_ONCE("packed slice_header data is missing for some slice"
+ " under packed SLICE_HEADER mode\n");
+ }
} else {
if (obj_context->codec_state.decode.pic_param == NULL) {
return VA_STATUS_ERROR_INVALID_PARAMETER;
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index fff301c..82ed18a 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -149,6 +149,12 @@ struct encode_state
int max_slice_params_ext;
int num_slice_params_ext;
+ /* Check the user-configurable packed_header attribute.
+ * Currently it is mainly used to check whether the packed slice_header data
+ * is provided by user or the driver.
+ * TBD: It will check for the packed SPS/PPS/MISC/RAWDATA and so on.
+ */
+ unsigned int packed_header_flag;
/* For the packed data that needs to be inserted into video clip */
/* currently it is mainly to track packed raw data and packed slice_header data. */
struct buffer_store **packed_header_params_ext;
@@ -158,8 +164,10 @@ struct encode_state
int max_packed_header_data_ext;
int num_packed_header_data_ext;
+ /* the index of current slice */
+ int slice_index;
/* the array is determined by max_slice_params_ext */
- int slice_num;
+ int max_slice_num;
/* This is to store the first index of packed data for one slice */
int *slice_rawdata_index;
/* This is to store the number of packed data for one slice.
--
1.7.12-rc1
More information about the Libva
mailing list