Improve the libmix parser efficiency by using short format

BZ: 146002

On baytrail, the GEN hardware support AVC short format parsing.
In multiple slice situation, the parsing work is a bottleneck for
CPU. If we use AVC short format, some slice header parsing work
can be done with GEN HW. This will increase the overall decoding
performance.

Change-Id: Ib2bff7f4cca6cde917700e501ee53e3f17c55a81
Signed-off-by: wfeng6 <wei.feng@intel.com>
Reviewed-on: http://android.intel.com:8080/140127
Reviewed-by: Shi, PingX <pingx.shi@intel.com>
Tested-by: Shi, PingX <pingx.shi@intel.com>
Reviewed-by: cactus <cactus@intel.com>
Tested-by: cactus <cactus@intel.com>
diff --git a/mixvbp/vbp_manager/vbp_h264_parser.c b/mixvbp/vbp_manager/vbp_h264_parser.c
index 0a8f141..dd93ea7 100755
--- a/mixvbp/vbp_manager/vbp_h264_parser.c
+++ b/mixvbp/vbp_manager/vbp_h264_parser.c
@@ -545,6 +545,7 @@
         {
             pic_parms->ReferenceFrames[frame_idx].frame_idx = store->frame_num;
             pic_parms->ReferenceFrames[frame_idx].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
+
             if (FRAME == parser->info.img.structure)
             {
                 pic_parms->ReferenceFrames[frame_idx].TopFieldOrderCnt = store->top_field.poc;
@@ -587,6 +588,11 @@
         if (viddec_h264_get_is_used(store))
         {
             pic_parms->ReferenceFrames[frame_idx].flags = VA_PICTURE_H264_LONG_TERM_REFERENCE;
+
+#ifdef USE_AVC_SHORT_FORMAT
+            pic_parms->ReferenceFrames[frame_idx].frame_idx = store->long_term_frame_idx;
+#endif
+
             if (FRAME == parser->info.img.structure)
             {
                 pic_parms->ReferenceFrames[frame_idx].TopFieldOrderCnt = store->frame.poc;
@@ -1149,6 +1155,13 @@
         /* actual num_ref_frames is set in vbp_set_reference_frames_h264 */
     }
 
+#ifdef USE_AVC_SHORT_FORMAT
+    {
+        pic_parms->num_ref_idx_l0_default_active_minus1 = parser->info.active_PPS.num_ref_idx_l0_active - 1;
+        pic_parms->num_ref_idx_l1_default_active_minus1 = parser->info.active_PPS.num_ref_idx_l1_active - 1;
+    }
+#endif
+
     return VBP_OK;
 }
 
@@ -1197,6 +1210,11 @@
     /* whole slice is in this buffer */
     slc_parms->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
 
+    slice_header = &(h264_parser->info.SliceHeader);
+    slc_parms->first_mb_in_slice = slice_header->first_mb_in_slice;
+    slc_parms->slice_type = slice_header->slice_type;
+
+#ifndef USE_AVC_SHORT_FORMAT
     /* bit offset from NAL start code to the beginning of slice data */
     slc_parms->slice_data_bit_offset = bit + byte * 8;
 
@@ -1249,6 +1267,7 @@
 
     vbp_set_pre_weight_table_h264(h264_parser, slc_parms);
     vbp_set_slice_ref_list_h264(h264_parser, slc_parms);
+#endif
 
     pic_data->num_slices++;
 
diff --git a/mixvbp/vbp_plugin/h264/Android.mk b/mixvbp/vbp_plugin/h264/Android.mk
index 2045d32..f661940 100755
--- a/mixvbp/vbp_plugin/h264/Android.mk
+++ b/mixvbp/vbp_plugin/h264/Android.mk
@@ -13,7 +13,7 @@
     h264parse_sps.c     \
     h264parse_dpb.c     \
     viddec_h264_parse.c \
-	mix_vbp_h264_stubs.c
+    mix_vbp_h264_stubs.c
 
 LOCAL_C_INCLUDES :=                   \
     $(LOCAL_PATH)/include             \
@@ -21,6 +21,11 @@
     $(MIXVBP_DIR)/vbp_manager/include \
     $(MIXVBP_DIR)/vbp_manager/h264/include
 
+PLATFORM_SUPPORT_AVC_SHORT_FORMAT := baytrail
+ifneq ($(filter $(TARGET_BOARD_PLATFORM),$(PLATFORM_SUPPORT_AVC_SHORT_FORMAT)),)
+LOCAL_CFLAGS += -DUSE_AVC_SHORT_FORMAT
+endif
+
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libmixvbp_h264
 
diff --git a/mixvbp/vbp_plugin/h264/h264parse_sh.c b/mixvbp/vbp_plugin/h264/h264parse_sh.c
index 0d8dc9d..71d16f6 100755
--- a/mixvbp/vbp_plugin/h264/h264parse_sh.c
+++ b/mixvbp/vbp_plugin/h264/h264parse_sh.c
@@ -224,6 +224,16 @@
             break;
         }
 
+#ifdef USE_AVC_SHORT_FORMAT
+        bool keepParsing = false;
+        keepParsing = h264_is_new_picture_start(pInfo, *SliceHeader, pInfo->SliceHeader) && (SliceHeader->nal_ref_idc != 0);
+        if (!keepParsing)
+        {
+            ITRACE("short format parsing: no need to go on!");
+            ret = H264_STATUS_OK;
+            break;
+        }
+#endif
         if (h264_Parse_Ref_Pic_List_Reordering(parent, pInfo, SliceHeader) != H264_STATUS_OK)
         {
             WTRACE("ref list reordering failed during slice header parsing.");
diff --git a/mixvbp/vbp_plugin/h264/viddec_h264_parse.c b/mixvbp/vbp_plugin/h264/viddec_h264_parse.c
index 2aa80b9..28a319a 100755
--- a/mixvbp/vbp_plugin/h264/viddec_h264_parse.c
+++ b/mixvbp/vbp_plugin/h264/viddec_h264_parse.c
@@ -207,9 +207,9 @@
         //////////////////////////////////////////////// Update frame Type--- IDR/I/P/B for frame or field
         h264_update_frame_type(pInfo);
 
-
-        h264_dpb_update_ref_lists( pInfo);
-
+#ifndef USE_AVC_SHORT_FORMAT
+        h264_dpb_update_ref_lists(pInfo);
+#endif
         /// Emit out the current "good" slice
         h264_parse_emit_current_slice(parent, pInfo);
 
@@ -285,7 +285,7 @@
     case h264_NAL_UNIT_TYPE_PPS:
     {
         //OS_INFO("*****************************PPS**************************************\n");
-
+        status = H264_STATUS_OK;
         uint32_t old_sps_id = pInfo->active_SPS.seq_parameter_set_id;
         uint32_t old_pps_id = pInfo->active_PPS.pic_parameter_set_id;
 
diff --git a/videodecoder/VideoDecoderAVC.cpp b/videodecoder/VideoDecoderAVC.cpp
index c075e8a..72131aa 100644
--- a/videodecoder/VideoDecoderAVC.cpp
+++ b/videodecoder/VideoDecoderAVC.cpp
@@ -295,10 +295,11 @@
         status = updateDPB(picParam);
         CHECK_STATUS("updateDPB");
 
+#ifndef USE_AVC_SHORT_FORMAT
         //We have to provide a hacked DPB rather than complete DPB for libva as workaround
         status = updateReferenceFrames(picData);
         CHECK_STATUS("updateReferenceFrames");
-
+#endif
         vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
         CHECK_VA_STATUS("vaBeginPicture");
 
@@ -328,6 +329,8 @@
         bufferIDCount++;
     }
 
+#ifndef USE_AVC_SHORT_FORMAT
+
     status = setReference(sliceParam);
     CHECK_STATUS("setReference");
 
@@ -339,6 +342,16 @@
         1,
         sliceParam,
         &bufferIDs[bufferIDCount]);
+#else
+    vaStatus = vaCreateBuffer(
+        mVADisplay,
+        mVAContext,
+        VASliceParameterBufferType,
+        sizeof(VASliceParameterBufferH264Base),
+        1,
+        sliceParam,
+        &bufferIDs[bufferIDCount]);
+#endif
     CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
     bufferIDCount++;
 
@@ -835,3 +848,46 @@
     return maxDPBSize;
 }
 
+#ifdef USE_AVC_SHORT_FORMAT
+Decode_Status VideoDecoderAVC::getCodecSpecificConfigs(
+    VAProfile profile, VAConfigID *config)
+{
+    VAStatus vaStatus;
+    VAConfigAttrib attrib[2];
+
+    if (config == NULL) {
+        ETRACE("Invalid parameter!");
+        return DECODE_FAIL;
+    }
+
+    attrib[0].type = VAConfigAttribRTFormat;
+    attrib[0].value = VA_RT_FORMAT_YUV420;
+    attrib[1].type = VAConfigAttribDecSliceMode;
+    attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
+
+    vaStatus = vaGetConfigAttributes(mVADisplay,profile,VAEntrypointVLD, &attrib[1], 1);
+
+    if (attrib[1].value & VA_DEC_SLICE_MODE_BASE)
+    {
+        ITRACE("AVC short format used");
+        attrib[1].value = VA_DEC_SLICE_MODE_BASE;
+    } else if (attrib[1].value & VA_DEC_SLICE_MODE_NORMAL) {
+        ITRACE("AVC long format used");
+        attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
+    } else {
+        ETRACE("Unsupported Decode Slice Mode!");
+        return DECODE_FAIL;
+    }
+
+    vaStatus = vaCreateConfig(
+            mVADisplay,
+            profile,
+            VAEntrypointVLD,
+            &attrib[0],
+            2,
+            config);
+    CHECK_VA_STATUS("vaCreateConfig");
+
+    return DECODE_SUCCESS;
+}
+#endif
diff --git a/videodecoder/VideoDecoderAVC.h b/videodecoder/VideoDecoderAVC.h
index 9c23e6b..6f3855d 100644
--- a/videodecoder/VideoDecoderAVC.h
+++ b/videodecoder/VideoDecoderAVC.h
@@ -58,7 +58,9 @@
     Decode_Status handleNewSequence(vbp_data_h264 *data);
     bool isNewFrame(vbp_data_h264 *data, bool equalPTS);
     int32_t getDPBSize(vbp_data_h264 *data);
-
+#ifdef USE_AVC_SHORT_FORMAT
+    virtual Decode_Status getCodecSpecificConfigs(VAProfile profile, VAConfigID*config);
+#endif
 private:
     struct DecodedPictureBuffer {
         VideoSurfaceBuffer *surfaceBuffer;