libmix/videodecoder: Patches porting from R2 to R3

BZ: 18443

original patches:
27557 - libmix: fix issue when B frame number between 2 P frames is bigger than 2 (BZ: 17193)
26595 - decoder: expose VA context surfaces vie getInfo() (BZ: 14001)
24710 - libmix: if the frame is sync frame in container, skip the reference frame check (BZ: 8998)
24457 - Flush decoded buffer while resolution is changed. (BZ: 14251)

Signed-off-by: Weian Chen <weian.chen@intel.com>
Change-Id: Ic954d2a7972649e8e21021b6547b31c2e0d78e57
Reviewed-on: http://android.intel.com:8080/30008
Reviewed-by: Ding, Haitao <haitao.ding@intel.com>
Tested-by: Ding, Haitao <haitao.ding@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/videodecoder/VideoDecoderAVC.cpp b/videodecoder/VideoDecoderAVC.cpp
index 7ceb4a6..6613935 100644
--- a/videodecoder/VideoDecoderAVC.cpp
+++ b/videodecoder/VideoDecoderAVC.cpp
@@ -136,7 +136,7 @@
                 (pic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE));
     }
 #endif
-    if (data->new_sps) {
+    if (data->new_sps || data->new_pps) {
         status = handleNewSequence(data);
         CHECK_STATUS("handleNewSequence");
     }
@@ -144,7 +144,9 @@
     // first pic_data always exists, check if any slice is parsed
     if (data->pic_data[0].num_slices == 0) {
         ITRACE("No slice available for decoding.");
-        return DECODE_SUCCESS;
+        status = mSizeChanged ? DECODE_FORMAT_CHANGE : DECODE_SUCCESS;
+        mSizeChanged = false;
+        return status;
     }
 
     uint64_t lastPTS = mCurrentPTS;
@@ -674,7 +676,7 @@
     } else {
         WTRACE("Video size changed from %d x %d to %d x %d.", width, height,
                 mVideoFormatInfo.width, mVideoFormatInfo.height);
-        flush();
+        flushSurfaceBuffers();
     }
     return DECODE_SUCCESS;
 }
diff --git a/videodecoder/VideoDecoderBase.cpp b/videodecoder/VideoDecoderBase.cpp
index c71eff6..0f7f4ae 100644
--- a/videodecoder/VideoDecoderBase.cpp
+++ b/videodecoder/VideoDecoderBase.cpp
@@ -568,6 +568,19 @@
     return DECODE_SUCCESS;
 }
 
+void VideoDecoderBase::flushSurfaceBuffers(void) {
+    endDecodingFrame(true);
+    VideoSurfaceBuffer *p = NULL;
+    while (mOutputHead) {
+        mOutputHead->renderBuffer.renderDone = true;
+        p = mOutputHead;
+        mOutputHead = mOutputHead->next;
+        p->next = NULL;
+    }
+    mOutputHead = NULL;
+    mOutputTail = NULL;
+}
+
 Decode_Status VideoDecoderBase::endDecodingFrame(bool dropFrame) {
     Decode_Status status = DECODE_SUCCESS;
     VAStatus vaStatus;
@@ -731,6 +744,7 @@
     mVideoFormatInfo.surfaceWidth = mVideoFormatInfo.width;
     mVideoFormatInfo.surfaceHeight = mVideoFormatInfo.height;
     mVideoFormatInfo.surfaceNumber = mNumSurfaces;
+    mVideoFormatInfo.ctxSurfaces = mSurfaces;
 
     if ((int32_t)profile != VAProfileSoftwareDecoding) {
         vaStatus = vaCreateContext(
diff --git a/videodecoder/VideoDecoderBase.h b/videodecoder/VideoDecoderBase.h
index 3df3e3f..8cf4579 100644
--- a/videodecoder/VideoDecoderBase.h
+++ b/videodecoder/VideoDecoderBase.h
@@ -62,6 +62,8 @@
     virtual Decode_Status outputSurfaceBuffer(void);
     // acquired surface  buffer is not used
     virtual Decode_Status releaseSurfaceBuffer(void);
+    // flush all decoded but not rendered buffers
+    virtual void flushSurfaceBuffers(void);
     virtual Decode_Status endDecodingFrame(bool dropFrame);
     virtual VideoSurfaceBuffer* findOutputByPoc(bool draining = false);
     virtual VideoSurfaceBuffer* findOutputByPct(bool draining = false);
diff --git a/videodecoder/VideoDecoderDefs.h b/videodecoder/VideoDecoderDefs.h
index 5f1eac4..92a5668 100644
--- a/videodecoder/VideoDecoderDefs.h
+++ b/videodecoder/VideoDecoderDefs.h
@@ -88,6 +88,9 @@
     // indicate if it use graphic buffer.
     USE_NATIVE_GRAPHIC_BUFFER = 0x2000,
 
+    // indicate whether it is a sync frame in container
+    IS_SYNC_FRAME = 0x4000,
+
 } VIDEO_BUFFER_FLAG;
 
 struct VideoDecodeBuffer {
@@ -146,6 +149,7 @@
     int32_t surfaceWidth;
     int32_t surfaceHeight;
     int32_t surfaceNumber;
+    VASurfaceID *ctxSurfaces;
     int32_t aspectX;
     int32_t aspectY;
     int32_t cropLeft;
diff --git a/videodecoder/VideoDecoderMPEG4.cpp b/videodecoder/VideoDecoderMPEG4.cpp
index 5975436..2abcf37 100644
--- a/videodecoder/VideoDecoderMPEG4.cpp
+++ b/videodecoder/VideoDecoderMPEG4.cpp
@@ -73,6 +73,11 @@
     if (buffer == NULL) {
         return DECODE_INVALID_DATA;
     }
+    if (buffer->flag & IS_SYNC_FRAME) {
+        mIsSyncFrame = true;
+    } else {
+        mIsSyncFrame = false;
+    }
     status =  VideoDecoderBase::parseBuffer(
             buffer->data,
             buffer->size,
@@ -209,7 +214,7 @@
                 return DECODE_NO_REFERENCE;
             }
         } else if (codingType == MP4_VOP_TYPE_P || codingType == MP4_VOP_TYPE_S) {
-            if (mLastReference == NULL) {
+            if (mLastReference == NULL&& mIsSyncFrame == false) {
                 return DECODE_NO_REFERENCE;
             }
         }
@@ -412,10 +417,14 @@
             picParam->backward_reference_picture = VA_INVALID_SURFACE;
             break;
         case MP4_VOP_TYPE_P:
-            if (mLastReference == NULL) {
+            if (mLastReference == NULL&& mIsSyncFrame == false) {
                 return DECODE_NO_REFERENCE;
             }
-            picParam->forward_reference_picture = mLastReference->renderBuffer.surface;
+            if (mLastReference != NULL) {
+                picParam->forward_reference_picture = mLastReference->renderBuffer.surface;
+            } else {
+                picParam->forward_reference_picture = VA_INVALID_SURFACE;
+            }
             picParam->backward_reference_picture = VA_INVALID_SURFACE;
             break;
         case MP4_VOP_TYPE_B:
diff --git a/videodecoder/VideoDecoderMPEG4.h b/videodecoder/VideoDecoderMPEG4.h
index 79e5b99..300b583 100644
--- a/videodecoder/VideoDecoderMPEG4.h
+++ b/videodecoder/VideoDecoderMPEG4.h
@@ -64,6 +64,7 @@
     bool mExpectingNVOP; // indicate if future n-vop is a placeholder of a packed frame
     bool mSendIQMatrixBuf; // indicate if iq_matrix_buffer is sent to driver
     int32_t mLastVOPCodingType;
+    bool mIsSyncFrame; // indicate if it is SyncFrame in container
 };