[Libva] [RFC PATCH Libva-intel-driver 5/6] H264_Encoding: Add the support of packed slice header to be flexible

Zhao, Yakui yakui.zhao at intel.com
Tue May 20 22:51:19 PDT 2014


From: "Zhao, Yakui" <yakui.zhao at intel.com>

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. And it follows the below points:
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.

Signed-off-by: Zhao, Yakui <yakui.zhao at intel.com>
---
 src/gen6_mfc.c        |  28 ------------
 src/gen6_mfc_common.c |  94 ++++++++++++++++++++++++++++++++++++--
 src/gen75_mfc.c       | 122 ++++----------------------------------------------
 src/gen8_mfc.c        | 105 +------------------------------------------
 src/i965_drv_video.c  |  32 +++++++++++--
 src/i965_drv_video.h  |   3 ++
 6 files changed, 133 insertions(+), 251 deletions(-)

diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c
index c6702e8..f1b29b9 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 ef31cf9..9f96bad 100644
--- a/src/gen6_mfc_common.c
+++ b/src/gen6_mfc_common.c
@@ -1475,10 +1475,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);
@@ -1490,6 +1492,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);
@@ -1508,6 +1515,87 @@ 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 */
+        if (encoder_context->codec == CODEC_H264_MVC) {
+            VAEncSequenceParameterBufferH264_MVC *mvc_seq_param   = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter;
+            VAEncPictureParameterBufferH264_MVC  *mvc_pic_param   = (VAEncPictureParameterBufferH264_MVC*)pPicParameter;
+            VAEncSliceParameterBufferH264   *slice_param     = pSliceParameter;
+
+            if (mvc_pic_param->view_id != 0) {
+                /* generate one extension slice header with type of 20 */
+                slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param,
+                                                                     mvc_pic_param,
+                                                                     slice_param,
+                                                                     &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,
+                                       8,  /* first 5 bytes are start code + nal unit type */
+                                       1, 0, 1, slice_batch);
+
+            } else {
+
+                /* generate common H264 slice header */
+                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);
+            }
+        } else {
+            /* 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 7b75e2b..4c54e08 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;
@@ -1183,68 +1181,16 @@ gen75_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
     assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52);
     assert(qp >= 0 && qp < 52);
 
-    if (encoder_context->codec == CODEC_H264_MVC) {
-          VAEncSequenceParameterBufferH264_MVC *mvc_seq_param   = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter;
-          VAEncPictureParameterBufferH264_MVC  *mvc_pic_param   = (VAEncPictureParameterBufferH264_MVC *)pPicParameter;
-          VAEncSliceParameterBufferH264   *mvc_slice_param = pSliceParameter;
-
-          gen75_mfc_avc_slice_state(ctx,
-                                    pPicParameter,
-                                    pSliceParameter,
-                                    encode_state, encoder_context,
-                                    (rate_control_mode == VA_RC_CBR), qp, slice_batch);
-
-          if (slice_index == 0)
-             intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
-
-          if (mvc_pic_param->view_id != 0) {
-               /* generate one extension slice header with type of 20 */
-               slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param,
-                                                                        mvc_pic_param,
-                                                                        mvc_slice_param,
-                                                                        &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,
-                                          8,  /* first 5 bytes are start code + nal unit type */
-                                          1, 0, 1, slice_batch);
-
-           } else {
-
-               intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
-               /* generate one common H264 slice header */
-               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);
-         }
-
-    } else {
-         gen75_mfc_avc_slice_state(ctx,
-                                  pPicParameter,
-                                  pSliceParameter,
-                                  encode_state, encoder_context,
-                                  (rate_control_mode == VA_RC_CBR), qp, slice_batch);
-
-        if ( slice_index == 0)
-            intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
-
-         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);
+    gen75_mfc_avc_slice_state(ctx,
+                              pPicParameter,
+                              pSliceParameter,
+                              encode_state, encoder_context,
+                              (rate_control_mode == VA_RC_CBR), qp, slice_batch);
 
-         // 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);
-    }
+    if ( slice_index == 0)
+          intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
 
-    free(slice_header);
+    intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
 
     dri_bo_map(vme_context->vme_output.bo , 1);
     msg_ptr = (unsigned char *)vme_context->vme_output.bo->virtual;
@@ -1560,8 +1506,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);
@@ -1590,55 +1534,7 @@ gen75_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
         intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
 
 
-    if (encoder_context->codec == CODEC_H264_MVC) {
-        VAEncSequenceParameterBufferH264_MVC *mvc_seq_param   = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter;
-        VAEncPictureParameterBufferH264_MVC  *mvc_pic_param   = (VAEncPictureParameterBufferH264_MVC*)pPicParameter;
-        VAEncSliceParameterBufferH264   *slice_param     = pSliceParameter;
-
-        if (mvc_pic_param->view_id != 0) {
-            /* generate one extension slice header with type of 20 */
-            slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param,
-                                                                     mvc_pic_param,
-                                                                     slice_param,
-                                                                     &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,
-                                       8,  /* first 5 bytes are start code + nal unit type */
-                                       1, 0, 1, slice_batch);
-
-         } else {
-            intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
-
-            /* generate common H264 slice header */
-            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);
-       }
-
-    } else {
-        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_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
 
     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 cb6e6a4..b0f3a5c 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;
@@ -1047,47 +1045,6 @@ gen8_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
     assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52);
     assert(qp >= 0 && qp < 52);
 
-    if (encoder_context->codec == CODEC_H264_MVC) {
-          VAEncSequenceParameterBufferH264_MVC *mvc_seq_param   = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter;
-          VAEncPictureParameterBufferH264_MVC  *mvc_pic_param   = (VAEncPictureParameterBufferH264_MVC *)pPicParameter;
-          VAEncSliceParameterBufferH264   *mvc_slice_param = pSliceParameter;
-
-          gen8_mfc_avc_slice_state(ctx,
-                                    pPicParameter,
-                                    pSliceParameter,
-                                    encode_state, encoder_context,
-                                    (rate_control_mode == VA_RC_CBR), qp, slice_batch);
-
-          if (slice_index == 0)
-             intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
-
-          if (mvc_pic_param->view_id != 0) {
-               /* generate one extension slice header with type of 20 */
-               slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param,
-                                                                        mvc_pic_param,
-                                                                        mvc_slice_param,
-                                                                        &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,
-                                          8,  /* first 5 bytes are start code + nal unit type */
-                                          1, 0, 1, slice_batch);
-
-           } else {
-               intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
-
-               /* generate one common H264 slice header */
-               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);
-         }
-
-    } else {
          gen8_mfc_avc_slice_state(ctx,
                                   pPicParameter,
                                   pSliceParameter,
@@ -1099,17 +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;
 
@@ -1453,8 +1399,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;
@@ -1486,55 +1430,8 @@ gen8_mfc_avc_batchbuffer_slice(VADriverContextP ctx,
         intel_mfc_avc_pipeline_header_programing(ctx, encode_state, encoder_context, slice_batch);
 
 
-    if (encoder_context->codec == CODEC_H264_MVC) {
-        VAEncSequenceParameterBufferH264_MVC *mvc_seq_param   = (VAEncSequenceParameterBufferH264_MVC *)pSequenceParameter;
-        VAEncPictureParameterBufferH264_MVC  *mvc_pic_param   = (VAEncPictureParameterBufferH264_MVC*)pPicParameter;
-        VAEncSliceParameterBufferH264   *slice_param     = pSliceParameter;
-
-        if (mvc_pic_param->view_id != 0) {
-            /* generate one extension slice header with type of 20 */
-            slice_header_length_in_bits = build_avc_mvc_slice_header(mvc_seq_param,
-                                                                     mvc_pic_param,
-                                                                     slice_param,
-                                                                     &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,
-                                       8,  /* first 5 bytes are start code + nal unit type */
-                                       1, 0, 1, slice_batch);
-
-         } else {
-            intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
-
-            /* generate common H264 slice header */
-            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);
-       }
-
-    } else {
-        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);
-    }
+    intel_avc_slice_insert_packed_data(ctx, encode_state, encoder_context, slice_index, slice_batch);
 
-    free(slice_header);
 
     intel_batchbuffer_align(slice_batch, 16); /* aligned by an Oword */
     used = intel_batchbuffer_used_size(slice_batch);
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 056b9e2..c5a4f37 100755
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -421,7 +421,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;
             }
@@ -1475,6 +1476,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);
@@ -1610,6 +1617,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 {
@@ -2034,6 +2044,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]);
@@ -2286,7 +2298,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;
@@ -2300,7 +2315,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,
@@ -2318,7 +2334,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 */
@@ -2327,6 +2344,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 15cf637..aae9735 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -159,6 +159,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];
-- 
1.7.12-rc1



More information about the Libva mailing list