VideoDecoderAVC: Return the frame info from a multiple frame buffer to decode more.

BZ: 63127

The orignal mix will drop the buffer which contains more than one frame.

Change-Id: I94d59e41a5874eeedae076353e66df479f1a3d48
Signed-off-by: fxiao4X <fengx.xiao@intel.com>
Reviewed-on: http://android.intel.com:8080/72469
Reviewed-by: Wang, Yi A <yi.a.wang@intel.com>
Reviewed-by: Guo, Nana N <nana.n.guo@intel.com>
Reviewed-by: Qiu, Junhai <junhai.qiu@intel.com>
Reviewed-by: Shi, PingX <pingx.shi@intel.com>
Tested-by: Shi, PingX <pingx.shi@intel.com>
Reviewed-by: lab_cactus <lab_cactus@intel.com>
Tested-by: lab_cactus <lab_cactus@intel.com>
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c b/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
index 1bf8ee6..8592e64 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_h264_parser.c
@@ -1192,7 +1192,6 @@
     /* bit offset from NAL start code to the beginning of slice data */
     slc_parms->slice_data_bit_offset = bit + byte * 8;
 
-
     if (is_emul)
     {
         WTRACE("next byte is emulation prevention byte.");
@@ -1571,21 +1570,18 @@
                                 &(cxt->sc_prefix_info));
             if (ret == 1)
             {
-                cubby.phase = 0;
-
                 if (cxt->list.num_items == 0)
                 {
                     cxt->list.data[0].stpos = cubby.sc_end_pos;
                 }
                 else
                 {
-                    cxt->list.data[cxt->list.num_items - 1].edpos =
-                        cubby.sc_end_pos + cxt->list.data[cxt->list.num_items - 1].stpos;
-
                     cxt->list.data[cxt->list.num_items].stpos =
-                        cxt->list.data[cxt->list.num_items - 1].edpos;
+                        cubby.sc_end_pos + cxt->list.data[cxt->list.num_items - 1].stpos;
+                    cxt->list.data[cxt->list.num_items - 1].edpos = cxt->list.data[cxt->list.num_items].stpos - cubby.phase; /* offset before start code */
                 }
 
+                cubby.phase = 0;
                 cubby.buf = cxt->parse_cubby.buf +
                             cxt->list.data[cxt->list.num_items].stpos;
 
@@ -1690,6 +1686,12 @@
         WTRACE("unknown header %d is parsed.", parser->info.nal_unit_type);
         break;
     }
+
+    if (query_data->num_pictures == MAX_NUM_PICTURES && parser->info.img.field_pic_flag != 1)
+    {
+        WTRACE("more than one frame in the buffer is found(%d)", query_data->num_pictures);
+        return (error == VBP_OK ? VBP_MULTI : error);
+    }
     return error;
 }
 
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_loader.h b/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
index 38e2a05..ffeb332 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
@@ -338,7 +338,8 @@
     VBP_DONE,
     VBP_MEM,
     VBP_PARM,
-    VBP_PARTIAL
+    VBP_PARTIAL,
+    VBP_MULTI
 };
 
 enum _vbp_parser_type
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_utils.c b/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
index 237a02f..42f9c96 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_utils.c
@@ -388,7 +388,10 @@
         /* process parsing result */
         error = pcontext->func_process_parsing_result(pcontext, i);
 
-        if (0 != error)
+        if (VBP_MULTI == error) {
+            return VBP_OK;
+        }
+        else if (0 != error)
         {
             ETRACE("Failed to process parsing result.");
             return error;
diff --git a/videodecoder/VideoDecoderAVC.cpp b/videodecoder/VideoDecoderAVC.cpp
index 2ef67c3..8863738 100644
--- a/videodecoder/VideoDecoderAVC.cpp
+++ b/videodecoder/VideoDecoderAVC.cpp
@@ -113,6 +113,12 @@
     }
 
     status = decodeFrame(buffer, data);
+    if (status == DECODE_MULTIPLE_FRAME) {
+        buffer->ext = &mExtensionBuffer;
+        mExtensionBuffer.extType = PACKED_FRAME_TYPE;
+        mExtensionBuffer.extSize = sizeof(mPackedFrame);
+        mExtensionBuffer.extData = (uint8_t*)&mPackedFrame;
+    }
     return status;
 }
 
@@ -228,6 +234,17 @@
             return DECODE_PARSER_FAIL;
         }
 
+        if (picIndex > 0 &&
+            (picData->pic_parms->CurrPic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
+            // it is a packed frame buffer
+            vbp_picture_data_h264 *lastPic = &data->pic_data[picIndex - 1];
+            vbp_slice_data_h264 *sliceData = &(lastPic->slc_data[lastPic->num_slices - 1]);
+            mPackedFrame.offSet = sliceData->slice_size + sliceData->slice_offset;
+            mPackedFrame.timestamp = mCurrentPTS; // use the current time stamp for the packed frame
+            ITRACE("slice data offset= %d, size = %d", sliceData->slice_offset, sliceData->slice_size);
+            return DECODE_MULTIPLE_FRAME;
+        }
+
         for (uint32_t sliceIndex = 0; sliceIndex < picData->num_slices; sliceIndex++) {
             status = decodeSlice(data, picIndex, sliceIndex);
             if (status != DECODE_SUCCESS) {
diff --git a/videodecoder/VideoDecoderAVC.h b/videodecoder/VideoDecoderAVC.h
index 339e05a..799ae2e 100644
--- a/videodecoder/VideoDecoderAVC.h
+++ b/videodecoder/VideoDecoderAVC.h
@@ -77,6 +77,8 @@
     uint8_t mToggleDPB; // 0 or 1
     bool mErrorConcealment;
     uint32_t mLastPictureFlags;
+    VideoExtensionBuffer mExtensionBuffer;
+    PackedFrameData mPackedFrame;
 };