Rockchip: Implement keyframe requests correctly

Currently, when rk_vepu_update_param() is called with keyframe request
the codingType field in EncoderParameters structure is set to intra
frame. However, every frame, frame counter is evaluated and this field
is overwritten with frame type determined automatically, which results
in ignoring keyframe requests.

To fix this, store keyframe request flag in a separate field and then
use it as additional factor for code determining frame type for next
frame.

BUG=chrome-os-partner:37203
TEST=video_encode_accelerator_unittest (after 4fc28962e2da8b3f278b952c55fefe10487db952); apprtc

Change-Id: I8acd8c5bfa6aded4b2139082b26b773828fc0dc8
Reviewed-on: https://chromium-review.googlesource.com/251970
Reviewed-by: Wu-cheng Li <wuchengli@chromium.org>
Commit-Queue: Tomasz Figa <tfiga@chromium.org>
Tested-by: Tomasz Figa <tfiga@chromium.org>
diff --git a/libv4l-rockchip/libv4l-encplugin-rockchip.c b/libv4l-rockchip/libv4l-encplugin-rockchip.c
index 4a7be00..120beb0 100644
--- a/libv4l-rockchip/libv4l-encplugin-rockchip.c
+++ b/libv4l-rockchip/libv4l-encplugin-rockchip.c
@@ -422,11 +422,8 @@
 		switch (ext_ctrls->controls[i].id) {
 		case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
 			if (ext_ctrls->controls[i].value ==
-					V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED)
-				break;
-			runtime_param_ptr->keyframe_request = true;
-			runtime_param_ptr->keyframe_value = (ext_ctrls->controls[i].value ==
-					V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME);
+					V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME)
+				runtime_param_ptr->keyframe_request = true;
 			break;
 		case V4L2_CID_MPEG_VIDEO_BITRATE:
 			runtime_param_ptr->bitrate = ext_ctrls->controls[i].value;
diff --git a/libv4l-rockchip/libvpu/rk_vepu_interface.h b/libv4l-rockchip/libvpu/rk_vepu_interface.h
index e40812e..b9d93ee 100644
--- a/libv4l-rockchip/libvpu/rk_vepu_interface.h
+++ b/libv4l-rockchip/libvpu/rk_vepu_interface.h
@@ -39,7 +39,6 @@
   int32_t framerate_denom;
   int32_t bitrate; /* bits per second */
   bool keyframe_request; /* have keyframe request */
-  bool keyframe_value; /* keyframe */
 };
 
 /**
diff --git a/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c b/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c
index ed3cc6e..c14df08 100644
--- a/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c
+++ b/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c
@@ -129,8 +129,7 @@
   enc->cmdl.frameCntTotal = 0;
 
   if (param->keyframe_request) {
-    enc->encIn.codingType =
-      param->keyframe_value ? VP8ENC_INTRA_FRAME : VP8ENC_PREDICTED_FRAME;
+    enc->cmdl.keyframeRequest = true;
   }
 }
 
@@ -213,26 +212,23 @@
     return -1;
   }
 
-  /* Select frame type */
-  if ((cml->intraPicRate != 0) && (enc->intraPeriodCnt >= cml->intraPicRate))
+  /* Code keyframe according to intra period counter
+   * or if requested by client. */
+  if (cml->keyframeRequest ||
+      (cml->intraPicRate != 0 &&
+       enc->intraPeriodCnt >= cml->intraPicRate)) {
     enc->encIn.codingType = VP8ENC_INTRA_FRAME;
-  else
-    enc->encIn.codingType = VP8ENC_PREDICTED_FRAME;
-
-  if (enc->encIn.codingType == VP8ENC_INTRA_FRAME)
     enc->intraPeriodCnt = 0;
+    cml->keyframeRequest = false;
+  } else {
+    enc->encIn.codingType = VP8ENC_PREDICTED_FRAME;
+  }
 
   /* This applies for PREDICTED frames only. By default always predict
    * from the previous frame only. */
   enc->encIn.ipf = VP8ENC_REFERENCE_AND_REFRESH;
   enc->encIn.grf = enc->encIn.arf = VP8ENC_REFERENCE;
 
-  /* Force odd frames to be coded as droppable. */
-  if (cml->droppable && cml->frameCnt & 1) {
-    enc->encIn.codingType = VP8ENC_PREDICTED_FRAME;
-    enc->encIn.ipf = enc->encIn.grf = enc->encIn.arf = VP8ENC_REFERENCE;
-  }
-
   /* Encode one frame */
   ret = VP8EncStrmEncode(enc->encoder, &enc->encIn, &cml->encOut, cml);
   if (ret < 0) {
@@ -602,8 +598,6 @@
   cml->intra16Favor       = 0;
   /* Penalty value for intra mode in intra/inter */
   cml->intraPenalty       = 0;
-  /* Code all odd frames as droppable */
-  cml->droppable          = 0;
 }
 
 void PrintTitle(EncoderParameters* cml) {
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h
index d37d474..7d5ce70 100644
--- a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h
@@ -385,7 +385,6 @@
 
   int32_t printPsnr;
   int32_t mvOutput;
-  int32_t droppable;
 
   int32_t intra16Favor;
   int32_t intraPenalty;
@@ -402,6 +401,7 @@
   ma_s ma;            /* Calculate moving average of bitrate */
   uint32_t psnrSum;        /* Calculate average PSNR over encoded frames */
   uint32_t psnrCnt;
+  uint32_t keyframeRequest;
 
   int32_t frameCnt;       /* Frame counter of input file */
   uint64_t frameCntTotal;  /* Frame counter of all frames */