diff options
author | Zhao, Yakui <yakui.zhao@intel.com> | 2014-06-12 08:54:41 +0800 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2014-06-16 12:00:11 +0800 |
commit | 745340dd013399f64507de73401ab3adb712dad5 (patch) | |
tree | e58afbbf2ef6272a6bf74dd2a42cc08bbb2cea5b | |
parent | 773525af39331df7a9d3178037320734774fc8be (diff) | |
download | libva-intel-driver-745340dd013399f64507de73401ab3adb712dad5.tar.gz libva-intel-driver-745340dd013399f64507de73401ab3adb712dad5.tar.bz2 libva-intel-driver-745340dd013399f64507de73401ab3adb712dad5.zip |
Encoding: Use the different delimeter to pass packed_rawdata and slice_header based on VAConfigAttribEncPackedHeaders attribute
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: some
user hope to be more flexible. 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 inser the packed rawdata/slice_header for the given slice.
So the VAConfigAttribEncPackedHeaders attriburation 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.
V1->V2: Return an error instead of only complaining warning message when packed
slice_header is missing for some slice under the VAEncPackedSlice mode. This
is the suggestion from Gwenole and Sreerenj Balachandran.
Signed-off-by: Zhao, Yakui <yakui.zhao@intel.com>
(cherry picked from commit 9d49a6d693aa6c862467a4a879bc86d9cb98dbe5)
-rwxr-xr-x | src/i965_drv_video.c | 119 | ||||
-rw-r--r-- | src/i965_drv_video.h | 10 |
2 files changed, 104 insertions, 25 deletions
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c index 68a6052..b7a0485 100755 --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -1778,6 +1778,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; @@ -1794,15 +1795,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 { @@ -2237,11 +2251,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]); @@ -2249,6 +2263,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); @@ -2488,21 +2503,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)) { @@ -2540,20 +2559,64 @@ 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) { + + /* 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->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); + 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] = + /* 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); - } else { - WARN_ONCE("Multi slice header data is passed for" - " slice %d!\n", 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->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); + } } } } @@ -2690,6 +2753,14 @@ 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"); + return VA_STATUS_ERROR_INVALID_PARAMETER; + } } 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 dfa2a7a..10e8778 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. |