libmix: A fix to enable VP8 HW 1080P playback on Merrifield VV

BZ: 81807

A fix to enable VP8 HW playback on Merrifield VV

Change-Id: I77c60e99214bc3838bb663259911dd67ed45acda
Signed-off-by: Tianmi Chen <tianmi.chen@intel.com>
Reviewed-on: http://android.intel.com:8080/87857
Reviewed-by: Wang, Yi A <yi.a.wang@intel.com>
Reviewed-by: Shi, PingX <pingx.shi@intel.com>
Tested-by: Shi, PingX <pingx.shi@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
diff --git a/mix_vbp/Android.mk b/mix_vbp/Android.mk
index 3df2e0a..819ded1 100644
--- a/mix_vbp/Android.mk
+++ b/mix_vbp/Android.mk
@@ -12,7 +12,8 @@
 MERRIFIELD_DEVICE := \
         mrfl_vp \
         mrfl_hvp \
-        mrfl_sle
+        mrfl_sle \
+        merr_vv
 ifneq ($(filter $(REF_DEVICE_NAME),$(MERRIFIELD_DEVICE)),)
 include $(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/vp8/parser/Android.mk
 endif
diff --git a/mix_vbp/viddec_fw/fw/parser/Android.mk b/mix_vbp/viddec_fw/fw/parser/Android.mk
index 6e403da..40410a0 100644
--- a/mix_vbp/viddec_fw/fw/parser/Android.mk
+++ b/mix_vbp/viddec_fw/fw/parser/Android.mk
@@ -48,7 +48,8 @@
 MERRIFIELD_DEVICE := \
         mrfl_vp \
         mrfl_hvp \
-        mrfl_sle
+        mrfl_sle \
+        merr_vv
 ifneq ($(filter $(REF_DEVICE_NAME),$(MERRIFIELD_DEVICE)),)
 LOCAL_SRC_FILES += vbp_vp8_parser.c
 LOCAL_C_INCLUDES += $(VENDORS_INTEL_MRST_MIXVBP_ROOT)/viddec_fw/fw/codecs/vp8/include
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_loader.h b/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
index 53988ab..1e888a9 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_loader.h
@@ -334,6 +334,12 @@
     int refresh_golden_frame;
     int refresh_last_frame;
 
+    /* cropping information */
+    int crop_top;
+    int crop_bottom;
+    int crop_left;
+    int crop_right;
+
     int golden_copied;
     int altref_copied;
 } vbp_codec_data_vp8;
diff --git a/mix_vbp/viddec_fw/fw/parser/vbp_vp8_parser.c b/mix_vbp/viddec_fw/fw/parser/vbp_vp8_parser.c
index 25aa85d..89ef068 100644
--- a/mix_vbp/viddec_fw/fw/parser/vbp_vp8_parser.c
+++ b/mix_vbp/viddec_fw/fw/parser/vbp_vp8_parser.c
@@ -64,6 +64,8 @@
     /* entry point not needed */
     pcontext->parser_ops->is_frame_start = NULL;
 
+    pcontext->parser_ops->flush = NULL;
+
     return VBP_OK;
 }
 
@@ -302,20 +304,7 @@
     VAProbabilityDataBufferVP8 *prob_data = query_data->prob_data;
 
     /* DCT coefficients probability */
-    int i, j, k, l;
-    for (i = 0; i < 4; i++)
-    {
-        for (j = 0; j < 8; j++)
-        {
-            for (k = 0; k < 3; k++)
-            {
-                for (l = 0; l < 11; l++)
-                {
-                    prob_data->dct_coeff_probs[i][j][k][l] = fc->DCT_Coefficients[i][j][k][l];
-                }
-            }
-        }
-    }
+    memcpy(prob_data->dct_coeff_probs, fc->DCT_Coefficients, 4*8*3*11*sizeof(uint8_t));
 }
 
 static void vbp_set_codec_data_vp8(vp8_viddec_parser *parser, vbp_codec_data_vp8* codec_data)
@@ -326,11 +315,14 @@
     codec_data->version_num = pi->frame_tag.version;
     codec_data->show_frame = pi->frame_tag.show_frame;
 
-    //codec_data->frame_width = pi->width;
-    //codec_data->frame_height = pi->height;
     codec_data->frame_width = ((pi->width + 15) / 16) * 16;
     codec_data->frame_height = ((pi->height + 15) / 16) * 16;
 
+    codec_data->crop_top = 0;
+    codec_data->crop_bottom = codec_data->frame_height - pi->height;
+    codec_data->crop_left = 0;
+    codec_data->crop_right = codec_data->frame_width - pi->width;
+
     codec_data->refresh_alt_frame = pi->refresh_af;
     codec_data->refresh_golden_frame = pi->refresh_gf;
     codec_data->refresh_last_frame = pi->refresh_lf;
diff --git a/videodecoder/Android.mk b/videodecoder/Android.mk
index 9c335f3..2998d4e 100644
--- a/videodecoder/Android.mk
+++ b/videodecoder/Android.mk
@@ -48,7 +48,8 @@
 MERRIFIELD_DEVICE := \
         mrfl_vp \
         mrfl_hvp \
-        mrfl_sle
+        mrfl_sle \
+        merr_vv
 ifneq ($(filter $(REF_DEVICE_NAME),$(MERRIFIELD_DEVICE)),)
 LOCAL_SRC_FILES += VideoDecoderVP8.cpp
 LOCAL_CFLAGS += -DUSE_HW_VP8
diff --git a/videodecoder/VideoDecoderVP8.cpp b/videodecoder/VideoDecoderVP8.cpp
index bc6274c..c08eb6a 100644
--- a/videodecoder/VideoDecoderVP8.cpp
+++ b/videodecoder/VideoDecoderVP8.cpp
@@ -45,6 +45,13 @@
     }
 }
 
+void VideoDecoderVP8::clearAsReference(int toggle, int ref_type) {
+    ReferenceFrameBuffer ref = mRFBs[toggle][ref_type];
+    if (ref.surfaceBuffer) {
+        ref.surfaceBuffer->asReferernce = false;
+    }
+}
+
 void VideoDecoderVP8::updateFormatInfo(vbp_data_vp8 *data) {
     int32_t width = data->codec_data->frame_width;
     int32_t height = data->codec_data->frame_height;
@@ -60,6 +67,12 @@
         ITRACE("Video size is changed.");
     }
 
+    mVideoFormatInfo.cropLeft = data->codec_data->crop_left;
+    mVideoFormatInfo.cropRight = data->codec_data->crop_right;
+    mVideoFormatInfo.cropTop = data->codec_data->crop_top;
+    mVideoFormatInfo.cropBottom = data->codec_data->crop_bottom;
+    ITRACE("Cropping: left = %d, top = %d, right = %d, bottom = %d", data->codec_data->crop_left, data->codec_data->crop_top, data->codec_data->crop_bottom);
+
     mVideoFormatInfo.valid = true;
 }
 
@@ -105,6 +118,9 @@
 
 void VideoDecoderVP8::flush(void) {
     VideoDecoderBase::flush();
+
+    invalidateReferenceFrames(0);
+    invalidateReferenceFrames(1);
 }
 
 Decode_Status VideoDecoderVP8::decode(VideoDecodeBuffer *buffer) {
@@ -144,6 +160,14 @@
         return DECODE_SUCCESS;
     }
 
+    if (VP8_KEY_FRAME == data->codec_data->frame_type) {
+        updateFormatInfo(data);
+        if (mSizeChanged == true) {
+            mSizeChanged = false;
+            return DECODE_FORMAT_CHANGE;
+        }
+    }
+
     if (data->codec_data->frame_type == VP8_SKIPPED_FRAME) {
         // Do nothing for skip frame as the last frame will be rendered agian by natively
         return DECODE_SUCCESS;
@@ -310,6 +334,20 @@
 
     /* Refresh alternative frame reference buffer using the currently reconstructed frame */
     refreshAltReference(data);
+
+    /* Update reference frames */
+    for (int i = 0; i < VP8_REF_SIZE; i++) {
+        VideoSurfaceBuffer *p = mRFBs[1][i].surfaceBuffer;
+        int j;
+        for (j = 0; j < VP8_REF_SIZE; j++) {
+            if (p == mRFBs[0][j].surfaceBuffer) {
+                break;
+            }
+            if (j == VP8_REF_SIZE) {
+                clearAsReference(1, i);
+            }
+        }
+    }
 }
 
 void VideoDecoderVP8::refreshLastReference(vbp_data_vp8 *data) {
@@ -321,13 +359,6 @@
     if (data->codec_data->refresh_last_frame) {
         mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer = mAcquiredBuffer;
         mRFBs[0][VP8_LAST_REF_PIC].index = mAcquiredBuffer->renderBuffer.surface;
-
-        if (mRFBs[1][VP8_LAST_REF_PIC].surfaceBuffer) {
-            mRFBs[1][VP8_LAST_REF_PIC].surfaceBuffer->asReferernce = false;
-        }
-    }
-
-    if (mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer) {
         mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer->asReferernce = true;
     }
 }
@@ -353,13 +384,6 @@
     if (data->codec_data->refresh_golden_frame) {
         mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer = mAcquiredBuffer;
         mRFBs[0][VP8_GOLDEN_REF_PIC].index = mAcquiredBuffer->renderBuffer.surface;
-
-        if (mRFBs[1][VP8_GOLDEN_REF_PIC].surfaceBuffer) {
-            mRFBs[1][VP8_GOLDEN_REF_PIC].surfaceBuffer->asReferernce = false;
-        }
-    }
-
-    if (mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer) {
         mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer->asReferernce = true;
     }
 }
@@ -385,13 +409,6 @@
     if (data->codec_data->refresh_alt_frame) {
         mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer = mAcquiredBuffer;
         mRFBs[0][VP8_ALT_REF_PIC].index = mAcquiredBuffer->renderBuffer.surface;
-
-        if (mRFBs[1][VP8_ALT_REF_PIC].surfaceBuffer) {
-            mRFBs[1][VP8_ALT_REF_PIC].surfaceBuffer->asReferernce = false;
-        }
-    }
-
-    if (mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer) {
         mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer->asReferernce = true;
     }
 }
diff --git a/videodecoder/VideoDecoderVP8.h b/videodecoder/VideoDecoderVP8.h
index f3b64e9..61db40d 100644
--- a/videodecoder/VideoDecoderVP8.h
+++ b/videodecoder/VideoDecoderVP8.h
@@ -49,6 +49,7 @@
     void refreshAltReference(vbp_data_vp8 *data);
     void updateFormatInfo(vbp_data_vp8 *data);
     void invalidateReferenceFrames(int toggle);
+    void clearAsReference(int toggle, int ref_type);
 
 private:
     enum {