[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