From: "Zhao, Yakui" <[email protected]> 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 <[email protected]> --- src/i965_drv_video.c | 119 ++++++++++++++++++++++++++++++++++++++++----------- 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 08b34fd..575b5d6 100755 --- a/src/i965_drv_video.c +++ b/src/i965_drv_video.c @@ -1789,6 +1789,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; @@ -1805,15 +1806,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 { @@ -2248,11 +2262,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]); @@ -2260,6 +2274,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); @@ -2499,21 +2514,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)) { @@ -2551,20 +2570,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); + } } } } @@ -2701,6 +2764,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 a46fbdd..ee4b163 100644 --- a/src/i965_drv_video.h +++ b/src/i965_drv_video.h @@ -154,6 +154,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; @@ -163,8 +169,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 _______________________________________________ Libva mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libva
