Rockchip: add VP8 encoder library.

Convert the v4l2 pixel format to VPU HW pixel format.
Add rate control and keyframe setting interface.

BUG=chrome-os-partner:33728
TEST=video_encode_accelerator_unittest

Change-Id: Ic4344a95a70c22178eff2a20420b57a41ccc84a6
Signed-off-by: Alpha Lin <Alpha.Lin@rock-chips.com>
Reviewed-on: https://chromium-review.googlesource.com/230081
Reviewed-by: Wu-cheng Li <wuchengli@chromium.org>
Commit-Queue: Wu-cheng Li <wuchengli@chromium.org>
Tested-by: Wu-cheng Li <wuchengli@chromium.org>
diff --git a/libv4l-rockchip/Makefile.am b/libv4l-rockchip/Makefile.am
index 2016e60..fe45119 100644
--- a/libv4l-rockchip/Makefile.am
+++ b/libv4l-rockchip/Makefile.am
@@ -6,7 +6,24 @@
 libv4l2plugin_LTLIBRARIES = libv4l-encplugin-rockchip.la
 endif
 
-libv4l_encplugin_rockchip_la_SOURCES = libv4l-encplugin-rockchip.c libvpu/rk_vepu.c
+libv4l_encplugin_rockchip_la_SOURCES = \
+	libv4l-encplugin-rockchip.c \
+	libvpu/rk_vepu.c \
+	libvpu/rk_vepu_debug.c \
+	libvpu/vp8_enc/encasiccontroller.c \
+	libvpu/vp8_enc/encasiccontroller_v2.c \
+	libvpu/vp8_enc/rk_vp8encapi.c \
+	libvpu/vp8_enc/vp8codeframe.c \
+	libvpu/vp8_enc/vp8encapi.c \
+	libvpu/vp8_enc/vp8entropy.c \
+	libvpu/vp8_enc/vp8header.c \
+	libvpu/vp8_enc/vp8init.c \
+	libvpu/vp8_enc/vp8macroblocktools.c \
+	libvpu/vp8_enc/vp8picparameterset.c \
+	libvpu/vp8_enc/vp8picturebuffer.c \
+	libvpu/vp8_enc/vp8putbits.c \
+	libvpu/vp8_enc/vp8ratecontrol.c \
+	libvpu/vp8_enc/vpu_mem.c
 libv4l_encplugin_rockchip_la_CPPFLAGS = $(CFLAG_VISIBILITY)
 libv4l_encplugin_rockchip_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
 libv4l_encplugin_rockchip_la_LIBADD = -lpthread
diff --git a/libv4l-rockchip/libv4l-encplugin-rockchip.c b/libv4l-rockchip/libv4l-encplugin-rockchip.c
index 2921c14..4a7be00 100644
--- a/libv4l-rockchip/libv4l-encplugin-rockchip.c
+++ b/libv4l-rockchip/libv4l-encplugin-rockchip.c
@@ -16,6 +16,7 @@
 #include <sys/syscall.h>
 #include "config.h"  /* For HAVE_VISIBILITY */
 #include "libv4l-plugin.h"
+#include "libvpu/rk_vepu_debug.h"
 #include "libvpu/rk_vepu_interface.h"
 
 #define VLOG(log_level, str, ...) ((g_log_level >= log_level) ?			\
@@ -158,12 +159,7 @@
 static int initialize_libvpu(struct encoder_context *ctx, int fd);
 /* Return the string represenation of a libv4l command for debugging. */
 static const char *v4l_cmd2str(unsigned long int cmd);
-/*
- * The current log level for VLOG. This is read from environment variable
- * LIBV4L_PLUGIN_LOG_LEVEL every time plugin_init is called.
- */
-static int g_log_level = 0;
-/* Get the log level from the environment variable. */
+/* Get the log level from the environment variable LIBV4L_PLUGIN_LOG_LEVEL. */
 static void get_log_level();
 static pthread_once_t g_get_log_level_once = PTHREAD_ONCE_INIT;
 
@@ -495,7 +491,7 @@
 	int ret = SYS_IOCTL(fd, VIDIOC_QUERYCAP, &cap);
 	if (ret)
 		return false;
-	return strcmp(RK3288_VPU_NAME, cap.driver) == 0;
+	return strcmp(RK3288_VPU_NAME, (const char *)cap.driver) == 0;
 }
 
 int set_encoder_config_locked(struct encoder_context *ctx, int fd,
@@ -556,25 +552,33 @@
 	struct rk_vepu_init_param init_param;
 	memset(&init_param, 0, sizeof(init_param));
 
+	/* Get the input format. */
 	struct v4l2_format format;
 	memset(&format, 0, sizeof(format));
 	format.type = ctx->output_streamon_type;
 	int ret = SYS_IOCTL(fd, VIDIOC_G_FMT, &format);
-	if (ret) {
+	if (ret)
 		return ret;
-	}
-	init_param.width = format.fmt.pix_mp.width;
-	init_param.height = format.fmt.pix_mp.height;
 	init_param.input_format = format.fmt.pix_mp.pixelformat;
 
+	/* Get the output format. */
 	memset(&format, 0, sizeof(format));
 	format.type = ctx->capture_streamon_type;
 	ret = SYS_IOCTL(fd, VIDIOC_G_FMT, &format);
-	if (ret) {
+	if (ret)
 		return ret;
-	}
 	init_param.output_format = format.fmt.pix_mp.pixelformat;
 
+	/* Get the cropped size. */
+	struct v4l2_crop crop;
+	memset(&crop, 0, sizeof(crop));
+	crop.type = ctx->output_streamon_type;
+	ret = SYS_IOCTL(fd, VIDIOC_G_CROP, &crop);
+	if (ret)
+		return ret;
+	init_param.width = crop.c.width;
+	init_param.height = crop.c.height;
+
 	/*
 	 * If the encoder library has initialized and parameters have not
 	 * changed, skip the initialization.
diff --git a/libv4l-rockchip/libvpu/rk_vepu.c b/libv4l-rockchip/libvpu/rk_vepu.c
index a30e4c7..f3d34f7 100644
--- a/libv4l-rockchip/libvpu/rk_vepu.c
+++ b/libv4l-rockchip/libvpu/rk_vepu.c
@@ -1,47 +1,92 @@
-/*
+/* Copyright 2014 The Chromium OS Authors. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
 #include "libvpu/rk_vepu_interface.h"
 
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
 #include <stdlib.h>
 
-#define NUM_CTRLS 3
+#include "libvpu/rk_vepu_debug.h"
+#include "vp8_enc/rk_vp8encapi.h"
 
-static uint32_t rk_ctrl_ids[NUM_CTRLS] = {
-  V4L2_CID_PRIVATE_RK3288_HEADER,
-  V4L2_CID_PRIVATE_RK3288_REG_PARAMS,
-  V4L2_CID_PRIVATE_RK3288_HW_PARAMS
-};
-static uint32_t rk_payloads[NUM_CTRLS] = {0};
-static uint32_t rk_payload_sizes[NUM_CTRLS] = {
-  sizeof(rk_payloads[0]), sizeof(rk_payloads[1]), sizeof(rk_payloads[2])
-};
+void *rk_vepu_init(struct rk_vepu_init_param *param) {
+  int retval;
+  struct rk_vp8_encoder *enc = rk_vp8_encoder_alloc_ctx();
 
-void *rk_vepu_init(struct rk_vepu_init_param *init_param) {
-  return malloc(sizeof(int));
+  assert(param != NULL);
+  if (enc == NULL) {
+    VPU_PLG_ERR("Allocate encoder instance failed\n");
+    return NULL;
+  }
+
+  enc->rk_ctrl_ids[0] = V4L2_CID_PRIVATE_RK3288_HEADER;
+  enc->rk_ctrl_ids[1] = V4L2_CID_PRIVATE_RK3288_REG_PARAMS;
+  enc->rk_ctrl_ids[2] = V4L2_CID_PRIVATE_RK3288_HW_PARAMS;
+
+  retval = enc->ops->init(enc, param);
+  if (retval < 0) {
+    VPU_PLG_ERR("Encoder initialize failed\n");
+    rk_vp8_encoder_free_ctx(enc);
+    return NULL;
+  }
+  return enc;
 }
 
 void rk_vepu_deinit(void *enc) {
-  free(enc);
+  struct rk_vp8_encoder *ienc = (struct rk_vp8_encoder*)enc;
+
+  assert(enc != NULL);
+  ienc->ops->deinit(ienc);
+  rk_vp8_encoder_free_ctx(ienc);
 }
 
 int rk_vepu_get_config(void *enc, size_t *num_ctrls, uint32_t **ctrl_ids,
-                       void ***payloads, uint32_t **payload_sizes) {
+                       void ***payloads, uint32_t **payload_sizes)
+{
+  int retval;
+  struct rk_vp8_encoder *ienc = (struct rk_vp8_encoder*)enc;
+
+  assert(enc != NULL && num_ctrls != NULL && ctrl_ids != NULL);
+  assert(payloads != NULL && payload_sizes != NULL);
+
+  retval = ienc->ops->before_encode(ienc);
+  if (retval < 0) {
+    VPU_PLG_ERR("Generate configuration failed\n");
+    return -1;
+  }
+
   *num_ctrls = NUM_CTRLS;
-  *ctrl_ids = rk_ctrl_ids;
-  *payloads = (void **)rk_payloads;
-  *payload_sizes = rk_payload_sizes;
+  *ctrl_ids = ienc->rk_ctrl_ids;
+  *payloads = (void **)ienc->rk_payloads;
+  *payload_sizes = ienc->rk_payload_sizes;
   return 0;
 }
 
 int rk_vepu_update_config(void *enc, void *config, uint32_t config_size,
                           uint32_t buffer_size) {
-  return 0;
+  int retval;
+  struct rk_vp8_encoder *ienc = (struct rk_vp8_encoder*)enc;
+
+  assert(enc != NULL && config != NULL);
+
+  retval = ienc->ops->updatepriv(ienc, config, config_size);
+  if (retval < 0) {
+    VPU_PLG_ERR("Update vp8 encoder private data failed\n");
+    return -1;
+  }
+  return ienc->ops->after_encode(ienc, buffer_size);
 }
 
 int rk_vepu_update_parameter(void *enc,
                              struct rk_vepu_runtime_param *runtime_param) {
+  struct rk_vp8_encoder *ienc = (struct rk_vp8_encoder*)enc;
+
+  assert(enc != NULL && runtime_param != NULL);
+  ienc->ops->updateparameter(ienc, runtime_param);
   return 0;
 }
diff --git a/libv4l-rockchip/libvpu/rk_vepu_debug.c b/libv4l-rockchip/libvpu/rk_vepu_debug.c
new file mode 100644
index 0000000..885ef0e
--- /dev/null
+++ b/libv4l-rockchip/libvpu/rk_vepu_debug.c
@@ -0,0 +1,5 @@
+/* Copyright 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+int g_log_level = 0;
diff --git a/libv4l-rockchip/libvpu/rk_vepu_debug.h b/libv4l-rockchip/libvpu/rk_vepu_debug.h
new file mode 100644
index 0000000..0362111
--- /dev/null
+++ b/libv4l-rockchip/libvpu/rk_vepu_debug.h
@@ -0,0 +1,28 @@
+/* Copyright 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef LIBVPU_RK_VEPU_DEBUG_H_
+#define LIBVPU_RK_VEPU_DEBUG_H_
+
+#include <stdio.h>
+
+/*
+ * The current log level. Higher value will enable more logs.
+ */
+extern int g_log_level;
+
+#define VPU_PLG_DBG(fmt, args...) ((g_log_level >= 2) ?				\
+	(void) fprintf(stderr, "%s:%d: " fmt, __func__, __LINE__, ## args)	\
+		: (void) 0)
+
+#define VPU_PLG_INF(fmt, args...) ((g_log_level >= 1) ?				\
+	(void) fprintf(stderr, "%s:%d: " fmt, __func__, __LINE__, ## args)	\
+		: (void) 0)
+
+#define VPU_PLG_ERR(fmt, args...) ((g_log_level >= 0) ?				\
+	(void) fprintf(stderr, "ERR, %s:%d: " fmt, __func__, __LINE__, ## args)	\
+		: (void) 0)
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller.c b/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller.c
new file mode 100644
index 0000000..cbb1319
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller.c
@@ -0,0 +1,907 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+#include <memory.h>
+#include <stdio.h>
+
+#include "enccommon.h"
+#include "encasiccontroller.h"
+#include "encswhwregisters.h"
+
+/* Mask fields */
+#define mask_2b         (uint32_t)0x00000003
+#define mask_3b         (uint32_t)0x00000007
+#define mask_4b         (uint32_t)0x0000000F
+#define mask_5b         (uint32_t)0x0000001F
+#define mask_6b         (uint32_t)0x0000003F
+#define mask_7b         (uint32_t)0x0000007F
+#define mask_11b        (uint32_t)0x000007FF
+#define mask_14b        (uint32_t)0x00003FFF
+#define mask_16b        (uint32_t)0x0000FFFF
+
+/* NOTE: Don't use ',' in descriptions, because it is used as separator in csv
+ * parsing. */
+static const regField_s asicRegisterDesc[] = {
+/* HW ID register, read-only */
+  { HEncProductID, 0x000, 0xffff0000, 16, 0, "Product ID" },
+  { HEncProductMajor, 0x000, 0x0000f000, 12, 0, "Major number" },
+  { HEncProductMinor, 0x000, 0x00000ff0,  4, 0, "Minor number" },
+  { HEncProductBuild, 0x000, 0x0000000f,  0, 0, "Build number defined in synthesis." },
+/* Encoder interrupt register */
+  { HEncIRQSliceReady, 0x004, 0x00000100,  8, 0, "IRQ slice ready status bit." },
+  { HEncIRQTimeout, 0x004, 0x00000040,  6, 0, "IRQ HW timeout status bit." },
+  { HEncIRQBuffer, 0x004, 0x00000020,  5, 1, "IRQ buffer full status bit. bufferFullInterrupt" },
+  { HEncIRQReset, 0x004, 0x00000010,  4, 0, "IRQ SW reset status bit." },
+  { HEncIRQBusError, 0x004, 0x00000008,  3, 0, "IRQ bus error status bit." },
+  { HEncIRQFrameReady, 0x004, 0x00000004,  2, 0, "IRQ frame ready status bit. Encoder has finished a frame." },
+  { HEncIRQDisable, 0x004, 0x00000002,  1, 0, "IRQ disable. No interrupts from HW. SW must use polling." },
+  { HEncIRQ, 0x004, 0x00000001,  0, 0, "HINTenc Interrupt from HW. SW resets at IRQ handler." },
+/* Encoder configuration register */
+  { HEncAXIWriteID, 0x008, 0xff000000, 24, 0, "AXI Write ID" },
+  { HEncAXIReadID, 0x008, 0x00ff0000, 16, 0, "AXI Read ID" },
+  { HEncOutputSwap16, 0x008, 0x00008000, 15, 0, "Enable output swap 16-bits" },
+  { HEncInputSwap16, 0x008, 0x00004000, 14, 0, "Enable input swap 16-bits" },
+  { HEncBurstLength, 0x008, 0x00003f00,  8, 0, "Burst length. 0=incremental. 4=max BURST4.8=max BURST8. 16=max BURST16" },
+  { HEncBurstDisable, 0x008, 0x00000080,  7, 0, "Disable burst mode for AXI" },
+  { HEncBurstIncr, 0x008, 0x00000040,  6, 0, "Burst incremental. 1=INCR burst allowed. 0=use SINGLE burst" },
+  { HEncDataDiscard, 0x008, 0x00000020,  5, 0, "Enable burst data discard. 2 or 3 long reads are using BURST4" },
+  { HEncClockGating, 0x008, 0x00000010,  4, 0, "Enable clock gating" },
+  { HEncOutputSwap32, 0x008, 0x00000008,  3, 0, "Enable output swap 32-bits" },
+  { HEncInputSwap32, 0x008, 0x00000004,  2, 0, "Enable input swap 32-bits" },
+  { HEncOutputSwap8, 0x008, 0x00000002,  1, 0, "Enable output swap 8-bits" },
+  { HEncInputSwap8, 0x008, 0x00000001,  0, 0, "Enable input swap 8-bits" },
+  { HEncTestCounter, 0x00c, 0xf0000000, 28, 0, "Test counter" },
+  { HEncTestLength, 0x00c, 0x001ffff8,  3, 0, "Test data length for memory test" },
+  { HEncTestMem, 0x00c, 0x00000004,  2, 0, "Enable memory coherency test. Reads BaseStream. Writes BaseControl" },
+  { HEncTestReg, 0x00c, 0x00000002,  1, 0, "Enable register coherency test. Increments test counter" },
+  { HEncTestIrq, 0x00c, 0x00000001,  0, 0, "Enable IRQ test. HW gives interrupt" },
+/* External memory base addresses for encoder input/output */
+  { HEncBaseStream, 0x014, 0xffffffff,  0, 0, "Base address for output stream data" },
+  { HEncBaseControl, 0x018, 0xffffffff,  0, 0, "Base address for output control data" },
+  { HEncBaseRefLum, 0x01c, 0xffffffff,  0, 0, "Base address for reference luma" },
+  { HEncBaseRefChr, 0x020, 0xffffffff,  0, 0, "Base address for reference chroma" },
+  { HEncBaseRecLum, 0x024, 0xffffffff,  0, 0, "Base address for reconstructed luma" },
+  { HEncBaseRecChr, 0x028, 0xffffffff,  0, 0, "Base address for reconstructed chroma" },
+  { HEncBaseInLum, 0x02c, 0xffffffff,  0, 0, "Base address for input picture luma" },
+  { HEncBaseInCb, 0x030, 0xffffffff,  0, 0, "Base address for input picture cb" },
+  { HEncBaseInCr, 0x034, 0xffffffff,  0, 0, "Base address for input picture cr" },
+  { HEncIntTimeout, 0x038, 0x80000000, 31, 0, "Enable interrupt for timeout" },
+  { HEncMvWrite, 0x038, 0x40000000, 30, 1, "Enable writing MV and SAD of each MB to BaseMvWrite" },
+  { HEncNalSizeWrite, 0x038, 0x20000000, 29, 1, "Enable writing size of each NAL unit to BaseControl, nalSizeWriteOut" },
+  { HEncIntSliceReady, 0x038, 0x10000000, 28, 0, "Enable interrupt for slice ready" },
+  { HEncWidth, 0x038, 0x0ff80000, 19, 1, "Encoded width. lumWidth (macroblocks) H264:[9..255] JPEG:[6..511]" },
+  { HEncHeight, 0x038, 0x0007fc00, 10, 1, "Encoded height. lumHeight (macroblocks) H264:[6..255] JPEG:[2..511]" },
+  { HEncRecWriteDisable, 0x038, 0x00000040,  6, 1, "Disable writing of reconstructed image. recWriteDisable" },
+  { HEncPictureType, 0x038, 0x00000018,  3, 1, "Encoded picture type. frameType. 0=INTER. 1=INTRA(IDR). 2=MVC-INTER. 3=MVC-INTER(ref mod)." },
+  { HEncEncodingMode, 0x038, 0x00000006,  1, 1, "Encoding mode. streamType. 1=VP8. 2=JPEG. 3=H264" },
+  { HEncEnable, 0x038, 0x00000001,  0, 0, "Encoder enable" },
+  { HEncChrOffset, 0x03c, 0xe0000000, 29, 0, "Input chrominance offset (bytes) [0..7]" },
+  { HEncLumOffset, 0x03c, 0x1c000000, 26, 0, "Input luminance offset (bytes) [0..7]" },
+  { HEncRowLength, 0x03c, 0x03fff000, 12, 1, "Input luminance row length. lumWidthSrc (bytes) [96..8192]" },
+  { HEncXFill, 0x03c, 0x00000c00, 10, 0, "Overfill pixels on right edge of image div4 [0..3]" },
+  { HEncYFill, 0x03c, 0x000003c0,  6, 1, "Overfill pixels on bottom edge of image. YFill. [0..15]" },
+  { HEncInputFormat, 0x03c, 0x0000003c,  2, 1, "Input image format. inputFormat. YUV420P/YUV420SP/YUYV422/UYVY422/RGB565/RGB555/RGB444/RGB888/RGB101010" },
+  { HEncInputRot, 0x03c, 0x00000003,  0, 1, "Input image rotation. 0=disabled. 1=90 degrees right. 2=90 degrees left" },
+
+/* VP8 / H.264 mixed definitions */
+  { HEncBaseRefLum2, 0x040, 0xffffffff,  0, 0, "Base address for second reference luma" },
+  { HEncBaseRefChr2, 0x044, 0xffffffff,  0, 0, "Base address for second reference chroma" },
+  { HEncPicInitQp, 0x040, 0xfc000000, 26, 0, "H.264 Pic init qp in PPS [0..51]" },
+  { HEncSliceAlpha, 0x040, 0x03c00000, 22, 0, "H.264 Slice filter alpha c0 offset div2 [-6..6]" },
+  { HEncSliceBeta, 0x040, 0x003c0000, 18, 0, "H.264 Slice filter beta offset div2 [-6..6]" },
+  { HEncChromaQp, 0x040, 0x0003e000, 13, 0, "H.264 Chroma qp index offset [-12..12]" },
+  { HEncIdrPicId, 0x040, 0x0000001e,  1, 0, "H.264 IDR picture ID" },
+  { HEncConstrIP, 0x040, 0x00000001,  0, 1, "H.264 Constrained intra prediction enable. constIntraPred" },
+  { HEncPPSID, 0x044, 0xff000000, 24, 0, "H.264 pic_parameter_set_id" },
+  { HEncIPPrevModeFavor, 0x044, 0x00ff0000, 16, 0, "H.264 Intra prediction previous 4x4 mode favor" },
+  { HEncFrameNum, 0x044, 0x0000ffff,  0, 0, "H.264 Frame num" },
+
+  { HEncDeblocking, 0x048, 0xc0000000, 30, 0, "Deblocking filter mode. 0=enabled. 1=disabled (vp8=simple). 2=disabled on slice borders" },
+  { HEncSliceSize, 0x048, 0x3f800000, 23, 1, "H.264 Slice size. mbRowPerSlice (mb rows) [0..127] 0=one slice per picture" },
+  { HEncDisableQPMV, 0x048, 0x00400000, 22, 1, "H.264 Disable quarter pixel MVs. disableQuarterPixelMv" },
+  { HEncTransform8x8, 0x048, 0x00200000, 21, 1, "H.264 Transform 8x8 enable. High Profile H.264. transform8x8Mode" },
+  { HEncCabacInitIdc, 0x048, 0x00180000, 19, 0, "H.264 CABAC initial IDC. [0..2]" },
+  { HEncCabacEnable, 0x048, 0x00040000, 18, 1, "H.264 CABAC / VP8 boolenc enable. entropyCodingMode. 0=CAVLC (Baseline Profile H.264). 1=CABAC (Main Profile H.264)" },
+  { HEncInter4Restrict, 0x048, 0x00020000, 17, 1, "H.264 Inter 4x4 mode restriction. restricted4x4Mode" },
+  { HEncStreamMode, 0x048, 0x00010000, 16, 1, "H.264 Stream mode. byteStream. 0=NAL unit stream. 1=Byte stream" },
+  { HEncIPIntra16Favor, 0x048, 0x0000ffff,  0, 0, "Intra prediction intra 16x16 mode favor" },
+  { HEncSplitMv, 0x04c, 0x40000000, 30, 1, "Enable using more than 1 MV per macroblock." },
+  { HEncDMVPenalty1p, 0x04c, 0x000003ff,  0, 1, "Differential MV penalty for 1p ME. DMVPenalty1p" },
+  { HEncDMVPenalty4p, 0x04c, 0x000ffc00, 10, 1, "Differential MV penalty for 4p ME. DMVPenalty4p" },
+  { HEncDMVPenaltyQp, 0x04c, 0x3ff00000, 20, 1, "Differential MV penalty for 1/4p ME. DMVPenaltyQp" },
+
+/* Mixed definitions JPEG / video */
+  { HEncJpegMode, 0x050, 0x02000000, 25, 0, "JPEG mode. 0=4:2:0 (4lum+2chr blocks/MCU). 1=4:2:2 (2lum+2chr blocks/MCU)" },
+  { HEncJpegSlice, 0x050, 0x01000000, 24, 0, "JPEG slice enable. 0=picture ends with EOI. 1=slice ends with RST" },
+  { HEncJpegRSTInt, 0x050, 0x00ff0000, 16, 0, "JPEG restart marker interval when slices are disabled (mb rows) [0..255]" },
+  { HEncJpegRST, 0x050, 0x0000ffff,  0, 0, "JPEG restart marker for first RST. incremented by HW for next RST" },
+  { HEncSplitPenalty16x8, 0x050, 0x3ff00000, 20, 0, "Penalty for using 16x8 or 8x16 MV." },
+  { HEncSplitPenalty8x8, 0x050, 0x000ffc00, 10, 0, "Penalty for using 8x8 MV." },
+  { HEncSplitPenalty8x4, 0x050, 0x000003ff,  0, 0, "Penalty for using 8x4 or 4x8 MV." },
+
+  { HEncSkipPenalty, 0x054, 0xff000000, 24, 0, "H.264 SKIP macroblock mode / VP8 zero/nearest/near mode penalty" },
+  { HEncNumSlicesReady, 0x054, 0x00ff0000, 16, 0, "H.264 amount of completed slices." },
+  { HEncInterFavor, 0x054, 0x0000ffff,  0, 0, "Inter MB mode favor in intra/inter selection" },
+  { HEncStrmHdrRem1, 0x058, 0xffffffff,  0, 0, "Stream header remainder bits MSB (MSB aligned)" },
+  { HEncStrmHdrRem2, 0x05c, 0xffffffff,  0, 0, "Stream header remainder bits LSB (MSB aligned)" },
+  { HEncStrmBufLimit, 0x060, 0xffffffff,  0, 1, "Stream buffer limit (64bit addresses) / output stream size (bits). HWStreamDataCount. If limit is reached buffer full IRQ is given." },
+  { HEncMadQpDelta, 0x064, 0xf0000000, 28, 1, "MAD based QP adjustment. madQpChange [-8..7]" },
+  { HEncMadThreshold, 0x064, 0x0fc00000, 22, 0, "MAD threshold div256" },
+  { HEncQpSum, 0x064, 0x001fffff,  0, 0, "QP Sum div2 output" },
+
+/* H.264 Rate control registers */
+  { HEncQp, 0x06c, 0xfc000000, 26, 1, "H.264 Initial QP. qpLum [0..51]" },
+  { HEncMaxQp, 0x06c, 0x03f00000, 20, 1, "H.264 Maximum QP. qpMax [0..51]" },
+  { HEncMinQp, 0x06c, 0x000fc000, 14, 1, "H.264 Minimum QP. qpMin [0..51]" },
+  { HEncCPDist, 0x06c, 0x00001fff,  0, 0, "H.264 Checkpoint distance (mb) 0=disabled [0..8191]" },
+  { HEncCP1WordTarget, 0x070, 0xffff0000, 16, 0, "H.264 Checkpoint 1 word target/usage div32 [0..65535]" },
+  { HEncCP2WordTarget, 0x070, 0x0000ffff,  0, 0, "H.264 Checkpoint 2 word target/usage div32 [0..65535]" },
+  { HEncCP3WordTarget, 0x074, 0xffff0000, 16, 0, "H.264 Checkpoint 3 word target/usage div32 [0..65535]" },
+  { HEncCP4WordTarget, 0x074, 0x0000ffff,  0, 0, "H.264 Checkpoint 4 word target/usage div32 [0..65535]" },
+  { HEncCP5WordTarget, 0x078, 0xffff0000, 16, 0, "H.264 Checkpoint 5 word target/usage div32 [0..65535]" },
+  { HEncCP6WordTarget, 0x078, 0x0000ffff,  0, 0, "H.264 Checkpoint 6 word target/usage div32 [0..65535]" },
+  { HEncCP7WordTarget, 0x07c, 0xffff0000, 16, 0, "H.264 Checkpoint 7 word target/usage div32 [0..65535]" },
+  { HEncCP8WordTarget, 0x07c, 0x0000ffff,  0, 0, "H.264 Checkpoint 8 word target/usage div32 [0..65535]" },
+  { HEncCP9WordTarget, 0x080, 0xffff0000, 16, 0, "H.264 Checkpoint 9 word target/usage div32 [0..65535]" },
+  { HEncCP10WordTarget, 0x080, 0x0000ffff,  0, 0, "H.264 Checkpoint 10 word target/usage div32 [0..65535]" },
+  { HEncCPWordError1, 0x084, 0xffff0000, 16, 0, "H.264 Checkpoint word error 1 div4 [-32768..32767]" },
+  { HEncCPWordError2, 0x084, 0x0000ffff,  0, 0, "H.264 Checkpoint word error 2 div4 [-32768..32767]" },
+  { HEncCPWordError3, 0x088, 0xffff0000, 16, 0, "H.264 Checkpoint word error 3 div4 [-32768..32767]" },
+  { HEncCPWordError4, 0x088, 0x0000ffff,  0, 0, "H.264 Checkpoint word error 4 div4 [-32768..32767]" },
+  { HEncCPWordError5, 0x08c, 0xffff0000, 16, 0, "H.264 Checkpoint word error 5 div4 [-32768..32767]" },
+  { HEncCPWordError6, 0x08c, 0x0000ffff,  0, 0, "H.264 Checkpoint word error 6 div4 [-32768..32767]" },
+  { HEncCPDeltaQp1, 0x090, 0x0f000000, 24, 0, "H.264 Checkpoint delta QP 1 [-8..7]" },
+  { HEncCPDeltaQp2, 0x090, 0x00f00000, 20, 0, "H.264 Checkpoint delta QP 2 [-8..7]" },
+  { HEncCPDeltaQp3, 0x090, 0x000f0000, 16, 0, "H.264 Checkpoint delta QP 3 [-8..7]" },
+  { HEncCPDeltaQp4, 0x090, 0x0000f000, 12, 0, "H.264 Checkpoint delta QP 4 [-8..7]" },
+  { HEncCPDeltaQp5, 0x090, 0x00000f00,  8, 0, "H.264 Checkpoint delta QP 5 [-8..7]" },
+  { HEncCPDeltaQp6, 0x090, 0x000000f0,  4, 0, "H.264 Checkpoint delta QP 6 [-8..7]" },
+  { HEncCPDeltaQp7, 0x090, 0x0000000f,  0, 0, "H.264 Checkpoint delta QP 7 [-8..7]" },
+/* VP8 Rate control registers, regs 0x6C - 0x90 redefined for VP8 */
+  { HEncVp8Y1QuantDc, 0x06C, 0x00003fff,  0, 1, "VP8 qpY1QuantDc 14b" },
+  { HEncVp8Y1ZbinDc, 0x06C, 0x007fc000, 14, 1, "VP8 qpY1ZbinDc 9b" },
+  { HEncVp8Y1RoundDc, 0x06C, 0x7f800000, 23, 1, "VP8 qpY1RoundDc 8b" },
+  { HEncVp8Y1QuantAc, 0x070, 0x00003fff,  0, 1, "VP8 qpY1QuantAc 14b" },
+  { HEncVp8Y1ZbinAc, 0x070, 0x007fc000, 14, 1, "VP8 qpY1ZbinAc 9b" },
+  { HEncVp8Y1RoundAc, 0x070, 0x7f800000, 23, 1, "VP8 qpY1RoundAc 8b" },
+  { HEncVp8Y2QuantDc, 0x074, 0x00003fff,  0, 1, "VP8 qpY2QuantDc 14b" },
+  { HEncVp8Y2ZbinDc, 0x074, 0x007fc000, 14, 1, "VP8 qpY2ZbinDc 9b" },
+  { HEncVp8Y2RoundDc, 0x074, 0x7f800000, 23, 1, "VP8 qpY2RoundDc 8b" },
+  { HEncVp8Y2QuantAc, 0x078, 0x00003fff,  0, 1, "VP8 qpY2QuantAc 14b" },
+  { HEncVp8Y2ZbinAc, 0x078, 0x007fc000, 14, 1, "VP8 qpY2ZbinAc 9b" },
+  { HEncVp8Y2RoundAc, 0x078, 0x7f800000, 23, 1, "VP8 qpY2RoundAc 8b" },
+  { HEncVp8ChQuantDc, 0x07C, 0x00003fff,  0, 1, "VP8 qpChQuantDc 14b" },
+  { HEncVp8ChZbinDc, 0x07C, 0x007fc000, 14, 1, "VP8 qpChZbinDc 9b" },
+  { HEncVp8ChRoundDc, 0x07C, 0x7f800000, 23, 1, "VP8 qpChRoundDc 8b" },
+  { HEncVp8ChQuantAc, 0x080, 0x00003fff,  0, 1, "VP8 qpChQuantAc 14b" },
+  { HEncVp8ChZbinAc, 0x080, 0x007fc000, 14, 1, "VP8 qpChZbinAc 9b" },
+  { HEncVp8ChRoundAc, 0x080, 0x7f800000, 23, 1, "VP8 qpChRoundAc 8b" },
+  { HEncVp8Y1DequantDc, 0x084, 0x000000ff,  0, 1, "VP8 qpY1DequantDc 8b" },
+  { HEncVp8Y1DequantAc, 0x084, 0x0001ff00,  8, 1, "VP8 qpY1DequantAc 9b" },
+  { HEncVp8Y2DequantDc, 0x084, 0x03fe0000, 17, 1, "VP8 qpY2DequantDc 9b" },
+  { HEncVp8MvRefIdx, 0x084, 0x0c000000, 26, 0, "VP8 mvRefIdx for first reference frame. 0=ipf. 1=grf. 2=arf." },
+  { HEncVp8Y2DequantAc, 0x088, 0x000001ff,  0, 1, "VP8 qpY2DequantAc 9b" },
+  { HEncVp8ChDequantDc, 0x088, 0x0001fe00,  9, 1, "VP8 qpChDequantDc 8b" },
+  { HEncVp8ChDequantAc, 0x088, 0x03fe0000, 17, 1, "VP8 qpChDequantAc 9b" },
+  { HEncVp8MvRefIdx2, 0x088, 0x0c000000, 26, 0, "VP8 mvRefIdx for second reference frame. 0=ipf. 1=grf. 2=arf." },
+  { HEncVp8Ref2Enable, 0x088, 0x10000000, 28, 0, "VP8 enable for second reference frame." },
+  { HEncVp8SegmentEnable, 0x088, 0x20000000, 29, 1, "VP8 enable for segmentation. Segmentation map is stored in BaseVp8SegmentMap." },
+  { HEncVp8SegmentMapUpdate, 0x088, 0x40000000, 30, 0, "VP8 enable for segmentation map update. Map is different from previous frame and is written in stream. " },
+  { HEncVp8BoolEncValue, 0x08C, 0xffffffff,  0, 1, "VP8 boolEncValue" },
+  { HEncVp8GoldenPenalty, 0x090, 0xff000000, 24, 0, "VP8 Penalty value for second reference frame zero-mv [0..255]" },
+  { HEncVp8FilterSharpness, 0x090, 0x00e00000, 21, 0, "VP8 Deblocking filter sharpness [0..7]" },
+  { HEncVp8FilterLevel, 0x090, 0x001f8000, 15, 0, "VP8 Deblocking filter level [0..63]" },
+  { HEncVp8DctPartitionCount, 0x090, 0x00006000, 13, 0, "VP8 DCT partition count. 0=1. 1=2 [0..1]" },
+  { HEncVp8BoolEncValueBits, 0x090, 0x00001f00,  8, 1, "VP8 boolEncValueBitsMinus8 [0..23]" },
+  { HEncVp8BoolEncRange, 0x090, 0x000000ff,  0, 1, "VP8 boolEncRange [0..255]" },
+
+  { HEncStartOffset, 0x094, 0x1f800000, 23, 0, "Stream start offset = amount of StrmHdrRem (bits) [0..63]" },
+  { HEncRlcSum, 0x094, 0x007fffff,  0, 0, "RLC codeword count div4 output. max 255*255*384/4" },
+  { HEncMadCount, 0x098, 0xffff0000, 16, 0, "Macroblock count with MAD value under threshold output" },
+  { HEncMbCount, 0x098, 0x0000ffff,  0, 0, "MB count output. max 255*255" },
+/* Stabilization parameters and outputs */
+  { HEncBaseNextLum, 0x09c, 0xffffffff,  0, 0, "Base address for next pic luminance" },
+  { HEncStabMode, 0x0a0, 0xc0000000, 30, 1, "Stabilization mode. 0=disabled. 1=stab only. 2=stab+encode" },
+  { HEncStabMinimum, 0x0a0, 0x00ffffff,  0, 0, "Stabilization minimum value output. max 253*253*255" },
+  { HEncStabMotionSum, 0x0a4, 0xffffffff,  0, 0, "Stabilization motion sum div8 output. max 253*253*255*1089/8" },
+  { HEncStabGmvX, 0x0a8, 0xfc000000, 26, 0, "Stabilization GMV horizontal output [-16..16]" },
+  { HEncStabMatrix1, 0x0a8, 0x00ffffff,  0, 0, "Stabilization matrix 1 (up-left position) output" },
+  { HEncStabGmvY, 0x0ac, 0xfc000000, 26, 0, "Stabilization GMV vertical output [-16..16]" },
+  { HEncStabMatrix2, 0x0ac, 0x00ffffff,  0, 0, "Stabilization matrix 2 (up position) output" },
+  { HEncStabMatrix3, 0x0b0, 0x00ffffff,  0, 0, "Stabilization matrix 3 (up-right position) output" },
+  { HEncStabMatrix4, 0x0b4, 0x00ffffff,  0, 0, "Stabilization matrix 4 (left position) output" },
+  { HEncStabMatrix5, 0x0b8, 0x00ffffff,  0, 0, "Stabilization matrix 5 (GMV position) output" },
+  { HEncStabMatrix6, 0x0bc, 0x00ffffff,  0, 0, "Stabilization matrix 6 (right position) output" },
+  { HEncStabMatrix7, 0x0c0, 0x00ffffff,  0, 0, "Stabilization matrix 7 (down-left position) output" },
+  { HEncStabMatrix8, 0x0c4, 0x00ffffff,  0, 0, "Stabilization matrix 8 (down position) output" },
+  { HEncStabMatrix9, 0x0c8, 0x00ffffff,  0, 0, "Stabilization matrix 9 (down-right position) output" },
+  { HEncBaseCabacCtx, 0x0cc, 0xffffffff,  0, 0, "Base address for cabac context tables (H264) or probability tables (VP8)" },
+  { HEncBaseMvWrite, 0x0d0, 0xffffffff,  0, 0, "Base address for MV output writing" },
+/* Pre-processor color conversion parameters */
+  { HEncRGBCoeffA, 0x0d4, 0x0000ffff,  0, 0, "RGB to YUV conversion coefficient A" },
+  { HEncRGBCoeffB, 0x0d4, 0xffff0000, 16, 0, "RGB to YUV conversion coefficient B" },
+  { HEncRGBCoeffC, 0x0d8, 0x0000ffff,  0, 0, "RGB to YUV conversion coefficient C" },
+  { HEncRGBCoeffE, 0x0d8, 0xffff0000, 16, 0, "RGB to YUV conversion coefficient E" },
+  { HEncRGBCoeffF, 0x0dc, 0x0000ffff,  0, 0, "RGB to YUV conversion coefficient F" },
+  { HEncRMaskMSB, 0x0dc, 0x001f0000, 16, 0, "RGB R-component mask MSB bit position [0..31]" },
+  { HEncGMaskMSB, 0x0dc, 0x03e00000, 21, 0, "RGB G-component mask MSB bit position [0..31]" },
+  { HEncBMaskMSB, 0x0dc, 0x7c000000, 26, 0, "RGB B-component mask MSB bit position [0..31]" },
+  { HEncIntraAreaLeft, 0x0e0, 0xff000000, 24, 0, "Intra area left mb column (inside area) [0..255]" },
+  { HEncIntraAreaRight, 0x0e0, 0x00ff0000, 16, 0, "Intra area right mb column (outside area) [0..255]" },
+  { HEncIntraAreaTop, 0x0e0, 0x0000ff00,  8, 0, "Intra area top mb row (inside area) [0..255]" },
+  { HEncIntraAreaBottom, 0x0e0, 0x000000ff,  0, 0, "Intra area bottom mb row (outside area) [0..255]" },
+  { HEncCirStart, 0x0e4, 0xffff0000, 16, 0, "CIR first intra mb. 0=disabled [0..65535]" },
+  { HEncCirInterval, 0x0e4, 0x0000ffff,  0, 0, "CIR intra mb interval. 0=disabled [0..65535]" },
+
+/* H264 / VP8 mixed definitions */
+  { HEncIntraSliceMap1, 0x0e8, 0xffffffff,  0, 0, "Intra slice bitmap for slices 0..31. LSB=slice0. MSB=slice31. 1=intra." },
+  { HEncIntraSliceMap2, 0x0ec, 0xffffffff,  0, 0, "Intra slice bitmap for slices 32..63. LSB=slice32. MSB=slice63. 1=intra." },
+  { HEncIntraSliceMap3, 0x068, 0xffffffff,  0, 0, "Intra slice bitmap for slices 64..95. LSB=slice64. MSB=slice95. 1=intra." },
+  { HEncBasePartition1, 0x0e8, 0xffffffff,  0, 0, "Base address for VP8 1st DCT partition" },
+  { HEncBasePartition2, 0x0ec, 0xffffffff,  0, 0, "Base address for VP8 2nd DCT partition" },
+  { HEncBaseVp8ProbCount, 0x068, 0xffffffff,  0, 0, "Base address for VP8 counters for probability updates" },
+
+  { HEncRoi1Left, 0x0f0, 0xff000000, 24, 0, "1st ROI area left mb column (inside area) qp+=Roi1DeltaQp" },
+  { HEncRoi1Right, 0x0f0, 0x00ff0000, 16, 0, "1st ROI area right mb column (outside area) qp-=Roi1DeltaQp" },
+  { HEncRoi1Top, 0x0f0, 0x0000ff00,  8, 0, "1st ROI area top mb row (inside area)" },
+  { HEncRoi1Bottom, 0x0f0, 0x000000ff,  0, 0, "1st ROI area bottom mb row (outside area)" },
+  { HEncRoi2Left, 0x0f4, 0xff000000, 24, 0, "2nd ROI area left mb column (inside area) qp+=Roi2DeltaQp" },
+  { HEncRoi2Right, 0x0f4, 0x00ff0000, 16, 0, "2nd ROI area right mb column (outside area) qp-=Roi2DeltaQp" },
+  { HEncRoi2Top, 0x0f4, 0x0000ff00,  8, 0, "2nd ROI area top mb row (inside area)" },
+  { HEncRoi2Bottom, 0x0f4, 0x000000ff,  0, 0, "2nd ROI area bottom mb row (outside area)" },
+  { HEncRoi1DeltaQp, 0x0f8, 0x000000f0,  4, 0, "1st ROI area delta QP. qp = Qp - Roi1DeltaQp [0..15]" },
+  { HEncRoi2DeltaQp, 0x0f8, 0x0000000f,  0, 0, "2nd ROI area delta QP. qp = Qp - Roi2DeltaQp [0..15]" },
+  { HEncZeroMvFavor, 0x0f8, 0xf0000000, 28, 0, "Zero 16x16 MV favor div2." },
+  { HEncSplitPenalty4x4, 0x0f8, 0x0ff80000, 19, 0, "Penalty for using 4x4 MV." },
+  { HEncMvcPriorityId, 0x0f8, 0x00070000, 16, 0, "MVC priority_id [0..7]" },
+  { HEncMvcViewId, 0x0f8, 0x0000e000, 13, 0, "MVC view_id [0..7]" },
+  { HEncMvcTemporalId, 0x0f8, 0x00001c00, 10, 0, "MVC temporal_id [0..7]" },
+  { HEncMvcAnchorPicFlag, 0x0f8, 0x00000200,  9, 0, "MVC anchor_pic_flag. Specifies that the picture is part of an anchor access unit." },
+  { HEncMvcInterViewFlag, 0x0f8, 0x00000100,  8, 0, "MVC inter_view_flag. Specifies that the picture is used for inter-view prediction." },
+
+/* HW synthesis config register, read-only */
+  { HEncHWTiledSupport, 0x0fc, 0x40000000, 30, 0, "Tiled 4x4 input mode supported by HW. 0=not supported. 1=supported" },
+  { HEncHWSearchArea, 0x0fc, 0x20000000, 29, 0, "HW search area height. 0=5 MB rows. 1=3 MB rows" },
+  { HEncHWRgbSupport, 0x0fc, 0x10000000, 28, 0, "RGB to YUV conversion supported by HW. 0=not supported. 1=supported" },
+  { HEncHWH264Support, 0x0fc, 0x08000000, 27, 0, "H.264 encoding supported by HW. 0=not supported. 1=supported" },
+  { HEncHWVp8Support, 0x0fc, 0x04000000, 26, 0, "VP8 encoding supported by HW. 0=not supported. 1=supported" },
+  { HEncHWJpegSupport, 0x0fc, 0x02000000, 25, 0, "JPEG encoding supported by HW. 0=not supported. 1=supported" },
+  { HEncHWStabSupport, 0x0fc, 0x01000000, 24, 0, "Stabilization supported by HW. 0=not supported. 1=supported" },
+  { HEncHWBus, 0x0fc, 0x00f00000, 20, 0, "Bus connection of HW. 1=AHB. 2=OCP. 3=AXI. 4=PCI. 5=AXIAHB. 6=AXIAPB." },
+  { HEncHWSynthesisLan, 0x0fc, 0x000f0000, 16, 0, "Synthesis language. 1=vhdl. 2=verilog" },
+  { HEncHWBusWidth, 0x0fc, 0x0000f000, 12, 0, "Bus width of HW. 0=32b. 1=64b. 2=128b" },
+  { HEncHWMaxVideoWidth, 0x0fc, 0x00000fff,  0, 0, "Maximum video width supported by HW (pixels)" },
+
+/* JPEG / VP8 mixed definitions regs 0x100-0x17C */
+  { HEncJpegQuantLuma1, 0x100, 0xffffffff,  0, 0, "JPEG luma quantization 1" },
+  { HEncJpegQuantLuma2, 0x104, 0xffffffff,  0, 0, "JPEG luma quantization 2" },
+  { HEncJpegQuantLuma3, 0x108, 0xffffffff,  0, 0, "JPEG luma quantization 3" },
+  { HEncJpegQuantLuma4, 0x10c, 0xffffffff,  0, 0, "JPEG luma quantization 4" },
+  { HEncJpegQuantLuma5, 0x110, 0xffffffff,  0, 0, "JPEG luma quantization 5" },
+  { HEncJpegQuantLuma6, 0x114, 0xffffffff,  0, 0, "JPEG luma quantization 6" },
+  { HEncJpegQuantLuma7, 0x118, 0xffffffff,  0, 0, "JPEG luma quantization 7" },
+  { HEncJpegQuantLuma8, 0x11c, 0xffffffff,  0, 0, "JPEG luma quantization 8" },
+  { HEncJpegQuantLuma9, 0x120, 0xffffffff,  0, 0, "JPEG luma quantization 9" },
+  { HEncJpegQuantLuma10, 0x124, 0xffffffff,  0, 0, "JPEG luma quantization 10" },
+  { HEncJpegQuantLuma11, 0x128, 0xffffffff,  0, 0, "JPEG luma quantization 11" },
+  { HEncJpegQuantLuma12, 0x12c, 0xffffffff,  0, 0, "JPEG luma quantization 12" },
+  { HEncJpegQuantLuma13, 0x130, 0xffffffff,  0, 0, "JPEG luma quantization 13" },
+  { HEncJpegQuantLuma14, 0x134, 0xffffffff,  0, 0, "JPEG luma quantization 14" },
+  { HEncJpegQuantLuma15, 0x138, 0xffffffff,  0, 0, "JPEG luma quantization 15" },
+  { HEncJpegQuantLuma16, 0x13c, 0xffffffff,  0, 0, "JPEG luma quantization 16" },
+  { HEncJpegQuantChroma1, 0x140, 0xffffffff,  0, 0, "JPEG chroma quantization 1" },
+  { HEncJpegQuantChroma2, 0x144, 0xffffffff,  0, 0, "JPEG chroma quantization 2" },
+  { HEncJpegQuantChroma3, 0x148, 0xffffffff,  0, 0, "JPEG chroma quantization 3" },
+  { HEncJpegQuantChroma4, 0x14c, 0xffffffff,  0, 0, "JPEG chroma quantization 4" },
+  { HEncJpegQuantChroma5, 0x150, 0xffffffff,  0, 0, "JPEG chroma quantization 5" },
+  { HEncJpegQuantChroma6, 0x154, 0xffffffff,  0, 0, "JPEG chroma quantization 6" },
+  { HEncJpegQuantChroma7, 0x158, 0xffffffff,  0, 0, "JPEG chroma quantization 7" },
+  { HEncJpegQuantChroma8, 0x15c, 0xffffffff,  0, 0, "JPEG chroma quantization 8" },
+  { HEncJpegQuantChroma9, 0x160, 0xffffffff,  0, 0, "JPEG chroma quantization 9" },
+  { HEncJpegQuantChroma10, 0x164, 0xffffffff,  0, 0, "JPEG chroma quantization 10" },
+  { HEncJpegQuantChroma11, 0x168, 0xffffffff,  0, 0, "JPEG chroma quantization 11" },
+  { HEncJpegQuantChroma12, 0x16c, 0xffffffff,  0, 0, "JPEG chroma quantization 12" },
+  { HEncJpegQuantChroma13, 0x170, 0xffffffff,  0, 0, "JPEG chroma quantization 13" },
+  { HEncJpegQuantChroma14, 0x174, 0xffffffff,  0, 0, "JPEG chroma quantization 14" },
+  { HEncJpegQuantChroma15, 0x178, 0xffffffff,  0, 0, "JPEG chroma quantization 15" },
+  { HEncJpegQuantChroma16, 0x17C, 0xffffffff,  0, 0, "JPEG chroma quantization 16" },
+  { HEncVp8Mode0Penalty, 0x100, 0x00000fff,  0, 0, "VP8 intra 16x16 mode 0 penalty" },
+  { HEncVp8Mode1Penalty, 0x100, 0x00fff000, 12, 0, "VP8 intra 16x16 mode 1 penalty" },
+  { HEncVp8Mode2Penalty, 0x104, 0x00000fff,  0, 0, "VP8 intra 16x16 mode 2 penalty" },
+  { HEncVp8Mode3Penalty, 0x104, 0x00fff000, 12, 0, "VP8 intra 16x16 mode 3 penalty" },
+  { HEncVp8Bmode0Penalty, 0x108, 0x00000fff,  0, 0, "VP8 intra 4x4 mode 0 penalty" },
+  { HEncVp8Bmode1Penalty, 0x108, 0x00fff000, 12, 0, "VP8 intra 4x4 mode 1 penalty" },
+  { HEncVp8Bmode2Penalty, 0x10C, 0x00000fff,  0, 0, "VP8 intra 4x4 mode 2 penalty" },
+  { HEncVp8Bmode3Penalty, 0x10C, 0x00fff000, 12, 0, "VP8 intra 4x4 mode 3 penalty" },
+  { HEncVp8Bmode4Penalty, 0x110, 0x00000fff,  0, 0, "VP8 intra 4x4 mode 4 penalty" },
+  { HEncVp8Bmode5Penalty, 0x110, 0x00fff000, 12, 0, "VP8 intra 4x4 mode 5 penalty" },
+  { HEncVp8Bmode6Penalty, 0x114, 0x00000fff,  0, 0, "VP8 intra 4x4 mode 6 penalty" },
+  { HEncVp8Bmode7Penalty, 0x114, 0x00fff000, 12, 0, "VP8 intra 4x4 mode 7 penalty" },
+  { HEncVp8Bmode8Penalty, 0x118, 0x00000fff,  0, 0, "VP8 intra 4x4 mode 8 penalty" },
+  { HEncVp8Bmode9Penalty, 0x118, 0x00fff000, 12, 0, "VP8 intra 4x4 mode 9 penalty" },
+  { HEncBaseVp8SegmentMap, 0x11C, 0xffffffff,  0, 0, "Base address for VP8 segmentation map, segmentId 2-bits/macroblock" },
+  { HEncVp8Seg1Y1QuantDc, 0x120, 0x00003fff,  0, 1, "VP8 segment1 qpY1QuantDc 14b" },
+  { HEncVp8Seg1Y1ZbinDc, 0x120, 0x007fc000, 14, 1, "VP8 segment1 qpY1ZbinDc 9b" },
+  { HEncVp8Seg1Y1RoundDc, 0x120, 0x7f800000, 23, 1, "VP8 segment1 qpY1RoundDc 8b" },
+  { HEncVp8Seg1Y1QuantAc, 0x124, 0x00003fff,  0, 1, "VP8 segment1 qpY1QuantAc 14b" },
+  { HEncVp8Seg1Y1ZbinAc, 0x124, 0x007fc000, 14, 1, "VP8 segment1 qpY1ZbinAc 9b" },
+  { HEncVp8Seg1Y1RoundAc, 0x124, 0x7f800000, 23, 1, "VP8 segment1 qpY1RoundAc 8b" },
+  { HEncVp8Seg1Y2QuantDc, 0x128, 0x00003fff,  0, 1, "VP8 segment1 qpY2QuantDc 14b" },
+  { HEncVp8Seg1Y2ZbinDc, 0x128, 0x007fc000, 14, 1, "VP8 segment1 qpY2ZbinDc 9b" },
+  { HEncVp8Seg1Y2RoundDc, 0x128, 0x7f800000, 23, 1, "VP8 segment1 qpY2RoundDc 8b" },
+  { HEncVp8Seg1Y2QuantAc, 0x12C, 0x00003fff,  0, 1, "VP8 segment1 qpY2QuantAc 14b" },
+  { HEncVp8Seg1Y2ZbinAc, 0x12C, 0x007fc000, 14, 1, "VP8 segment1 qpY2ZbinAc 9b" },
+  { HEncVp8Seg1Y2RoundAc, 0x12C, 0x7f800000, 23, 1, "VP8 segment1 qpY2RoundAc 8b" },
+  { HEncVp8Seg1ChQuantDc, 0x130, 0x00003fff,  0, 1, "VP8 segment1 qpChQuantDc 14b" },
+  { HEncVp8Seg1ChZbinDc, 0x130, 0x007fc000, 14, 1, "VP8 segment1 qpChZbinDc 9b" },
+  { HEncVp8Seg1ChRoundDc, 0x130, 0x7f800000, 23, 1, "VP8 segment1 qpChRoundDc 8b" },
+  { HEncVp8Seg1ChQuantAc, 0x134, 0x00003fff,  0, 1, "VP8 segment1 qpChQuantAc 14b" },
+  { HEncVp8Seg1ChZbinAc, 0x134, 0x007fc000, 14, 1, "VP8 segment1 qpChZbinAc 9b" },
+  { HEncVp8Seg1ChRoundAc, 0x134, 0x7f800000, 23, 1, "VP8 segment1 qpChRoundAc 8b" },
+  { HEncVp8Seg1Y1DequantDc, 0x138, 0x000000ff,  0, 1, "VP8 segment1 qpY1DequantDc 8b" },
+  { HEncVp8Seg1Y1DequantAc, 0x138, 0x0001ff00,  8, 1, "VP8 segment1 qpY1DequantAc 9b" },
+  { HEncVp8Seg1Y2DequantDc, 0x138, 0x03fe0000, 17, 1, "VP8 segment1 qpY2DequantDc 9b" },
+  { HEncVp8Seg1Y2DequantAc, 0x13C, 0x000001ff,  0, 1, "VP8 segment1 qpY2DequantAc 9b" },
+  { HEncVp8Seg1ChDequantDc, 0x13C, 0x0001fe00,  9, 1, "VP8 segment1 qpChDequantDc 8b" },
+  { HEncVp8Seg1ChDequantAc, 0x13C, 0x03fe0000, 17, 1, "VP8 segment1 qpChDequantAc 9b" },
+  { HEncVp8Seg1FilterLevel, 0x13C, 0xfc000000, 26, 1, "VP8 segment1 filter level 6b" },
+  { HEncVp8Seg2Y1QuantDc, 0x140, 0x00003fff,  0, 1, "VP8 segment2 qpY1QuantDc 14b" },
+  { HEncVp8Seg2Y1ZbinDc, 0x140, 0x007fc000, 14, 1, "VP8 segment2 qpY1ZbinDc 9b" },
+  { HEncVp8Seg2Y1RoundDc, 0x140, 0x7f800000, 23, 1, "VP8 segment2 qpY1RoundDc 8b" },
+  { HEncVp8Seg2Y1QuantAc, 0x144, 0x00003fff,  0, 1, "VP8 segment2 qpY1QuantAc 14b" },
+  { HEncVp8Seg2Y1ZbinAc, 0x144, 0x007fc000, 14, 1, "VP8 segment2 qpY1ZbinAc 9b" },
+  { HEncVp8Seg2Y1RoundAc, 0x144, 0x7f800000, 23, 1, "VP8 segment2 qpY1RoundAc 8b" },
+  { HEncVp8Seg2Y2QuantDc, 0x148, 0x00003fff,  0, 1, "VP8 segment2 qpY2QuantDc 14b" },
+  { HEncVp8Seg2Y2ZbinDc, 0x148, 0x007fc000, 14, 1, "VP8 segment2 qpY2ZbinDc 9b" },
+  { HEncVp8Seg2Y2RoundDc, 0x148, 0x7f800000, 23, 1, "VP8 segment2 qpY2RoundDc 8b" },
+  { HEncVp8Seg2Y2QuantAc, 0x14C, 0x00003fff,  0, 1, "VP8 segment2 qpY2QuantAc 14b" },
+  { HEncVp8Seg2Y2ZbinAc, 0x14C, 0x007fc000, 14, 1, "VP8 segment2 qpY2ZbinAc 9b" },
+  { HEncVp8Seg2Y2RoundAc, 0x14C, 0x7f800000, 23, 1, "VP8 segment2 qpY2RoundAc 8b" },
+  { HEncVp8Seg2ChQuantDc, 0x150, 0x00003fff,  0, 1, "VP8 segment2 qpChQuantDc 14b" },
+  { HEncVp8Seg2ChZbinDc, 0x150, 0x007fc000, 14, 1, "VP8 segment2 qpChZbinDc 9b" },
+  { HEncVp8Seg2ChRoundDc, 0x150, 0x7f800000, 23, 1, "VP8 segment2 qpChRoundDc 8b" },
+  { HEncVp8Seg2ChQuantAc, 0x154, 0x00003fff,  0, 1, "VP8 segment2 qpChQuantAc 14b" },
+  { HEncVp8Seg2ChZbinAc, 0x154, 0x007fc000, 14, 1, "VP8 segment2 qpChZbinAc 9b" },
+  { HEncVp8Seg2ChRoundAc, 0x154, 0x7f800000, 23, 1, "VP8 segment2 qpChRoundAc 8b" },
+  { HEncVp8Seg2Y1DequantDc, 0x158, 0x000000ff,  0, 1, "VP8 segment2 qpY1DequantDc 8b" },
+  { HEncVp8Seg2Y1DequantAc, 0x158, 0x0001ff00,  8, 1, "VP8 segment2 qpY1DequantAc 9b" },
+  { HEncVp8Seg2Y2DequantDc, 0x158, 0x03fe0000, 17, 1, "VP8 segment2 qpY2DequantDc 9b" },
+  { HEncVp8Seg2Y2DequantAc, 0x15C, 0x000001ff,  0, 1, "VP8 segment2 qpY2DequantAc 9b" },
+  { HEncVp8Seg2ChDequantDc, 0x15C, 0x0001fe00,  9, 1, "VP8 segment2 qpChDequantDc 8b" },
+  { HEncVp8Seg2ChDequantAc, 0x15C, 0x03fe0000, 17, 1, "VP8 segment2 qpChDequantAc 9b" },
+  { HEncVp8Seg2FilterLevel, 0x15C, 0xfc000000, 26, 1, "VP8 segment2 filter level 6b" },
+  { HEncVp8Seg3Y1QuantDc, 0x160, 0x00003fff,  0, 1, "VP8 segment3 qpY1QuantDc 14b" },
+  { HEncVp8Seg3Y1ZbinDc, 0x160, 0x007fc000, 14, 1, "VP8 segment3 qpY1ZbinDc 9b" },
+  { HEncVp8Seg3Y1RoundDc, 0x160, 0x7f800000, 23, 1, "VP8 segment3 qpY1RoundDc 8b" },
+  { HEncVp8Seg3Y1QuantAc, 0x164, 0x00003fff,  0, 1, "VP8 segment3 qpY1QuantAc 14b" },
+  { HEncVp8Seg3Y1ZbinAc, 0x164, 0x007fc000, 14, 1, "VP8 segment3 qpY1ZbinAc 9b" },
+  { HEncVp8Seg3Y1RoundAc, 0x164, 0x7f800000, 23, 1, "VP8 segment3 qpY1RoundAc 8b" },
+  { HEncVp8Seg3Y2QuantDc, 0x168, 0x00003fff,  0, 1, "VP8 segment3 qpY2QuantDc 14b" },
+  { HEncVp8Seg3Y2ZbinDc, 0x168, 0x007fc000, 14, 1, "VP8 segment3 qpY2ZbinDc 9b" },
+  { HEncVp8Seg3Y2RoundDc, 0x168, 0x7f800000, 23, 1, "VP8 segment3 qpY2RoundDc 8b" },
+  { HEncVp8Seg3Y2QuantAc, 0x16C, 0x00003fff,  0, 1, "VP8 segment3 qpY2QuantAc 14b" },
+  { HEncVp8Seg3Y2ZbinAc, 0x16C, 0x007fc000, 14, 1, "VP8 segment3 qpY2ZbinAc 9b" },
+  { HEncVp8Seg3Y2RoundAc, 0x16C, 0x7f800000, 23, 1, "VP8 segment3 qpY2RoundAc 8b" },
+  { HEncVp8Seg3ChQuantDc, 0x170, 0x00003fff,  0, 1, "VP8 segment3 qpChQuantDc 14b" },
+  { HEncVp8Seg3ChZbinDc, 0x170, 0x007fc000, 14, 1, "VP8 segment3 qpChZbinDc 9b" },
+  { HEncVp8Seg3ChRoundDc, 0x170, 0x7f800000, 23, 1, "VP8 segment3 qpChRoundDc 8b" },
+  { HEncVp8Seg3ChQuantAc, 0x174, 0x00003fff,  0, 1, "VP8 segment3 qpChQuantAc 14b" },
+  { HEncVp8Seg3ChZbinAc, 0x174, 0x007fc000, 14, 1, "VP8 segment3 qpChZbinAc 9b" },
+  { HEncVp8Seg3ChRoundAc, 0x174, 0x7f800000, 23, 1, "VP8 segment3 qpChRoundAc 8b" },
+  { HEncVp8Seg3Y1DequantDc, 0x178, 0x000000ff,  0, 1, "VP8 segment3 qpY1DequantDc 8b" },
+  { HEncVp8Seg3Y1DequantAc, 0x178, 0x0001ff00,  8, 1, "VP8 segment3 qpY1DequantAc 9b" },
+  { HEncVp8Seg3Y2DequantDc, 0x178, 0x03fe0000, 17, 1, "VP8 segment3 qpY2DequantDc 9b" },
+  { HEncVp8Seg3Y2DequantAc, 0x17C, 0x000001ff,  0, 1, "VP8 segment3 qpY2DequantAc 9b" },
+  { HEncVp8Seg3ChDequantDc, 0x17C, 0x0001fe00,  9, 1, "VP8 segment3 qpChDequantDc 8b" },
+  { HEncVp8Seg3ChDequantAc, 0x17C, 0x03fe0000, 17, 1, "VP8 segment3 qpChDequantAc 9b" },
+  { HEncVp8Seg3FilterLevel, 0x17C, 0xfc000000, 26, 1, "VP8 segment3 filter level 6b" },
+
+  { HEncDmvPenalty1, 0x180, 0xffffffff,  0, 0, "DMV 4p/1p penalty values 0-3" },
+  { HEncDmvPenalty2, 0x184, 0xffffffff,  0, 0, "DMV 4p/1p penalty values 4-7" },
+  { HEncDmvPenalty3, 0x188, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty4, 0x18C, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty5, 0x190, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty6, 0x194, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty7, 0x198, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty8, 0x19C, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty9, 0x1A0, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty10, 0x1A4, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty11, 0x1A8, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty12, 0x1AC, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty13, 0x1B0, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty14, 0x1B4, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty15, 0x1B8, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty16, 0x1BC, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty17, 0x1C0, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty18, 0x1C4, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty19, 0x1C8, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty20, 0x1CC, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty21, 0x1D0, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty22, 0x1D4, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty23, 0x1D8, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty24, 0x1DC, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty25, 0x1E0, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty26, 0x1E4, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty27, 0x1E8, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty28, 0x1EC, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty29, 0x1F0, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty30, 0x1F4, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty31, 0x1F8, 0xffffffff,  0, 0, "DMV 4p/1p penalty values" },
+  { HEncDmvPenalty32, 0x1FC, 0xffffffff,  0, 0, "DMV 4p/1p penalty values 124-127" },
+
+  { HEncDmvQpelPenalty1, 0x200, 0xffffffff,  0, 0, "DMV qpel penalty values 0-3" },
+  { HEncDmvQpelPenalty2, 0x204, 0xffffffff,  0, 0, "DMV qpel penalty values 4-7" },
+  { HEncDmvQpelPenalty3, 0x208, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty4, 0x20C, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty5, 0x210, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty6, 0x214, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty7, 0x218, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty8, 0x21C, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty9, 0x220, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty10, 0x224, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty11, 0x228, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty12, 0x22C, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty13, 0x230, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty14, 0x234, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty15, 0x238, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty16, 0x23C, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty17, 0x240, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty18, 0x244, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty19, 0x248, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty20, 0x24C, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty21, 0x250, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty22, 0x254, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty23, 0x258, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty24, 0x25C, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty25, 0x260, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty26, 0x264, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty27, 0x268, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty28, 0x26C, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty29, 0x270, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty30, 0x274, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty31, 0x278, 0xffffffff,  0, 0, "DMV qpel penalty values" },
+  { HEncDmvQpelPenalty32, 0x27C, 0xffffffff,  0, 0, "DMV qpel penalty values 124-127" },
+
+  { HEncVp8CostInter, 0x280, 0x00000fff,  0, 0, "VP8 bit cost of inter type" },
+  { HEncVp8DmvCostConst, 0x280, 0x00fff000, 12, 0, "VP8 coeff for dmv penalty for intra/inter selection" },
+  { HEncVp8CostGoldenRef, 0x284, 0x00000fff,  0, 0, "VP8 bit cost of golden ref frame" },
+  { HEncVp8LfRefDelta0, 0x288, 0x0000007f,  0, 0, "VP8 loop filter delta for intra mb" },
+  { HEncVp8LfRefDelta1, 0x288, 0x00003f80,  7, 0, "VP8 loop filter delta for last ref" },
+  { HEncVp8LfRefDelta2, 0x288, 0x001fc000, 14, 0, "VP8 loop filter delta for golden ref" },
+  { HEncVp8LfRefDelta3, 0x288, 0x0fe00000, 21, 0, "VP8 loop filter delta for alt ref" },
+  { HEncVp8LfModeDelta0, 0x28C, 0x0000007f,  0, 0, "VP8 loop filter delta for BPRED" },
+  { HEncVp8LfModeDelta1, 0x28C, 0x00003f80,  7, 0, "VP8 loop filter delta for ZEROMV" },
+  { HEncVp8LfModeDelta2, 0x28C, 0x001fc000, 14, 0, "VP8 loop filter delta for NEWMV" },
+  { HEncVp8LfModeDelta3, 0x28C, 0x0fe00000, 21, 0, "VP8 loop filter delta for SPLITMV" }
+
+};
+
+
+/*------------------------------------------------------------------------------
+    Local function prototypes
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+    Initialize empty structure with default values.
+------------------------------------------------------------------------------*/
+int32_t VP8_EncAsicControllerInit(asicData_s* asic) {
+  ASSERT(asic != NULL);
+
+  /* Initialize default values from defined configuration */
+  asic->regs.irqDisable = ENCH1_IRQ_DISABLE;
+
+  asic->regs.asicCfgReg =
+      ((ENCH1_AXI_WRITE_ID & (255)) << 24) |
+          ((ENCH1_AXI_READ_ID & (255)) << 16) |
+          ((ENCH1_OUTPUT_SWAP_16 & (1)) << 15) |
+          ((ENCH1_BURST_LENGTH & (63)) << 8) |
+          ((ENCH1_BURST_SCMD_DISABLE & (1)) << 7) |
+          ((ENCH1_BURST_INCR_TYPE_ENABLED & (1)) << 6) |
+          ((ENCH1_BURST_DATA_DISCARD_ENABLED & (1)) << 5) |
+          ((ENCH1_ASIC_CLOCK_GATING_ENABLED & (1)) << 4) |
+          ((ENCH1_OUTPUT_SWAP_32 & (1)) << 3) |
+          ((ENCH1_OUTPUT_SWAP_8 & (1)) << 1);
+
+  /* Initialize default values */
+  asic->regs.roundingCtrl = 0;
+  asic->regs.cpDistanceMbs = 0;
+  asic->regs.reconImageId = 0;
+
+  asic->internalImageLuma[0].vir_addr = NULL;
+  asic->internalImageChroma[0].vir_addr = NULL;
+  asic->internalImageLuma[1].vir_addr = NULL;
+  asic->internalImageChroma[1].vir_addr = NULL;
+  asic->internalImageLuma[2].vir_addr = NULL;
+  asic->internalImageChroma[2].vir_addr = NULL;
+  asic->cabacCtx.vir_addr = NULL;
+  asic->probCount.vir_addr = NULL;
+
+  return ENCHW_OK;
+}
+
+/*------------------------------------------------------------------------------
+    EncAsicSetRegisterValue
+    Set a value into a defined register field
+------------------------------------------------------------------------------*/
+void VP8_EncAsicSetRegisterValue(uint32_t* regMirror, regName name, uint32_t value) {
+  const regField_s* field;
+  uint32_t regVal;
+
+  field = &asicRegisterDesc[name];
+
+  /* Check that value fits in field */
+  ASSERT(field->name == name);
+  ASSERT((field->mask >> field->lsb) >= value);
+  ASSERT(field->base < ASIC_SWREG_AMOUNT * 4);
+
+  /* Clear previous value of field in register */
+  regVal = regMirror[field->base / 4] & ~(field->mask);
+
+  /* Put new value of field in register */
+  regMirror[field->base / 4] = regVal | ((value << field->lsb) & field->mask);
+}
+
+void VP8_CheckRegisterValues(regValues_s* val) {
+  uint32_t i;
+
+  ASSERT(val->irqDisable <= 1);
+  ASSERT(val->rlcLimitSpace / 2 < (1 << 20));
+  ASSERT(val->mbsInCol <= 511);
+  ASSERT(val->mbsInRow <= 511);
+  ASSERT(val->filterDisable <= 2);
+  ASSERT(val->skipPenalty <= 255);
+  ASSERT(val->goldenPenalty <= 255);
+  ASSERT(val->recWriteDisable <= 1);
+  ASSERT(val->madThreshold <= 63);
+  ASSERT(val->madQpDelta >= -8 && val->madQpDelta <= 7);
+  ASSERT(val->qp <= 63);
+  ASSERT(val->constrainedIntraPrediction <= 1);
+  ASSERT(val->roundingCtrl <= 1);
+  ASSERT(val->frameCodingType <= 3);
+  ASSERT(val->codingType <= 3);
+  ASSERT(val->outputStrmSize <= 0x1FFFFFF);
+  ASSERT(val->pixelsOnRow >= 16 && val->pixelsOnRow <= 8192); /* max input for cropping */
+  ASSERT(val->xFill <= 3);
+  ASSERT(val->yFill <= 14 && ((val->yFill & 0x01) == 0));
+  ASSERT(val->sliceAlphaOffset >= -6 && val->sliceAlphaOffset <= 6);
+  ASSERT(val->sliceBetaOffset >= -6 && val->sliceBetaOffset <= 6);
+  ASSERT(val->chromaQpIndexOffset >= -12 && val->chromaQpIndexOffset <= 12);
+  ASSERT(val->sliceSizeMbRows <= 127);
+  ASSERT(val->inputImageFormat <= ASIC_INPUT_YUYV422TILED);
+  ASSERT(val->inputImageRotation <= 2);
+  ASSERT(val->cpDistanceMbs <= 8191);
+  ASSERT(val->cirStart <= 65535);
+  ASSERT(val->cirInterval <= 65535);
+  ASSERT(val->intraAreaTop <= 255);
+  ASSERT(val->intraAreaLeft <= 255);
+  ASSERT(val->intraAreaBottom <= 255);
+  ASSERT(val->intraAreaRight <= 255);
+  ASSERT(val->roi1Top <= 255);
+  ASSERT(val->roi1Left <= 255);
+  ASSERT(val->roi1Bottom <= 255);
+  ASSERT(val->roi1Right <= 255);
+  ASSERT(val->roi2Top <= 255);
+  ASSERT(val->roi2Left <= 255);
+  ASSERT(val->roi2Bottom <= 255);
+  ASSERT(val->roi2Right <= 255);
+
+  if (val->cpTarget != NULL) {
+    ASSERT(val->cpTargetResults != NULL);
+
+    for (i = 0; i < 10; i++) {
+      ASSERT(*val->cpTarget < (1 << 16));
+    }
+
+    ASSERT(val->targetError != NULL);
+
+    for (i = 0; i < 7; i++) {
+      ASSERT((*val->targetError) >= -32768 &&
+             (*val->targetError) < 32768);
+    }
+
+    ASSERT(val->deltaQp != NULL);
+
+    for (i = 0; i < 7; i++) {
+      ASSERT((*val->deltaQp) >= -8 && (*val->deltaQp) < 8);
+    }
+  }
+
+  (void)val;
+}
+
+/*------------------------------------------------------------------------------
+    Function name   : EncAsicFrameStart
+    Description     :
+    Return type     : void
+    Argument        : regValues_s * val
+------------------------------------------------------------------------------*/
+void VP8_EncAsicFrameStart(regValues_s* val) {
+  int32_t i;
+
+  VP8_CheckRegisterValues(val);
+
+  memset(val->regMirror, 0, sizeof(val->regMirror));
+
+  /* encoder interrupt */
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncIRQDisable, val->irqDisable);
+
+  /* system configuration */
+  if (val->inputImageFormat < ASIC_INPUT_RGB565)      /* YUV input */
+    val->regMirror[2] = val->asicCfgReg |
+            ((ENCH1_INPUT_SWAP_16_YUV & (1)) << 14) |
+            ((ENCH1_INPUT_SWAP_32_YUV & (1)) << 2) |
+            (ENCH1_INPUT_SWAP_8_YUV & (1));
+  else if (val->inputImageFormat < ASIC_INPUT_RGB888) /* 16-bit RGB input */
+    val->regMirror[2] = val->asicCfgReg |
+            ((ENCH1_INPUT_SWAP_16_RGB16 & (1)) << 14) |
+            ((ENCH1_INPUT_SWAP_32_RGB16 & (1)) << 2) |
+            (ENCH1_INPUT_SWAP_8_RGB16 & (1));
+  else    /* 32-bit RGB input */
+    val->regMirror[2] = val->asicCfgReg |
+            ((ENCH1_INPUT_SWAP_16_RGB32 & (1)) << 14) |
+            ((ENCH1_INPUT_SWAP_32_RGB32 & (1)) << 2) |
+            (ENCH1_INPUT_SWAP_8_RGB32 & (1));
+
+  /* output stream buffer */
+  /// TODO, set in driver with value val->outputStrmOffset
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseStream, val->outputStrmBase);
+
+  /* Video encoding output buffers and reference picture buffers */
+
+  /// TODO, set in driver, and need to copy to user by g_ext_ctrl.
+  //VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseControl, val->sizeTblBase);
+  //VP8_EncAsicSetRegisterValue(val->regMirror, HEncNalSizeWrite, val->sizeTblBase != 0);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncNalSizeWrite, 1);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncMvWrite, val->mvOutputBase != 0);
+
+  /// TODO: set in driver.
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseRefLum, val->internalImageLumBaseR[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseRefChr, val->internalImageChrBaseR[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseRecLum, val->internalImageLumBaseW);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseRecChr, val->internalImageChrBaseW);
+
+  /* Input picture buffers */
+  /// TODO, set in driver, with input yuv buffer dma_addr.
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseInLum, 0);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseInCb, 0);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseInCr, 0);
+
+  /* Common control register */
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncIntTimeout, ENCH1_TIMEOUT_INTERRUPT & 1);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncIntSliceReady, val->sliceReadyInterrupt);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRecWriteDisable, val->recWriteDisable);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncWidth, val->mbsInRow);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncHeight, val->mbsInCol);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncPictureType, val->frameCodingType);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncEncodingMode, val->codingType);
+
+  /* PreP control */
+  /// TODO: set in driver, correpond to Chrome base align.
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncChrOffset, 0);
+  /// TODO: set in driver, correspond to Luma base align.
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncLumOffset, 0);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRowLength, val->pixelsOnRow);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncXFill, val->xFill);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncYFill, val->yFill);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncInputFormat, val->inputImageFormat);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncInputRot, val->inputImageRotation);
+
+  /* Common controls */
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncCabacEnable, val->enableCabac);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncIPIntra16Favor, val->intra16Favor);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncInterFavor, val->interFavor);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncDisableQPMV, val->disableQuarterPixelMv);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncDeblocking, val->filterDisable);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncSkipPenalty, val->skipPenalty);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncSplitMv, val->splitMvMode);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncSplitPenalty16x8, val->splitPenalty[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncSplitPenalty8x8, val->splitPenalty[1]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncSplitPenalty8x4, val->splitPenalty[2]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncSplitPenalty4x4, val->splitPenalty[3]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncZeroMvFavor, val->zeroMvFavorDiv2);
+
+  /* stream buffer limits */
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncStrmHdrRem1, val->strmStartMSB);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncStrmHdrRem2, val->strmStartLSB);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncStrmBufLimit, val->outputStrmSize);
+
+  /* video encoding rate control regs 0x6C - 0x90,
+   * different register definitions for VP8 and H.264 */
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseRefLum2, val->internalImageLumBaseR[1]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseRefChr2, val->internalImageChrBaseR[1]);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y1QuantDc, val->qpY1QuantDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y1QuantAc, val->qpY1QuantAc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y2QuantDc, val->qpY2QuantDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y2QuantAc, val->qpY2QuantAc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8ChQuantDc, val->qpChQuantDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8ChQuantAc, val->qpChQuantAc[0]);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y1ZbinDc, val->qpY1ZbinDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y1ZbinAc, val->qpY1ZbinAc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y2ZbinDc, val->qpY2ZbinDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y2ZbinAc, val->qpY2ZbinAc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8ChZbinDc, val->qpChZbinDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8ChZbinAc, val->qpChZbinAc[0]);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y1RoundDc, val->qpY1RoundDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y1RoundAc, val->qpY1RoundAc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y2RoundDc, val->qpY2RoundDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y2RoundAc, val->qpY2RoundAc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8ChRoundDc, val->qpChRoundDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8ChRoundAc, val->qpChRoundAc[0]);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y1DequantDc, val->qpY1DequantDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y1DequantAc, val->qpY1DequantAc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y2DequantDc, val->qpY2DequantDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Y2DequantAc, val->qpY2DequantAc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8ChDequantDc, val->qpChDequantDc[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8ChDequantAc, val->qpChDequantAc[0]);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8MvRefIdx, val->mvRefIdx[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8MvRefIdx2, val->mvRefIdx[1]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Ref2Enable, val->ref2Enable);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8BoolEncValue, val->boolEncValue);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8BoolEncValueBits, val->boolEncValueBits);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8BoolEncRange, val->boolEncRange);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8FilterLevel, val->filterLevel[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8GoldenPenalty, val->goldenPenalty);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8FilterSharpness, val->filterSharpness);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8DctPartitionCount, val->dctPartitions);
+  /* Stream start offset */
+  /// TODO, set firstFreeBit in driver, assosiatte to strm output bus address.
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncStartOffset, val->firstFreeBit);
+
+  /* Stabilization */
+  /// disable stability.
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseNextLum, 0);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncStabMode, 0);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncDMVPenalty4p, val->diffMvPenalty[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncDMVPenalty1p, val->diffMvPenalty[1]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncDMVPenaltyQp, val->diffMvPenalty[2]);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseCabacCtx, val->cabacCtxBase);
+  /// TODO: set in driver.
+  //VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseMvWrite, val->mvOutputBase);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRGBCoeffA,
+                              val->colorConversionCoeffA & mask_16b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRGBCoeffB,
+                              val->colorConversionCoeffB & mask_16b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRGBCoeffC,
+                              val->colorConversionCoeffC & mask_16b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRGBCoeffE,
+                              val->colorConversionCoeffE & mask_16b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRGBCoeffF,
+                              val->colorConversionCoeffF & mask_16b);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRMaskMSB, val->rMaskMsb & mask_5b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncGMaskMSB, val->gMaskMsb & mask_5b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBMaskMSB, val->bMaskMsb & mask_5b);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncCirStart, val->cirStart);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncCirInterval, val->cirInterval);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncIntraAreaLeft, val->intraAreaLeft);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncIntraAreaRight, val->intraAreaRight);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncIntraAreaTop, val->intraAreaTop);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncIntraAreaBottom, val->intraAreaBottom);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRoi1Left, val->roi1Left);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRoi1Right, val->roi1Right);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRoi1Top, val->roi1Top);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRoi1Bottom, val->roi1Bottom);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRoi2Left, val->roi2Left);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRoi2Right, val->roi2Right);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRoi2Top, val->roi2Top);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncRoi2Bottom, val->roi2Bottom);
+
+  /// TODO, set in driver with value val->partitionOffset[0]
+  //VP8_EncAsicSetRegisterValue(val->regMirror, HEncBasePartition1, val->partitionBase[0]);
+  /// TODO, set in driver with value val->partitionOffset[1]
+  //VP8_EncAsicSetRegisterValue(val->regMirror, HEncBasePartition2, val->partitionBase[1]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseVp8ProbCount, val->probCountBase);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Mode0Penalty, val->intraModePenalty[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Mode1Penalty, val->intraModePenalty[1]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Mode2Penalty, val->intraModePenalty[2]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Mode3Penalty, val->intraModePenalty[3]);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode0Penalty, val->intraBmodePenalty[0]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode1Penalty, val->intraBmodePenalty[1]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode2Penalty, val->intraBmodePenalty[2]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode3Penalty, val->intraBmodePenalty[3]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode4Penalty, val->intraBmodePenalty[4]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode5Penalty, val->intraBmodePenalty[5]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode6Penalty, val->intraBmodePenalty[6]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode7Penalty, val->intraBmodePenalty[7]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode8Penalty, val->intraBmodePenalty[8]);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Bmode9Penalty, val->intraBmodePenalty[9]);
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8SegmentEnable, val->segmentEnable);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8SegmentMapUpdate, val->segmentMapUpdate);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncBaseVp8SegmentMap, val->segmentMapBase);
+
+  for (i = 0; i < 3; i++) {
+    int32_t off = (HEncVp8Seg2Y1QuantDc - HEncVp8Seg1Y1QuantDc) * i;
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y1QuantDc + off, val->qpY1QuantDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y1QuantAc + off, val->qpY1QuantAc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y2QuantDc + off, val->qpY2QuantDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y2QuantAc + off, val->qpY2QuantAc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1ChQuantDc + off, val->qpChQuantDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1ChQuantAc + off, val->qpChQuantAc[i + 1]);
+
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y1ZbinDc + off, val->qpY1ZbinDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y1ZbinAc + off, val->qpY1ZbinAc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y2ZbinDc + off, val->qpY2ZbinDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y2ZbinAc + off, val->qpY2ZbinAc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1ChZbinDc + off, val->qpChZbinDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1ChZbinAc + off, val->qpChZbinAc[i + 1]);
+
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y1RoundDc + off, val->qpY1RoundDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y1RoundAc + off, val->qpY1RoundAc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y2RoundDc + off, val->qpY2RoundDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y2RoundAc + off, val->qpY2RoundAc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1ChRoundDc + off, val->qpChRoundDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1ChRoundAc + off, val->qpChRoundAc[i + 1]);
+
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y1DequantDc + off, val->qpY1DequantDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y1DequantAc + off, val->qpY1DequantAc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y2DequantDc + off, val->qpY2DequantDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1Y2DequantAc + off, val->qpY2DequantAc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1ChDequantDc + off, val->qpChDequantDc[i + 1]);
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1ChDequantAc + off, val->qpChDequantAc[i + 1]);
+
+    VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8Seg1FilterLevel + off, val->filterLevel[i + 1]);
+  }
+
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8LfRefDelta0, val->lfRefDelta[0] & mask_7b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8LfRefDelta1, val->lfRefDelta[1] & mask_7b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8LfRefDelta2, val->lfRefDelta[2] & mask_7b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8LfRefDelta3, val->lfRefDelta[3] & mask_7b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8LfModeDelta0, val->lfModeDelta[0] & mask_7b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8LfModeDelta1, val->lfModeDelta[1] & mask_7b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8LfModeDelta2, val->lfModeDelta[2] & mask_7b);
+  VP8_EncAsicSetRegisterValue(val->regMirror, HEncVp8LfModeDelta3, val->lfModeDelta[3] & mask_7b);
+
+  {
+    int32_t i = 0;
+
+    /* Write DMV penalty tables to regs */
+    for (i = 0; i < 128; i += 4) {
+      /* swreg[96]=0x180 to swreg[127]=0x1FC */
+      val->regMirror[96 + (i / 4)] =
+          ((val->dmvPenalty[i] << 24) |
+               (val->dmvPenalty[i + 1] << 16) |
+               (val->dmvPenalty[i + 2] << 8) |
+               (val->dmvPenalty[i + 3]));
+    }
+    for (i = 0; i < 128; i += 4) {
+      /* swreg[128]=0x200 to swreg[159]=0x27C */
+      val->regMirror[128 + (i / 4)] =
+          ((val->dmvQpelPenalty[i] << 24) |
+               (val->dmvQpelPenalty[i + 1] << 16) |
+               (val->dmvQpelPenalty[i + 2] << 8) |
+               (val->dmvQpelPenalty[i + 3]));
+    }
+  }
+
+  /* Register with enable bit is written last */
+  val->regMirror[14] |= ASIC_STATUS_ENABLE;
+}
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller.h b/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller.h
new file mode 100644
index 0000000..797a134
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller.h
@@ -0,0 +1,267 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _ENC_ASIC_CONTROLLER_H_
+#define _ENC_ASIC_CONTROLLER_H_
+
+#include <stdint.h>
+#include "enccfg.h"
+#include "vpu_mem.h"
+#include "encswhwregisters.h"
+
+/* HW status register bits */
+#define ASIC_STATUS_ALL                 0x1FD
+
+#define ASIC_STATUS_SLICE_READY         0x100
+#define ASIC_STATUS_HW_TIMEOUT          0x040
+#define ASIC_STATUS_BUFF_FULL           0x020
+#define ASIC_STATUS_HW_RESET            0x010
+#define ASIC_STATUS_ERROR               0x008
+#define ASIC_STATUS_FRAME_READY         0x004
+
+#define ASIC_IRQ_LINE                   0x001
+
+#define ASIC_STATUS_ENABLE              0x001
+
+#define ASIC_H264_BYTE_STREAM           0x00
+#define ASIC_H264_NAL_UNIT              0x01
+
+#define ASIC_INPUT_YUV420PLANAR         0x00
+#define ASIC_INPUT_YUV420SEMIPLANAR     0x01
+#define ASIC_INPUT_YUYV422INTERLEAVED   0x02
+#define ASIC_INPUT_UYVY422INTERLEAVED   0x03
+#define ASIC_INPUT_RGB565               0x04
+#define ASIC_INPUT_RGB555               0x05
+#define ASIC_INPUT_RGB444               0x06
+#define ASIC_INPUT_RGB888               0x07
+#define ASIC_INPUT_RGB101010            0x08
+#define ASIC_INPUT_YUYV422TILED         0x09
+
+#define ASIC_PENALTY_UNDEFINED          -1
+
+#define ASIC_PENALTY_TABLE_SIZE         128
+
+typedef enum
+{
+  ASIC_VP8 = 1,
+  ASIC_JPEG = 2,
+  ASIC_H264 = 3
+} asicCodingType_e;
+
+typedef enum
+{
+  ASIC_P_16x16 = 0,
+  ASIC_P_16x8 = 1,
+  ASIC_P_8x16 = 2,
+  ASIC_P_8x8 = 3,
+  ASIC_I_4x4 = 4,
+  ASIC_I_16x16 = 5
+} asicMbType_e;
+
+typedef enum
+{
+  ASIC_INTER = 0,
+  ASIC_INTRA = 1,
+  ASIC_MVC = 2,
+  ASIC_MVC_REF_MOD = 3
+} asicFrameCodingType_e;
+
+typedef struct
+{
+  uint32_t socket;
+  uint32_t irqDisable;
+  uint32_t irqInterval;
+  uint32_t mbsInCol;
+  uint32_t mbsInRow;
+  uint32_t qp;
+  uint32_t qpMin;
+  uint32_t qpMax;
+  uint32_t constrainedIntraPrediction;
+  uint32_t roundingCtrl;
+  uint32_t frameCodingType;
+  uint32_t codingType;
+  uint32_t pixelsOnRow;
+  uint32_t xFill;
+  uint32_t yFill;
+  uint32_t ppsId;
+  uint32_t idrPicId;
+  uint32_t frameNum;
+  uint32_t picInitQp;
+  int32_t sliceAlphaOffset;
+  int32_t sliceBetaOffset;
+  uint32_t filterDisable;
+  uint32_t transform8x8Mode;
+  uint32_t enableCabac;
+  uint32_t cabacInitIdc;
+  int32_t chromaQpIndexOffset;
+  uint32_t sliceSizeMbRows;
+  uint32_t inputImageFormat;
+  uint32_t inputImageRotation;
+  uint32_t outputStrmFrmTagOffset;
+  uint32_t outputStrmBase;
+  uint32_t outputStrmSize;
+  uint32_t firstFreeBit;
+  uint32_t strmStartMSB;
+  uint32_t strmStartLSB;
+  uint32_t rlcBase;
+  uint32_t rlcLimitSpace;
+  uint32_t sizeTblBase;
+  uint32_t sliceReadyInterrupt;
+  uint32_t recWriteDisable;
+  uint32_t reconImageId;
+  uint32_t internalImageLumBaseW;
+  uint32_t internalImageChrBaseW;
+  uint32_t internalImageLumBaseR[2];
+  uint32_t internalImageChrBaseR[2];
+  uint32_t cpDistanceMbs;
+  uint32_t* cpTargetResults;
+  const uint32_t* cpTarget;
+  const int32_t* targetError;
+  const int32_t* deltaQp;
+  uint32_t rlcCount;
+  uint32_t qpSum;
+  uint32_t h264StrmMode;   /* 0 - byte stream, 1 - NAL units */
+  uint8_t quantTable[8 * 8 * 2];
+  uint8_t dmvPenalty[ASIC_PENALTY_TABLE_SIZE];
+  uint8_t dmvQpelPenalty[ASIC_PENALTY_TABLE_SIZE];
+  uint32_t jpegMode;
+  uint32_t jpegSliceEnable;
+  uint32_t jpegRestartInterval;
+  uint32_t jpegRestartMarker;
+  uint32_t regMirror[ASIC_SWREG_AMOUNT];
+  uint32_t inputLumaBaseOffsetVert;
+  uint32_t h264Inter4x4Disabled;
+  uint32_t disableQuarterPixelMv;
+  uint32_t vsNextLumaBase;
+  uint32_t vsMode;
+  uint32_t asicCfgReg;
+  int32_t intra16Favor;
+  int32_t prevModeFavor;
+  int32_t interFavor;
+  int32_t skipPenalty;
+  int32_t goldenPenalty;
+  int32_t diffMvPenalty[3];
+  int32_t madQpDelta;
+  uint32_t madThreshold;
+  uint32_t madCount;
+  uint32_t mvcAnchorPicFlag;
+  uint32_t mvcPriorityId;
+  uint32_t mvcViewId;
+  uint32_t mvcTemporalId;
+  uint32_t mvcInterViewFlag;
+  uint32_t cirStart;
+  uint32_t cirInterval;
+  uint32_t intraSliceMap1;
+  uint32_t intraSliceMap2;
+  uint32_t intraSliceMap3;
+  uint32_t intraAreaTop;
+  uint32_t intraAreaLeft;
+  uint32_t intraAreaBottom;
+  uint32_t intraAreaRight;
+  uint32_t roi1Top;
+  uint32_t roi1Left;
+  uint32_t roi1Bottom;
+  uint32_t roi1Right;
+  uint32_t roi2Top;
+  uint32_t roi2Left;
+  uint32_t roi2Bottom;
+  uint32_t roi2Right;
+  int32_t roi1DeltaQp;
+  int32_t roi2DeltaQp;
+  uint32_t mvOutputBase;
+  uint32_t cabacCtxBase;
+  uint32_t probCountBase;
+  uint32_t segmentMapBase;
+  uint32_t colorConversionCoeffA;
+  uint32_t colorConversionCoeffB;
+  uint32_t colorConversionCoeffC;
+  uint32_t colorConversionCoeffE;
+  uint32_t colorConversionCoeffF;
+  uint32_t rMaskMsb;
+  uint32_t gMaskMsb;
+  uint32_t bMaskMsb;
+  uint32_t partitionOffset[8];
+  uint32_t partitionBase[8];
+  uint32_t qpY1QuantDc[4];
+  uint32_t qpY1QuantAc[4];
+  uint32_t qpY2QuantDc[4];
+  uint32_t qpY2QuantAc[4];
+  uint32_t qpChQuantDc[4];
+  uint32_t qpChQuantAc[4];
+  uint32_t qpY1ZbinDc[4];
+  uint32_t qpY1ZbinAc[4];
+  uint32_t qpY2ZbinDc[4];
+  uint32_t qpY2ZbinAc[4];
+  uint32_t qpChZbinDc[4];
+  uint32_t qpChZbinAc[4];
+  uint32_t qpY1RoundDc[4];
+  uint32_t qpY1RoundAc[4];
+  uint32_t qpY2RoundDc[4];
+  uint32_t qpY2RoundAc[4];
+  uint32_t qpChRoundDc[4];
+  uint32_t qpChRoundAc[4];
+  uint32_t qpY1DequantDc[4];
+  uint32_t qpY1DequantAc[4];
+  uint32_t qpY2DequantDc[4];
+  uint32_t qpY2DequantAc[4];
+  uint32_t qpChDequantDc[4];
+  uint32_t qpChDequantAc[4];
+  uint32_t segmentEnable;
+  uint32_t segmentMapUpdate;
+  uint32_t mvRefIdx[2];
+  uint32_t ref2Enable;
+  uint32_t boolEncValue;
+  uint32_t boolEncValueBits;
+  uint32_t boolEncRange;
+  uint32_t dctPartitions;
+  uint32_t filterLevel[4];
+  uint32_t filterSharpness;
+  uint32_t intraModePenalty[4];
+  uint32_t intraBmodePenalty[10];
+  uint32_t zeroMvFavorDiv2;
+  uint32_t splitMvMode;
+  uint32_t splitPenalty[4];
+  int32_t lfRefDelta[4];
+  int32_t lfModeDelta[4];
+} regValues_s;
+
+#define FRAME_HEADER_SIZE 256
+typedef struct
+{
+  regValues_s regs;
+  VPUMemLinear_t internalImageLuma[3];
+  VPUMemLinear_t internalImageChroma[4];
+  VPUMemLinear_t cabacCtx;
+  VPUMemLinear_t probCount;
+  VPUMemLinear_t segmentMap;
+  uint32_t sizeTblSize;
+  uint32_t traceRecon;
+  uint8_t hdr[FRAME_HEADER_SIZE + 8];
+  uint32_t frmHdrBufLen;
+  uint8_t *frmhdr;
+} asicData_s;
+
+int32_t VP8_EncAsicControllerInit(asicData_s* asic);
+
+int32_t VP8_EncAsicMemAlloc_V2(
+    asicData_s* asic, uint32_t width, uint32_t height, uint32_t encodingType,
+    uint32_t numRefBuffsLum, uint32_t numRefBuffsChr);
+
+void VP8_EncAsicMemFree_V2(asicData_s* asic);
+
+void VP8_EncAsicFrameStart(regValues_s* val);
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller_v2.c b/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller_v2.c
new file mode 100644
index 0000000..ebd1802
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller_v2.c
@@ -0,0 +1,80 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include <malloc.h>
+#include <memory.h>
+#include "encasiccontroller.h"
+#include "enccommon.h"
+
+int32_t VP8_EncAsicMemAlloc_V2(asicData_s* asic, uint32_t width, uint32_t height,
+                               uint32_t encodingType, uint32_t numRefBuffsLum,
+                               uint32_t numRefBuffsChr) {
+  uint32_t mbTotal, cabacTablSize;
+  regValues_s* regs;
+
+  ASSERT(asic != NULL);
+  ASSERT(width != 0);
+  ASSERT(height != 0);
+  ASSERT((height % 2) == 0);
+  ASSERT((width % 4) == 0);
+
+  regs = &asic->regs;
+
+  regs->codingType = encodingType;
+
+  width = (width + 15) / 16;
+  height = (height + 15) / 16;
+
+  mbTotal = width * height;
+
+  /* H264: CABAC context tables: all qps, intra+inter, 464 bytes/table.
+   * VP8: The same table is used for probability tables, 1208 bytes. */
+  cabacTablSize = 8 * 55 + 8 * 96;
+
+  if (VPUMallocLinear(&asic->cabacCtx, cabacTablSize) != 0) {
+    VP8_EncAsicMemFree_V2(asic);
+    return ENCHW_NOK;
+  }
+  regs->cabacCtxBase = asic->cabacCtx.phy_addr;
+
+  /* VP8: Table of counter for probability updates. */
+  if (VPUMallocLinear(&asic->probCount, ASIC_VP8_PROB_COUNT_SIZE) != 0) {
+    VP8_EncAsicMemFree_V2(asic);
+    return ENCHW_NOK;
+  }
+  regs->probCountBase = asic->probCount.phy_addr;
+
+  /* VP8: Segmentation map, 4 bits/mb, 64-bit multiple. */
+  if (VPUMallocLinear(&asic->segmentMap, (mbTotal * 4 + 63) / 64 * 8) != 0) {
+    VP8_EncAsicMemFree_V2(asic);
+    return ENCHW_NOK;
+  }
+  regs->segmentMapBase = asic->segmentMap.phy_addr;
+
+  memset(asic->segmentMap.vir_addr, 0, asic->segmentMap.size);
+
+  asic->frmhdr = (uint8_t*)(((int)asic->hdr + 7) & (~7));
+  asic->frmHdrBufLen = FRAME_HEADER_SIZE;
+
+  return ENCHW_OK;
+}
+
+void VP8_EncAsicMemFree_V2(asicData_s* asic) {
+  ASSERT(asic != NULL);
+  VPUFreeLinear(&asic->cabacCtx);
+  VPUFreeLinear(&asic->probCount);
+}
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/enccfg.h b/libv4l-rockchip/libvpu/vp8_enc/enccfg.h
new file mode 100644
index 0000000..2a24267
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/enccfg.h
@@ -0,0 +1,190 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _ENCCFG_H_
+#define _ENCCFG_H_
+
+#include <stdint.h>
+
+/* The default values for the encoder build-time configuration are defined here.
+ * You can override these settings by defining the values as compiler flags in
+ * the Makefile.
+ */
+
+/* The input image's 32-bit swap: 0 or 1
+ * This defines the 32-bit endianess of the ASIC input YUV
+ * 1 = 64-bit endianess */
+#ifndef ENCH1_INPUT_SWAP_32_YUV
+#define ENCH1_INPUT_SWAP_32_YUV                   1
+#endif
+
+/* The input image's 16-bit swap: 0 or 1
+ * This defines the 16-bit endianess of the ASIC input YUV
+ */
+#ifndef ENCH1_INPUT_SWAP_16_YUV
+#define ENCH1_INPUT_SWAP_16_YUV                   1
+#endif
+
+/* The input image's 8-bit swap: 0 or 1
+ * This defines the byte endianess of the ASIC input YUV
+ */
+#ifndef ENCH1_INPUT_SWAP_8_YUV
+#define ENCH1_INPUT_SWAP_8_YUV                    1
+#endif
+
+/* The input image's 32-bit swap: 0 or 1
+ * This defines the 32-bit endianess of the ASIC input RGB16
+ * 1 = 64-bit endianess */
+#ifndef ENCH1_INPUT_SWAP_32_RGB16
+#define ENCH1_INPUT_SWAP_32_RGB16                 1
+#endif
+
+/* The input image's 16-bit swap: 0 or 1
+ * This defines the 16-bit endianess of the ASIC input RGB16
+ */
+#ifndef ENCH1_INPUT_SWAP_16_RGB16
+#define ENCH1_INPUT_SWAP_16_RGB16                 1
+#endif
+
+/* The input image's byte swap: 0 or 1
+ * This defines the byte endianess of the ASIC input RGB16
+ */
+#ifndef ENCH1_INPUT_SWAP_8_RGB16
+#define ENCH1_INPUT_SWAP_8_RGB16                  0
+#endif
+
+/* The input image's 32-bit swap: 0 or 1
+ * This defines the 32-bit endianess of the ASIC input RGB32
+ * 1 = 64-bit endianess */
+#ifndef ENCH1_INPUT_SWAP_32_RGB32
+#define ENCH1_INPUT_SWAP_32_RGB32                 1
+#endif
+
+/* The input image's 16-bit swap: 0 or 1
+ * This defines the 16-bit endianess of the ASIC input RGB32
+ */
+#ifndef ENCH1_INPUT_SWAP_16_RGB32
+#define ENCH1_INPUT_SWAP_16_RGB32                 0
+#endif
+
+/* The input image's byte swap: 0 or 1
+ * This defines the byte endianess of the ASIC input RGB32
+ */
+#ifndef ENCH1_INPUT_SWAP_8_RGB32
+#define ENCH1_INPUT_SWAP_8_RGB32                  0
+#endif
+
+/* ENCH1_OUTPUT_SWAP_XX define the byte endianess of the ASIC output data.
+ * This MUST be configured to be the same as the native system endianess,
+ * because the control software relies on system endianess when reading
+ * the data from the memory. */
+
+/* The output data's 32-bit swap: 0 or 1
+ * This defines the 32-bit endianess of the ASIC output data
+ * 1 = 64-bit endianess */
+#ifndef ENCH1_OUTPUT_SWAP_32
+#define ENCH1_OUTPUT_SWAP_32                      1
+#endif
+
+/* The output data's 16-bit swap: 0 or 1
+ * This defines the 16-bit endianess of the ASIC output data.
+ */
+#ifndef ENCH1_OUTPUT_SWAP_16
+#define ENCH1_OUTPUT_SWAP_16                      1
+#endif
+
+/* The output data's 8-bit swap: 0 or 1
+ * This defines the byte endianess of the ASIC output data.
+ */
+#ifndef ENCH1_OUTPUT_SWAP_8
+#define ENCH1_OUTPUT_SWAP_8                       1
+#endif
+
+/* ASIC interrupt enable.
+ * This enables/disables the ASIC to generate interrupts
+ * If this is '1', the EWL must poll the registers to find out
+ * when the HW is ready.
+ */
+#ifndef ENCH1_IRQ_DISABLE
+#define ENCH1_IRQ_DISABLE                         0
+#endif
+
+/* ASIC bus interface configuration values                  */
+/* DO NOT CHANGE IF NOT FAMILIAR WITH THE CONCEPTS INVOLVED */
+
+/* Burst length. This sets the maximum length of a single ASIC burst in addresses.
+ * Allowed values are:
+ *          AHB {0, 4, 8, 16} ( 0 means incremental burst type INCR)
+ *          OCP [1,63]
+ *          AXI [1,16]
+ */
+#ifndef ENCH1_BURST_LENGTH
+#define ENCH1_BURST_LENGTH                               16
+#endif
+
+/* SCMD burst mode disable                                                    */
+/* 0 - enable SCMD burst mode                                                 */
+/* 1 - disable SCMD burst mode                                                */
+#ifndef ENCH1_BURST_SCMD_DISABLE
+#define ENCH1_BURST_SCMD_DISABLE                         0
+#endif
+
+/* INCR type burst mode                                                       */
+/* 0 - enable INCR type bursts                                                */
+/* 1 - disable INCR type and use SINGLE instead                               */
+#ifndef ENCH1_BURST_INCR_TYPE_ENABLED
+#define ENCH1_BURST_INCR_TYPE_ENABLED                    0
+#endif
+
+/* Data discard mode. When enabled read bursts of length 2 or 3 are converted */
+/* to BURST4 and  useless data is discarded. Otherwise use INCR type for that */
+/* kind  of read bursts */
+/* 0 - disable data discard                                                   */
+/* 1 - enable data discard                                                    */
+#ifndef ENCH1_BURST_DATA_DISCARD_ENABLED
+#define ENCH1_BURST_DATA_DISCARD_ENABLED                 0
+#endif
+
+/* AXI bus read and write ID values used by HW. 0 - 255 */
+#ifndef ENCH1_AXI_READ_ID
+#define ENCH1_AXI_READ_ID                                0
+#endif
+
+#ifndef ENCH1_AXI_WRITE_ID
+#define ENCH1_AXI_WRITE_ID                               0
+#endif
+
+/* End of "ASIC bus interface configuration values"                           */
+
+/* ASIC internal clock gating control. 0 - disabled, 1 - enabled              */
+#ifndef ENCH1_ASIC_CLOCK_GATING_ENABLED
+#define ENCH1_ASIC_CLOCK_GATING_ENABLED                  0
+#endif
+
+/* ASIC timeout interrupt enable/disable                                      */
+#ifndef ENCH1_TIMEOUT_INTERRUPT
+#define ENCH1_TIMEOUT_INTERRUPT                          1
+#endif
+
+/* H.264 slice ready interrupt enable/disable. When enabled the HW will raise */
+/* interrupt after every completed slice creating several IRQ per frame.      */
+/* When disabled the HW will raise interrupt only when the frame encoding is  */
+/* finished.                                                                  */
+#ifndef ENCH1_SLICE_READY_INTERRUPT
+#define ENCH1_SLICE_READY_INTERRUPT                      1
+#endif
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/enccommon.h b/libv4l-rockchip/libvpu/vp8_enc/enccommon.h
new file mode 100644
index 0000000..dc9eeb5
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/enccommon.h
@@ -0,0 +1,43 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _ENC_COMMON_H_
+#define _ENC_COMMON_H_
+
+#define ASSERT(expr)
+#define COMMENT(x)
+#define TRACE_BIT_STREAM(v,n)
+
+typedef enum
+{
+  ENCHW_NOK = -1,
+  ENCHW_OK = 0
+} bool_e;
+
+typedef enum
+{
+  ENCHW_NO = 0,
+  ENCHW_YES = 1
+} true_e;
+
+/* General tools */
+#define ABS(x)          ((x) < (0) ? -(x) : (x))
+#define MAX(a, b)       ((a) > (b) ?  (a) : (b))
+#define MIN(a, b)       ((a) < (b) ?  (a) : (b))
+#define SIGN(a)         ((a) < (0) ? (-1) : (1))
+#define CLIP3(v, min, max)  ((v) < (min) ? (min) : ((v) > (max) ? (max) : (v)))
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/encswhwregisters.h b/libv4l-rockchip/libvpu/vp8_enc/encswhwregisters.h
new file mode 100644
index 0000000..5b1b35f
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/encswhwregisters.h
@@ -0,0 +1,527 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _ENC_SWHWREGISTERS_H_
+#define _ENC_SWHWREGISTERS_H_
+
+#include <stdint.h>
+
+#define ASIC_SWREG_AMOUNT               (0x28C/4+1)
+
+#define ASIC_INPUT_YUV420PLANAR         0x00
+#define ASIC_INPUT_YUV420SEMIPLANAR     0x01
+#define ASIC_INPUT_YUYV422INTERLEAVED   0x02
+#define ASIC_INPUT_UYVY422INTERLEAVED   0x03
+#define ASIC_INPUT_RGB565               0x04
+#define ASIC_INPUT_RGB555               0x05
+#define ASIC_INPUT_RGB444               0x06
+#define ASIC_INPUT_RGB888               0x07
+#define ASIC_INPUT_RGB101010            0x08
+
+/* Bytes of external memory for VP8 counters for probability updates,
+ * 252 counters for dct coeff probs, 1 for skipped, 1 for intra type and
+ * 2 * 11 for mv probs, each counter 2 bytes */
+#define ASIC_VP8_PROB_COUNT_SIZE            (244*2)
+#define ASIC_VP8_PROB_COUNT_MODE_OFFSET     220
+#define ASIC_VP8_PROB_COUNT_MV_OFFSET       222
+
+/* HW Register field names */
+typedef enum {
+  HEncProductID,
+  HEncProductMajor,
+  HEncProductMinor,
+  HEncProductBuild,
+
+  HEncIRQSliceReady,
+  HEncIRQTimeout,
+  HEncIRQBuffer,
+  HEncIRQReset,
+  HEncIRQBusError,
+  HEncIRQFrameReady,
+  HEncIRQDisable,
+  HEncIRQ,
+
+  HEncAXIWriteID,
+  HEncAXIReadID,
+  HEncOutputSwap16,
+  HEncInputSwap16,
+  HEncBurstLength,
+  HEncBurstDisable,
+  HEncBurstIncr,
+  HEncDataDiscard,
+  HEncClockGating,
+  HEncOutputSwap32,
+  HEncInputSwap32,
+  HEncOutputSwap8,
+  HEncInputSwap8,
+
+  HEncTestCounter,
+  HEncTestLength,
+  HEncTestMem,
+  HEncTestReg,
+  HEncTestIrq,
+
+  HEncBaseStream,
+  HEncBaseControl,
+  HEncBaseRefLum,
+  HEncBaseRefChr,
+  HEncBaseRecLum,
+  HEncBaseRecChr,
+  HEncBaseInLum,
+  HEncBaseInCb,
+  HEncBaseInCr,
+
+  HEncIntTimeout,
+  HEncMvWrite,
+  HEncNalSizeWrite,
+  HEncIntSliceReady,
+  HEncWidth,
+  HEncHeight,
+  HEncRecWriteDisable,
+  HEncPictureType,
+  HEncEncodingMode,
+  HEncEnable,
+
+  HEncChrOffset,
+  HEncLumOffset,
+  HEncRowLength,
+  HEncXFill,
+  HEncYFill,
+  HEncInputFormat,
+  HEncInputRot,
+
+  HEncBaseRefLum2,
+  HEncBaseRefChr2,
+  HEncPicInitQp,
+  HEncSliceAlpha,
+  HEncSliceBeta,
+  HEncChromaQp,
+  HEncIdrPicId,
+  HEncConstrIP,
+  HEncPPSID,
+  HEncIPPrevModeFavor,
+  HEncFrameNum,
+
+  HEncDeblocking,
+  HEncSliceSize,
+  HEncDisableQPMV,
+  HEncTransform8x8,
+  HEncCabacInitIdc,
+  HEncCabacEnable,
+  HEncInter4Restrict,
+  HEncStreamMode,
+  HEncIPIntra16Favor,
+
+  HEncSplitMv,
+  HEncDMVPenalty1p,
+  HEncDMVPenalty4p,
+  HEncDMVPenaltyQp,
+
+  HEncJpegMode,
+  HEncJpegSlice,
+  HEncJpegRSTInt,
+  HEncJpegRST,
+  HEncSplitPenalty16x8,
+  HEncSplitPenalty8x8,
+  HEncSplitPenalty8x4,
+
+  HEncSkipPenalty,
+  HEncNumSlicesReady,
+  HEncInterFavor,
+
+  HEncStrmHdrRem1,
+  HEncStrmHdrRem2,
+
+  HEncStrmBufLimit,
+
+  HEncMadQpDelta,
+  HEncMadThreshold,
+  HEncQpSum,
+
+  HEncQp,
+  HEncMaxQp,
+  HEncMinQp,
+  HEncCPDist,
+
+  HEncCP1WordTarget,
+  HEncCP2WordTarget,
+  HEncCP3WordTarget,
+  HEncCP4WordTarget,
+  HEncCP5WordTarget,
+  HEncCP6WordTarget,
+  HEncCP7WordTarget,
+  HEncCP8WordTarget,
+  HEncCP9WordTarget,
+  HEncCP10WordTarget,
+
+  HEncCPWordError1,
+  HEncCPWordError2,
+  HEncCPWordError3,
+  HEncCPWordError4,
+  HEncCPWordError5,
+  HEncCPWordError6,
+
+  HEncCPDeltaQp1,
+  HEncCPDeltaQp2,
+  HEncCPDeltaQp3,
+  HEncCPDeltaQp4,
+  HEncCPDeltaQp5,
+  HEncCPDeltaQp6,
+  HEncCPDeltaQp7,
+
+  HEncVp8Y1QuantDc,
+  HEncVp8Y1ZbinDc,
+  HEncVp8Y1RoundDc,
+  HEncVp8Y1QuantAc,
+  HEncVp8Y1ZbinAc,
+  HEncVp8Y1RoundAc,
+  HEncVp8Y2QuantDc,
+  HEncVp8Y2ZbinDc,
+  HEncVp8Y2RoundDc,
+  HEncVp8Y2QuantAc,
+  HEncVp8Y2ZbinAc,
+  HEncVp8Y2RoundAc,
+  HEncVp8ChQuantDc,
+  HEncVp8ChZbinDc,
+  HEncVp8ChRoundDc,
+  HEncVp8ChQuantAc,
+  HEncVp8ChZbinAc,
+  HEncVp8ChRoundAc,
+
+  HEncVp8Y1DequantDc,
+  HEncVp8Y1DequantAc,
+  HEncVp8Y2DequantDc,
+  HEncVp8MvRefIdx,
+  HEncVp8Y2DequantAc,
+  HEncVp8ChDequantDc,
+  HEncVp8ChDequantAc,
+  HEncVp8MvRefIdx2,
+  HEncVp8Ref2Enable,
+  HEncVp8SegmentEnable,
+  HEncVp8SegmentMapUpdate,
+
+  HEncVp8BoolEncValue,
+  HEncVp8GoldenPenalty,
+  HEncVp8FilterSharpness,
+  HEncVp8FilterLevel,
+  HEncVp8DctPartitionCount,
+  HEncVp8BoolEncValueBits,
+  HEncVp8BoolEncRange,
+
+  HEncStartOffset,
+  HEncRlcSum,
+  HEncMadCount,
+  HEncMbCount,
+
+  HEncBaseNextLum,
+
+  HEncStabMode,
+  HEncStabMinimum,
+  HEncStabMotionSum,
+  HEncStabGmvX,
+  HEncStabMatrix1,
+  HEncStabGmvY,
+  HEncStabMatrix2,
+  HEncStabMatrix3,
+  HEncStabMatrix4,
+  HEncStabMatrix5,
+  HEncStabMatrix6,
+  HEncStabMatrix7,
+  HEncStabMatrix8,
+  HEncStabMatrix9,
+
+  HEncBaseCabacCtx,
+  HEncBaseMvWrite,
+
+  HEncRGBCoeffA,
+  HEncRGBCoeffB,
+  HEncRGBCoeffC,
+  HEncRGBCoeffE,
+  HEncRGBCoeffF,
+
+  HEncRMaskMSB,
+  HEncGMaskMSB,
+  HEncBMaskMSB,
+
+  HEncIntraAreaLeft,
+  HEncIntraAreaRight,
+  HEncIntraAreaTop,
+  HEncIntraAreaBottom,
+
+  HEncCirStart,
+  HEncCirInterval,
+
+  HEncIntraSliceMap1,
+  HEncIntraSliceMap2,
+  HEncIntraSliceMap3,
+  HEncBasePartition1,
+  HEncBasePartition2,
+  HEncBaseVp8ProbCount,
+
+  HEncRoi1Left,
+  HEncRoi1Right,
+  HEncRoi1Top,
+  HEncRoi1Bottom,
+
+  HEncRoi2Left,
+  HEncRoi2Right,
+  HEncRoi2Top,
+  HEncRoi2Bottom,
+
+  HEncRoi1DeltaQp,
+  HEncRoi2DeltaQp,
+  HEncZeroMvFavor,
+  HEncSplitPenalty4x4,
+
+  HEncMvcPriorityId,
+  HEncMvcViewId,
+  HEncMvcTemporalId,
+  HEncMvcAnchorPicFlag,
+  HEncMvcInterViewFlag,
+
+  HEncHWTiledSupport,
+  HEncHWSearchArea,
+  HEncHWRgbSupport,
+  HEncHWH264Support,
+  HEncHWVp8Support,
+  HEncHWJpegSupport,
+  HEncHWStabSupport,
+  HEncHWBus,
+  HEncHWSynthesisLan,
+  HEncHWBusWidth,
+  HEncHWMaxVideoWidth,
+
+  HEncJpegQuantLuma1,
+  HEncJpegQuantLuma2,
+  HEncJpegQuantLuma3,
+  HEncJpegQuantLuma4,
+  HEncJpegQuantLuma5,
+  HEncJpegQuantLuma6,
+  HEncJpegQuantLuma7,
+  HEncJpegQuantLuma8,
+  HEncJpegQuantLuma9,
+  HEncJpegQuantLuma10,
+  HEncJpegQuantLuma11,
+  HEncJpegQuantLuma12,
+  HEncJpegQuantLuma13,
+  HEncJpegQuantLuma14,
+  HEncJpegQuantLuma15,
+  HEncJpegQuantLuma16,
+
+  HEncJpegQuantChroma1,
+  HEncJpegQuantChroma2,
+  HEncJpegQuantChroma3,
+  HEncJpegQuantChroma4,
+  HEncJpegQuantChroma5,
+  HEncJpegQuantChroma6,
+  HEncJpegQuantChroma7,
+  HEncJpegQuantChroma8,
+  HEncJpegQuantChroma9,
+  HEncJpegQuantChroma10,
+  HEncJpegQuantChroma11,
+  HEncJpegQuantChroma12,
+  HEncJpegQuantChroma13,
+  HEncJpegQuantChroma14,
+  HEncJpegQuantChroma15,
+  HEncJpegQuantChroma16,
+
+  /* VP8 penalty registers */
+  HEncVp8Mode0Penalty,
+  HEncVp8Mode1Penalty,
+  HEncVp8Mode2Penalty,
+  HEncVp8Mode3Penalty,
+  HEncVp8Bmode0Penalty,
+  HEncVp8Bmode1Penalty,
+  HEncVp8Bmode2Penalty,
+  HEncVp8Bmode3Penalty,
+  HEncVp8Bmode4Penalty,
+  HEncVp8Bmode5Penalty,
+  HEncVp8Bmode6Penalty,
+  HEncVp8Bmode7Penalty,
+  HEncVp8Bmode8Penalty,
+  HEncVp8Bmode9Penalty,
+  HEncBaseVp8SegmentMap,
+  HEncVp8Seg1Y1QuantDc,
+  HEncVp8Seg1Y1ZbinDc,
+  HEncVp8Seg1Y1RoundDc,
+  HEncVp8Seg1Y1QuantAc,
+  HEncVp8Seg1Y1ZbinAc,
+  HEncVp8Seg1Y1RoundAc,
+  HEncVp8Seg1Y2QuantDc,
+  HEncVp8Seg1Y2ZbinDc,
+  HEncVp8Seg1Y2RoundDc,
+  HEncVp8Seg1Y2QuantAc,
+  HEncVp8Seg1Y2ZbinAc,
+  HEncVp8Seg1Y2RoundAc,
+  HEncVp8Seg1ChQuantDc,
+  HEncVp8Seg1ChZbinDc,
+  HEncVp8Seg1ChRoundDc,
+  HEncVp8Seg1ChQuantAc,
+  HEncVp8Seg1ChZbinAc,
+  HEncVp8Seg1ChRoundAc,
+  HEncVp8Seg1Y1DequantDc,
+  HEncVp8Seg1Y1DequantAc,
+  HEncVp8Seg1Y2DequantDc,
+  HEncVp8Seg1Y2DequantAc,
+  HEncVp8Seg1ChDequantDc,
+  HEncVp8Seg1ChDequantAc,
+  HEncVp8Seg1FilterLevel,
+  HEncVp8Seg2Y1QuantDc,
+  HEncVp8Seg2Y1ZbinDc,
+  HEncVp8Seg2Y1RoundDc,
+  HEncVp8Seg2Y1QuantAc,
+  HEncVp8Seg2Y1ZbinAc,
+  HEncVp8Seg2Y1RoundAc,
+  HEncVp8Seg2Y2QuantDc,
+  HEncVp8Seg2Y2ZbinDc,
+  HEncVp8Seg2Y2RoundDc,
+  HEncVp8Seg2Y2QuantAc,
+  HEncVp8Seg2Y2ZbinAc,
+  HEncVp8Seg2Y2RoundAc,
+  HEncVp8Seg2ChQuantDc,
+  HEncVp8Seg2ChZbinDc,
+  HEncVp8Seg2ChRoundDc,
+  HEncVp8Seg2ChQuantAc,
+  HEncVp8Seg2ChZbinAc,
+  HEncVp8Seg2ChRoundAc,
+  HEncVp8Seg2Y1DequantDc,
+  HEncVp8Seg2Y1DequantAc,
+  HEncVp8Seg2Y2DequantDc,
+  HEncVp8Seg2Y2DequantAc,
+  HEncVp8Seg2ChDequantDc,
+  HEncVp8Seg2ChDequantAc,
+  HEncVp8Seg2FilterLevel,
+  HEncVp8Seg3Y1QuantDc,
+  HEncVp8Seg3Y1ZbinDc,
+  HEncVp8Seg3Y1RoundDc,
+  HEncVp8Seg3Y1QuantAc,
+  HEncVp8Seg3Y1ZbinAc,
+  HEncVp8Seg3Y1RoundAc,
+  HEncVp8Seg3Y2QuantDc,
+  HEncVp8Seg3Y2ZbinDc,
+  HEncVp8Seg3Y2RoundDc,
+  HEncVp8Seg3Y2QuantAc,
+  HEncVp8Seg3Y2ZbinAc,
+  HEncVp8Seg3Y2RoundAc,
+  HEncVp8Seg3ChQuantDc,
+  HEncVp8Seg3ChZbinDc,
+  HEncVp8Seg3ChRoundDc,
+  HEncVp8Seg3ChQuantAc,
+  HEncVp8Seg3ChZbinAc,
+  HEncVp8Seg3ChRoundAc,
+  HEncVp8Seg3Y1DequantDc,
+  HEncVp8Seg3Y1DequantAc,
+  HEncVp8Seg3Y2DequantDc,
+  HEncVp8Seg3Y2DequantAc,
+  HEncVp8Seg3ChDequantDc,
+  HEncVp8Seg3ChDequantAc,
+  HEncVp8Seg3FilterLevel,
+
+  HEncDmvPenalty1,
+  HEncDmvPenalty2,
+  HEncDmvPenalty3,
+  HEncDmvPenalty4,
+  HEncDmvPenalty5,
+  HEncDmvPenalty6,
+  HEncDmvPenalty7,
+  HEncDmvPenalty8,
+  HEncDmvPenalty9,
+  HEncDmvPenalty10,
+  HEncDmvPenalty11,
+  HEncDmvPenalty12,
+  HEncDmvPenalty13,
+  HEncDmvPenalty14,
+  HEncDmvPenalty15,
+  HEncDmvPenalty16,
+  HEncDmvPenalty17,
+  HEncDmvPenalty18,
+  HEncDmvPenalty19,
+  HEncDmvPenalty20,
+  HEncDmvPenalty21,
+  HEncDmvPenalty22,
+  HEncDmvPenalty23,
+  HEncDmvPenalty24,
+  HEncDmvPenalty25,
+  HEncDmvPenalty26,
+  HEncDmvPenalty27,
+  HEncDmvPenalty28,
+  HEncDmvPenalty29,
+  HEncDmvPenalty30,
+  HEncDmvPenalty31,
+  HEncDmvPenalty32,
+
+  HEncDmvQpelPenalty1,
+  HEncDmvQpelPenalty2,
+  HEncDmvQpelPenalty3,
+  HEncDmvQpelPenalty4,
+  HEncDmvQpelPenalty5,
+  HEncDmvQpelPenalty6,
+  HEncDmvQpelPenalty7,
+  HEncDmvQpelPenalty8,
+  HEncDmvQpelPenalty9,
+  HEncDmvQpelPenalty10,
+  HEncDmvQpelPenalty11,
+  HEncDmvQpelPenalty12,
+  HEncDmvQpelPenalty13,
+  HEncDmvQpelPenalty14,
+  HEncDmvQpelPenalty15,
+  HEncDmvQpelPenalty16,
+  HEncDmvQpelPenalty17,
+  HEncDmvQpelPenalty18,
+  HEncDmvQpelPenalty19,
+  HEncDmvQpelPenalty20,
+  HEncDmvQpelPenalty21,
+  HEncDmvQpelPenalty22,
+  HEncDmvQpelPenalty23,
+  HEncDmvQpelPenalty24,
+  HEncDmvQpelPenalty25,
+  HEncDmvQpelPenalty26,
+  HEncDmvQpelPenalty27,
+  HEncDmvQpelPenalty28,
+  HEncDmvQpelPenalty29,
+  HEncDmvQpelPenalty30,
+  HEncDmvQpelPenalty31,
+  HEncDmvQpelPenalty32,
+
+  HEncVp8CostInter,
+  HEncVp8DmvCostConst,
+  HEncVp8CostGoldenRef,
+
+  /* VP8 loop filter deltas */
+  HEncVp8LfRefDelta0,
+  HEncVp8LfRefDelta1,
+  HEncVp8LfRefDelta2,
+  HEncVp8LfRefDelta3,
+  HEncVp8LfModeDelta0,
+  HEncVp8LfModeDelta1,
+  HEncVp8LfModeDelta2,
+  HEncVp8LfModeDelta3,
+
+  HEncRegisterAmount
+
+} regName;
+
+/* HW Register field descriptions */
+typedef struct {
+  int32_t name;               /* Register name and index  */
+  int32_t base;               /* Register base address  */
+  uint32_t mask;              /* Bitmask for this field */
+  int32_t lsb;                /* LSB for this field [31..0] */
+  int32_t trace;              /* Enable/disable writing in swreg_params.trc */
+  char* description;          /* Field description */
+} regField_s;
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c b/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c
new file mode 100644
index 0000000..ed3cc6e
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.c
@@ -0,0 +1,735 @@
+/* Copyright 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "rk_vp8encapi.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "enccommon.h"
+#include "vp8encapi.h"
+#include "vp8instance.h"
+#include "libvpu/rk_vepu_debug.h"
+#include "libvpu/vp8_enc/vpu_mem.h"
+
+/* Value for parameter to use API default */
+#define DEFAULT -100
+
+/* Intermediate Video File Format */
+#define IVF_HDR_BYTES       32
+#define IVF_FRM_BYTES       12
+
+#define PRIVATE_DATA_HEADER_SIZE  192
+
+static int rk_vp8_encoder_after_encode(struct rk_vp8_encoder *enc,
+                                      uint32_t outputStreamSize);
+static int rk_vp8_encoder_before_encode(struct rk_vp8_encoder *enc);
+static int rk_vp8_encoder_init(struct rk_vp8_encoder *enc,
+                               struct rk_vepu_init_param *enc_parms);
+static void rk_vp8_encoder_genpriv(struct rk_vp8_encoder *enc);
+static void rk_vp8_encoder_getpriv(struct rk_vp8_encoder *enc,
+                                   uint8_t **priv_data, uint32_t *size);
+static void rk_vp8_encoder_setconfig(struct rk_vp8_encoder *enc,
+                                     struct rk_vepu_runtime_param *param);
+static void rk_vp8_encoder_store_priv_data(struct rk_vp8_encoder *enc,
+                                          uint8_t *priv, uint32_t size,
+                                          int32_t type);
+static int rk_vp8_encoder_updatepriv(struct rk_vp8_encoder *enc,
+                                     void *config, uint32_t cfglen);
+static int OpenEncoder(EncoderParameters* cml, VP8EncInst* pEnc);
+static void CloseEncoder(VP8EncInst encoder);
+static void MaAddFrame(ma_s* ma, int32_t frameSizeBits);
+static int32_t Ma(ma_s* ma);
+static void SetDefaultParameter(EncoderParameters* tb);
+
+
+static int rk_vp8_encoder_init(struct rk_vp8_encoder *enc,
+                              struct rk_vepu_init_param *enc_parms) {
+  EncoderParameters* cml = &enc->cmdl;
+
+  SetDefaultParameter(cml);
+
+  /* modify parameters using input encode setting */
+  cml->lumWidthSrc = enc_parms->width;
+  cml->lumHeightSrc = enc_parms->height;
+  cml->width = enc_parms->width;
+  cml->height = enc_parms->height;
+
+  switch (enc_parms->input_format) {
+    case V4L2_PIX_FMT_YUV420:
+    case V4L2_PIX_FMT_YUV420M:
+      cml->inputFormat = VP8ENC_YUV420_PLANAR;
+      break;
+    case V4L2_PIX_FMT_NV12:
+    case V4L2_PIX_FMT_NV12M:
+      cml->inputFormat = VP8ENC_YUV420_SEMIPLANAR;
+      break;
+    case V4L2_PIX_FMT_YUYV:
+      cml->inputFormat = VP8ENC_YUV422_INTERLEAVED_YUYV;
+      break;
+    case V4L2_PIX_FMT_UYVY:
+      cml->inputFormat = VP8ENC_YUV422_INTERLEAVED_UYVY;
+      break;
+    default:
+      VPU_PLG_ERR("Unsupport format 0x%08x\n", enc_parms->input_format);
+      return -1;
+  }
+
+  /* Encoder initialization */
+  if (OpenEncoder(cml, &enc->encoder) != 0)
+    return -1;
+
+  /* First frame is always intra with zero time increment */
+  enc->encIn.codingType = VP8ENC_INTRA_FRAME;
+  enc->encIn.timeIncrement = 0;
+
+  enc->priv_data = (uint8_t *)calloc(1, 5487);
+  if (enc->priv_data == NULL) {
+    VPU_PLG_ERR("allocate private data buffer failed\n");
+    CloseEncoder(enc->encoder);
+    return -1;
+  }
+
+  enc->hdr_idx = 0;
+  enc->priv_offset = 0;
+  return 0;
+}
+
+static void rk_vp8_encoder_setconfig(struct rk_vp8_encoder *enc,
+                                    struct rk_vepu_runtime_param *param)
+{
+  int ret;
+  vp8Instance_s *pEncInst = (vp8Instance_s *)enc->encoder;
+  VP8EncRateCtrl rc;
+  pEncInst->encStatus = VP8ENCSTAT_INIT;
+  VP8EncGetRateCtrl(enc->encoder, &rc);
+  if (param->bitrate != 0) {
+    rc.bitPerSecond = param->bitrate;
+    rc.pictureRc = ENCHW_YES;
+    rc.qpHdr = -1;
+  }
+
+  if (param->framerate_denom != 0 && param->framerate_numer != 0) {
+    pEncInst->rateControl.outRateNum = param->framerate_numer;
+    pEncInst->rateControl.outRateDenom = param->framerate_denom;
+    enc->cmdl.outputRateDenom = param->framerate_denom;
+    enc->cmdl.outputRateNumer = param->framerate_numer;
+  }
+
+  ret = VP8EncSetRateCtrl(enc->encoder, &rc);
+  if (ret < 0) {
+    VPU_PLG_ERR("failed to set rate control\n");
+  }
+
+  VPU_PLG_INF("Reset bitrate calculation parameters\n");
+  enc->cmdl.streamSize = 0;
+  enc->cmdl.frameCntTotal = 0;
+
+  if (param->keyframe_request) {
+    enc->encIn.codingType =
+      param->keyframe_value ? VP8ENC_INTRA_FRAME : VP8ENC_PREDICTED_FRAME;
+  }
+}
+
+static int rk_vp8_encoder_after_encode(struct rk_vp8_encoder *enc,
+                                      uint32_t outputStreamSize) {
+  VP8EncRet ret;
+  EncoderParameters* cml = &enc->cmdl;
+
+  ret = VP8EncStrmEncodeResult(enc->encoder, &cml->encOut, outputStreamSize);
+
+  VP8EncGetRateCtrl(enc->encoder, &cml->rc);
+
+  cml->streamSize += cml->encOut.frameSize;
+
+  MaAddFrame(&cml->ma, cml->encOut.frameSize * 8);
+
+  enc->encIn.timeIncrement = cml->outputRateDenom;
+
+  cml->frameCnt++;
+  cml->frameCntTotal++;
+
+  if (cml->encOut.codingType != VP8ENC_NOTCODED_FRAME) {
+    enc->intraPeriodCnt++;
+    enc->codedFrameCnt++;
+  }
+
+  /* calculate the bitrate using output stream size. */
+  if ((cml->frameCntTotal + 1) && cml->outputRateDenom) {
+    /* Using 64-bits to avoid overflow */
+    uint64_t tmp = cml->streamSize / (cml->frameCntTotal + 1);
+    tmp *= (uint32_t)cml->outputRateNumer;
+
+    cml->bitrate = (uint32_t)(8 * (tmp / (uint32_t)cml->outputRateDenom));
+  }
+
+  /* Print information about encoded frames */
+  VPU_PLG_INF("\nBitrate target %d bps, actual %d bps (%d%%).\n",
+              cml->rc.bitPerSecond, cml->bitrate,
+              (cml->rc.bitPerSecond) ?
+              cml->bitrate * 100 / cml->rc.bitPerSecond : 0);
+  VPU_PLG_INF("Total of %llu frames processed, %d frames encoded, %d bytes.\n",
+              cml->frameCntTotal, enc->codedFrameCnt, cml->streamSize);
+
+  if (cml->psnrCnt)
+    VPU_PLG_INF("Average PSNR %d.%02d\n",
+                (cml->psnrSum / cml->psnrCnt) / 100,
+                (cml->psnrSum / cml->psnrCnt) % 100);
+
+  return ret;
+}
+
+static int rk_vp8_encoder_before_encode(struct rk_vp8_encoder *enc) {
+  int ret = 0;
+  EncoderParameters* cml = &enc->cmdl;
+
+  cml->ma.pos = cml->ma.count = 0;
+  cml->ma.frameRateNumer = cml->outputRateNumer;
+  cml->ma.frameRateDenom = cml->outputRateDenom;
+  if (cml->outputRateDenom)
+    cml->ma.length = MAX(1, MIN(cml->outputRateNumer / cml->outputRateDenom,
+                                MOVING_AVERAGE_FRAMES));
+  else
+    cml->ma.length = MOVING_AVERAGE_FRAMES;
+
+  /* Source Image Size */
+  if (cml->inputFormat <= 1) {
+    enc->src_img_size = cml->lumWidthSrc * cml->lumHeightSrc +
+        2 * (((cml->lumWidthSrc + 1) >> 1) *
+             ((cml->lumHeightSrc + 1) >> 1));
+  } else if ((cml->inputFormat <= 9) || (cml->inputFormat == 14)) {
+    /* 422 YUV or 16-bit RGB */
+    enc->src_img_size = cml->lumWidthSrc * cml->lumHeightSrc * 2;
+  } else {
+    /* 32-bit RGB */
+    enc->src_img_size = cml->lumWidthSrc * cml->lumHeightSrc * 4;
+  }
+
+  if (VP8EncGetRateCtrl(enc->encoder, &cml->rc) < 0) {
+    VPU_PLG_ERR("VP8 Get Rate Control failed\n");
+    return -1;
+  }
+
+  /* Select frame type */
+  if ((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;
+
+  /* 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) {
+    VPU_PLG_ERR("Generate Encoder configuration failed\n");
+    return -1;
+  }
+
+  VP8EncGetFrameHeader(enc->encoder, (uint8_t**)&enc->rk_payloads[0],
+                       &enc->rk_payload_sizes[0]);
+  VP8EncGetRegs(enc->encoder, (uint32_t**)&enc->rk_payloads[1],
+                &enc->rk_payload_sizes[1]);
+  rk_vp8_encoder_getpriv(
+      enc, (uint8_t**)&enc->rk_payloads[2], &enc->rk_payload_sizes[2]);
+  return 0;
+}
+
+static void rk_vp8_encoder_store_priv_data(struct rk_vp8_encoder *enc,
+                                          uint8_t *priv, uint32_t size,
+                                          int32_t type) {
+  uint32_t* hdr = (uint32_t*)enc->priv_data;
+  uint8_t* data = (uint8_t*)enc->priv_data + PRIVATE_DATA_HEADER_SIZE;
+
+  VPU_PLG_DBG("store type %02x, size %02x\n", type, size);
+  enc->priv_offset = (enc->priv_offset + 7) & (~7);
+
+  hdr[enc->hdr_idx++] = type;
+  hdr[enc->hdr_idx++] = size;
+  hdr[enc->hdr_idx++] = enc->priv_offset;
+
+  memcpy(data + enc->priv_offset, priv, size);
+  enc->priv_offset += size;
+}
+
+static void rk_vp8_encoder_genpriv(struct rk_vp8_encoder *enc) {
+  uint8_t *priv;
+  uint32_t size;
+
+  enc->hdr_idx = 0;
+  enc->priv_offset = 0;
+  VP8EncGetCabacCtx(enc->encoder, &priv, &size);
+  rk_vp8_encoder_store_priv_data(enc, priv, size, VP8E_PRIVATE_DATA_TYPE_CABAC);
+  VP8EncGetSegmentMap(enc->encoder, &priv, &size);
+  rk_vp8_encoder_store_priv_data(enc, priv, size, VP8E_PRIVATE_DATA_TYPE_SEGMAP);
+  rk_vp8_encoder_store_priv_data(enc, NULL, 0, VP8E_PRIVATE_DATA_TYPE_END);
+}
+
+static void rk_vp8_encoder_getpriv(struct rk_vp8_encoder *enc,
+                                 uint8_t **priv_data, uint32_t *size) {
+  rk_vp8_encoder_genpriv(enc);
+  *priv_data = enc->priv_data;
+  *size = 5487;
+}
+
+static int rk_vp8_encoder_updatepriv(struct rk_vp8_encoder *enc,
+                                    void *config, uint32_t cfglen) {
+  return VP8EncSetProbCnt(enc->encoder, (uint8_t *)config, cfglen);
+}
+
+static void rk_vp8_encoder_deinit(struct rk_vp8_encoder *enc) {
+  free(enc->priv_data);
+  enc->priv_data = NULL;
+  CloseEncoder(enc->encoder);
+}
+
+/*----------------------------------------------------------------------------
+
+    OpenEncoder
+        Create and configure an encoder instance.
+
+    Params:
+        cml     - processed command line options
+        pEnc    - place where to save the new encoder instance
+    Return:
+        0   - for success
+        -1  - error
+
+-----------------------------------------------------------------------------*/
+static int OpenEncoder(EncoderParameters* cml, VP8EncInst* pEnc) {
+  VP8EncRet ret;
+  VP8EncConfig cfg;
+  VP8EncCodingCtrl codingCfg;
+  VP8EncRateCtrl rcCfg;
+
+  VP8EncInst encoder;
+
+  /* input resolution == encoded resolution if not defined */
+  if (cml->width == DEFAULT)
+    cml->width = cml->lumWidthSrc;
+  if (cml->height == DEFAULT)
+    cml->height = cml->lumHeightSrc;
+
+  if (cml->rotation) {
+    cfg.width = cml->height;
+    cfg.height = cml->width;
+  } else {
+    cfg.width = cml->width;
+    cfg.height = cml->height;
+  }
+
+  cfg.frameRateDenom = cml->outputRateDenom;
+  cfg.frameRateNum = cml->outputRateNumer;
+  cfg.refFrameAmount = cml->refFrameAmount;
+
+  VPU_PLG_DBG("Init config: size %dx%d   %d/%d fps  %d refFrames\n",
+         cfg.width, cfg.height, cfg.frameRateNum, cfg.frameRateDenom,
+         cfg.refFrameAmount);
+
+  if ((ret = VP8EncInit(&cfg, pEnc)) != VP8ENC_OK) {
+    VPU_PLG_ERR("VP8EncInit() failed. ret %d\n", ret);
+    return ret;
+  }
+
+  encoder = *pEnc;
+
+  /* Encoder setup: rate control */
+  if ((ret = VP8EncGetRateCtrl(encoder, &rcCfg)) != VP8ENC_OK) {
+    VPU_PLG_ERR("VP8EncGetRateCtrl() failed. ret %d\n", ret);
+    CloseEncoder(encoder);
+    return -1;
+  }
+
+  VPU_PLG_INF("Get rate control: qp=%2d [%2d..%2d] %8d bps,"
+              " picRc=%d gop=%d\n",
+              rcCfg.qpHdr, rcCfg.qpMin, rcCfg.qpMax, rcCfg.bitPerSecond,
+              rcCfg.pictureRc, rcCfg.bitrateWindow);
+
+  if (cml->picRc != DEFAULT)
+    rcCfg.pictureRc = cml->picRc;
+  if (cml->picSkip != DEFAULT)
+    rcCfg.pictureSkip = cml->picSkip;
+  if (cml->qpHdr != DEFAULT)
+    rcCfg.qpHdr = cml->qpHdr;
+  if (cml->qpMin != DEFAULT)
+    rcCfg.qpMin = cml->qpMin;
+  if (cml->qpMax != DEFAULT)
+    rcCfg.qpMax = cml->qpMax;
+  if (cml->bitPerSecond != DEFAULT)
+    rcCfg.bitPerSecond = cml->bitPerSecond;
+  if (cml->gopLength != DEFAULT)
+    rcCfg.bitrateWindow = cml->gopLength;
+  if (cml->intraQpDelta != DEFAULT)
+    rcCfg.intraQpDelta = cml->intraQpDelta;
+  if (cml->fixedIntraQp != DEFAULT)
+    rcCfg.fixedIntraQp = cml->fixedIntraQp;
+
+  VPU_PLG_DBG("Set rate control: qp=%2d [%2d..%2d] %8d bps,"
+         " picRc=%d gop=%d\n",
+         rcCfg.qpHdr, rcCfg.qpMin, rcCfg.qpMax, rcCfg.bitPerSecond,
+         rcCfg.pictureRc, rcCfg.bitrateWindow);
+
+  if ((ret = VP8EncSetRateCtrl(encoder, &rcCfg)) != VP8ENC_OK) {
+    VPU_PLG_ERR("VP8EncSetRateCtrl() failed. ret %d\n", ret);
+    CloseEncoder(encoder);
+    return -1;
+  }
+
+  /* Encoder setup: coding control */
+  if ((ret = VP8EncGetCodingCtrl(encoder, &codingCfg)) != VP8ENC_OK) {
+    VPU_PLG_ERR("VP8EncGetCodingCtrl() failed. ret %d\n", ret);
+    CloseEncoder(encoder);
+    return -1;
+  }
+
+  if (cml->dctPartitions != DEFAULT)
+    codingCfg.dctPartitions = cml->dctPartitions;
+  if (cml->errorResilient != DEFAULT)
+    codingCfg.errorResilient = cml->errorResilient;
+  if (cml->ipolFilter != DEFAULT)
+    codingCfg.interpolationFilter = cml->ipolFilter;
+  if (cml->filterType != DEFAULT)
+    codingCfg.filterType = cml->filterType;
+  if (cml->filterLevel != DEFAULT)
+    codingCfg.filterLevel = cml->filterLevel;
+  if (cml->filterSharpness != DEFAULT)
+    codingCfg.filterSharpness = cml->filterSharpness;
+  if (cml->quarterPixelMv != DEFAULT)
+    codingCfg.quarterPixelMv = cml->quarterPixelMv;
+  if (cml->splitMv != DEFAULT)
+    codingCfg.splitMv = cml->splitMv;
+
+  codingCfg.cirStart = cml->cirStart;
+  codingCfg.cirInterval = cml->cirInterval;
+  codingCfg.intraArea.enable = cml->intraAreaEnable;
+  codingCfg.intraArea.top = cml->intraAreaTop;
+  codingCfg.intraArea.left = cml->intraAreaLeft;
+  codingCfg.intraArea.bottom = cml->intraAreaBottom;
+  codingCfg.intraArea.right = cml->intraAreaRight;
+  codingCfg.roi1Area.enable = cml->roi1AreaEnable;
+  codingCfg.roi1Area.top = cml->roi1AreaTop;
+  codingCfg.roi1Area.left = cml->roi1AreaLeft;
+  codingCfg.roi1Area.bottom = cml->roi1AreaBottom;
+  codingCfg.roi1Area.right = cml->roi1AreaRight;
+  codingCfg.roi2Area.enable = cml->roi2AreaEnable;
+  codingCfg.roi2Area.top = cml->roi2AreaTop;
+  codingCfg.roi2Area.left = cml->roi2AreaLeft;
+  codingCfg.roi2Area.bottom = cml->roi2AreaBottom;
+  codingCfg.roi2Area.right = cml->roi2AreaRight;
+  codingCfg.roi1DeltaQp = cml->roi1DeltaQp;
+  codingCfg.roi2DeltaQp = cml->roi2DeltaQp;
+
+  VPU_PLG_DBG("Set coding control: dctPartitions=%d ipolFilter=%d"
+              " errorResilient=%d\n"
+              " filterType=%d filterLevel=%d filterSharpness=%d"
+              " quarterPixelMv=%d"
+              " splitMv=%d\n",
+              codingCfg.dctPartitions, codingCfg.interpolationFilter,
+              codingCfg.errorResilient, codingCfg.filterType,
+              codingCfg.filterLevel, codingCfg.filterSharpness,
+              codingCfg.quarterPixelMv, codingCfg.splitMv);
+
+  if (codingCfg.cirInterval)
+    VPU_PLG_DBG("  CIR: %d %d\n",
+                codingCfg.cirStart, codingCfg.cirInterval);
+
+  if (codingCfg.intraArea.enable)
+    VPU_PLG_DBG("  IntraArea: %dx%d-%dx%d\n",
+                codingCfg.intraArea.left, codingCfg.intraArea.top,
+                codingCfg.intraArea.right, codingCfg.intraArea.bottom);
+
+  if (codingCfg.roi1Area.enable)
+    VPU_PLG_DBG("  ROI 1: %d  %dx%d-%dx%d\n", codingCfg.roi1DeltaQp,
+                codingCfg.roi1Area.left, codingCfg.roi1Area.top,
+                codingCfg.roi1Area.right, codingCfg.roi1Area.bottom);
+
+  if (codingCfg.roi2Area.enable)
+    VPU_PLG_DBG("  ROI 2: %d  %dx%d-%dx%d\n", codingCfg.roi2DeltaQp,
+                codingCfg.roi2Area.left, codingCfg.roi2Area.top,
+                codingCfg.roi2Area.right, codingCfg.roi2Area.bottom);
+
+
+  if ((ret = VP8EncSetCodingCtrl(encoder, &codingCfg)) != VP8ENC_OK) {
+    VPU_PLG_ERR("VP8EncSetCodingCtrl() failed. ret %d\n", ret);
+    CloseEncoder(encoder);
+    return -1;
+  }
+
+  return 0;
+}
+
+/*------------------------------------------------------------------------------
+
+    CloseEncoder
+       Release an encoder insatnce.
+
+   Params:
+        encoder - the instance to be released
+------------------------------------------------------------------------------*/
+static void CloseEncoder(VP8EncInst encoder) {
+  VP8EncRet ret;
+
+  if ((ret = VP8EncRelease(encoder)) != VP8ENC_OK)
+    VPU_PLG_ERR("VP8EncRelease() failed. ret %d\n", ret);
+}
+
+void SetDefaultParameter(EncoderParameters* cml) {
+  memset(cml, 0, sizeof(EncoderParameters));
+
+  /* Default setting tries to parse resolution from file name */
+
+  /* Width of encoded output image */
+  cml->width              = 176;
+  /* Height of encoded output image */
+  cml->height             = 144;
+  /* Width of source image [176] */
+  cml->lumWidthSrc        = 176;
+  /* Height of source image [144] */
+  cml->lumHeightSrc       = 144;
+  /* Output image horizontal cropping offset [0] */
+  cml->horOffsetSrc       = 0;
+  /* Output image vertical cropping offset [0] */
+  cml->verOffsetSrc       = 0;
+
+  /* Input YUV format [1] */
+  cml->inputFormat        = VP8ENC_YUV420_SEMIPLANAR;
+  /* 1..1048575 Output picture rate numerator. [--inputRateNumer] */
+  cml->outputRateNumer    = 30;
+  /* 1..1048575 Output picture rate denominator. [--inputRateDenom] */
+  cml->outputRateDenom    = 1;
+  /* 1..3 Amount of buffered reference frames. [1] */
+  cml->refFrameAmount     = 1;
+
+  /* Default settings are get from API and not changed in testbench */
+
+  /* RGB to YCbCr color conversion type. [0] */
+  cml->colorConversion    = VP8ENC_RGBTOYUV_BT601;
+  /* Enable video stabilization or scene change detection. [0] */
+  cml->videoStab          = 0;
+  /* Rotate input image. [0] */
+  cml->rotation           = 0;
+
+  /* -1..127, Initial QP used for the first frame. [36] */
+  cml->qpHdr              = 36;
+  /* 0..127, Minimum frame header QP. [10] */
+  cml->qpMin              = 0;
+  /* 0..127, Maximum frame header QP. [51] */
+  cml->qpMax              = QINDEX_RANGE - 1;
+  /* 10000..60000000, Target bitrate for rate control [1000000] */
+  cml->bitPerSecond       = 1000000;
+  /* 0=OFF, 1=ON, Picture rate control enable. [1] */
+  cml->picRc              = 0;
+  /* 0=OFF, 1=ON, Picture skip rate control. [0] */
+  cml->picSkip            = 0;
+  /* -12..12, Intra QP delta. [0] */
+  cml->intraQpDelta       = 0;
+  /* 0..127, Fixed Intra QP, 0 = disabled. [0] */
+  cml->fixedIntraQp       = 0;
+
+  /* Intra picture rate in frames. [0] */
+  cml->intraPicRate       = 150;
+  /* 1..300, Group Of Pictures length in frames. [--intraPicRate] */
+  cml->gopLength          = cml->intraPicRate;
+  /* 0=1, 1=2, 2=4, 3=8, Amount of DCT partitions to create */
+  cml->dctPartitions      = 0;
+  /* Enable error resilient stream mode. [0] */
+  cml->errorResilient     = 0;
+  /* 0=Bicubic, 1=Bilinear, 2=None, Interpolation filter mode. [1] */
+  cml->ipolFilter         = 1;
+  /* 0=Normal, 1=Simple, Type of in-loop deblocking filter. [0] */
+  cml->filterType         = 0;
+  /* 0..64, 64=auto, Filter strength level for deblocking. [64] */
+  cml->filterLevel        = 64;
+  /* 0..8, 8=auto, Filter sharpness for deblocking. [8] */
+  cml->filterSharpness    = 8;
+  /* 0=OFF, 1=Adaptive, 2=ON, use 1/4 pixel MVs. [1] */
+  cml->quarterPixelMv     = 1;
+  /* 0=OFF, 1=Adaptive, 2=ON, allowed to to use more than 1 MV/MB. [1] */
+  cml->splitMv            = 1;
+
+  /* start:interval for Cyclic Intra Refresh, forces MBs intra */
+  cml->cirStart           = 0;
+  /* start:interval for Cyclic Intra Refresh, forces MBs intra */
+  cml->cirInterval        = 0;
+
+  /* left:top:right:bottom macroblock coordinates */
+  cml->intraAreaLeft      = 0;
+  cml->intraAreaTop       = 0;
+  cml->intraAreaRight     = 0;
+  cml->intraAreaBottom    = 0;
+  cml->intraAreaEnable    = 0;
+
+  /* left:top:right:bottom macroblock coordinates */
+  cml->roi1AreaLeft      = 0;
+  cml->roi1AreaTop       = 0;
+  cml->roi1AreaRight     = 0;
+  cml->roi1AreaBottom    = 0;
+  cml->roi1AreaEnable    = 0;
+  cml->roi2AreaLeft      = 0;
+  cml->roi2AreaTop       = 0;
+  cml->roi2AreaRight     = 0;
+  cml->roi2AreaBottom    = 0;
+  cml->roi2AreaEnable    = 0;
+
+  /* QP delta value for 1st Region-Of-Interest. [-50,0] */
+  cml->roi1DeltaQp    = 0;
+  cml->roi2DeltaQp    = 0;
+  cml->roi1AreaEnable = cml->roi1DeltaQp;
+  cml->roi2AreaEnable = cml->roi2DeltaQp;
+
+  /* Enables PSNR calculation for each frame. [0] */
+  cml->psnrSum        = 0;
+  cml->psnrCnt        = 0;
+
+  /* Enable MV writing in <mv.txt> [0] */
+  cml->mvOutput           = 0;
+
+  /* Favor value for I16x16 mode in I16/I4 */
+  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) {
+  VPU_PLG_DBG("\n");
+  VPU_PLG_DBG("Input | Pic |  QP | Type | IP GR AR |   "
+         "BR avg    MA(%3d) | ByteCnt (inst) |",
+         cml->ma.length);
+
+  if (cml->printPsnr)
+    VPU_PLG_DBG(" PSNR  |");
+
+  VPU_PLG_DBG("\n");
+  VPU_PLG_DBG("----------------------------------------"
+         "-----------------------------------------\n");
+
+  VPU_PLG_DBG("      |     | %3d | HDR  |          |   "
+         "                  | %7i %6i |",
+         cml->rc.qpHdr, cml->streamSize, IVF_HDR_BYTES);
+
+  if (cml->printPsnr)
+    VPU_PLG_DBG("       |");
+  VPU_PLG_DBG("\n");
+}
+
+void PrintFrame(EncoderParameters* cml, VP8EncInst encoder,
+                uint32_t frameNumber,
+                VP8EncRet ret) {
+  if ((cml->frameCntTotal + 1) && cml->outputRateDenom) {
+    /* Using 64-bits to avoid overflow */
+    uint64_t tmp = cml->streamSize / (cml->frameCntTotal + 1);
+    tmp *= (uint32_t)cml->outputRateNumer;
+
+    cml->bitrate = (uint32_t)(8 * (tmp / (uint32_t)cml->outputRateDenom));
+  }
+
+  VPU_PLG_DBG("%5i | %3llu | %3d | ",
+         frameNumber, cml->frameCntTotal, cml->rc.qpHdr);
+
+  VPU_PLG_DBG("%s",
+         (ret == VP8ENC_OUTPUT_BUFFER_OVERFLOW) ?
+         "lost" : (cml->encOut.codingType == VP8ENC_INTRA_FRAME) ? " I  " :
+         (cml->encOut.codingType == VP8ENC_PREDICTED_FRAME) ? " P  " : "skip");
+
+  /* Print reference frame usage */
+  VPU_PLG_DBG(" | %c%c %c%c %c%c",
+         cml->encOut.ipf & VP8ENC_REFERENCE ? 'R' : ' ',
+         cml->encOut.ipf & VP8ENC_REFRESH   ? 'W' : ' ',
+         cml->encOut.grf & VP8ENC_REFERENCE ? 'R' : ' ',
+         cml->encOut.grf & VP8ENC_REFRESH   ? 'W' : ' ',
+         cml->encOut.arf & VP8ENC_REFERENCE ? 'R' : ' ',
+         cml->encOut.arf & VP8ENC_REFRESH   ? 'W' : ' ');
+
+  /* Print bitrate statistics and frame size */
+  VPU_PLG_DBG(" | %9u %9u | %7i %6i | ",
+         cml->bitrate, Ma(&cml->ma), cml->streamSize, cml->encOut.frameSize);
+
+  /* Print size of each partition in bytes */
+  VPU_PLG_DBG("%d %d %d %d\n", cml->encOut.frameSize ? IVF_FRM_BYTES : 0,
+         cml->encOut.streamSize[0],
+         cml->encOut.streamSize[1], cml->encOut.streamSize[2]);
+
+  /* Check that partition sizes match frame size */
+  if (cml->encOut.frameSize != (cml->encOut.streamSize[0] +
+                                cml->encOut.streamSize[1] +
+                                cml->encOut.streamSize[2])) {
+    VPU_PLG_DBG("ERROR: Frame size doesn't match partition sizes!\n");
+  }
+}
+
+/*----------------------------------------------------------------------------
+    Add new frame bits for moving average bitrate calculation
+-----------------------------------------------------------------------------*/
+static void MaAddFrame(ma_s* ma, int32_t frameSizeBits) {
+  ma->frame[ma->pos++] = frameSizeBits;
+
+  if (ma->pos == ma->length)
+    ma->pos = 0;
+
+  if (ma->count < ma->length)
+    ma->count++;
+}
+
+/*----------------------------------------------------------------------------
+    Calculate average bitrate of moving window
+-----------------------------------------------------------------------------*/
+static int32_t Ma(ma_s* ma) {
+  int32_t i;
+  uint64_t sum = 0;     /* Using 64-bits to avoid overflow */
+
+  for (i = 0; i < ma->count; i++)
+    sum += ma->frame[i];
+
+  if (!ma->frameRateDenom)
+    return 0;
+
+  sum = sum / ma->length;
+
+  return sum * ma->frameRateNumer / ma->frameRateDenom;
+}
+
+static struct rk_venc_ops vp8_enc_ops = {
+  .init = rk_vp8_encoder_init,
+  .before_encode = rk_vp8_encoder_before_encode,
+  .after_encode = rk_vp8_encoder_after_encode,
+  .deinit = rk_vp8_encoder_deinit,
+  .updatepriv = rk_vp8_encoder_updatepriv,
+  .updateparameter = rk_vp8_encoder_setconfig,
+};
+
+struct rk_vp8_encoder* rk_vp8_encoder_alloc_ctx(void)
+{
+  struct rk_vp8_encoder* enc =
+    (struct rk_vp8_encoder*)calloc(1, sizeof(struct rk_vp8_encoder));
+
+  if (enc == NULL) {
+    VPU_PLG_ERR("allocate decoder context failed\n");
+    return NULL;
+  }
+
+  enc->ops = &vp8_enc_ops;
+
+  return enc;
+}
+
+void rk_vp8_encoder_free_ctx(struct rk_vp8_encoder *enc)
+{
+  free(enc);
+}
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.h b/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.h
new file mode 100644
index 0000000..783f5bf
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/rk_vp8encapi.h
@@ -0,0 +1,56 @@
+/* Copyright 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef _RK_VP8ENCAPI_H_
+#define _RK_VP8ENCAPI_H_
+
+#include "vp8encapi.h"
+#include "libvpu/rk_vepu_interface.h"
+
+enum VP8E_PRIVATE_DATA_TYPE {
+  VP8E_PRIVATE_DATA_TYPE_END,
+  VP8E_PRIVATE_DATA_TYPE_FRAMETAG,
+  VP8E_PRIVATE_DATA_TYPE_FRAMEHEADER,
+  VP8E_PRIVATE_DATA_TYPE_CABAC,
+  VP8E_PRIVATE_DATA_TYPE_SEGMAP,
+  VP8E_PRIVATE_DATA_TYPE_REG,
+  VP8E_PRIVATE_DATA_TYPE_PROBCNT
+};
+
+struct rk_vp8_encoder;
+
+struct rk_venc_ops {
+  int (*init)(struct rk_vp8_encoder *enc, struct rk_vepu_init_param *enc_parms);
+  int (*before_encode)(struct rk_vp8_encoder *enc);
+  int (*after_encode)(struct rk_vp8_encoder *enc, uint32_t outputStreamSize);
+  void (*deinit)(struct rk_vp8_encoder *enc);
+  int (*updatepriv)(struct rk_vp8_encoder *enc, void *config, uint32_t cfglen);
+  void (*updateparameter)(struct rk_vp8_encoder *enc, struct rk_vepu_runtime_param *param);
+};
+
+#define NUM_CTRLS 3
+struct rk_vp8_encoder {
+  struct rk_venc_ops *ops;
+
+  EncoderParameters cmdl;
+  VP8EncInst encoder;
+  VP8EncIn encIn;
+  int intraPeriodCnt;
+  int codedFrameCnt;
+  int src_img_size;
+  int next;
+  uint8_t *priv_data;
+  uint32_t priv_offset; /* offset of current private data */
+  uint32_t hdr_idx;
+  bool first_frame;
+  uint32_t rk_ctrl_ids[NUM_CTRLS];
+  void *rk_payloads[NUM_CTRLS];
+  uint32_t rk_payload_sizes[NUM_CTRLS];
+};
+
+struct rk_vp8_encoder* rk_vp8_encoder_alloc_ctx(void);
+void rk_vp8_encoder_free_ctx(struct rk_vp8_encoder *enc);
+#endif /* _RK_VP8ENCAPI_H_ */
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.c b/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.c
new file mode 100644
index 0000000..7b62b35
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.c
@@ -0,0 +1,479 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include <memory.h>
+#include "enccommon.h"
+#include "encasiccontroller.h"
+#include "vp8codeframe.h"
+#include "vp8ratecontrol.h"
+#include "vp8header.h"
+#include "vp8entropy.h"
+
+/* Intra 16x16 mode tree penalty values */
+static const int32_t const intra16ModeTreePenalty[] = {
+  305, 841, 914, 1082
+};
+
+
+/* Intra 4x4 mode tree penalty values */
+static const int32_t const intra4ModeTreePenalty[] = {
+  280, 622, 832, 1177, 1240, 1341, 1085, 1259, 1357, 1495
+};
+
+/* This is visually fitted. TODO use GNUPLOT or octave to fit curve at
+ * given data. ~round((2*(2+exp((x+22)/39)) + (2+exp((x+15)/32)))/3) */
+const int32_t const weight[128] = {
+  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+  4,  4,  4,  4,  4,  5,  5,  5,  5,  5,
+  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,
+  6,  6,  6,  6,  6,  6,  6,  7,  7,  7,
+  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,
+  8,  8,  9,  9,  9,  9,  9, 10, 10, 10,
+  10, 11, 11, 11, 12, 12, 13, 13, 13, 13,
+  14, 14, 14, 14, 15, 15, 15, 16, 16, 17,
+  17, 18, 18, 19, 19, 20, 20, 20, 21, 22,
+  23, 23, 24, 24, 25, 25, 26, 27, 28, 28,
+  29, 30, 31, 32, 32, 33, 34, 35, 36, 37,
+  38, 39, 40, 41, 42, 44, 44, 46, 47, 48,
+  50, 51, 52, 54, 55, 57, 58, 61
+};
+
+/* experimentally fitted, 24.893*exp(0.02545*qp) */
+const int32_t vp8SplitPenalty[128] = {
+  24, 25, 26, 26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36,
+  37, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 52, 53, 54,
+  56, 57, 59, 60, 62, 63, 65, 67, 68, 70, 72, 74, 76, 78, 80, 82,
+  84, 86, 88, 91, 93, 95, 98, 100, 103, 106, 108, 111, 114, 117, 120, 123,
+  126, 130, 133, 136, 140, 144, 147, 151, 155, 159, 163, 167, 172, 176, 181, 185,
+  190, 195, 200, 205, 211, 216, 222, 227, 233, 239, 245, 252, 258, 265, 272, 279,
+  286, 293, 301, 309, 317, 325, 333, 342, 351, 360, 369, 379, 388, 398, 409, 419,
+  430, 441, 453, 464, 476, 488, 501, 514, 527, 541, 555, 569, 584, 599, 614, 630
+};
+
+static void VP8SetNewFrame(vp8Instance_s* inst);
+static void SetIntraPredictionPenalties(regValues_s* regs, uint32_t qp);
+static void SetSegmentation(vp8Instance_s* inst);
+static void SetFilterParameters(vp8Instance_s* inst);
+
+void VP8SetFrameParams(vp8Instance_s* inst) {
+  pps* pps = inst->ppss.pps;  /* Active picture parameters */
+  sps* sps = &inst->sps;
+  int32_t qp = inst->rateControl.qpHdr;
+  int32_t i;
+
+  /* Segment parameters, testId/ROI may override qpSgm and
+   * auto filter level setting may override levelSgm. */
+  for (i = 0; i < SGM_CNT; i++) {
+    pps->qpSgm[i] = qp;
+    pps->levelSgm[i] = sps->filterLevel;
+  }
+}
+
+void VP8CodeFrame(vp8Instance_s* inst, EncoderParameters* cml) {
+  /* Initialize probability tables for frame header. */
+  InitEntropy(inst);
+  SetSegmentation(inst);
+  SetFilterParameters(inst);
+
+  /* Write frame headers, also updates segmentation probs. */
+  VP8FrameHeader(inst);
+  VP8FrameTag(inst);
+  VP8SetNewFrame(inst);
+
+  /* Write final probability tables for ASIC. */
+  WriteEntropyTables(inst);
+
+  VP8_EncAsicFrameStart(&inst->asic.regs);
+}
+
+void VP8SetNewFrame(vp8Instance_s* inst) {
+  regValues_s* regs = &inst->asic.regs;
+  sps* sps = &inst->sps;
+  int32_t qp, i;
+
+  /* We tell HW the size of DCT partition buffers, they all are equal size.
+   * There is no overflow check for control partition on ASIC, but since
+   * the stream buffers are in one linear memory the overflow of control
+   * partition will only corrupt the first DCT partition and SW will
+   * notice this and discard the frame. */
+  regs->outputStrmSize /= 8;  /* 64-bit addresses */
+  regs->outputStrmSize &= (~0x07);    /* 8 multiple size */
+
+  /* Since frame tag is 10 bytes the stream base is not 64-bit aligned.
+   * Now the frame headers have been written so we must align the base for
+   * HW and set the header remainder properly. */
+  regs->outputStrmBase = inst->buffer[0].byteCnt;
+  regs->outputStrmBase += inst->buffer[1].byteCnt;
+
+  /* bit offset in the last 64-bit word */
+  /** TODO, no StrmBase here, firstFreeBit also need to be
+   *  config in the driver. */
+  regs->firstFreeBit = (regs->outputStrmBase & 0x07) * 8;
+
+  /* 64-bit aligned HW base */
+  regs->outputStrmBase = regs->outputStrmBase & (~0x07);
+
+  /* header remainder is byte aligned, max 7 bytes = 56 bits */
+  if (regs->firstFreeBit != 0) {
+    /* 64-bit aligned stream pointer */
+    uint8_t* pTmp = (uint8_t*)((size_t)(inst->buffer[1].data) & (uint32_t)(~0x07));
+    uint32_t val;
+
+    /* Clear remaining bits */
+    for (val = 6; val >= regs->firstFreeBit / 8; val--)
+      pTmp[val] = 0;
+
+    val = pTmp[0] << 24;
+    val |= pTmp[1] << 16;
+    val |= pTmp[2] << 8;
+    val |= pTmp[3];
+
+    regs->strmStartMSB = val;  /* 32 bits to MSB */
+
+    if (regs->firstFreeBit > 32) {
+      val = pTmp[4] << 24;
+      val |= pTmp[5] << 16;
+      val |= pTmp[6] << 8;
+
+      regs->strmStartLSB = val;
+    } else
+      regs->strmStartLSB = 0;
+  } else {
+    regs->strmStartMSB = regs->strmStartLSB = 0;
+  }
+
+  /* Quarter pixel MV mode */
+  if (sps->quarterPixelMv == 0)
+    regs->disableQuarterPixelMv = 1;
+  else if (sps->quarterPixelMv == 1) {
+    /* Adaptive setting. When resolution larger than 1080p = 8160 macroblocks
+     * there is not enough time to do 1/4 pixel ME */
+    if (inst->mbPerFrame > 8160)
+      regs->disableQuarterPixelMv = 1;
+    else
+      regs->disableQuarterPixelMv = 0;
+  } else
+    regs->disableQuarterPixelMv = 0;
+
+  /* Cabac enable bit signals ASIC to read probability tables */
+  regs->enableCabac = 1;
+
+  /* Split MV mode */
+  if (sps->splitMv == 0)
+    regs->splitMvMode = 0;
+  else if (sps->splitMv == 1) {
+    /* Adaptive setting. When resolution larger than 4CIF = 1584 macroblocks
+     * there is no benefit from using split MVs */
+    if (inst->mbPerFrame > 1584)
+      regs->splitMvMode = 0;
+    else
+      regs->splitMvMode = 1;
+  } else
+    regs->splitMvMode = 1;
+
+  qp = inst->rateControl.qpHdr;
+
+  /* If favor has not been set earlier by testId use default */
+  if (regs->interFavor == ASIC_PENALTY_UNDEFINED) {
+    int32_t tmp = 128 - inst->entropy->intraProb;
+
+    /* This is called intraPenalty in system model */
+    if (tmp < 0) {
+      regs->interFavor = tmp & 0xFFFF;    /* Signed 16-bit value */
+    } else {
+      tmp = qp * 2 - 40;
+      regs->interFavor = MAX(0, tmp);
+    }
+  }
+  if (regs->diffMvPenalty[0] == ASIC_PENALTY_UNDEFINED)
+    regs->diffMvPenalty[0] = 64 / 2;
+  if (regs->diffMvPenalty[1] == ASIC_PENALTY_UNDEFINED)
+    regs->diffMvPenalty[1] = 60 / 2 * 32;
+  if (regs->diffMvPenalty[2] == ASIC_PENALTY_UNDEFINED)
+    regs->diffMvPenalty[2] = 8;
+  if (regs->skipPenalty == ASIC_PENALTY_UNDEFINED)
+    regs->skipPenalty = (qp >= 100) ? (3 * qp / 4) : 0;    /* Zero/nearest/near */
+  if (regs->goldenPenalty == ASIC_PENALTY_UNDEFINED)
+    regs->goldenPenalty = MAX(0, 5 * qp / 4 - 10);
+  if (regs->splitPenalty[0] == ASIC_PENALTY_UNDEFINED)
+    regs->splitPenalty[0] = MIN(1023, vp8SplitPenalty[qp] / 2);
+  if (regs->splitPenalty[1] == ASIC_PENALTY_UNDEFINED)
+    regs->splitPenalty[1] = MIN(1023, (2 * vp8SplitPenalty[qp] + 40) / 4);
+  if (regs->splitPenalty[3] == ASIC_PENALTY_UNDEFINED)
+    regs->splitPenalty[3] = MIN(511, (8 * vp8SplitPenalty[qp] + 500) / 16);
+
+  /* DMV penalty tables */
+  for (i = 0; i < ASIC_PENALTY_TABLE_SIZE; i++) {
+    int32_t y, x;
+
+    regs->dmvPenalty[i] = i * 2;
+    y = CostMv(i * 2, inst->entropy->mvProb[0]);  /* mv y */
+    x = CostMv(i * 2, inst->entropy->mvProb[1]);  /* mv x */
+    regs->dmvQpelPenalty[i] = MIN(255, (y + x + 1) / 2 * weight[qp] >> 8);
+  }
+
+  /* Quantization tables for each segment */
+  for (i = 0; i < SGM_CNT; i++) {
+    qp = inst->ppss.pps->qpSgm[i];
+    regs->qpY1QuantDc[i] = inst->qpY1[qp].quant[0];
+    regs->qpY1QuantAc[i] = inst->qpY1[qp].quant[1];
+    regs->qpY2QuantDc[i] = inst->qpY2[qp].quant[0];
+    regs->qpY2QuantAc[i] = inst->qpY2[qp].quant[1];
+    regs->qpChQuantDc[i] = inst->qpCh[qp].quant[0];
+    regs->qpChQuantAc[i] = inst->qpCh[qp].quant[1];
+    regs->qpY1ZbinDc[i] = inst->qpY1[qp].zbin[0];
+    regs->qpY1ZbinAc[i] = inst->qpY1[qp].zbin[1];
+    regs->qpY2ZbinDc[i] = inst->qpY2[qp].zbin[0];
+    regs->qpY2ZbinAc[i] = inst->qpY2[qp].zbin[1];
+    regs->qpChZbinDc[i] = inst->qpCh[qp].zbin[0];
+    regs->qpChZbinAc[i] = inst->qpCh[qp].zbin[1];
+    regs->qpY1RoundDc[i] = inst->qpY1[qp].round[0];
+    regs->qpY1RoundAc[i] = inst->qpY1[qp].round[1];
+    regs->qpY2RoundDc[i] = inst->qpY2[qp].round[0];
+    regs->qpY2RoundAc[i] = inst->qpY2[qp].round[1];
+    regs->qpChRoundDc[i] = inst->qpCh[qp].round[0];
+    regs->qpChRoundAc[i] = inst->qpCh[qp].round[1];
+    regs->qpY1DequantDc[i] = inst->qpY1[qp].dequant[0];
+    regs->qpY1DequantAc[i] = inst->qpY1[qp].dequant[1];
+    regs->qpY2DequantDc[i] = inst->qpY2[qp].dequant[0];
+    regs->qpY2DequantAc[i] = inst->qpY2[qp].dequant[1];
+    regs->qpChDequantDc[i] = inst->qpCh[qp].dequant[0];
+    regs->qpChDequantAc[i] = inst->qpCh[qp].dequant[1];
+
+    regs->filterLevel[i] = inst->ppss.pps->levelSgm[i];
+  }
+
+  regs->boolEncValue = inst->buffer[1].bottom;
+  regs->boolEncValueBits = 24 - inst->buffer[1].bitsLeft;
+  regs->boolEncRange = inst->buffer[1].range;
+
+  regs->cpTarget = NULL;
+
+  /* Select frame type */
+  if (inst->picBuffer.cur_pic->i_frame)
+    regs->frameCodingType = ASIC_INTRA;
+  else
+    regs->frameCodingType = ASIC_INTER;
+
+  regs->dctPartitions          = sps->dctPartitions;
+  regs->filterDisable          = sps->filterType;
+  regs->filterSharpness        = sps->filterSharpness;
+  regs->segmentEnable          = inst->ppss.pps->segmentEnabled;
+  regs->segmentMapUpdate       = inst->ppss.pps->sgm.mapModified;
+
+  /* For next frame the segmentation map is not needed unless it is modified. */
+  inst->ppss.pps->sgm.mapModified = false;
+
+  for (i = 0; i < 4; i++) {
+    regs->lfRefDelta[i] = sps->refDelta[i];
+    regs->lfModeDelta[i] = sps->modeDelta[i];
+  }
+
+  SetIntraPredictionPenalties(regs, qp);
+
+  memset(inst->asic.probCount.vir_addr, 0,
+         inst->asic.probCount.size);
+}
+
+void SetIntraPredictionPenalties(regValues_s* regs, uint32_t qp) {
+
+  int32_t i, tmp;
+
+  /* Intra 4x4 mode */
+  tmp = qp * 2 + 8;
+  for (i = 0; i < 10; i++) {
+    regs->intraBmodePenalty[i] = (intra4ModeTreePenalty[i] * tmp) >> 8;
+
+  }
+
+  /* Intra 16x16 mode */
+  tmp = qp * 2 + 64;
+  for (i = 0; i < 4; i++) {
+    regs->intraModePenalty[i] = (intra16ModeTreePenalty[i] * tmp) >> 8;
+  }
+
+  /* If favor has not been set earlier by testId use default */
+  if (regs->intra16Favor == ASIC_PENALTY_UNDEFINED)
+    regs->intra16Favor = qp * 1024 / 128;
+}
+
+void SetSegmentation(vp8Instance_s* inst) {
+  regValues_s* regs = &inst->asic.regs;
+  uint32_t* map = inst->asic.segmentMap.vir_addr;
+  ppss* ppss = &inst->ppss;
+  pps* pps = inst->ppss.pps;  /* Active picture parameters */
+  int32_t qp = inst->rateControl.qpHdr;
+  uint32_t x, y, mb, mask, id;
+  uint32_t mapSize = (inst->mbPerFrame + 15) / 16 * 8;   /* Bytes, 64-bit multiple */
+
+  /* Set the segmentation parameters according to ROI settings.
+   * This will override any earlier segmentation settings. */
+
+  if (regs->roi1DeltaQp)
+    pps->qpSgm[1] = CLIP3(qp - regs->roi1DeltaQp, 0, 127);
+
+  if (regs->roi2DeltaQp)
+    pps->qpSgm[2] = CLIP3(qp - regs->roi2DeltaQp, 0, 127);
+
+  if (regs->roi1DeltaQp || regs->roi2DeltaQp) {
+    pps->segmentEnabled = 1;
+
+    memset(pps->sgm.idCnt, 0, sizeof(pps->sgm.idCnt));
+
+    /* Set ROI 1 (ID == 1) and ROI 2 (ID == 2) into map */
+    for (y = 0, mb = 0, mask = 0; y < inst->mbPerCol; y++) {
+      for (x = 0; x < inst->mbPerRow; x++) {
+        id = 0;
+        if ((x >= regs->roi1Left) && (x <= regs->roi1Right) &&
+            (y >= regs->roi1Top) && (y <= regs->roi1Bottom)) id = 1;
+        if ((x >= regs->roi2Left) && (x <= regs->roi2Right) &&
+            (y >= regs->roi2Top) && (y <= regs->roi2Bottom)) id = 2;
+
+        pps->sgm.idCnt[id]++;
+
+        mask |= id << (28 - 4 * (mb % 8));
+        if ((mb % 8) == 7) {
+          *map++ = mask;
+          mask = 0;
+        }
+        mb++;
+      }
+    }
+    *map++ = mask;
+    EncSwapEndianess((uint32_t*)inst->asic.segmentMap.vir_addr, mapSize);
+  } else if (pps->segmentEnabled && pps->sgm.mapModified) {
+    memset(pps->sgm.idCnt, 0, sizeof(pps->sgm.idCnt));
+
+    /* Use the map to calculate id counts */
+    for (mb = 0, mask = 0; mb < mapSize / 4; mb++) {
+      mask = map[mb];
+      for (x = 0; x < 8; x++) {
+        if (mb * 8 + x < inst->mbPerFrame) {
+          id = (mask >> (28 - 4 * x)) & 0xF;
+          pps->sgm.idCnt[id]++;
+        }
+      }
+    }
+    EncSwapEndianess((uint32_t*)inst->asic.segmentMap.vir_addr, mapSize);
+  }
+
+  /* If current frame is key frame or segmentation is not enabled old
+   * segmentation data is not valid anymore, set out of range data to
+   * inform Segmentation(). */
+  if (inst->picBuffer.cur_pic->i_frame || !pps->segmentEnabled) {
+    memset(ppss->qpSgm, 0xff, sizeof(ppss->qpSgm));
+    memset(ppss->levelSgm, 0xff, sizeof(ppss->levelSgm));
+    ppss->prevPps = NULL;
+  } else {
+    ppss->prevPps = ppss->pps;
+  }
+}
+
+void SetFilterParameters(vp8Instance_s* inst) {
+  sps* sps = &inst->sps;
+  pps* pps = inst->ppss.pps;  /* Active picture parameters */
+  uint32_t qp = inst->rateControl.qpHdr;
+  uint32_t tmp, i;
+  uint32_t iframe = inst->picBuffer.cur_pic->i_frame;
+  const int32_t const interLevel[128] = {
+    8,  8,  8,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 11, 11, 11, 11, 11,
+    11, 11, 12, 12, 12, 12, 12, 12, 13, 13,
+    13, 13, 13, 14, 14, 14, 14, 15, 15, 15,
+    15, 16, 16, 16, 16, 17, 17, 17, 18, 18,
+    18, 19, 19, 20, 20, 20, 21, 21, 22, 22,
+    23, 23, 24, 24, 25, 25, 26, 26, 27, 28,
+    28, 29, 30, 30, 31, 32, 33, 33, 34, 35,
+    36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+    46, 48, 49, 50, 51, 53, 54, 56, 57, 59,
+    60, 62, 63, 63, 63, 63, 63, 63, 63, 63,
+    63, 63, 63, 63, 63, 63, 63, 63
+  };
+
+
+  /* auto level */
+  if (sps->autoFilterLevel) {
+    if (iframe) {
+      tmp = (qp * 64) / 128 + 8;
+      sps->filterLevel = CLIP3(tmp, 0, 63);
+      pps->levelSgm[0] = CLIP3((pps->qpSgm[0] * 64) / 128 + 8, 0, 63);
+      pps->levelSgm[1] = CLIP3((pps->qpSgm[1] * 64) / 128 + 8, 0, 63);
+      pps->levelSgm[2] = CLIP3((pps->qpSgm[2] * 64) / 128 + 8, 0, 63);
+      pps->levelSgm[3] = CLIP3((pps->qpSgm[3] * 64) / 128 + 8, 0, 63);
+    } else {
+      sps->filterLevel = interLevel[qp];
+      pps->levelSgm[0] = interLevel[pps->qpSgm[0]];
+      pps->levelSgm[1] = interLevel[pps->qpSgm[1]];
+      pps->levelSgm[2] = interLevel[pps->qpSgm[2]];
+      pps->levelSgm[3] = interLevel[pps->qpSgm[3]];
+    }
+  }
+  /* auto sharpness */
+  if (sps->autoFilterSharpness) {
+    sps->filterSharpness = 0;
+  }
+
+  if (!sps->filterDeltaEnable) return;
+
+  if (sps->filterDeltaEnable == 2) {
+    /* Special meaning, test ID set filter delta values */
+    sps->filterDeltaEnable = true;
+    return;
+  }
+
+  /* force deltas to 0 if filterLevel == 0 (assumed to mean that filtering
+   * is completely disabled) */
+  if (sps->filterLevel == 0) {
+    sps->refDelta[0] =  0;      /* Intra frame */
+    sps->refDelta[1] =  0;      /* Last frame */
+    sps->refDelta[2] =  0;      /* Golden frame */
+    sps->refDelta[3] =  0;      /* Altref frame */
+    sps->modeDelta[0] = 0;      /* BPRED */
+    sps->modeDelta[1] = 0;      /* Zero */
+    sps->modeDelta[2] = 0;      /* New mv */
+    sps->modeDelta[3] = 0;      /* Split mv */
+    return;
+  }
+
+  if (!inst->picBuffer.cur_pic->ipf && !inst->picBuffer.cur_pic->grf &&
+      !inst->picBuffer.cur_pic->arf) {
+    /* Frame is droppable, ie. doesn't update ipf, grf nor arf so don't
+     * update the filter level deltas. */
+    memcpy(sps->refDelta, sps->oldRefDelta, sizeof(sps->refDelta));
+    memcpy(sps->modeDelta, sps->oldModeDelta, sizeof(sps->modeDelta));
+    return;
+  }
+
+  /* Adjustment based on reference frame */
+  sps->refDelta[0] =  2;      /* Intra frame */
+  sps->refDelta[1] =  0;      /* Last frame */
+  sps->refDelta[2] = -2;      /* Golden frame */
+  sps->refDelta[3] = -2;      /* Altref frame */
+
+  /* Adjustment based on mb mode */
+  sps->modeDelta[0] =  4;     /* BPRED */
+  sps->modeDelta[1] = -2;     /* Zero */
+  sps->modeDelta[2] =  2;     /* New mv */
+  sps->modeDelta[3] =  4;     /* Split mv */
+
+  /* ABS(delta) is 6bits, see FilterLevelDelta() */
+  for (i = 0; i < 4; i++) {
+    sps->refDelta[i] = CLIP3(sps->refDelta[i], -0x3f, 0x3f);
+    sps->modeDelta[i] = CLIP3(sps->modeDelta[i], -0x3f, 0x3f);
+  }
+}
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.h b/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.h
new file mode 100644
index 0000000..eb8faab
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.h
@@ -0,0 +1,50 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef __VP8_CODE_FRAME_H__
+#define __VP8_CODE_FRAME_H__
+
+/*------------------------------------------------------------------------------
+    1. Include headers
+------------------------------------------------------------------------------*/
+#include "vp8instance.h"
+#include "vp8encapi.h"
+
+/*------------------------------------------------------------------------------
+    2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+    3. Module defines
+------------------------------------------------------------------------------*/
+
+typedef enum
+{
+  VP8ENCODE_OK = 0,
+  VP8ENCODE_TIMEOUT = 1,
+  VP8ENCODE_DATA_ERROR = 2,
+  VP8ENCODE_HW_ERROR = 3,
+  VP8ENCODE_SYSTEM_ERROR = 4,
+  VP8ENCODE_HW_RESET = 5
+} vp8EncodeFrame_e;
+
+/*------------------------------------------------------------------------------
+    4. Function prototypes
+------------------------------------------------------------------------------*/
+void VP8SetFrameParams(vp8Instance_s* inst);
+void VP8CodeFrame(vp8Instance_s* inst, EncoderParameters* cml);
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c
new file mode 100644
index 0000000..53c5f77
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c
@@ -0,0 +1,651 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include <memory.h>
+#include <stdio.h>
+
+#include "vp8encapi.h"
+#include "libvpu/rk_vepu_debug.h"
+
+#include "enccommon.h"
+#include "vp8codeframe.h"
+#include "vp8init.h"
+#include "vp8instance.h"
+#include "vp8ratecontrol.h"
+#include "vp8putbits.h"
+
+#ifdef VIDEOSTAB_ENABLED
+#include "vidstabcommon.h"
+#endif
+
+/* Parameter limits */
+#define VP8ENC_MAX_PP_INPUT_WIDTH      8176
+#define VP8ENC_MAX_PP_INPUT_HEIGHT     8176
+#define VP8ENC_MAX_BITRATE             (50000*1200)
+
+/*----------------------------------------------------------------------------
+    Function name : VP8EncInit
+    Description   : Initialize an encoder instance and
+                    returns it to application
+
+    Return type   : VP8EncRet
+    Argument      : pEncCfg - initialization parameters
+                    instAddr - where to save the created instance
+-----------------------------------------------------------------------------*/
+VP8EncRet VP8EncInit(const VP8EncConfig* pEncCfg, VP8EncInst* instAddr) {
+  VP8EncRet ret;
+  vp8Instance_s* pEncInst = NULL;
+
+  VPU_PLG_DBG("VP8EncInit#");
+
+  /* check that right shift on negative numbers is performed signed */
+#if (((-1) >> 1) != (-1))
+#error Right bit-shifting (>>) does not preserve the sign
+#endif
+
+  /* Check for illegal inputs */
+  if (pEncCfg == NULL || instAddr == NULL) {
+    VPU_PLG_ERR("VP8EncInit: ERROR Null argument");
+    return VP8ENC_NULL_ARGUMENT;
+  }
+
+  /* Check that configuration is valid */
+  if (VP8CheckCfg(pEncCfg) == ENCHW_NOK) {
+    VPU_PLG_ERR("VP8EncInit: ERROR Invalid configuration");
+    return VP8ENC_INVALID_ARGUMENT;
+  }
+
+  /* Initialize encoder instance and allocate memories */
+  ret = VP8Init(pEncCfg, &pEncInst);
+  if (ret != VP8ENC_OK) {
+    VPU_PLG_ERR("VP8EncInit: ERROR Initialization failed");
+    return ret;
+  }
+
+  pEncInst->encStatus = VP8ENCSTAT_INIT;
+
+  pEncInst->inst = pEncInst;
+
+  *instAddr = (VP8EncInst)pEncInst;
+
+  VPU_PLG_DBG("VP8EncInit: OK");
+  return VP8ENC_OK;
+}
+
+/*----------------------------------------------------------------------------
+
+    Function name : VP8EncRelease
+    Description   : Releases encoder instance and all associated resource
+
+    Return type   : VP8EncRet
+    Argument      : inst - the instance to be released
+-----------------------------------------------------------------------------*/
+VP8EncRet VP8EncRelease(VP8EncInst inst) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+
+  VPU_PLG_DBG("VP8EncRelease#");
+
+  /* Check for illegal inputs */
+  if (pEncInst == NULL) {
+    VPU_PLG_DBG("VP8EncRelease: ERROR Null argument");
+    return VP8ENC_NULL_ARGUMENT;
+  }
+
+  /* Check for existing instance */
+  if (pEncInst->inst != pEncInst) {
+    VPU_PLG_DBG("VP8EncRelease: ERROR Invalid instance");
+    return VP8ENC_INSTANCE_ERROR;
+  }
+
+#ifdef TRACE_STREAM
+  EncCloseStreamTrace();
+#endif
+
+  VP8Shutdown(pEncInst);
+
+  VPU_PLG_DBG("VP8EncRelease: OK");
+  return VP8ENC_OK;
+}
+
+/*----------------------------------------------------------------------------
+
+    Function name : VP8EncSetCodingCtrl
+    Description   : Sets encoding parameters
+
+    Return type   : VP8EncRet
+    Argument      : inst - the instance in use
+                    pCodeParams - user provided parameters
+-----------------------------------------------------------------------------*/
+VP8EncRet VP8EncSetCodingCtrl(VP8EncInst inst,
+                              const VP8EncCodingCtrl* pCodeParams) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+  regValues_s* regs;
+  sps* sps;
+  uint32_t area1 = 0, area2 = 0;
+
+  VPU_PLG_DBG("VP8EncSetCodingCtrl#");
+
+  /* Check for illegal inputs */
+  if ((pEncInst == NULL) || (pCodeParams == NULL)) {
+    VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Null argument\n");
+    return VP8ENC_NULL_ARGUMENT;
+  }
+
+  /* Check for existing instance */
+  if (pEncInst->inst != pEncInst) {
+    VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Invalid instance\n");
+    return VP8ENC_INSTANCE_ERROR;
+  }
+
+  /* check limits */
+  if (pCodeParams->filterLevel > VP8ENC_FILTER_LEVEL_AUTO ||
+      pCodeParams->filterSharpness > VP8ENC_FILTER_SHARPNESS_AUTO) {
+    VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Invalid parameter\n");
+    return VP8ENC_INVALID_ARGUMENT;
+  }
+
+  if (pCodeParams->cirStart > pEncInst->mbPerFrame ||
+      pCodeParams->cirInterval > pEncInst->mbPerFrame) {
+    VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Invalid CIR value\n");
+    return VP8ENC_INVALID_ARGUMENT;
+  }
+
+  if (pCodeParams->intraArea.enable) {
+    if (!(pCodeParams->intraArea.top <= pCodeParams->intraArea.bottom &&
+          pCodeParams->intraArea.bottom < pEncInst->mbPerCol &&
+          pCodeParams->intraArea.left <= pCodeParams->intraArea.right &&
+          pCodeParams->intraArea.right < pEncInst->mbPerRow)) {
+      VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Invalid intraArea\n");
+      return VP8ENC_INVALID_ARGUMENT;
+    }
+  }
+
+  if (pCodeParams->roi1Area.enable) {
+    if (!(pCodeParams->roi1Area.top <= pCodeParams->roi1Area.bottom &&
+          pCodeParams->roi1Area.bottom < pEncInst->mbPerCol &&
+          pCodeParams->roi1Area.left <= pCodeParams->roi1Area.right &&
+          pCodeParams->roi1Area.right < pEncInst->mbPerRow)) {
+      VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Invalid roi1Area\n");
+      return VP8ENC_INVALID_ARGUMENT;
+    }
+    area1 = (pCodeParams->roi1Area.right + 1 - pCodeParams->roi1Area.left) *
+        (pCodeParams->roi1Area.bottom + 1 - pCodeParams->roi1Area.top);
+  }
+
+  if (pCodeParams->roi2Area.enable) {
+    if (!pCodeParams->roi1Area.enable) {
+      VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Roi2 enabled but not Roi1\n");
+      return VP8ENC_INVALID_ARGUMENT;
+    }
+    if (!(pCodeParams->roi2Area.top <= pCodeParams->roi2Area.bottom &&
+          pCodeParams->roi2Area.bottom < pEncInst->mbPerCol &&
+          pCodeParams->roi2Area.left <= pCodeParams->roi2Area.right &&
+          pCodeParams->roi2Area.right < pEncInst->mbPerRow)) {
+      VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Invalid roi2Area\n");
+      return VP8ENC_INVALID_ARGUMENT;
+    }
+    area2 = (pCodeParams->roi2Area.right + 1 - pCodeParams->roi2Area.left) *
+        (pCodeParams->roi2Area.bottom + 1 - pCodeParams->roi2Area.top);
+  }
+
+  if (area1 + area2 >= pEncInst->mbPerFrame) {
+    VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Invalid roi (whole frame)\n");
+    return VP8ENC_INVALID_ARGUMENT;
+  }
+
+  if (pCodeParams->roi1DeltaQp < -50 ||
+      pCodeParams->roi1DeltaQp > 0 ||
+      pCodeParams->roi2DeltaQp < -50 ||
+      pCodeParams->roi2DeltaQp > 0) {
+    VPU_PLG_ERR("VP8EncSetCodingCtrl: ERROR Invalid ROI delta QP\n");
+    return VP8ENC_INVALID_ARGUMENT;
+  }
+
+  sps = &pEncInst->sps;
+
+  /* TODO check limits */
+  sps->filterType        = pCodeParams->filterType;
+  if (pCodeParams->filterLevel == VP8ENC_FILTER_LEVEL_AUTO) {
+    sps->autoFilterLevel = 1;
+    sps->filterLevel     = 0;
+  } else {
+    sps->autoFilterLevel = 0;
+    sps->filterLevel     = pCodeParams->filterLevel;
+  }
+
+  if (pCodeParams->filterSharpness == VP8ENC_FILTER_SHARPNESS_AUTO) {
+    sps->autoFilterSharpness = 1;
+    sps->filterSharpness     = 0;
+  } else {
+    sps->autoFilterSharpness = 0;
+    sps->filterSharpness     = pCodeParams->filterSharpness;
+  }
+
+  sps->dctPartitions     = pCodeParams->dctPartitions;
+  sps->partitionCnt      = 2 + (1 << sps->dctPartitions);
+  sps->refreshEntropy    = pCodeParams->errorResilient ? 0 : 1;
+  sps->quarterPixelMv    = pCodeParams->quarterPixelMv;
+  sps->splitMv           = pCodeParams->splitMv;
+
+  regs = &pEncInst->asic.regs;
+  regs->cirStart = pCodeParams->cirStart;
+  regs->cirInterval = pCodeParams->cirInterval;
+  if (pCodeParams->intraArea.enable) {
+    regs->intraAreaTop = pCodeParams->intraArea.top;
+    regs->intraAreaLeft = pCodeParams->intraArea.left;
+    regs->intraAreaBottom = pCodeParams->intraArea.bottom;
+    regs->intraAreaRight = pCodeParams->intraArea.right;
+  }
+  if (pCodeParams->roi1Area.enable) {
+    regs->roi1Top = pCodeParams->roi1Area.top;
+    regs->roi1Left = pCodeParams->roi1Area.left;
+    regs->roi1Bottom = pCodeParams->roi1Area.bottom;
+    regs->roi1Right = pCodeParams->roi1Area.right;
+  }
+  if (pCodeParams->roi2Area.enable) {
+    regs->roi2Top = pCodeParams->roi2Area.top;
+    regs->roi2Left = pCodeParams->roi2Area.left;
+    regs->roi2Bottom = pCodeParams->roi2Area.bottom;
+    regs->roi2Right = pCodeParams->roi2Area.right;
+  }
+
+  /* ROI setting updates the segmentation map usage */
+  if (pCodeParams->roi1Area.enable || pCodeParams->roi2Area.enable)
+    pEncInst->ppss.pps->segmentEnabled = 1;
+  else {
+    pEncInst->ppss.pps->segmentEnabled = 0;
+    /* Disabling ROI will clear the segment ID map */
+    memset(pEncInst->asic.segmentMap.vir_addr, 0,
+           pEncInst->asic.segmentMap.size);
+  }
+  pEncInst->ppss.pps->sgm.mapModified = true;
+
+  regs->roi1DeltaQp = -pCodeParams->roi1DeltaQp;
+  regs->roi2DeltaQp = -pCodeParams->roi2DeltaQp;
+
+  VPU_PLG_DBG("VP8EncSetCodingCtrl: OK");
+  return VP8ENC_OK;
+}
+
+/*----------------------------------------------------------------------------
+
+    Function name : VP8EncGetCodingCtrl
+    Description   : Returns current encoding parameters
+
+    Return type   : VP8EncRet
+    Argument      : inst - the instance in use
+                    pCodeParams - palce where parameters are returned
+-----------------------------------------------------------------------------*/
+VP8EncRet VP8EncGetCodingCtrl(VP8EncInst inst,
+                              VP8EncCodingCtrl* pCodeParams) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+  regValues_s* regs;
+  sps* sps;
+
+  VPU_PLG_DBG("VP8EncGetCodingCtrl#");
+
+  /* Check for illegal inputs */
+  if ((pEncInst == NULL) || (pCodeParams == NULL)) {
+    VPU_PLG_ERR("VP8EncGetCodingCtrl: ERROR Null argument\n");
+    return VP8ENC_NULL_ARGUMENT;
+  }
+
+  /* Check for existing instance */
+  if (pEncInst->inst != pEncInst) {
+    VPU_PLG_ERR("VP8EncGetCodingCtrl: ERROR Invalid instance\n");
+    return VP8ENC_INSTANCE_ERROR;
+  }
+
+  sps = &pEncInst->sps;
+
+  pCodeParams->interpolationFilter    = 1;    /* Only bicubic supported */
+  pCodeParams->dctPartitions          = sps->dctPartitions;
+  pCodeParams->quarterPixelMv         = sps->quarterPixelMv;
+  pCodeParams->splitMv                = sps->splitMv;
+  pCodeParams->filterType             = sps->filterType;
+  pCodeParams->errorResilient         = !sps->refreshEntropy;
+
+  if (sps->autoFilterLevel)
+    pCodeParams->filterLevel            = VP8ENC_FILTER_LEVEL_AUTO;
+  else
+    pCodeParams->filterLevel            = sps->filterLevel;
+
+  if (sps->autoFilterSharpness)
+    pCodeParams->filterSharpness        = VP8ENC_FILTER_SHARPNESS_AUTO;
+  else
+    pCodeParams->filterSharpness        = sps->filterSharpness;
+
+  regs = &pEncInst->asic.regs;
+  pCodeParams->cirStart = regs->cirStart;
+  pCodeParams->cirInterval = regs->cirInterval;
+  pCodeParams->intraArea.enable =
+    regs->intraAreaTop < pEncInst->mbPerCol ? 1 : 0;
+  pCodeParams->intraArea.top    = regs->intraAreaTop;
+  pCodeParams->intraArea.left   = regs->intraAreaLeft;
+  pCodeParams->intraArea.bottom = regs->intraAreaBottom;
+  pCodeParams->intraArea.right  = regs->intraAreaRight;
+
+  VPU_PLG_DBG("VP8EncGetCodingCtrl: OK\n");
+  return VP8ENC_OK;
+}
+
+/*----------------------------------------------------------------------------
+
+    Function name : VP8EncSetRateCtrl
+    Description   : Sets rate control parameters
+
+    Return type   : VP8EncRet
+    Argument      : inst - the instance in use
+                    pRateCtrl - user provided parameters
+-----------------------------------------------------------------------------*/
+VP8EncRet VP8EncSetRateCtrl(VP8EncInst inst,
+                            const VP8EncRateCtrl* pRateCtrl) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+  vp8RateControl_s rc_tmp;
+
+  VPU_PLG_DBG("VP8EncSetRateCtrl#");
+
+  /* Check for illegal inputs */
+  if ((pEncInst == NULL) || (pRateCtrl == NULL)) {
+    VPU_PLG_ERR("VP8EncSetRateCtrl: ERROR Null argument\n");
+    return VP8ENC_NULL_ARGUMENT;
+  }
+
+  /* Check for existing instance */
+  if (pEncInst->inst != pEncInst) {
+    VPU_PLG_ERR("VP8EncSetRateCtrl: ERROR Invalid instance\n");
+    return VP8ENC_INSTANCE_ERROR;
+  }
+
+  /* TODO Check for invalid values */
+
+  rc_tmp = pEncInst->rateControl;
+  rc_tmp.qpHdr                    = pRateCtrl->qpHdr;
+  rc_tmp.picRc                    = pRateCtrl->pictureRc;
+  rc_tmp.picSkip                  = pRateCtrl->pictureSkip;
+  rc_tmp.qpMin                    = pRateCtrl->qpMin;
+  rc_tmp.qpMax                    = pRateCtrl->qpMax;
+  rc_tmp.virtualBuffer.bitRate    = pRateCtrl->bitPerSecond;
+  rc_tmp.gopLen                   = pRateCtrl->bitrateWindow;
+  rc_tmp.intraQpDelta             = pRateCtrl->intraQpDelta;
+  rc_tmp.fixedIntraQp             = pRateCtrl->fixedIntraQp;
+  rc_tmp.intraPictureRate         = pRateCtrl->intraPictureRate;
+  rc_tmp.goldenPictureRate        = pRateCtrl->goldenPictureRate;
+  rc_tmp.altrefPictureRate        = pRateCtrl->altrefPictureRate;
+
+  VP8InitRc(&rc_tmp, pEncInst->encStatus == VP8ENCSTAT_INIT);
+
+  /* Set final values into instance */
+  pEncInst->rateControl = rc_tmp;
+
+  VPU_PLG_DBG("VP8EncSetRateCtrl: OK\n");
+  return VP8ENC_OK;
+}
+
+/*----------------------------------------------------------------------------
+
+    Function name : VP8EncGetRateCtrl
+    Description   : Return current rate control parameters
+
+    Return type   : VP8EncRet
+    Argument      : inst - the instance in use
+                    pRateCtrl - place where parameters are returned
+-----------------------------------------------------------------------------*/
+VP8EncRet VP8EncGetRateCtrl(VP8EncInst inst, VP8EncRateCtrl* pRateCtrl) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+
+  VPU_PLG_DBG("VP8EncGetRateCtrl#");
+
+  /* Check for illegal inputs */
+  if (pEncInst == NULL || pRateCtrl == NULL) {
+    VPU_PLG_ERR("%s ERROR, Instance doesn't initialized\n", __func__);
+    return VP8ENC_NULL_ARGUMENT;
+  }
+
+  /* Check for existing instance */
+  if (pEncInst->inst != pEncInst) {
+    VPU_PLG_ERR("VP8EncGetRateCtrl: ERROR Invalid instance\n");
+    return VP8ENC_INSTANCE_ERROR;
+  }
+
+  pRateCtrl->qpHdr            = pEncInst->rateControl.qpHdr;
+  pRateCtrl->pictureRc        = pEncInst->rateControl.picRc;
+  pRateCtrl->pictureSkip      = pEncInst->rateControl.picSkip;
+  pRateCtrl->qpMin            = pEncInst->rateControl.qpMin;
+  pRateCtrl->qpMax            = pEncInst->rateControl.qpMax;
+  pRateCtrl->bitPerSecond     = pEncInst->rateControl.virtualBuffer.bitRate;
+  pRateCtrl->bitrateWindow    = pEncInst->rateControl.gopLen;
+  pRateCtrl->intraQpDelta     = pEncInst->rateControl.intraQpDelta;
+  pRateCtrl->fixedIntraQp     = pEncInst->rateControl.fixedIntraQp;
+  pRateCtrl->intraPictureRate = pEncInst->rateControl.intraPictureRate;
+  pRateCtrl->goldenPictureRate = pEncInst->rateControl.goldenPictureRate;
+  pRateCtrl->altrefPictureRate = pEncInst->rateControl.altrefPictureRate;
+
+  VPU_PLG_DBG("VP8EncGetRateCtrl: OK\n");
+  return VP8ENC_OK;
+}
+
+VP8EncRet VP8EncStrmEncodeResult(VP8EncInst inst, VP8EncOut* pEncOut,
+                                 uint32_t outputStreamSize) {
+
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+  picBuffer* picBuffer;
+
+  pEncOut->frameSize = outputStreamSize;
+
+  picBuffer = &pEncInst->picBuffer;
+
+  /* Rate control action after frame */
+  VP8AfterPicRc(&pEncInst->rateControl, outputStreamSize);
+
+  if (picBuffer->cur_pic->i_frame) {
+    pEncOut->codingType = VP8ENC_INTRA_FRAME;
+    pEncOut->arf = pEncOut->grf = pEncOut->ipf = 0;
+  } else {
+    pEncOut->codingType = VP8ENC_PREDICTED_FRAME;
+    pEncOut->ipf = picBuffer->refPicList[0].search ? VP8ENC_REFERENCE : 0;
+    pEncOut->grf = picBuffer->refPicList[1].search ? VP8ENC_REFERENCE : 0;
+    pEncOut->arf = picBuffer->refPicList[2].search ? VP8ENC_REFERENCE : 0;
+  }
+
+  /* Mark which reference frame was refreshed */
+  pEncOut->arf |= picBuffer->cur_pic->arf ? VP8ENC_REFRESH : 0;
+  pEncOut->grf |= picBuffer->cur_pic->grf ? VP8ENC_REFRESH : 0;
+  pEncOut->ipf |= picBuffer->cur_pic->ipf ? VP8ENC_REFRESH : 0;
+
+  UpdatePictureBuffer(picBuffer);
+
+  /* Frame was encoded so increment frame number */
+  pEncInst->frameCnt++;
+  pEncInst->encStatus = VP8ENCSTAT_START_FRAME;
+  pEncInst->prevFrameLost = 0;
+
+  VPU_PLG_DBG("VP8EncStrmEncode: OK\n");
+  return 0;
+}
+
+void VP8EncGetFrameHeader(VP8EncInst inst, uint8_t** frmhdr, uint32_t* size) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+
+  *frmhdr = pEncInst->asic.frmhdr;
+  *size = pEncInst->asic.frmHdrBufLen;
+}
+
+void VP8EncGetCabacCtx(VP8EncInst inst, uint8_t** cabac, uint32_t* size) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+
+  *cabac = (uint8_t*)pEncInst->asic.cabacCtx.vir_addr;
+  *size = pEncInst->asic.cabacCtx.size;
+}
+
+void VP8EncGetSegmentMap(VP8EncInst inst, uint8_t** segmap, uint32_t* size) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+
+  *segmap = (uint8_t*)pEncInst->asic.segmentMap.vir_addr;
+  *size = pEncInst->asic.segmentMap.size;
+}
+
+void VP8EncGetRegs(VP8EncInst inst, uint32_t** regs, uint32_t* size) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+
+  *regs = pEncInst->asic.regs.regMirror;
+  *size = sizeof(pEncInst->asic.regs.regMirror);
+}
+
+VP8EncRet VP8EncSetProbCnt(VP8EncInst inst, uint8_t* probcnt, uint32_t size) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+  if (probcnt == NULL || size > pEncInst->asic.probCount.size) {
+    VPU_PLG_ERR("Invalid input parameter\n");
+    return -1;
+  }
+
+  memcpy(pEncInst->asic.probCount.vir_addr, probcnt, size);
+
+  return 0;
+}
+
+/*----------------------------------------------------------------------------
+
+    Function name : VP8EncStrmEncode
+    Description   : Encodes a new picture
+    Return type   : VP8EncRet
+    Argument      : inst - encoder instance
+    Argument      : pEncIn - user provided input parameters
+                    pEncOut - place where output info is returned
+-----------------------------------------------------------------------------*/
+VP8EncRet VP8EncStrmEncode(VP8EncInst inst, const VP8EncIn* pEncIn,
+                           VP8EncOut* pEncOut, EncoderParameters* cml) {
+  vp8Instance_s* pEncInst = (vp8Instance_s*)inst;
+  picBuffer* picBuffer;
+  int32_t i;
+  VP8EncPictureCodingType ct;
+
+  VPU_PLG_DBG("VP8EncStrmEncode#\n");
+
+  /* Check for illegal inputs */
+  if ((pEncInst == NULL) || (pEncIn == NULL) || (pEncOut == NULL)) {
+    VPU_PLG_ERR("VP8EncStrmEncode: ERROR Null argument\n");
+    return VP8ENC_NULL_ARGUMENT;
+  }
+
+  /* Check for existing instance */
+  if (pEncInst->inst != pEncInst) {
+    VPU_PLG_ERR("VP8EncStrmEncode: ERROR Invalid instance\n");
+    return VP8ENC_INSTANCE_ERROR;
+  }
+
+  /* Clear the output structure */
+  pEncOut->codingType = VP8ENC_NOTCODED_FRAME;
+  pEncOut->frameSize = 0;
+  for (i = 0; i < 9; i++) {
+    pEncOut->pOutBuf[i] = NULL;
+    pEncOut->streamSize[i] = 0;
+  }
+
+  /* Check status, ERROR not allowed */
+  if ((pEncInst->encStatus != VP8ENCSTAT_INIT) &&
+      (pEncInst->encStatus != VP8ENCSTAT_KEYFRAME) &&
+      (pEncInst->encStatus != VP8ENCSTAT_START_FRAME)) {
+    VPU_PLG_ERR("VP8EncStrmEncode: ERROR Invalid status\n");
+    return VP8ENC_INVALID_STATUS;
+  }
+
+  /* Choose frame coding type */
+  ct = pEncIn->codingType;
+
+  /* Status may affect the frame coding type */
+  if ((pEncInst->encStatus == VP8ENCSTAT_INIT) ||
+      (pEncInst->encStatus == VP8ENCSTAT_KEYFRAME))
+    ct = VP8ENC_INTRA_FRAME;
+
+  /* Divide stream buffer for every partition */
+  {
+    uint8_t* pStart = (uint8_t*)pEncInst->asic.frmhdr;
+    uint32_t bufSize = pEncInst->asic.frmHdrBufLen;
+    uint8_t* pEnd;
+    int32_t status = ENCHW_OK;
+
+    /* Frame tag 10 bytes (I-frame) or 3 bytes (P-frame),
+     * written by SW at end of frame */
+    pEnd = pStart + 3;
+    if (ct == VP8ENC_INTRA_FRAME) pEnd += 7;
+    if (VP8SetBuffer(&pEncInst->buffer[0], pStart, pEnd - pStart) == ENCHW_NOK)
+      status = ENCHW_NOK;
+
+    pStart = pEnd;
+    pEnd = pStart + bufSize;
+    if (VP8SetBuffer(&pEncInst->buffer[1], pStart, pEnd - pStart) == ENCHW_NOK)
+      status = ENCHW_NOK;
+
+    if (status == ENCHW_NOK) {
+      VPU_PLG_ERR("VP8 Set frame header buffer failed\n");
+      return status;
+    }
+  }
+
+  /* Initialize picture buffer and ref pic list according to frame type */
+  picBuffer = &pEncInst->picBuffer;
+  picBuffer->cur_pic->show    = 1;
+  picBuffer->cur_pic->poc     = pEncInst->frameCnt;
+  picBuffer->cur_pic->i_frame = (ct == VP8ENC_INTRA_FRAME);
+  InitializePictureBuffer(picBuffer);
+
+  /* Set picture buffer according to frame coding type */
+  if (ct == VP8ENC_PREDICTED_FRAME) {
+    picBuffer->cur_pic->p_frame = 1;
+    picBuffer->cur_pic->arf = (pEncIn->arf & VP8ENC_REFRESH) ? 1 : 0;
+    picBuffer->cur_pic->grf = (pEncIn->grf & VP8ENC_REFRESH) ? 1 : 0;
+    picBuffer->cur_pic->ipf = (pEncIn->ipf & VP8ENC_REFRESH) ? 1 : 0;
+    picBuffer->refPicList[0].search = (pEncIn->ipf & VP8ENC_REFERENCE) ? 1 : 0;
+    picBuffer->refPicList[1].search = (pEncIn->grf & VP8ENC_REFERENCE) ? 1 : 0;
+    picBuffer->refPicList[2].search = (pEncIn->arf & VP8ENC_REFERENCE) ? 1 : 0;
+  }
+
+  /* Rate control */
+  VP8BeforePicRc(&pEncInst->rateControl, pEncIn->timeIncrement,
+                 picBuffer->cur_pic->i_frame);
+
+  /* Rate control may choose to skip the frame */
+  if (pEncInst->rateControl.frameCoded == ENCHW_NO) {
+    VPU_PLG_DBG("VP8EncStrmEncode: OK, frame skipped");
+    return VP8ENC_FRAME_READY;
+  }
+
+  /* TODO: RC can set frame to grf and copy grf to arf */
+  if (pEncInst->rateControl.goldenPictureRate) {
+    picBuffer->cur_pic->grf = 1;
+    if (!picBuffer->cur_pic->arf)
+      picBuffer->refPicList[1].arf = 1;
+  }
+
+  /* Set some frame coding parameters before internal test configure */
+  VP8SetFrameParams(pEncInst);
+
+#ifdef TRACE_STREAM
+  traceStream.frameNum = pEncInst->frameCnt;
+  traceStream.id = 0; /* Stream generated by SW */
+  traceStream.bitCnt = 0;  /* New frame */
+#endif
+
+  /* Get the reference frame buffers from picture buffer */
+  PictureBufferSetRef(picBuffer, &pEncInst->asic);
+
+  /* Code one frame */
+  VP8CodeFrame(pEncInst, cml);
+
+  return VP8ENC_OK;
+}
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h
new file mode 100644
index 0000000..d37d474
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.h
@@ -0,0 +1,449 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _VP8ENCAPI_H_
+#define _VP8ENCAPI_H_
+
+#include "vpu_mem.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* The maximum amount of frames for bitrate moving average calculation */
+#define MOVING_AVERAGE_FRAMES    30
+
+typedef const void* VP8EncInst;
+
+/* Function return values */
+typedef enum
+{
+  VP8ENC_OK = 0,
+  VP8ENC_FRAME_READY = 1,
+
+  VP8ENC_ERROR = -1,
+  VP8ENC_NULL_ARGUMENT = -2,
+  VP8ENC_INVALID_ARGUMENT = -3,
+  VP8ENC_MEMORY_ERROR = -4,
+  VP8ENC_EWL_ERROR = -5,
+  VP8ENC_EWL_MEMORY_ERROR = -6,
+  VP8ENC_INVALID_STATUS = -7,
+  VP8ENC_OUTPUT_BUFFER_OVERFLOW = -8,
+  VP8ENC_HW_BUS_ERROR = -9,
+  VP8ENC_HW_DATA_ERROR = -10,
+  VP8ENC_HW_TIMEOUT = -11,
+  VP8ENC_HW_RESERVED = -12,
+  VP8ENC_SYSTEM_ERROR = -13,
+  VP8ENC_INSTANCE_ERROR = -14,
+  VP8ENC_HRD_ERROR = -15,
+  VP8ENC_HW_RESET = -16
+} VP8EncRet;
+
+/* Picture YUV type for pre-processing */
+typedef enum
+{
+  VP8ENC_YUV420_PLANAR = 0,               /* YYYY... UUUU... VVVV */
+  VP8ENC_YUV420_SEMIPLANAR = 1,           /* YYYY... UVUVUV...    */
+  VP8ENC_YUV422_INTERLEAVED_YUYV = 2,     /* YUYVYUYV...          */
+  VP8ENC_YUV422_INTERLEAVED_UYVY = 3,     /* UYVYUYVY...          */
+  VP8ENC_RGB565 = 4,                      /* 16-bit RGB           */
+  VP8ENC_BGR565 = 5,                      /* 16-bit RGB           */
+  VP8ENC_RGB555 = 6,                      /* 15-bit RGB           */
+  VP8ENC_BGR555 = 7,                      /* 15-bit RGB           */
+  VP8ENC_RGB444 = 8,                      /* 12-bit RGB           */
+  VP8ENC_BGR444 = 9,                      /* 12-bit RGB           */
+  VP8ENC_RGB888 = 10,                     /* 24-bit RGB           */
+  VP8ENC_BGR888 = 11,                     /* 24-bit RGB           */
+  VP8ENC_RGB101010 = 12,                  /* 30-bit RGB           */
+  VP8ENC_BGR101010 = 13                   /* 30-bit RGB           */
+} VP8EncPictureType;
+
+/* Picture rotation for pre-processing */
+typedef enum
+{
+  VP8ENC_ROTATE_0 = 0,
+  VP8ENC_ROTATE_90R = 1, /* Rotate 90 degrees clockwise           */
+  VP8ENC_ROTATE_90L = 2  /* Rotate 90 degrees counter-clockwise   */
+} VP8EncPictureRotation;
+
+/* Picture color space conversion (RGB input) for pre-processing */
+typedef enum
+{
+  VP8ENC_RGBTOYUV_BT601 = 0, /* Color conversion according to BT.601  */
+  VP8ENC_RGBTOYUV_BT709 = 1, /* Color conversion according to BT.709  */
+  VP8ENC_RGBTOYUV_USER_DEFINED = 2   /* User defined color conversion */
+} VP8EncColorConversionType;
+
+/* Picture type for encoding */
+typedef enum
+{
+  VP8ENC_INTRA_FRAME = 0,
+  VP8ENC_PREDICTED_FRAME = 1,
+  VP8ENC_NOTCODED_FRAME = 2              /* Used just as a return value  */
+} VP8EncPictureCodingType;
+
+/* Reference picture mode for reading and writing */
+typedef enum
+{
+  VP8ENC_NO_REFERENCE_NO_REFRESH = 0,
+  VP8ENC_REFERENCE = 1,
+  VP8ENC_REFRESH = 2,
+  VP8ENC_REFERENCE_AND_REFRESH = 3
+} VP8EncRefPictureMode;
+
+/* Definitions to enable encoder internal control of filter parameters */
+#define VP8ENC_FILTER_SHARPNESS_AUTO 8
+#define VP8ENC_FILTER_LEVEL_AUTO 64
+
+/*------------------------------------------------------------------------------
+    3. Structures for API function parameters
+------------------------------------------------------------------------------*/
+
+/* Configuration info for initialization
+ * Width and height are picture dimensions after rotation
+ */
+typedef struct
+{
+  uint32_t refFrameAmount; /* Amount of reference frame buffers, [1..3]
+                       * 1 = only last frame buffered,
+                       *     always predict from and refresh ipf,
+                       *     stream buffer overflow causes new key frame
+                       * 2 = last and golden frames buffered
+                       * 3 = last and golden and altref frame buffered  */
+  uint32_t width;          /* Encoded picture width in pixels, multiple of 4 */
+  uint32_t height;         /* Encoded picture height in pixels, multiple of 2*/
+  uint32_t frameRateNum;   /* The stream time scale, [1..1048575]            */
+  uint32_t frameRateDenom; /* Maximum frame rate is frameRateNum/frameRateDenom
+                       * in frames/second. [1..frameRateNum]            */
+} VP8EncConfig;
+
+/* Defining rectangular macroblock area in encoded picture */
+typedef struct
+{
+  uint32_t enable;         /* [0,1] Enables this area */
+  uint32_t top;            /* Top mb row inside area [0..heightMbs-1]      */
+  uint32_t left;           /* Left mb row inside area [0..widthMbs-1]      */
+  uint32_t bottom;         /* Bottom mb row inside area [top..heightMbs-1] */
+  uint32_t right;          /* Right mb row inside area [left..widthMbs-1]  */
+} VP8EncPictureArea;
+
+/* Coding control parameters */
+typedef struct
+{
+  /* The following parameters can only be adjusted before stream is
+   * started. They affect the stream profile and decoding complexity. */
+  uint32_t interpolationFilter; /* Defines the type of interpolation filter
+                            * for reconstruction. [0..2]
+                            * 0 = Bicubic (6-tap interpolation filter),
+                            * 1 = Bilinear (2-tap interpolation filter),
+                            * 2 = None (Full pixel motion vectors)     */
+  uint32_t filterType;         /* Deblocking loop filter type,
+                           * 0 = Normal deblocking filter,
+                           * 1 = Simple deblocking filter             */
+
+  /* The following parameters can be adjusted between frames.         */
+  uint32_t filterLevel;        /* Deblocking filter level [0..64]
+                           * 0 = No filtering,
+                           * higher level => more filtering,
+                           * VP8ENC_FILTER_LEVEL_AUTO = calculate
+                           *      filter level based on quantization  */
+  uint32_t filterSharpness;    /* Deblocking filter sharpness [0..8],
+                           * VP8ENC_FILTER_SHARPNESS_AUTO = calculate
+                           *      filter sharpness automatically      */
+  uint32_t dctPartitions;      /* Amount of DCT coefficient partitions to
+                           * create for each frame, subject to HW
+                           * limitations on maximum partition amount.
+                           * 0 = 1 DCT residual partition,
+                           * 1 = 2 DCT residual partitions,
+                           * 2 = 4 DCT residual partitions,
+                           * 3 = 8 DCT residual partitions            */
+  uint32_t errorResilient;     /* Enable error resilient stream mode. [0,1]
+                           * This prevents cumulative probability
+                           * updates.                                 */
+  uint32_t splitMv;            /* Split MV mode ie. using more than 1 MV/MB
+                           * 0=disabled, 1=adaptive, 2=enabled        */
+  uint32_t quarterPixelMv;     /* 1/4 pixel motion estimation
+                           * 0=disabled, 1=adaptive, 2=enabled        */
+  uint32_t cirStart;           /* [0..mbTotal] First macroblock for
+                           * Cyclic Intra Refresh                     */
+  uint32_t cirInterval;        /* [0..mbTotal] Macroblock interval for
+                           * Cyclic Intra Refresh, 0=disabled         */
+  VP8EncPictureArea intraArea;  /* Area for forcing intra macroblocks */
+  VP8EncPictureArea roi1Area;   /* Area for 1st Region-Of-Interest */
+  VP8EncPictureArea roi2Area;   /* Area for 2nd Region-Of-Interest */
+  int32_t roi1DeltaQp;              /* [-50..0] QP delta value for 1st ROI */
+  int32_t roi2DeltaQp;              /* [-50..0] QP delta value for 2nd ROI */
+} VP8EncCodingCtrl;
+
+/* Rate control parameters */
+typedef struct
+{
+  uint32_t pictureRc;       /* Adjust QP between pictures, [0,1]           */
+  uint32_t pictureSkip;     /* Allow rate control to skip pictures, [0,1]  */
+  int32_t qpHdr;           /* QP for next encoded picture, [-1..127]
+                        * -1 = Let rate control calculate initial QP.
+                        * qpHdr is used for all pictures if
+                        * pictureRc is disabled.                      */
+  uint32_t qpMin;           /* Minimum QP for any picture, [0..127]        */
+  uint32_t qpMax;           /* Maximum QP for any picture, [0..127]        */
+  uint32_t bitPerSecond;    /* Target bitrate in bits/second
+                        * [10000..60000000]                           */
+  uint32_t bitrateWindow;   /* Number of pictures over which the target
+                        * bitrate should be achieved. Smaller window
+                        * maintains constant bitrate but forces rapid
+                        * quality changes whereas larger window
+                        * allows smoother quality changes. [1..150]   */
+  int32_t intraQpDelta;    /* Intra QP delta. intraQP = QP + intraQpDelta
+                        * This can be used to change the relative
+                        * quality of the Intra pictures or to decrease
+                        * the size of Intra pictures. [-12..12]       */
+  uint32_t fixedIntraQp;    /* Fixed QP value for all Intra pictures, [0..127]
+                        * 0 = Rate control calculates intra QP.       */
+  uint32_t intraPictureRate; /* The distance of two intra pictures, [0..300]
+                         * This will force periodical intra pictures.
+                         * 0=disabled.                                 */
+  uint32_t goldenPictureRate; /* The distance of two golden pictures, [0..300]
+                         * This will force periodical golden pictures.
+                         * 0=disabled.                                 */
+  uint32_t altrefPictureRate; /* The distance of two altref pictures, [0..300]
+                         * This will force periodical altref pictures.
+                         * 0=disabled.                                 */
+} VP8EncRateCtrl;
+
+/* Encoder input structure */
+typedef struct
+{
+  uint32_t busLuma;         /* Bus address for input picture
+                        * planar format: luminance component
+                        * semiplanar format: luminance component
+                        * interleaved format: whole picture
+                        */
+  uint32_t busChromaU;      /* Bus address for input chrominance
+                        * planar format: cb component
+                        * semiplanar format: both chrominance
+                        * interleaved format: not used
+                        */
+  uint32_t busChromaV;      /* Bus address for input chrominance
+                        * planar format: cr component
+                        * semiplanar format: not used
+                        * interleaved format: not used
+                        */
+  VP8EncPictureCodingType codingType; /* Proposed picture coding type,
+                                       * INTRA/PREDICTED              */
+  uint32_t timeIncrement;   /* The previous picture duration in units
+                        * of 1/frameRateNum. 0 for the very first
+                        * picture and typically equal to frameRateDenom
+                        * for the rest.                               */
+
+  /* The following three parameters apply when
+   * codingType == PREDICTED. They define for each
+   * of the reference pictures if it should be used
+   * for prediction and if it should be refreshed
+   * with the encoded frame. There must always be
+   * atleast one (ipf/grf/arf) that is referenced
+   * and atleast one that is refreshed.
+   * Note that refFrameAmount may limit the
+   * availability of golden and altref frames.   */
+  VP8EncRefPictureMode ipf; /* Immediately previous == last frame */
+  VP8EncRefPictureMode grf; /* Golden reference frame */
+  VP8EncRefPictureMode arf; /* Alternative reference frame */
+} VP8EncIn;
+
+/* Encoder output structure */
+typedef struct
+{
+  VP8EncPictureCodingType codingType;     /* Realized picture coding type,
+                                           * INTRA/PREDICTED/NOTCODED   */
+  uint32_t* pOutBuf[9];     /* Pointers to start of each partition in
+                        * output stream buffer,
+                        * pOutBuf[0] = Frame header + mb mode partition,
+                        * pOutBuf[1] = First DCT partition,
+                        * pOutBuf[2] = Second DCT partition (if exists)
+                        * etc.                                          */
+  uint32_t streamSize[9];   /* Size of each partition of output stream
+                        * in bytes.                                     */
+  uint32_t frameSize;       /* Size of output frame in bytes
+                        * (==sum of partition sizes)                    */
+  int8_t* motionVectors;   /* Pointer to buffer storing encoded frame MVs.
+                        * One pixel motion vector x and y and
+                        * corresponding SAD value for every macroblock.
+                        * Format: mb0x mb0y mb0sadMsb mb0sadLsb mb1x .. */
+
+  /* The following three parameters apply when
+   * codingType == PREDICTED. They define for each
+   * of the reference pictures if it was used for
+   * prediction and it it was refreshed. */
+  VP8EncRefPictureMode ipf; /* Immediately previous == last frame */
+  VP8EncRefPictureMode grf; /* Golden reference frame */
+  VP8EncRefPictureMode arf; /* Alternative reference frame */
+} VP8EncOut;
+
+/* Input pre-processing */
+typedef struct
+{
+  VP8EncColorConversionType type;
+  uint16_t coeffA;          /* User defined color conversion coefficient */
+  uint16_t coeffB;          /* User defined color conversion coefficient */
+  uint16_t coeffC;          /* User defined color conversion coefficient */
+  uint16_t coeffE;          /* User defined color conversion coefficient */
+  uint16_t coeffF;          /* User defined color conversion coefficient */
+} VP8EncColorConversion;
+
+/* Version information */
+typedef struct
+{
+  uint32_t major;           /* Encoder API major version */
+  uint32_t minor;           /* Encoder API minor version */
+} VP8EncApiVersion;
+
+typedef struct
+{
+  uint32_t swBuild;         /* Software build ID */
+  uint32_t hwBuild;         /* Hardware build ID */
+} VP8EncBuild;
+
+
+typedef struct {
+  int32_t frame[MOVING_AVERAGE_FRAMES];
+  int32_t length;
+  int32_t count;
+  int32_t pos;
+  int32_t frameRateNumer;
+  int32_t frameRateDenom;
+} ma_s;
+
+/* Structure for command line options and testbench variables */
+typedef struct
+{
+  int32_t width;
+  int32_t height;
+  int32_t lumWidthSrc;
+  int32_t lumHeightSrc;
+  int32_t horOffsetSrc;
+  int32_t verOffsetSrc;
+  int32_t outputRateNumer;
+  int32_t outputRateDenom;
+  int32_t refFrameAmount;
+
+  int32_t inputFormat;
+  int32_t rotation;
+  int32_t colorConversion;
+  int32_t videoStab;
+
+  int32_t bitPerSecond;
+  int32_t picRc;
+  int32_t picSkip;
+  int32_t gopLength;
+  int32_t qpHdr;
+  int32_t qpMin;
+  int32_t qpMax;
+  int32_t intraQpDelta;
+  int32_t fixedIntraQp;
+
+  int32_t intraPicRate;
+  int32_t dctPartitions;  /* Dct data partitions 0=1, 1=2, 2=4, 3=8 */
+  int32_t errorResilient;
+  int32_t ipolFilter;
+  int32_t quarterPixelMv;
+  int32_t splitMv;
+  int32_t filterType;
+  int32_t filterLevel;
+  int32_t filterSharpness;
+  int32_t cirStart;
+  int32_t cirInterval;
+  int32_t intraAreaEnable;
+  int32_t intraAreaLeft;
+  int32_t intraAreaTop;
+  int32_t intraAreaRight;
+  int32_t intraAreaBottom;
+  int32_t roi1AreaEnable;
+  int32_t roi2AreaEnable;
+  int32_t roi1AreaTop;
+  int32_t roi1AreaLeft;
+  int32_t roi1AreaBottom;
+  int32_t roi1AreaRight;
+  int32_t roi2AreaTop;
+  int32_t roi2AreaLeft;
+  int32_t roi2AreaBottom;
+  int32_t roi2AreaRight;
+  int32_t roi1DeltaQp;
+  int32_t roi2DeltaQp;
+
+  int32_t printPsnr;
+  int32_t mvOutput;
+  int32_t droppable;
+
+  int32_t intra16Favor;
+  int32_t intraPenalty;
+
+  /* SW/HW shared memories for input/output buffers */
+  VPUMemLinear_t pictureMem;
+  VPUMemLinear_t pictureStabMem;
+
+  VP8EncRateCtrl rc;
+  VP8EncOut encOut;
+
+  uint32_t streamSize;     /* Size of output stream in bytes */
+  uint32_t bitrate;        /* Calculate average bitrate of encoded frames */
+  ma_s ma;            /* Calculate moving average of bitrate */
+  uint32_t psnrSum;        /* Calculate average PSNR over encoded frames */
+  uint32_t psnrCnt;
+
+  int32_t frameCnt;       /* Frame counter of input file */
+  uint64_t frameCntTotal;  /* Frame counter of all frames */
+} EncoderParameters;
+
+
+/* Initialization & release */
+VP8EncRet VP8EncInit(const VP8EncConfig* pEncConfig,
+                     VP8EncInst* instAddr);
+VP8EncRet VP8EncRelease(VP8EncInst inst);
+
+/* Encoder configuration before stream generation */
+VP8EncRet VP8EncSetCodingCtrl(VP8EncInst inst, const VP8EncCodingCtrl*
+                              pCodingParams);
+VP8EncRet VP8EncGetCodingCtrl(VP8EncInst inst, VP8EncCodingCtrl*
+                              pCodingParams);
+
+/* Encoder configuration before and during stream generation */
+VP8EncRet VP8EncSetRateCtrl(VP8EncInst inst,
+                            const VP8EncRateCtrl* pRateCtrl);
+VP8EncRet VP8EncGetRateCtrl(VP8EncInst inst,
+                            VP8EncRateCtrl* pRateCtrl);
+
+/* Stream generation */
+
+void VP8EncGetFrameHeader(VP8EncInst inst, uint8_t** frmhdr, uint32_t* size);
+void VP8EncGetCabacCtx(VP8EncInst inst, uint8_t** cabac, uint32_t* size);
+void VP8EncGetSegmentMap(VP8EncInst inst, uint8_t** segmap, uint32_t* size);
+void VP8EncGetRegs(VP8EncInst inst, uint32_t** regs, uint32_t* size);
+VP8EncRet VP8EncSetProbCnt(VP8EncInst inst, uint8_t* probcnt, uint32_t size);
+
+/* VP8EncStrmEncode encodes one video frame. */
+VP8EncRet VP8EncStrmEncodeResult(VP8EncInst inst, VP8EncOut* pEncOut, uint32_t outputStreamSize);
+VP8EncRet VP8EncStrmEncode(VP8EncInst inst, const VP8EncIn* pEncIn,
+                           VP8EncOut* pEncOut, EncoderParameters* cml);
+
+void PrintTitle(EncoderParameters* cml);
+void PrintFrame(EncoderParameters* cml, VP8EncInst encoder, uint32_t frameNumber,
+                VP8EncRet ret);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__VP8ENCAPI_H__*/
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8entropy.c b/libv4l-rockchip/libvpu/vp8_enc/vp8entropy.c
new file mode 100644
index 0000000..d9719fd
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8entropy.c
@@ -0,0 +1,530 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include "vp8entropy.h"
+
+#include <memory.h>
+#include "enccommon.h"
+#include "vp8entropytable.h"
+#include "vp8macroblocktools.h"
+
+/* Approximate bit cost of bin at given probability prob */
+#define COST_BOOL(prob, bin)\
+      ((bin) ? vp8_prob_cost[255 - (prob)] : vp8_prob_cost[prob])
+
+enum {
+  MAX_BAND = 7,
+  MAX_CTX  = 3,
+};
+
+static int32_t CostTree(tree const* tree, int32_t* prob);
+static void UpdateEntropy(vp8Instance_s* inst);
+
+void EncSwapEndianess(uint32_t* buf, uint32_t sizeBytes) {
+#if (ENCH1_OUTPUT_SWAP_8 == 1)
+  uint32_t i = 0;
+  int32_t words = sizeBytes / 4;
+
+  ASSERT((sizeBytes % 8) == 0);
+
+  while (words > 0) {
+    uint32_t val = buf[i];
+    uint32_t tmp = 0;
+
+    tmp |= (val & 0xFF) << 24;
+    tmp |= (val & 0xFF00) << 8;
+    tmp |= (val & 0xFF0000) >> 8;
+    tmp |= (val & 0xFF000000) >> 24;
+
+#if(ENCH1_OUTPUT_SWAP_32 == 1)    /* need this for 64-bit HW */
+    {
+      uint32_t val2 = buf[i + 1];
+      uint32_t tmp2 = 0;
+
+      tmp2 |= (val2 & 0xFF) << 24;
+      tmp2 |= (val2 & 0xFF00) << 8;
+      tmp2 |= (val2 & 0xFF0000) >> 8;
+      tmp2 |= (val2 & 0xFF000000) >> 24;
+
+      buf[i] = tmp2;
+      words--;
+      i++;
+    }
+#endif
+    buf[i] = tmp;
+    words--;
+    i++;
+  }
+#endif
+
+}
+
+void InitEntropy(vp8Instance_s* inst) {
+  entropy* entropy = inst->entropy;
+
+  ASSERT(sizeof(defaultCoeffProb) == sizeof(entropy->coeffProb));
+  ASSERT(sizeof(defaultCoeffProb) == sizeof(coeffUpdateProb));
+  ASSERT(sizeof(defaultMvProb) == sizeof(mvUpdateProb));
+  ASSERT(sizeof(defaultMvProb) == sizeof(entropy->mvProb));
+
+  UpdateEntropy(inst);
+
+  /* Default propability */
+  entropy->lastProb = 255;        /* Stetson-Harrison method TODO */
+  entropy->gfProb = 128;          /* Stetson-Harrison method TODO */
+  memcpy(entropy->YmodeProb, YmodeProb, sizeof(YmodeProb));
+  memcpy(entropy->UVmodeProb, UVmodeProb, sizeof(UVmodeProb));
+}
+
+void WriteEntropyTables(vp8Instance_s* inst) {
+  entropy* entropy = inst->entropy;
+  uint8_t* table = (uint8_t*)inst->asic.cabacCtx.vir_addr;
+  int32_t i, j, k, l;
+
+  ASSERT(table);
+
+  /* Write probability tables to ASIC linear memory, reg + mem */
+  memset(table, 0, 56);
+  table[0] = entropy->skipFalseProb;
+  table[1] = entropy->intraProb;
+  table[2] = entropy->lastProb;
+  table[3] = entropy->gfProb;
+  table[4] = entropy->segmentProb[0];
+  table[5] = entropy->segmentProb[1];
+  table[6] = entropy->segmentProb[2];
+
+  table[8] = entropy->YmodeProb[0];
+  table[9] = entropy->YmodeProb[1];
+  table[10] = entropy->YmodeProb[2];
+  table[11] = entropy->YmodeProb[3];
+  table[12] = entropy->UVmodeProb[0];
+  table[13] = entropy->UVmodeProb[1];
+  table[14] = entropy->UVmodeProb[2];
+
+  /* MV probabilities x+y: short, sign, size 8-9 */
+  table[16] = entropy->mvProb[1][0];
+  table[17] = entropy->mvProb[0][0];
+  table[18] = entropy->mvProb[1][1];
+  table[19] = entropy->mvProb[0][1];
+  table[20] = entropy->mvProb[1][17];
+  table[21] = entropy->mvProb[1][18];
+  table[22] = entropy->mvProb[0][17];
+  table[23] = entropy->mvProb[0][18];
+
+  /* MV X size */
+  for (i = 0; i < 8; i++)
+    table[24 + i] = entropy->mvProb[1][9 + i];
+
+  /* MV Y size */
+  for (i = 0; i < 8; i++)
+    table[32 + i] = entropy->mvProb[0][9 + i];
+
+  /* MV X short tree */
+  for (i = 0; i < 7; i++)
+    table[40 + i] = entropy->mvProb[1][2 + i];
+
+  /* MV Y short tree */
+  for (i = 0; i < 7; i++)
+    table[48 + i] = entropy->mvProb[0][2 + i];
+
+  /* Update the ASIC table when needed. */
+  if (entropy->updateCoeffProbFlag) {
+    table += 56;
+    /* DCT coeff probabilities 0-2, two fields per line. */
+    for (i = 0; i < 4; i++)
+      for (j = 0; j < 8; j++)
+        for (k = 0; k < 3; k++) {
+          for (l = 0; l < 3; l++) {
+            *table++ = entropy->coeffProb[i][j][k][l];
+          }
+          *table++ = 0;
+        }
+
+    /* ASIC second probability table in ext mem.
+     * DCT coeff probabilities 4 5 6 7 8 9 10 3 on each line.
+     * coeff 3 was moved from first table to second so it is last. */
+    for (i = 0; i < 4; i++)
+      for (j = 0; j < 8; j++)
+        for (k = 0; k < 3; k++) {
+          for (l = 4; l < 11; l++) {
+            *table++ = entropy->coeffProb[i][j][k][l];
+          }
+          *table++ = entropy->coeffProb[i][j][k][3];
+        }
+  }
+
+  table = (uint8_t*)inst->asic.cabacCtx.vir_addr;
+  if (entropy->updateCoeffProbFlag)
+    EncSwapEndianess((uint32_t*)table, 56 + 8 * 48 + 8 * 96);
+  else
+    EncSwapEndianess((uint32_t*)table, 56);
+}
+
+void InitTreePenaltyTables(vp8Instance_s* container) {
+  mbs* mbs = &container->mbs;     /* Macroblock related stuff */
+  int32_t tmp, i;
+
+  /* Calculate bit cost for each 16x16 mode, uses p-frame probs */
+  for (i = DC_PRED; i <= B_PRED; i++) {
+    tmp = CostTree(YmodeTree[i], (int32_t*)YmodeProb);
+    mbs->intra16ModeBitCost[i] = tmp;
+  }
+
+  /* Calculate bit cost for each 4x4 mode, uses p-frame probs */
+  for (i = B_DC_PRED; i <= B_HU_PRED; i++) {
+    tmp = CostTree(BmodeTree[i], (int32_t*)BmodeProb);
+    mbs->intra4ModeBitCost[i] = tmp;
+  }
+}
+
+int32_t CostTree(tree const* tree, int32_t* prob) {
+  int32_t value = tree->value;
+  int32_t number = tree->number;
+  int32_t const* index = tree->index;
+  int32_t bitCost = 0;
+
+  while (number--) {
+    bitCost += COST_BOOL(prob[*index++], (value >> number) & 1);
+  }
+
+  return bitCost;
+}
+
+int32_t CostMv(int32_t mvd, int32_t* mvProb) {
+  int32_t i, tmp, bitCost = 0;
+
+  /* Luma motion vectors are doubled, see 18.1 in "VP8 Data Format and
+   * Decoding Guide". */
+  ASSERT(!(mvd & 1));
+  tmp = ABS(mvd >> 1);
+
+  /* Short Tree */
+  if (tmp < 8) {
+    bitCost += COST_BOOL(mvProb[0], 0);
+    bitCost += CostTree(&mvTree[tmp], mvProb + 2);
+    if (!tmp) return bitCost;
+
+    /* Sign */
+    bitCost += COST_BOOL(mvProb[1], mvd < 0);
+    return bitCost;
+  }
+
+  /* Long Tree */
+  bitCost += COST_BOOL(mvProb[0], 1);
+
+  /* Bits 0, 1, 2 */
+  for (i = 0; i < 3; i++) {
+    bitCost += COST_BOOL(mvProb[9 + i], (tmp >> i) & 1);
+  }
+
+  /* Bits 9, 8, 7, 6, 5, 4 */
+  for (i = 9; i > 3; i--) {
+    bitCost += COST_BOOL(mvProb[9 + i], (tmp >> i) & 1);
+  }
+
+  /* Bit 3: if ABS(mvd) < 8, it is coded with short tree, so if here
+   * ABS(mvd) <= 15, bit 3 must be one (because here we code values
+   * 8,...,15) and is not explicitly coded. */
+  if (tmp > 15) {
+    bitCost += COST_BOOL(mvProb[9 + 3], (tmp >> 3) & 1);
+  }
+
+  /* Sign */
+  bitCost += COST_BOOL(mvProb[1], mvd < 0);
+
+  return bitCost;
+}
+
+void CoeffProb(vp8buffer* buffer, int32_t curr[4][8][3][11],
+               int32_t prev[4][8][3][11]) {
+  int32_t i, j, k, l;
+  int32_t prob, new, old;
+
+  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 = coeffUpdateProb[i][j][k][l];
+          old = prev[i][j][k][l];
+          new = curr[i][j][k][l];
+
+          if (new == old) {
+            VP8PutBool(buffer, prob, 0);
+            COMMENT("Coeff prob update");
+          } else {
+            VP8PutBool(buffer, prob, 1);
+            COMMENT("Coeff prob update");
+            VP8PutLit(buffer, new, 8);
+            COMMENT("New prob");
+          }
+        }
+      }
+    }
+  }
+}
+
+void MvProb(vp8buffer* buffer, int32_t curr[2][19], int32_t prev[2][19]) {
+  int32_t i, j;
+  int32_t prob, new, old;
+
+  for (i = 0; i < 2; i++) {
+    for (j = 0; j < 19; j++) {
+      prob = mvUpdateProb[i][j];
+      old = prev[i][j];
+      new = curr[i][j];
+
+      if (new == old) {
+        VP8PutBool(buffer, prob, 0);
+        COMMENT("MV prob update");
+      } else {
+        VP8PutBool(buffer, prob, 1);
+        COMMENT("MV prob update");
+        VP8PutLit(buffer, new >> 1, 7);
+        COMMENT("New prob");
+      }
+    }
+  }
+}
+
+/*------------------------------------------------------------------------------
+    update
+    determine if given probability is to be updated (savings larger than
+    cost of update)
+------------------------------------------------------------------------------*/
+uint32_t update(uint32_t updP, uint32_t left, uint32_t right, uint32_t oldP,
+                uint32_t newP, uint32_t fixed) {
+  int32_t u, s;
+
+  /* how much it costs to update a coeff */
+  u = (int32_t)fixed + ((vp8_prob_cost[255 - updP] - vp8_prob_cost[updP]) >> 8);
+  /* bit savings if updated */
+  s = ((int32_t)left * /* zero branch count */
+       /* diff cost for '0' bin */
+       (vp8_prob_cost[oldP] - vp8_prob_cost[newP]) +
+       (int32_t)right * /* one branch count */
+       /* diff cost for '1' bin */
+       (vp8_prob_cost[255 - oldP] - vp8_prob_cost[255 - newP])) >> 8;
+
+  return (s > u);
+}
+
+/*------------------------------------------------------------------------------
+    mvprob
+    compute new mv probability
+------------------------------------------------------------------------------*/
+uint32_t mvprob(uint32_t left, uint32_t right, uint32_t oldP) {
+  uint32_t p;
+
+  if (left + right) {
+    p = (left * 255) / (left + right);
+    p &= -2;
+    if (!p) p = 1;
+  } else
+    p = oldP;
+
+  return p;
+}
+
+/*------------------------------------------------------------------------------
+    UpdateEntropy
+------------------------------------------------------------------------------*/
+void UpdateEntropy(vp8Instance_s* inst) {
+  entropy* entropy = inst->entropy;
+  int32_t i, j, k, l, tmp, ii;
+  uint16_t* pCnt = (uint16_t*)inst->asic.probCount.vir_addr;
+  uint16_t* pTmp;
+  uint32_t p, left, right, oldP, updP;
+  uint32_t type;
+  uint32_t branchCnt[2];
+  const int32_t offset[] = {
+    -1, -1, -1,  0,  1,  2, -1,  3,  4, -1,  5,  6, -1,  7,  8, -1,
+    9, 10, -1, 11, 12, 13, 14, 15, -1, 16, 17, -1, 18, 19, -1, 20,
+    21, -1, 22, 23, -1, 24, 25, -1, 26, 27, 28, 29, 30, -1, 31, 32,
+    -1, 33, 34, -1, 35, 36, -1, 37, 38, -1, 39, 40, -1, 41, 42, 43,
+    44, 45, -1, 46, 47, -1, 48, 49, -1, 50, 51, -1, 52, 53, -1, 54,
+    55, -1, 56, 57, -1, -1, -1, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+    67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+    83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
+    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+    115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
+    131, 132, 133, 134, 135, 136, 137, 138, -1, -1, -1, 139, 140, 141, 142, 143,
+    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
+    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
+    208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219 };
+
+  /* Update the HW prob table only when needed. */
+  entropy->updateCoeffProbFlag = 0;
+
+  /* Use default propabilities as reference when needed. */
+  if (!inst->sps.refreshEntropy || inst->picBuffer.cur_pic->i_frame) {
+    /* Only do the copying when something has changed. */
+    if (!entropy->defaultCoeffProbFlag) {
+      memcpy(entropy->coeffProb, defaultCoeffProb,
+             sizeof(defaultCoeffProb));
+      entropy->updateCoeffProbFlag = 1;
+    }
+    memcpy(entropy->mvProb, defaultMvProb, sizeof(defaultMvProb));
+    entropy->defaultCoeffProbFlag = 1;
+  }
+
+  /* store current probs */
+  memcpy(entropy->oldCoeffProb, entropy->coeffProb, sizeof(entropy->coeffProb));
+  if (inst->frameCnt == 0 || !inst->picBuffer.last_pic->i_frame)
+    memcpy(entropy->oldMvProb, entropy->mvProb, sizeof(entropy->mvProb));
+
+  /* init probs */
+  entropy->skipFalseProb = defaultSkipFalseProb[inst->rateControl.qpHdr];
+
+  /* Do not update on first frame, token/branch counters not valid yet. */
+  if (inst->frameCnt == 0) return;
+
+  /* Do not update probabilities for droppable frames. */
+  if (!inst->picBuffer.cur_pic->ipf && !inst->picBuffer.cur_pic->grf &&
+      !inst->picBuffer.cur_pic->arf) return;
+
+  /* If previous frame was lost the prob counters are not valid. */
+  if (inst->prevFrameLost) return;
+
+#ifdef TRACE_PROBS
+  /* Trace HW output prob counters into file */
+  EncTraceProbs(pCnt, ASIC_VP8_PROB_COUNT_SIZE);
+#endif
+
+  /* All four block types */
+  for (i = 0; i < 4; i++) {
+    /* All but last (==7) bands */
+    for (j = 0; j < MAX_BAND; j++)
+      /* All three neighbour contexts */
+      for (k = 0; k < MAX_CTX; k++) {
+        /* last token of current (type,band,ctx) */
+        tmp = i * MAX_BAND * MAX_CTX + j * MAX_CTX + k;
+        tmp += 2 * 4 * MAX_BAND * MAX_CTX;
+        ii = offset[tmp];
+
+        right = ii >= 0 ? pCnt[ii] : 0;
+
+        /* first two branch probabilities */
+        for (l = 2; l--;) {
+          oldP = entropy->coeffProb[i][j][k][l];
+          updP = coeffUpdateProb[i][j][k][l];
+
+          tmp -= 4 * MAX_BAND * MAX_CTX;
+          ii = offset[tmp];
+          left = ii >= 0 ? pCnt[ii] : 0;
+          /* probability of 0 for current branch */
+          if (left + right) {
+            p = ((left * 256) + ((left + right) >> 1)) / (left + right);
+            if (p > 255) p = 255;
+          } else
+            p = oldP;
+
+          if (update(updP, left, right, oldP, p, 8)) {
+            entropy->coeffProb[i][j][k][l] = p;
+            entropy->updateCoeffProbFlag = 1;
+          }
+          right += left;
+        }
+      }
+  }
+
+  /* If updating coeffProbs the defaults are no longer in use. */
+  if (entropy->updateCoeffProbFlag)
+    entropy->defaultCoeffProbFlag = 0;
+
+  /* skip prob */
+  pTmp = pCnt + ASIC_VP8_PROB_COUNT_MODE_OFFSET;
+  p = pTmp[0] * 256 / inst->mbPerFrame;
+  entropy->skipFalseProb = CLIP3(256 - (int32_t)p, 0, 255);
+
+  /* intra prob,, do not update if previous was I frame */
+  if (!inst->picBuffer.last_pic->i_frame) {
+    p = pTmp[1] * 255 / inst->mbPerFrame;
+    entropy->intraProb = CLIP3(p, 0, 255);
+  } else
+    entropy->intraProb = 63; /* TODO default value */
+
+  /* MV probs shouldn't be updated if previous or current frame is intra */
+  if (inst->picBuffer.last_pic->i_frame || inst->picBuffer.cur_pic->i_frame)
+    return;
+
+  /* mv probs */
+  pTmp = pCnt + ASIC_VP8_PROB_COUNT_MV_OFFSET;
+  for (i = 0; i < 2; i++) {
+    /* is short prob */
+    left = *pTmp++; /* short */
+    right = *pTmp++; /* long */
+
+    p = mvprob(left, right, entropy->oldMvProb[i][0]);
+    if (update(mvUpdateProb[i][0], left, right,
+               entropy->oldMvProb[i][0], p, 6))
+      entropy->mvProb[i][0] = p;
+
+    /* sign prob */
+    right += left; /* total mvs */
+    left = *pTmp++; /* num positive */
+    /* amount of negative vectors = total - positive - zero vectors */
+    right -= left - pTmp[0];
+
+    p = mvprob(left, right, entropy->oldMvProb[i][1]);
+    if (update(mvUpdateProb[i][1], left, right,
+               entropy->oldMvProb[i][1], p, 6))
+      entropy->mvProb[i][1] = p;
+
+    /* short mv probs, branches 2 and 3 (0/1 and 2/3) */
+    for (j = 0; j < 2; j++) {
+      left = *pTmp++;
+      right = *pTmp++;
+      p = mvprob(left, right, entropy->oldMvProb[i][4 + j]);
+      if (update(mvUpdateProb[i][4 + j], left, right,
+                 entropy->oldMvProb[i][4 + j], p, 6))
+        entropy->mvProb[i][4 + j] = p;
+      branchCnt[j] = left + right;
+    }
+    /* short mv probs, branch 1 */
+    p = mvprob(branchCnt[0], branchCnt[1], entropy->oldMvProb[i][3]);
+    if (update(mvUpdateProb[i][3], branchCnt[0], branchCnt[1],
+               entropy->oldMvProb[i][3], p, 6))
+      entropy->mvProb[i][3] = p;
+
+    /* store total count for branch 0 computation */
+    type = branchCnt[0] + branchCnt[1];
+
+    /* short mv probs, branches 5 and 6 (4/5 and 6/7) */
+    for (j = 0; j < 2; j++) {
+      left = *pTmp++;
+      right = *pTmp++;
+      p = mvprob(left, right, entropy->oldMvProb[i][7 + j]);
+      if (update(mvUpdateProb[i][7 + j], left, right,
+                 entropy->oldMvProb[i][7 + j], p, 6))
+        entropy->mvProb[i][7 + j] = p;
+      branchCnt[j] = left + right;
+    }
+    /* short mv probs, branch 4 */
+    p = mvprob(branchCnt[0], branchCnt[1], entropy->oldMvProb[i][6]);
+    if (update(mvUpdateProb[i][6], branchCnt[0], branchCnt[1],
+               entropy->oldMvProb[i][6], p, 6))
+      entropy->mvProb[i][6] = p;
+
+    /* short mv probs, branch 0 */
+    p = mvprob(type, branchCnt[0] + branchCnt[1], entropy->oldMvProb[i][2]);
+    if (update(mvUpdateProb[i][2], type, branchCnt[0] + branchCnt[1],
+               entropy->oldMvProb[i][2], p, 6))
+      entropy->mvProb[i][2] = p;
+  }
+}
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8entropy.h b/libv4l-rockchip/libvpu/vp8_enc/vp8entropy.h
new file mode 100644
index 0000000..4168ea9
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8entropy.h
@@ -0,0 +1,32 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef VP8ENTROPY_H
+#define VP8ENTROPY_H
+
+#include "vp8entropytools.h"
+#include "vp8putbits.h"
+#include "vp8instance.h"
+
+void EncSwapEndianess(uint32_t* buf, uint32_t sizeBytes);
+void InitEntropy(vp8Instance_s* inst);
+void WriteEntropyTables(vp8Instance_s* inst);
+void CoeffProb(vp8buffer* buffer, int32_t curr[4][8][3][11],
+               int32_t prev[4][8][3][11]);
+void MvProb(vp8buffer* buffer, int32_t curr[2][19], int32_t prev[2][19]);
+int32_t CostMv(int32_t mvd, int32_t* mvProb);
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8entropytable.h b/libv4l-rockchip/libvpu/vp8_enc/vp8entropytable.h
new file mode 100644
index 0000000..3b20196
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8entropytable.h
@@ -0,0 +1,697 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef VP8ENTROPY_TABLE_H
+#define VP8ENTROPY_TABLE_H
+
+/*------------------------------------------------------------------------------
+    1. Include headers
+------------------------------------------------------------------------------*/
+#include "vp8putbits.h"
+
+/*------------------------------------------------------------------------------
+    2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+    3. Module defines
+------------------------------------------------------------------------------*/
+
+/* Luma trees of keyframe and not key frame and default propability */
+static const tree const Ymode[] = {
+  { 0, 1, { 0 } },            /* (kf) B_PRED  / DC_PRED   0 */
+  { 4, 3, { 0, 1, 2 } },        /* (kf) DC_PRED / V_PRED  100 */
+  { 5, 3, { 0, 1, 2 } },        /* (kf) V_PRED  / H_PRED  101 */
+  { 6, 3, { 0, 1, 3 } },        /* (kf) H_PRED  / TM_PRED 110 */
+  { 7, 3, { 0, 1, 3 } }         /* (kf) TM_PRED / B_PRED  111 */
+};
+
+static const tree const* YmodeTree[] = {
+  Ymode,              /* prediction type = DC_PRED */
+  Ymode + 1,          /* prediction type = V_PRED  */
+  Ymode + 2,          /* prediction type = H_PRED  */
+  Ymode + 3,          /* prediction type = TM_PRED */
+  Ymode + 4           /* prediction type = B_PRED  */
+};
+
+static const int32_t const kfYmodeProb[4] = {
+  145, 156, 163, 128
+};
+
+static const int32_t const YmodeProb[4] = {
+  112, 86, 140, 37
+};
+
+/* Luma tree of subblocks */
+static const tree const Bmode[] = {
+  { 0,   1, { 0 } },          /* B_DC_PRED,        0 */
+  { 2,   2, { 0, 1 } },        /* B_TM_PRED,       10 */
+  { 6,   3, { 0, 1, 2 } },      /* B_VE_PRED,      110 */
+  { 28,  5, { 0, 1, 2, 3, 4 } },      /* B_HE_PRED,    11100 */
+  { 58,  6, { 0, 1, 2, 3, 4, 5 } },    /* B_LD_PRED,   111010 */
+  { 59,  6, { 0, 1, 2, 3, 4, 5 } },    /* B_RD_PRED,   111011 */
+  { 30,  5, { 0, 1, 2, 3, 6 } },      /* B_VR_PRED,    11110 */
+  { 62,  6, { 0, 1, 2, 3, 6, 7 } },    /* B_VL_PRED,   111110 */
+  { 126, 7, { 0, 1, 2, 3, 6, 7, 8 } },  /* B_HD_PRED,  1111110 */
+  { 127, 7, { 0, 1, 2, 3, 6, 7, 8 } }   /* B_HU_PRED,  1111111 */
+};
+
+static const tree const* BmodeTree[] = {
+  NULL,               /* prediction type = DC_PRED,     */
+  NULL,               /* prediction type = V_PRED,      */
+  NULL,               /* prediction type = H_PRED,      */
+  NULL,               /* prediction type = TM_PRED,     */
+  NULL,               /* prediction type = B_PRED,      */
+  Bmode,              /* prediction type = B_DC_PRED,   */
+  Bmode + 1,          /* prediction type = B_TM_PRED,   */
+  Bmode + 2,          /* prediction type = B_VE_PRED,   */
+  Bmode + 3,          /* prediction type = B_HE_PRED,   */
+  Bmode + 6,          /* prediction type = B_LD_PRED,   */
+  Bmode + 4,          /* prediction type = B_RD_PRED,   */
+  Bmode + 5,          /* prediction type = B_VR_PRED,   */
+  Bmode + 7,          /* prediction type = B_VL_PRED,   */
+  Bmode + 8,          /* prediction type = B_HD_PRED,   */
+  Bmode + 9           /* prediction type = B_HU_PRED,   */
+};
+
+static const int32_t const kfBmodeProb[10][10][9] = {
+  {
+    { 231, 120,  48,  89, 115, 113, 120, 152, 112 },
+    { 152, 179,  64, 126, 170, 118,  46,  70,  95 },
+    { 175,  69, 143,  80,  85,  82,  72, 155, 103 },
+    { 56,  58,  10, 171, 218, 189,  17,  13, 152 },
+    { 144,  71,  10,  38, 171, 213, 144,  34,  26 },
+    { 114,  26,  17, 163,  44, 195,  21,  10, 173 },
+    { 121,  24,  80, 195,  26,  62,  44,  64,  85 },
+    { 170,  46,  55,  19, 136, 160,  33, 206,  71 },
+    { 63,  20,   8, 114, 114, 208,  12,   9, 226 },
+    { 81,  40,  11,  96, 182,  84,  29,  16,  36 }
+  },
+
+  {
+    { 134, 183,  89, 137,  98, 101, 106, 165, 148 },
+    { 72, 187, 100, 130, 157, 111,  32,  75,  80 },
+    { 66, 102, 167,  99,  74,  62,  40, 234, 128 },
+    { 41,  53,   9, 178, 241, 141,  26,   8, 107 },
+    { 104,  79,  12,  27, 217, 255,  87,  17,   7 },
+    { 74,  43,  26, 146,  73, 166,  49,  23, 157 },
+    { 65,  38, 105, 160,  51,  52,  31, 115, 128 },
+    { 87,  68,  71,  44, 114,  51,  15, 186,  23 },
+    { 47,  41,  14, 110, 182, 183,  21,  17, 194 },
+    { 66,  45,  25, 102, 197, 189,  23,  18,  22 }
+  },
+
+  {
+    { 88,  88, 147, 150,  42,  46,  45, 196, 205 },
+    { 43,  97, 183, 117,  85,  38,  35, 179,  61 },
+    { 39,  53, 200,  87,  26,  21,  43, 232, 171 },
+    { 56,  34,  51, 104, 114, 102,  29,  93,  77 },
+    { 107,  54,  32,  26,  51,   1,  81,  43,  31 },
+    { 39,  28,  85, 171,  58, 165,  90,  98,  64 },
+    { 34,  22, 116, 206,  23,  34,  43, 166,  73 },
+    { 68,  25, 106,  22,  64, 171,  36, 225, 114 },
+    { 34,  19,  21, 102, 132, 188,  16,  76, 124 },
+    { 62,  18,  78,  95,  85,  57,  50,  48,  51 }
+  },
+
+  {
+    { 193, 101,  35, 159, 215, 111,  89,  46, 111 },
+    { 60, 148,  31, 172, 219, 228,  21,  18, 111 },
+    { 112, 113,  77,  85, 179, 255,  38, 120, 114 },
+    { 40,  42,   1, 196, 245, 209,  10,  25, 109 },
+    { 100,  80,   8,  43, 154,   1,  51,  26,  71 },
+    { 88,  43,  29, 140, 166, 213,  37,  43, 154 },
+    { 61,  63,  30, 155,  67,  45,  68,   1, 209 },
+    { 142,  78,  78,  16, 255, 128,  34, 197, 171 },
+    { 41,  40,   5, 102, 211, 183,   4,   1, 221 },
+    { 51,  50,  17, 168, 209, 192,  23,  25,  82 }
+  },
+
+  {
+    { 125,  98,  42,  88, 104,  85, 117, 175,  82 },
+    { 95,  84,  53,  89, 128, 100, 113, 101,  45 },
+    { 75,  79, 123,  47,  51, 128,  81, 171,   1 },
+    { 57,  17,   5,  71, 102,  57,  53,  41,  49 },
+    { 115,  21,   2,  10, 102, 255, 166,  23,   6 },
+    { 38,  33,  13, 121,  57,  73,  26,   1,  85 },
+    { 41,  10,  67, 138,  77, 110,  90,  47, 114 },
+    { 101,  29,  16,  10,  85, 128, 101, 196,  26 },
+    { 57,  18,  10, 102, 102, 213,  34,  20,  43 },
+    { 117,  20,  15,  36, 163, 128,  68,   1,  26 }
+  },
+
+  {
+    { 138,  31,  36, 171,  27, 166,  38,  44, 229 },
+    { 67,  87,  58, 169,  82, 115,  26,  59, 179 },
+    { 63,  59,  90, 180,  59, 166,  93,  73, 154 },
+    { 40,  40,  21, 116, 143, 209,  34,  39, 175 },
+    { 57,  46,  22,  24, 128,   1,  54,  17,  37 },
+    { 47,  15,  16, 183,  34, 223,  49,  45, 183 },
+    { 46,  17,  33, 183,   6,  98,  15,  32, 183 },
+    { 65,  32,  73, 115,  28, 128,  23, 128, 205 },
+    { 40,   3,   9, 115,  51, 192,  18,   6, 223 },
+    { 87,  37,   9, 115,  59,  77,  64,  21,  47 }
+  },
+
+  {
+    { 104,  55,  44, 218,   9,  54,  53, 130, 226 },
+    { 64,  90,  70, 205,  40,  41,  23,  26,  57 },
+    { 54,  57, 112, 184,   5,  41,  38, 166, 213 },
+    { 30,  34,  26, 133, 152, 116,  10,  32, 134 },
+    { 75,  32,  12,  51, 192, 255, 160,  43,  51 },
+    { 39,  19,  53, 221,  26, 114,  32,  73, 255 },
+    { 31,   9,  65, 234,   2,  15,   1, 118,  73 },
+    { 88,  31,  35,  67, 102,  85,  55, 186,  85 },
+    { 56,  21,  23, 111,  59, 205,  45,  37, 192 },
+    { 55,  38,  70, 124,  73, 102,   1,  34,  98 }
+  },
+
+  {
+    { 102,  61,  71,  37,  34,  53,  31, 243, 192 },
+    { 69,  60,  71,  38,  73, 119,  28, 222,  37 },
+    { 68,  45, 128,  34,   1,  47,  11, 245, 171 },
+    { 62,  17,  19,  70, 146,  85,  55,  62,  70 },
+    { 75,  15,   9,   9,  64, 255, 184, 119,  16 },
+    { 37,  43,  37, 154, 100, 163,  85, 160,   1 },
+    { 63,   9,  92, 136,  28,  64,  32, 201,  85 },
+    { 86,   6,  28,   5,  64, 255,  25, 248,   1 },
+    { 56,   8,  17, 132, 137, 255,  55, 116, 128 },
+    { 58,  15,  20,  82, 135,  57,  26, 121,  40 }
+  },
+
+  {
+    { 164,  50,  31, 137, 154, 133,  25,  35, 218 },
+    { 51, 103,  44, 131, 131, 123,  31,   6, 158 },
+    { 86,  40,  64, 135, 148, 224,  45, 183, 128 },
+    { 22,  26,  17, 131, 240, 154,  14,   1, 209 },
+    { 83,  12,  13,  54, 192, 255,  68,  47,  28 },
+    { 45,  16,  21,  91,  64, 222,   7,   1, 197 },
+    { 56,  21,  39, 155,  60, 138,  23, 102, 213 },
+    { 85,  26,  85,  85, 128, 128,  32, 146, 171 },
+    { 18,  11,   7,  63, 144, 171,   4,   4, 246 },
+    { 35,  27,  10, 146, 174, 171,  12,  26, 128 }
+  },
+
+  {
+    { 190,  80,  35,  99, 180,  80, 126,  54,  45 },
+    { 85, 126,  47,  87, 176,  51,  41,  20,  32 },
+    { 101,  75, 128, 139, 118, 146, 116, 128,  85 },
+    { 56,  41,  15, 176, 236,  85,  37,   9,  62 },
+    { 146,  36,  19,  30, 171, 255,  97,  27,  20 },
+    { 71,  30,  17, 119, 118, 255,  17,  18, 138 },
+    { 101,  38,  60, 138,  55,  70,  43,  26, 142 },
+    { 138,  45,  61,  62, 219,   1,  81, 188,  64 },
+    { 32,  41,  20, 117, 151, 142,  20,  21, 163 },
+    { 112,  19,  12,  61, 195, 128,  48,   4,  24 }
+  }
+};
+
+static const int32_t const BmodeProb[9] = {
+  120, 90, 79, 133, 87, 85, 80, 111, 151
+};
+
+static const int32_t const kfUVmodeProb[3] = {
+  142, 114, 183
+};
+
+static const int32_t const UVmodeProb[3] = {
+  162, 101, 204
+};
+
+static const int32_t const defaultCoeffProb[4][8][3][11] = {
+  {
+    {
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    {
+      { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128 },
+      { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128 },
+      { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128 }
+    },
+    {
+      {  1,  98, 248, 255, 236, 226, 255, 255, 128, 128, 128 },
+      { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128 },
+      { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128 }
+    },
+    {
+      {  1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128 },
+      { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128 },
+      { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128 }
+    },
+    {
+      {  1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128 },
+      { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128 },
+      { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128 }
+    },
+    {
+      {  1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128 },
+      { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128 },
+      { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128 }
+    },
+    {
+      {  1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128 },
+      { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128 },
+      { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128 }
+    },
+    {
+      {  1,   1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 246,   1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  },
+
+  {
+    {
+      { 198,  35, 237, 223, 193, 187, 162, 160, 145, 155,  62 },
+      { 131,  45, 198, 221, 172, 176, 220, 157, 252, 221,   1 },
+      { 68,  47, 146, 208, 149, 167, 221, 162, 255, 223, 128 }
+    },
+    {
+      {  1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128 },
+      { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128 },
+      { 81,  99, 181, 242, 176, 190, 249, 202, 255, 255, 128 }
+    },
+    {
+      {  1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128 },
+      { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128 },
+      { 23,  91, 163, 242, 170, 187, 247, 210, 255, 255, 128 }
+    },
+    {
+      {  1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128 },
+      { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128 },
+      { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128 }
+    },
+    {
+      {  1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128 },
+      { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128 },
+      { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128 }
+    },
+    {
+      {  1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128 },
+      { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128 },
+      { 35,  77, 181, 251, 193, 211, 255, 205, 128, 128, 128 }
+    },
+    {
+      {  1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128 },
+      { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128 },
+      { 45,  99, 188, 251, 195, 217, 255, 224, 128, 128, 128 }
+    },
+    {
+      {  1,   1, 251, 255, 213, 255, 128, 128, 128, 128, 128 },
+      { 203,   1, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 137,   1, 177, 255, 224, 255, 128, 128, 128, 128, 128 }
+    }
+  },
+
+  {
+    {
+      { 253,   9, 248, 251, 207, 208, 255, 192, 128, 128, 128 },
+      { 175,  13, 224, 243, 193, 185, 249, 198, 255, 255, 128 },
+      { 73,  17, 171, 221, 161, 179, 236, 167, 255, 234, 128 }
+    },
+    {
+      {  1,  95, 247, 253, 212, 183, 255, 255, 128, 128, 128 },
+      { 239,  90, 244, 250, 211, 209, 255, 255, 128, 128, 128 },
+      { 155,  77, 195, 248, 188, 195, 255, 255, 128, 128, 128 }
+    },
+    {
+      {  1,  24, 239, 251, 218, 219, 255, 205, 128, 128, 128 },
+      { 201,  51, 219, 255, 196, 186, 128, 128, 128, 128, 128 },
+      { 69,  46, 190, 239, 201, 218, 255, 228, 128, 128, 128 }
+    },
+    {
+      {  1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128 },
+      { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128 }
+    },
+    {
+      {  1,  16, 248, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 190,  36, 230, 255, 236, 255, 128, 128, 128, 128, 128 },
+      { 149,   1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    {
+      {  1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    {
+      {  1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 213,  62, 250, 255, 255, 128, 128, 128, 128, 128, 128 },
+      { 55,  93, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    },
+    {
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  },
+
+  {
+    {
+      { 202,  24, 213, 235, 186, 191, 220, 160, 240, 175, 255 },
+      { 126,  38, 182, 232, 169, 184, 228, 174, 255, 187, 128 },
+      { 61,  46, 138, 219, 151, 178, 240, 170, 255, 216, 128 }
+    },
+    {
+      {  1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128 },
+      { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128 },
+      { 39,  77, 162, 232, 172, 180, 245, 178, 255, 255, 128 }
+    },
+    {
+      {  1,  52, 220, 246, 198, 199, 249, 220, 255, 255, 128 },
+      { 124,  74, 191, 243, 183, 193, 250, 221, 255, 255, 128 },
+      { 24,  71, 130, 219, 154, 170, 243, 182, 255, 255, 128 }
+    },
+    {
+      {  1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128 },
+      { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128 },
+      { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128 }
+    },
+    {
+      {  1,  81, 230, 252, 204, 203, 255, 192, 128, 128, 128 },
+      { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128 },
+      { 20,  95, 153, 243, 164, 173, 255, 203, 128, 128, 128 }
+    },
+    {
+      {  1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128 },
+      { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128 },
+      { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128 }
+    },
+    {
+      {  1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128 },
+      { 141,  84, 213, 252, 201, 202, 255, 219, 128, 128, 128 },
+      { 42,  80, 160, 240, 162, 185, 255, 205, 128, 128, 128 }
+    },
+    {
+      {  1,   1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 244,   1, 255, 128, 128, 128, 128, 128, 128, 128, 128 },
+      { 238,   1, 255, 128, 128, 128, 128, 128, 128, 128, 128 }
+    }
+  }
+};
+
+static const int32_t const coeffUpdateProb[4][8][3][11] = {
+  {
+    {
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+  {
+    {
+      { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255 },
+      { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255 }
+    },
+    {
+      { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+
+  {
+    {
+      { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  },
+
+  {
+    {
+      { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255 },
+      { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    },
+    {
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }
+    }
+  }
+};
+
+static const int32_t const mvUpdateProb[2][19] = {
+  { 237, 246, 253, 253, 254, 254, 254, 254, 254, 254,
+    254, 254, 254, 254, 250, 250, 252, 254, 254 },
+
+  { 231, 243, 245, 253, 254, 254, 254, 254, 254, 254,
+    254, 254, 254, 254, 251, 251, 254, 254, 254 }
+};
+
+static const int32_t const defaultMvProb[2][19] = {
+  { 162, 128, 225, 146, 172, 147, 214,  39, 156, 128,
+    129, 132,  75, 145, 178, 206, 239, 254, 254 },
+
+  { 164, 128, 204, 170, 119, 235, 140, 230, 228, 128,
+    130, 130,  74, 148, 180, 203, 236, 254, 254 }
+};
+
+static const int32_t const subMvPartProb[3] = {
+  110, 111, 150
+};
+
+static const int32_t const subMvRefProb[5][3] = {
+  { 147, 136, 18 },
+  { 106, 145,  1 },
+  { 179, 121,  1 },
+  { 223,   1, 34 },
+  { 208,   1,  1 }
+};
+
+/* Motion vector tree */
+static const tree const mvTree[] = {
+  { 0, 3, { 0, 1, 2 } },        /* mv_0 000 */
+  { 1, 3, { 0, 1, 2 } },        /* mv_1 001 */
+  { 2, 3, { 0, 1, 3 } },        /* mv_2 010 */
+  { 3, 3, { 0, 1, 3 } },        /* mv_3 011 */
+  { 4, 3, { 0, 4, 5 } },        /* mv_4 100 */
+  { 5, 3, { 0, 4, 5 } },        /* mv_5 101 */
+  { 6, 3, { 0, 4, 6 } },        /* mv_6 110 */
+  { 7, 3, { 0, 4, 6 } },        /* mv_7 111 */
+};
+
+/* Segment tree and default propability */
+static const tree const segmentTree[] = {
+  { 0, 2, { 0, 1 } },          /* segmentId = 0, 00 */
+  { 1, 2, { 0, 1 } },          /* segmentId = 1, 01 */
+  { 2, 2, { 0, 2 } },          /* segmentId = 2, 10 */
+  { 3, 2, { 0, 2 } },          /* segmentId = 3, 11 */
+};
+
+static const int32_t const segmentProb[3] = {
+  255, 255, 255
+};
+
+/* If probability being zero is p, then avarage bits used when bool is
+zero = log2(1/p) and when bool is one = log2(1/(1-p)).
+
+For example bins probability being zero is p = 0.5
+bin = 0 -> average bits used is log2(1/0.5)      = 1 bits/bin
+bin = 1 -> average bits used is log2(1/(1 - 0.5) = 1 bits/bin
+
+For example bins probability being zero is p = 0.95
+bin = 0 -> average bits used is log2(1/0.95)      = 0.074 bits/bin
+bin = 1 -> average bits used is log2(1/(1 - 0.95) = 4.321 bits/bin
+
+Table cost[] below is calculated as follow: cost[p] is zero bin's average bit
+cost at given p = [1..255] (note that probability is p/256) scaled up by SCALE.
+for (i = 0; i < 256; i++) cost[i] = round((log2((double)256/i) * SCALE)).
+Magic number SCALE = 256. */
+static const int32_t const vp8_prob_cost[] = {
+  2048, 2048, 1792, 1642, 1536, 1454, 1386, 1329, 1280, 1236,
+  1198, 1162, 1130, 1101, 1073, 1048, 1024, 1002,  980,  961,
+  942,  924,  906,  890,  874,  859,  845,  831,  817,  804,
+  792,  780,  768,  757,  746,  735,  724,  714,  705,  695,
+  686,  676,  668,  659,  650,  642,  634,  626,  618,  611,
+  603,  596,  589,  582,  575,  568,  561,  555,  548,  542,
+  536,  530,  524,  518,  512,  506,  501,  495,  490,  484,
+  479,  474,  468,  463,  458,  453,  449,  444,  439,  434,
+  430,  425,  420,  416,  412,  407,  403,  399,  394,  390,
+  386,  382,  378,  374,  370,  366,  362,  358,  355,  351,
+  347,  343,  340,  336,  333,  329,  326,  322,  319,  315,
+  312,  309,  305,  302,  299,  296,  292,  289,  286,  283,
+  280,  277,  274,  271,  268,  265,  262,  259,  256,  253,
+  250,  247,  245,  242,  239,  236,  234,  231,  228,  226,
+  223,  220,  218,  215,  212,  210,  207,  205,  202,  200,
+  197,  195,  193,  190,  188,  185,  183,  181,  178,  176,
+  174,  171,  169,  167,  164,  162,  160,  158,  156,  153,
+  151,  149,  147,  145,  143,  140,  138,  136,  134,  132,
+  130,  128,  126,  124,  122,  120,  118,  116,  114,  112,
+  110,  108,  106,  104,  102,  101,   99,   97,   95,   93,
+  91,   89,   87,   86,   84,   82,   80,   78,   77,   75,
+  73,   71,   70,   68,   66,   64,   63,   61,   59,   58,
+  56,   54,   53,   51,   49,   48,   46,   44,   43,   41,
+  40,   38,   36,   35,   33,   32,   30,   28,   27,   25,
+  24,   22,   21,   19,   18,   16,   15,   13,   12,   10,
+  9,    7,    6,    4,    3,    1
+};
+
+static const int32_t const defaultSkipFalseProb[128] =
+{
+  255, 255, 255, 255, 255, 255, 255, 255,
+  255, 255, 255, 255, 255, 255, 255, 255,
+  255, 255, 255, 255, 255, 255, 255, 255,
+  255, 255, 255, 255, 255, 255, 255, 255,
+  255, 255, 255, 255, 255, 255, 255, 255,
+  255, 255, 255, 255, 255, 255, 255, 255,
+  255, 255, 255, 255, 255, 255, 255, 255,
+  251, 248, 244, 240, 236, 232, 229, 225,
+  221, 217, 213, 208, 204, 199, 194, 190,
+  187, 183, 179, 175, 172, 168, 164, 160,
+  157, 153, 149, 145, 142, 138, 134, 130,
+  127, 124, 120, 117, 114, 110, 107, 104,
+  101, 98,  95,  92,  89,  86,  83, 80,
+  77,  74,  71,  68,  65,  62,  59, 56,
+  53,  50,  47,  44,  41,  38,  35, 32,
+  30,  28,  26,  24,  22,  20,  18, 16,
+};
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8entropytools.h b/libv4l-rockchip/libvpu/vp8_enc/vp8entropytools.h
new file mode 100644
index 0000000..53dc86d
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8entropytools.h
@@ -0,0 +1,45 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _VP8ENTROPY_TOOLS_H_
+#define _VP8ENTROPY_TOOLS_H_
+
+#include <stdint.h>
+
+typedef struct {
+  int32_t skipFalseProb;
+  int32_t intraProb;
+  int32_t lastProb;
+  int32_t gfProb;
+  int32_t kfYmodeProb[4];
+  int32_t YmodeProb[4];
+  int32_t kfUVmodeProb[3];
+  int32_t UVmodeProb[3];
+  int32_t kfBmodeProb[10][10][9];
+  int32_t BmodeProb[9];
+  int32_t coeffProb[4][8][3][11];
+  int32_t oldCoeffProb[4][8][3][11];
+  int32_t mvRefProb[4];
+  int32_t mvProb[2][19];
+  int32_t oldMvProb[2][19];
+  int32_t subMvPartProb[3];   /* TODO use pointer directly to subMvPartProb */
+  int32_t subMvRefProb[5][3]; /* TODO use pointer directly to subMvRefProb */
+  int32_t defaultCoeffProbFlag;   /* Flag for coeffProb == defaultCoeffProb */
+  int32_t updateCoeffProbFlag;    /* Flag for coeffProb != oldCoeffProb */
+  int32_t segmentProb[3];
+} entropy;
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8header.c b/libv4l-rockchip/libvpu/vp8_enc/vp8header.c
new file mode 100644
index 0000000..01dac05
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8header.c
@@ -0,0 +1,378 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include "vp8header.h"
+
+#include <memory.h>
+#include "vp8entropy.h"
+
+static void Segmentation(vp8buffer* buffer, sps* sps, ppss* ppss,
+                         entropy* entropy, mbs* mbs);
+static void FilterLevelDelta(vp8buffer* buffer, sps* sps);
+
+void VP8FrameHeader(vp8Instance_s* container) {
+  refPic* cur_pic = container->picBuffer.cur_pic;
+  refPic* refPicList = container->picBuffer.refPicList;
+  entropy* entropy = container->entropy;
+  sps* sps = &container->sps;                 /* Sequence container */
+  pps* pps = container->ppss.pps;
+  vp8buffer* buffer = &container->buffer[1];  /* "Frame header" buffer */
+
+  /* Color space and pixel Type (Key frames only) */
+  if (cur_pic->i_frame) {
+    VP8PutLit(buffer, sps->colorType, 1);
+    COMMENT("Frame header, buffer 1, color space type");
+
+    VP8PutLit(buffer, sps->clampType, 1);
+    COMMENT("Frame header, buffer 1, clamping type");
+  }
+
+  /* Segmentation */
+  VP8PutLit(buffer, pps->segmentEnabled, 1);
+  COMMENT("Frame header, buffer 1, segmentation flag");
+  if (pps->segmentEnabled) {
+    Segmentation(buffer, &container->sps, &container->ppss,
+                 entropy, &container->mbs);
+  }
+
+  VP8PutLit(buffer, sps->filterType, 1);
+  COMMENT("Frame header, buffer 1, filter type");
+
+  VP8PutLit(buffer, sps->filterLevel, 6);
+  COMMENT("Frame header, buffer 1, filter level");
+
+  VP8PutLit(buffer, sps->filterSharpness, 3);
+  COMMENT("Frame header, buffer 1, filter sharpness level");
+
+  /* Loop filter adjustments */
+  VP8PutLit(buffer, sps->filterDeltaEnable, 1);
+  COMMENT("Frame header, buffer 1, loop filter adjustments");
+  if (sps->filterDeltaEnable) {
+    /* Filter level delta references reset by key frame */
+    if (cur_pic->i_frame) {
+      memset(sps->oldRefDelta, 0, sizeof(sps->refDelta));
+      memset(sps->oldModeDelta, 0, sizeof(sps->modeDelta));
+    }
+    FilterLevelDelta(buffer, sps);
+  }
+
+  VP8PutLit(buffer, sps->dctPartitions, 2);
+  COMMENT("Frame header, buffer 1, token partition");
+
+  VP8PutLit(buffer, container->rateControl.qpHdr, 7);
+  COMMENT("Frame header, buffer 1, YacQi quantizer index");
+
+  /* TODO: delta quantization index */
+  VP8PutLit(buffer, 0, 1);
+  COMMENT("Frame header, buffer 1, YdcDelta flag");
+  VP8PutLit(buffer, 0, 1);
+  COMMENT("Frame header, buffer 1, Y2dcDelta flag");
+  VP8PutLit(buffer, 0, 1);
+  COMMENT("Frame header, buffer 1, Y2acDelta flag");
+  VP8PutLit(buffer, 0, 1);
+  COMMENT("Frame header, buffer 1, UVdcDelta flag");
+  VP8PutLit(buffer, 0, 1);
+  COMMENT("Frame header, buffer 1, UVacDelta flag");
+
+  /* Update grf and arf buffers and sing bias, see decodframe.c 863.
+   * TODO swaping arg->grf and grf->arf in the same time is not working
+   * because of bug in the libvpx? */
+  if (!cur_pic->i_frame) {
+    /* Input picture after reconstruction is set to new grf/arf */
+    VP8PutLit(buffer, cur_pic->grf, 1); /* Grf refresh */
+    COMMENT("Frame header, buffer 1, grf refresh");
+    VP8PutLit(buffer, cur_pic->arf, 1); /* Arf refresh */
+    COMMENT("Frame header, buffer 1, arf refresh");
+
+    if (!cur_pic->grf) {
+      if (refPicList[0].grf) {
+        VP8PutLit(buffer, 1, 2);    /* Ipf -> grf */
+        COMMENT("Frame header, buffer 1, ipf -> grf");
+      } else if (refPicList[2].grf) {
+        VP8PutLit(buffer, 2, 2);    /* Arf -> grf */
+        COMMENT("Frame header, buffer 1, arf -> grf");
+      } else {
+        VP8PutLit(buffer, 0, 2);    /* Not updated */
+        COMMENT("Frame header, buffer 1, no update");
+      }
+    }
+
+    if (!cur_pic->arf) {
+      if (refPicList[0].arf) {
+        VP8PutLit(buffer, 1, 2);    /* Ipf -> arf */
+        COMMENT("Frame header, buffer 1, ipf -> arf");
+      } else if (refPicList[1].arf) {
+        VP8PutLit(buffer, 2, 2);    /* Grf -> arf */
+        COMMENT("Frame header, buffer 1, grf -> arf");
+      } else {
+        VP8PutLit(buffer, 0, 2);    /* Not updated */
+        COMMENT("Frame header, buffer 1, no update");
+      }
+    }
+
+    /* Sing bias. TODO adaptive sing bias. */
+    VP8PutLit(buffer, sps->singBias[1], 1);  /* Grf */
+    COMMENT("Frame header, buffer 1, grf sign bias");
+    VP8PutLit(buffer, sps->singBias[2], 1);  /* Arf */
+    COMMENT("Frame header, buffer 1, arf sign bias");
+  }
+
+
+  /* RefreshEntropyProbs, if 0 -> put default proabilities. If 1
+   * use previous frame probabilities */
+  VP8PutLit(buffer, sps->refreshEntropy, 1);
+  COMMENT("Frame header, buffer 1, Refresh entropy probs flag");
+
+  /* RefreshLastFrame flag. Note that key frame always updates ipf */
+  if (!cur_pic->i_frame) {
+    VP8PutLit(buffer, cur_pic->ipf, 1);
+    COMMENT("Frame header, buffer 1, ipf refresh last frame flag");
+  }
+
+  /* Coeff probabilities, TODO: real updates */
+  CoeffProb(buffer, entropy->coeffProb, entropy->oldCoeffProb);
+
+  /*  mb_no_coeff_skip . This flag indicates at the frame level if
+   *  skipping of macroblocks with no non-zero coefficients is enabled.
+   *  If it is set to 0 then prob_skip_false is not read and
+   *  mb_skip_coeff is forced to 0 for all macroblocks (see Sections 11.1
+   *  and 12.1). TODO  */
+  VP8PutLit(buffer, 1, 1);
+  COMMENT("Frame header, buffer 1, mb no coeff skip");
+  /* Probability used for decoding noCoeff flag, depens above flag TODO*/
+  VP8PutLit(buffer, entropy->skipFalseProb, 8);
+  COMMENT("Frame header, buffer 1, skip false prob");
+
+  if (cur_pic->i_frame) return;
+
+  /* The rest are inter frame only */
+
+  /* Macroblock is intra predicted probability */
+  VP8PutLit(buffer, entropy->intraProb, 8);
+  COMMENT("Frame header, buffer 1, intra prob");
+
+  /* Inter is predicted from immediately previous frame probability */
+  VP8PutLit(buffer, entropy->lastProb, 8);
+  COMMENT("Frame header, buffer 1, last prob");
+
+  /* Inter is predicted from golden frame probability */
+  VP8PutLit(buffer, entropy->gfProb, 8);
+  COMMENT("Frame header, buffer 1, gf prob");
+
+  /* Intra mode probability updates not supported yet TODO */
+  VP8PutLit(buffer, 0, 1);
+  COMMENT("Frame header, buffer 1, intra mode prob update");
+
+  /* Intra chroma probability updates not supported yet TODO */
+  VP8PutLit(buffer, 0, 1);
+  COMMENT("Frame header, buffer 1, intra chroma prob update");
+
+  /* Motion vector probability update not supported yet TOTO real updates */
+  MvProb(buffer, entropy->mvProb, entropy->oldMvProb);
+}
+
+/*------------------------------------------------------------------------------
+    FrameTag
+------------------------------------------------------------------------------*/
+void VP8FrameTag(vp8Instance_s* container) {
+  picBuffer* picBuffer = &container->picBuffer;
+  refPic* cur_pic = picBuffer->cur_pic;
+  sps* sps = &container->sps;                 /* Sequence container */
+  vp8buffer* buffer = &container->buffer[0];  /* Frame tag buffer */
+  int32_t tmp;
+
+  /* Frame tag contains (lsb first):
+   * 1. A 1-bit frame type (0 for key frames, 1 for inter frames)
+   * 2. A 3-bit version number (0 - 3 are defined as 4 different profiles
+   * 3. A 1-bit showFrame flag (1 when current frame is display)
+   * 4. A 19-bit size of the first data partition in bytes
+   * Note that frame tag is written to the stream in little endian mode */
+
+  tmp = ((container->buffer[1].byteCnt) << 5) |
+          ((cur_pic->show ? 1 : 0) << 4) |
+          (container->sps.profile << 1) |
+          (cur_pic->i_frame ? 0 : 1);
+
+  /* Note that frame tag is written _really_ literal to buffer, don't use
+   * VP8PutLit() use VP8PutBit() instead */
+
+  VP8PutByte(buffer, tmp & 0xff);
+  COMMENT("Frame tag, buffer 0, The first byte");
+
+  VP8PutByte(buffer, (tmp >> 8) & 0xff);
+  COMMENT("Frame tag, buffer 0, The second byte");
+
+  VP8PutByte(buffer, (tmp >> 16) & 0xff);
+  COMMENT("Frame tag, buffer 0, The third byte");
+
+  if (!cur_pic->i_frame) return;
+
+  /* For key frames this is followed by a further 7 bytes of uncompressed
+   * data as follows */
+  VP8PutByte(buffer, 0x9d);
+  COMMENT("Frame tag, buffer 0, next byte");
+  VP8PutByte(buffer, 0x01);
+  COMMENT("Frame tag, buffer 0, next byte");
+  VP8PutByte(buffer, 0x2a);
+  COMMENT("Frame tag, buffer 0, next byte");
+
+  tmp = sps->picWidthInPixel | (sps->horizontalScaling << 14);
+  VP8PutByte(buffer, tmp & 0xff);
+  COMMENT("Frame tag, buffer 0, next byte");
+  VP8PutByte(buffer, tmp >> 8);
+  COMMENT("Frame tag, buffer 0, next byte");
+
+  tmp = sps->picHeightInPixel | (sps->verticalScaling << 14);
+  VP8PutByte(buffer, tmp & 0xff);
+  COMMENT("Frame tag, buffer 0, next byte");
+  VP8PutByte(buffer, tmp >> 8);
+  COMMENT("Frame tag, buffer 0, next byte");
+}
+
+/*------------------------------------------------------------------------------
+    Segmentation
+------------------------------------------------------------------------------*/
+void Segmentation(vp8buffer* buffer, sps* sps, ppss* ppss, entropy* entropy,
+                  mbs* mbs) {
+  pps* pps = ppss->pps;
+  sgm* sgm = &ppss->pps->sgm;     /* New segmentation data */
+  int32_t i, tmp;
+  bool dataModified = false;
+
+  /* Do we need to updata segmentation data */
+  if (memcmp(ppss->qpSgm, pps->qpSgm, sizeof(ppss->qpSgm)))
+    dataModified = true;
+
+  if (memcmp(ppss->levelSgm, pps->levelSgm, sizeof(ppss->levelSgm)))
+    dataModified = true;
+
+  /* Update segmentation map only if there are no previous map or
+   * previous map differs or previous frame did not use segmentation at
+   * all. Note also that API set mapModified=true if user changes
+   * segmentation map */
+  if (!ppss->prevPps) {
+    sgm->mapModified = true;
+  }
+
+  COMMENT("Frame header, buffer 1, segmentation map modified");
+  VP8PutLit(buffer, sgm->mapModified, 1);
+  COMMENT("Frame header, buffer 1, segmentation data modified");
+  VP8PutLit(buffer, dataModified, 1);
+
+  if (dataModified) {
+    COMMENT("Frame header, buffer 1, segmentation data abs");
+    /* ABS=1 vs. Deltas=0 */
+    VP8PutLit(buffer, 1, 1);
+
+    for (i = 0; i < SGM_CNT; i++) {
+      tmp = pps->qpSgm[i];
+      VP8PutLit(buffer, 1, 1);
+      VP8PutLit(buffer, ABS(tmp), 7);
+      VP8PutLit(buffer, tmp < 0, 1);
+    }
+
+    for (i = 0; i < SGM_CNT; i++) {
+      tmp = pps->levelSgm[i];
+      VP8PutLit(buffer, 1, 1);
+      VP8PutLit(buffer, ABS(tmp), 6);
+      VP8PutLit(buffer, tmp < 0, 1);
+    }
+  }
+
+  /* Segmentation map probabilities */
+  if (sgm->mapModified) {
+    int32_t sum1 = sgm->idCnt[0] + sgm->idCnt[1];
+    int32_t sum2 = sgm->idCnt[2] + sgm->idCnt[3];
+
+    ASSERT(sum1);
+    ASSERT(sum2);
+
+    tmp = 255 * sum1 / (sum1 + sum2);
+    entropy->segmentProb[0] = CLIP3(tmp, 1, 255);
+
+    tmp = sum1 ? 255 * sgm->idCnt[0] / sum1 : 255;
+    entropy->segmentProb[1] = CLIP3(tmp, 1, 255);
+
+    tmp = sum2 ? 255 * sgm->idCnt[2] / sum2 : 255;
+    entropy->segmentProb[2] = CLIP3(tmp, 1, 255);
+
+    for (i = 0; i < 3; i++) {
+      if (sgm->idCnt[i] != 0) {
+        COMMENT("Frame header, buffer 1, segment prob");
+        VP8PutLit(buffer, 1, 1);
+        VP8PutLit(buffer, entropy->segmentProb[i], 8);
+      } else {
+        COMMENT("Frame header, buffer 1, no segment prob");
+        VP8PutLit(buffer, 0, 1);
+      }
+    }
+  }
+
+  /* This point new segmentation data is written to the stream, save new
+   * values because they are reference values of next frame */
+  memcpy(ppss->qpSgm, pps->qpSgm, sizeof(ppss->qpSgm));
+  memcpy(ppss->levelSgm, pps->levelSgm, sizeof(ppss->levelSgm));
+}
+
+/*------------------------------------------------------------------------------
+    FilterLevelDelta
+------------------------------------------------------------------------------*/
+void FilterLevelDelta(vp8buffer* buffer, sps* sps) {
+  int32_t i, tmp;
+  int32_t modeUpdate[4];
+  int32_t refUpdate[4];
+  bool update = false;
+
+  /* Find out what delta values are changed */
+  for (i = 0; i < 4; i++) {
+    modeUpdate[i] = sps->modeDelta[i] != sps->oldModeDelta[i];
+    refUpdate[i] = sps->refDelta[i] != sps->oldRefDelta[i];
+    if (modeUpdate[i] || refUpdate[i])
+      update = true;
+  }
+
+  /* With error resilient mode update the level values for every frame. */
+  if (!sps->refreshEntropy)
+    update = true;
+
+  /* Do the deltas need to be updated */
+  VP8PutLit(buffer, update, 1);
+  if (!update) return;
+
+  /* Reference frame mode based deltas */
+  for (i = 0; i < 4; i++) {
+    VP8PutLit(buffer, refUpdate[i], 1);
+    if (refUpdate[i]) {
+      tmp = sps->refDelta[i];
+      VP8PutLit(buffer, ABS(tmp), 6);    /* Delta */
+      VP8PutLit(buffer, tmp < 0, 1); /* Sign */
+    }
+  }
+
+  /* Macroblock mode based deltas */
+  for (i = 0; i < 4; i++) {
+    VP8PutLit(buffer, modeUpdate[i], 1);
+    if (modeUpdate[i]) {
+      tmp = sps->modeDelta[i];
+      VP8PutLit(buffer, ABS(tmp), 6);    /* Delta */
+      VP8PutLit(buffer, tmp < 0, 1); /* Sign */
+    }
+  }
+
+  /* Store the new values as reference for next frame */
+  memcpy(sps->oldRefDelta, sps->refDelta, sizeof(sps->refDelta));
+  memcpy(sps->oldModeDelta, sps->modeDelta, sizeof(sps->modeDelta));
+}
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8header.h b/libv4l-rockchip/libvpu/vp8_enc/vp8header.h
new file mode 100644
index 0000000..6ffb96c
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8header.h
@@ -0,0 +1,24 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef VP8HEADERS_H
+#define VP8HEADERS_H
+
+#include "vp8instance.h"
+
+void VP8FrameHeader(vp8Instance_s*);
+void VP8FrameTag(vp8Instance_s*);
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8init.c b/libv4l-rockchip/libvpu/vp8_enc/vp8init.c
new file mode 100644
index 0000000..f96a34e
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8init.c
@@ -0,0 +1,304 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include <memory.h>
+#include <malloc.h>
+#include "vp8init.h"
+#include "vp8macroblocktools.h"
+#include "enccommon.h"
+
+#define VP8ENC_MIN_ENC_WIDTH       132     /* 144 - 12 pixels overfill */
+#define VP8ENC_MAX_ENC_WIDTH       4080
+#define VP8ENC_MIN_ENC_HEIGHT      96
+#define VP8ENC_MAX_ENC_HEIGHT      4080
+
+#define VP8ENC_MAX_MBS_PER_PIC     65025   /* 4080x4080 */
+
+static void SetParameter(vp8Instance_s* inst, const VP8EncConfig* pEncCfg);
+
+static int32_t SetPictureBuffer(vp8Instance_s* inst);
+
+/*------------------------------------------------------------------------------
+
+    VP8CheckCfg
+
+    Function checks that the configuration is valid.
+
+    Input   pEncCfg Pointer to configuration structure.
+
+    Return  ENCHW_OK      The configuration is valid.
+            ENCHW_NOK     Some of the parameters in configuration are not valid.
+
+------------------------------------------------------------------------------*/
+bool_e VP8CheckCfg(const VP8EncConfig* pEncCfg) {
+  ASSERT(pEncCfg);
+
+  /* Encoded image width limits, multiple of 4 */
+  if (pEncCfg->width < VP8ENC_MIN_ENC_WIDTH ||
+      pEncCfg->width > VP8ENC_MAX_ENC_WIDTH || (pEncCfg->width & 0x3) != 0)
+    return ENCHW_NOK;
+
+  /* Encoded image height limits, multiple of 2 */
+  if (pEncCfg->height < VP8ENC_MIN_ENC_HEIGHT ||
+      pEncCfg->height > VP8ENC_MAX_ENC_HEIGHT || (pEncCfg->height & 0x1) != 0)
+    return ENCHW_NOK;
+
+  /* total macroblocks per picture limit */
+  if (((pEncCfg->height + 15) / 16) * ((pEncCfg->width + 15) / 16) >
+          VP8ENC_MAX_MBS_PER_PIC) {
+    return ENCHW_NOK;
+  }
+
+  /* Check frame rate */
+  if (pEncCfg->frameRateNum < 1 || pEncCfg->frameRateNum > ((1 << 20) - 1))
+    return ENCHW_NOK;
+
+  if (pEncCfg->frameRateDenom < 1) {
+    return ENCHW_NOK;
+  }
+
+  /* special allowal of 1000/1001, 0.99 fps by customer request */
+  if (pEncCfg->frameRateDenom > pEncCfg->frameRateNum &&
+      !(pEncCfg->frameRateDenom == 1001 && pEncCfg->frameRateNum == 1000)) {
+    return ENCHW_NOK;
+  }
+
+  return ENCHW_OK;
+}
+
+/*------------------------------------------------------------------------------
+
+    VP8Init
+
+    Function initializes the Encoder and creates new encoder instance.
+
+    Input   pEncCfg     Encoder configuration.
+            instAddr    Pointer to instance will be stored in this address
+
+    Return  VP8ENC_OK
+            VP8ENC_MEMORY_ERROR
+            VP8ENC_EWL_ERROR
+            VP8ENC_EWL_MEMORY_ERROR
+            VP8ENC_INVALID_ARGUMENT
+
+------------------------------------------------------------------------------*/
+VP8EncRet VP8Init(const VP8EncConfig* pEncCfg, vp8Instance_s** instAddr) {
+  vp8Instance_s* inst = NULL;
+  VP8EncRet ret = VP8ENC_OK;
+  int32_t i;
+
+  ASSERT(pEncCfg);
+  ASSERT(instAddr);
+
+  *instAddr = NULL;
+
+  /* Encoder instance */
+  inst = (vp8Instance_s*)malloc(sizeof(vp8Instance_s));
+
+  if (inst == NULL) {
+    ret = VP8ENC_MEMORY_ERROR;
+    goto err;
+  }
+
+  memset(inst, 0, sizeof(vp8Instance_s));
+
+  /* Set parameters depending on user config */
+  SetParameter(inst, pEncCfg);
+  InitQuantTables(inst);
+
+  if (SetPictureBuffer(inst) != ENCHW_OK) {
+    ret = VP8ENC_INVALID_ARGUMENT;
+    goto err;
+  }
+
+  VP8InitRc(&inst->rateControl, 1);
+
+  /* Initialize ASIC */
+  (void) VP8_EncAsicControllerInit(&inst->asic);
+
+  /* Allocate internal SW/HW shared memories */
+  if (VP8_EncAsicMemAlloc_V2(&inst->asic,
+                             pEncCfg->width,
+                             pEncCfg->height,
+                             ASIC_VP8, inst->numRefBuffsLum,
+                             inst->numRefBuffsChr) != ENCHW_OK) {
+    ret = VP8ENC_EWL_MEMORY_ERROR;
+    goto err;
+  }
+
+  /* Assign allocated HW frame buffers into picture buffer */
+  inst->picBuffer.size = inst->numRefBuffsLum;
+  for (i = 0; i < inst->numRefBuffsLum; i++)
+    inst->picBuffer.refPic[i].picture.lum = i;
+  for (i = 0; i < inst->numRefBuffsChr; i++)
+    inst->picBuffer.refPic[i].picture.cb = i;
+
+  *instAddr = inst;
+
+  inst->asic.regs.intra16Favor    = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.prevModeFavor   = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.interFavor      = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.skipPenalty     = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.diffMvPenalty[0] = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.diffMvPenalty[1] = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.diffMvPenalty[2] = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.splitPenalty[0] = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.splitPenalty[1] = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.splitPenalty[2] = 0x3FF; /* No 8x4 MVs in VP8 */
+  inst->asic.regs.splitPenalty[3] = ASIC_PENALTY_UNDEFINED;
+  inst->asic.regs.zeroMvFavorDiv2 = 0; /* No favor for VP8 */
+
+  /* Disable intra and ROI areas by default */
+  inst->asic.regs.intraAreaTop = inst->asic.regs.intraAreaBottom =
+      inst->asic.regs.intraAreaLeft = inst->asic.regs.intraAreaRight =
+      inst->asic.regs.roi1Top = inst->asic.regs.roi1Bottom =
+      inst->asic.regs.roi1Left = inst->asic.regs.roi1Right =
+      inst->asic.regs.roi2Top = inst->asic.regs.roi2Bottom =
+      inst->asic.regs.roi2Left = inst->asic.regs.roi2Right = 255;
+
+  return ret;
+
+ err:
+  free(inst);
+  return ret;
+}
+
+/*------------------------------------------------------------------------------
+
+    VP8Shutdown
+
+    Function frees the encoder instance.
+
+    Input   vp8Instance_s *    Pointer to the encoder instance to be freed.
+                            After this the pointer is no longer valid.
+
+------------------------------------------------------------------------------*/
+void VP8Shutdown(vp8Instance_s* data) {
+  ASSERT(data);
+
+  VP8_EncAsicMemFree_V2(&data->asic);
+
+  PictureBufferFree(&data->picBuffer);
+
+  PicParameterSetFree(&data->ppss);
+
+  free(data);
+}
+
+/*------------------------------------------------------------------------------
+
+    SetParameter
+
+    Set all parameters in instance to valid values depending on user config.
+
+------------------------------------------------------------------------------*/
+void SetParameter(vp8Instance_s* inst, const VP8EncConfig* pEncCfg) {
+  int32_t width, height;
+  sps* sps = &inst->sps;
+
+  ASSERT(inst);
+
+  /* Internal images, next macroblock boundary */
+  width = 16 * ((pEncCfg->width + 15) / 16);
+  height = 16 * ((pEncCfg->height + 15) / 16);
+
+  /* Luma ref buffers can be read and written at the same time,
+   * but chroma buffers must be one for reading and one for writing */
+  inst->numRefBuffsLum    = pEncCfg->refFrameAmount;
+  inst->numRefBuffsChr    = inst->numRefBuffsLum + 1;
+
+  /* Macroblock */
+  inst->mbPerFrame        = width / 16 * height / 16;
+  inst->mbPerRow          = width / 16;
+  inst->mbPerCol          = height / 16;
+
+  /* Sequence parameter set */
+  sps->picWidthInPixel    = pEncCfg->width;
+  sps->picHeightInPixel   = pEncCfg->height;
+  sps->picWidthInMbs      = width / 16;
+  sps->picHeightInMbs     = height / 16;
+
+  sps->horizontalScaling = 0; /* TODO, not supported yet */
+  sps->verticalScaling   = 0; /* TODO, not supported yet */
+  sps->colorType         = 0; /* TODO, not supported yet */
+  sps->clampType         = 0; /* TODO, not supported yet */
+  sps->dctPartitions     = 0; /* Dct data partitions 0=1, 1=2, 2=4, 3=8 */
+  sps->partitionCnt      = 2 + (1 << sps->dctPartitions);
+  sps->profile           = 1; /* Currently ASIC only supports bilinear ipol */
+  sps->filterType        = 0;
+  sps->filterLevel       = 0;
+  sps->filterSharpness   = 0;
+  sps->autoFilterLevel     = 1; /* Automatic filter values by default. */
+  sps->autoFilterSharpness = 1;
+  sps->quarterPixelMv    = 1; /* 1=adaptive by default */
+  sps->splitMv           = 1; /* 1=adaptive by default */
+  sps->refreshEntropy    = 1; /* 0=default probs, 1=prev frame probs */
+  memset(sps->singBias, 0, sizeof(sps->singBias));
+
+  sps->filterDeltaEnable = true;
+  memset(sps->refDelta, 0, sizeof(sps->refDelta));
+  memset(sps->modeDelta, 0, sizeof(sps->modeDelta));
+
+  /* Rate control */
+  inst->rateControl.virtualBuffer.bitRate = 1000000;
+  inst->rateControl.qpHdr         = -1;
+  inst->rateControl.picRc         = ENCHW_YES;
+  inst->rateControl.picSkip       = ENCHW_NO;
+  inst->rateControl.qpMin         = 0;
+  inst->rateControl.qpMax         = 127;
+  inst->rateControl.gopLen        = 150;
+  inst->rateControl.mbPerPic      = inst->mbPerFrame;
+  inst->rateControl.outRateDenom  = pEncCfg->frameRateDenom;
+  inst->rateControl.outRateNum    = pEncCfg->frameRateNum;
+}
+
+int32_t SetPictureBuffer(vp8Instance_s* inst) {
+  picBuffer* picBuffer = &inst->picBuffer;
+  sps* sps = &inst->sps;
+  int32_t width, height;
+
+  width = sps->picWidthInMbs * 16;
+  height = sps->picHeightInMbs * 16;
+  PictureBufferAlloc(picBuffer, width, height);
+
+  width = sps->picWidthInMbs;
+  height = sps->picHeightInMbs;
+  if (PicParameterSetAlloc(&inst->ppss) != ENCHW_OK)
+    return ENCHW_NOK;
+
+  inst->ppss.pps = inst->ppss.store;
+  inst->ppss.pps->segmentEnabled  = 0; /* Segmentation disabled by default. */
+  inst->ppss.pps->sgm.mapModified = 0;
+
+  return ENCHW_OK;
+}
+
+/*------------------------------------------------------------------------------
+
+    Round the width to the next multiple of 8 or 16 depending on YUV type.
+
+------------------------------------------------------------------------------*/
+int32_t VP8GetAllowedWidth(int32_t width, VP8EncPictureType inputType) {
+  if (inputType == VP8ENC_YUV420_PLANAR) {
+    /* Width must be multiple of 16 to make
+     * chrominance row 64-bit aligned */
+    return ((width + 15) / 16) * 16;
+  } else {   /* VP8ENC_YUV420_SEMIPLANAR */
+    /* VP8ENC_YUV422_INTERLEAVED_YUYV */
+    /* VP8ENC_YUV422_INTERLEAVED_UYVY */
+    return ((width + 7) / 8) * 8;
+  }
+}
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8init.h b/libv4l-rockchip/libvpu/vp8_enc/vp8init.h
new file mode 100644
index 0000000..e871bb0
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8init.h
@@ -0,0 +1,27 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef __VP8_INIT_H__
+#define __VP8_INIT_H__
+
+#include "vp8encapi.h"
+#include "vp8instance.h"
+
+bool_e VP8CheckCfg(const VP8EncConfig* pEncCfg);
+int32_t VP8GetAllowedWidth(int32_t width, VP8EncPictureType inputType);
+VP8EncRet VP8Init(const VP8EncConfig* pEncCfg, vp8Instance_s** instAddr);
+void VP8Shutdown(vp8Instance_s* data);
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8instance.h b/libv4l-rockchip/libvpu/vp8_enc/vp8instance.h
new file mode 100644
index 0000000..ec9d05e
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8instance.h
@@ -0,0 +1,77 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef __VP8_INSTANCE_H__
+#define __VP8_INSTANCE_H__
+
+#include "encasiccontroller.h"
+#include "enccommon.h"
+#include "vp8seqparameterset.h"
+#include "vp8picparameterset.h"
+#include "vp8picturebuffer.h"
+#include "vp8putbits.h"
+#include "vp8ratecontrol.h"
+#include "vp8quanttable.h"
+
+enum VP8EncStatus {
+  VP8ENCSTAT_INIT = 0xA1,
+  VP8ENCSTAT_KEYFRAME,
+  VP8ENCSTAT_START_FRAME,
+  VP8ENCSTAT_ERROR
+};
+
+typedef struct {
+  int32_t quant[2];
+  int32_t zbin[2];
+  int32_t round[2];
+  int32_t dequant[2];
+} qp;
+
+typedef struct {
+  /* Approximate bit cost of mode. IOW bits used when selected mode is
+   * boolean encoded using appropriate tree and probabilities. Note that
+   * this value is scale up with SCALE (=256) */
+  int32_t intra16ModeBitCost[4 + 1];
+  int32_t intra4ModeBitCost[14 + 1];
+} mbs;
+
+typedef struct
+{
+  uint32_t encStatus;
+  uint32_t mbPerFrame;
+  uint32_t mbPerRow;
+  uint32_t mbPerCol;
+  uint32_t frameCnt;
+  uint32_t testId;
+  uint32_t numRefBuffsLum;
+  uint32_t numRefBuffsChr;
+  uint32_t prevFrameLost;
+  vp8RateControl_s rateControl;
+  picBuffer picBuffer;         /* Reference picture container */
+  sps sps;                     /* Sequence parameter set */
+  ppss ppss;                   /* Picture parameter set */
+  vp8buffer buffer[4];         /* Stream buffer per partition */
+  qp qpY1[QINDEX_RANGE];  /* Quant table for 1'st order luminance */
+  qp qpY2[QINDEX_RANGE];  /* Quant table for 2'nd order luminance */
+  qp qpCh[QINDEX_RANGE];  /* Quant table for chrominance */
+  mbs mbs;
+  asicData_s asic;
+  uint32_t* pOutBuf;           /* User given stream output buffer */
+  const void* inst;            /* Pointer to this instance for checking */
+  entropy entropy[1];
+} vp8Instance_s;
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8macroblocktools.c b/libv4l-rockchip/libvpu/vp8_enc/vp8macroblocktools.c
new file mode 100644
index 0000000..8b8b54b
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8macroblocktools.c
@@ -0,0 +1,72 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include "vp8macroblocktools.h"
+#include "vp8quanttable.h"
+
+void InitQuantTables(vp8Instance_s* mbs) {
+  int32_t i, j, tmp;
+  qp* qp;
+
+  for (i = 0; i < QINDEX_RANGE; i++) {
+    /* Quant table for 1'st order luminance */
+    qp = &mbs->qpY1[i];
+    for (j = 0; j < 2; j++) {
+      if (j == 0) {
+        tmp = DcQLookup[i];
+      } else {
+        tmp = AcQLookup[i];
+      }
+      qp->quant[j] = MIN((1 << 16) / tmp, 0x3FFF);
+      qp->zbin[j] = ((QZbinFactors[i] * tmp) + 64) >> 7;
+      qp->round[j] = (QRoundingFactors[i] * tmp) >> 7;
+      qp->dequant[j] = tmp;
+    }
+
+    /* Quant table for 2'st order luminance */
+    qp = &mbs->qpY2[i];
+    for (j = 0; j < 2; j++) {
+      if (j == 0) {
+        tmp = DcQLookup[i] * 2;
+      } else {
+        tmp = AcQLookup[i];
+        tmp = (tmp * 155) / 100;
+        if (tmp < 8) tmp = 8;
+      }
+      qp->quant[j] = MIN((1 << 16) / tmp, 0x3FFF);
+      qp->zbin[j] = ((QZbinFactors[i] * tmp) + 64) >> 7;
+      qp->round[j] = (QRoundingFactors[i] * tmp) >> 7;
+      qp->dequant[j] = tmp;
+    }
+
+    /* Quant table for chrominance */
+    qp = &mbs->qpCh[i];
+    for (j = 0; j < 2; j++) {
+      if (j == 0) {
+        tmp = DcQLookup[i];
+        if (tmp > 132) tmp = 132;
+      } else {
+        tmp = AcQLookup[i];
+      }
+      qp->quant[j] = MIN((1 << 16) / tmp, 0x3FFF);
+      qp->zbin[j] = ((QZbinFactors[i] * tmp) + 64) >> 7;
+      qp->round[j] = (QRoundingFactors[i] * tmp) >> 7;
+      qp->dequant[j] = tmp;
+    }
+  }
+}
+
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8macroblocktools.h b/libv4l-rockchip/libvpu/vp8_enc/vp8macroblocktools.h
new file mode 100644
index 0000000..8c126dd
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8macroblocktools.h
@@ -0,0 +1,54 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _VP8MACROBLOCK_TOOLS_H_
+#define _VP8MACROBLOCK_TOOLS_H_
+
+#include "vp8instance.h"
+
+typedef enum {
+  /* Intra luma 16x16 or intra chroma 8x8 prediction modes */
+  DC_PRED,
+  V_PRED,
+  H_PRED,
+  TM_PRED,
+
+  /* Common name of intra predicted mb where partition size is 4x4 */
+  B_PRED,
+
+  /* Intra 4x4 prediction modes */
+  B_DC_PRED,
+  B_TM_PRED,
+  B_VE_PRED,
+  B_HE_PRED,
+  B_LD_PRED,
+  B_RD_PRED,
+  B_VR_PRED,
+  B_VL_PRED,
+  B_HD_PRED,
+  B_HU_PRED,
+
+  /* Inter prediction (partitioning) types */
+  P_16x16,        /* [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] */
+  P_16x8,         /* [0,1,2,3,4,5,6,7,8][9,10,11,12,13,14,15] */
+  P_8x16,         /* [0,1,4,5,8,9,12,13][2,3,6,7,10,11,14,15] */
+  P_8x8,          /* [0,1,4,5][2,3,6,7][8,9,12,13][10,11,14,15] */
+  P_4x4           /* Every subblock gets its own vector */
+} type;
+
+void InitQuantTables(vp8Instance_s*);
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8picparameterset.c b/libv4l-rockchip/libvpu/vp8_enc/vp8picparameterset.c
new file mode 100644
index 0000000..653bb98
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8picparameterset.c
@@ -0,0 +1,38 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include "vp8picparameterset.h"
+
+#include <malloc.h>
+#include <memory.h>
+
+#include "enccommon.h"
+#include "libvpu/rk_vepu_debug.h"
+
+int32_t PicParameterSetAlloc(ppss* ppss) {
+  ppss->size = 1;
+  ppss->store = (pps*) malloc(ppss->size * sizeof(pps));
+  if (ppss->store == NULL) {
+    VPU_PLG_ERR("Fail to malloc ppss store.\n");
+    return ENCHW_NOK;
+  }
+  return ENCHW_OK;
+}
+
+void PicParameterSetFree(ppss* ppss) {
+  free(ppss->store);
+  ppss->store = NULL;
+}
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8picparameterset.h b/libv4l-rockchip/libvpu/vp8_enc/vp8picparameterset.h
new file mode 100644
index 0000000..8b2047f
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8picparameterset.h
@@ -0,0 +1,54 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef VP8PIC_PARAMETER_SET_H
+#define VP8PIC_PARAMETER_SET_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define SGM_CNT 4
+
+typedef struct sgm {
+  bool mapModified;   /* Segmentation map has been modified */
+  int32_t  idCnt[SGM_CNT];    /* Id counts because of probability */
+  /* Segment ID map is stored in ASIC SW/HW mem regs->segmentMap */
+} sgm;
+
+typedef struct {
+  struct sgm sgm;     /* Segmentation data */
+  int32_t qp;         /* Final qp value of current macroblock */
+  bool segmentEnabled;    /* Segmentation enabled */
+  int32_t qpSgm[SGM_CNT]; /* Qp if segments enabled (encoder set) */
+  int32_t levelSgm[SGM_CNT];  /* Level if segments enabled (encoder set) */
+} pps;
+
+typedef struct {
+  pps* store;     /* Picture parameter set tables */
+  int32_t size;       /* Size of above storage table */
+  pps* pps;       /* Active picture parameter set */
+  pps* prevPps;       /* Previous picture parameter set */
+  int32_t qpSgm[SGM_CNT]; /* Current qp and level of segmentation... */
+  int32_t levelSgm[SGM_CNT];  /* ...which are written to the stream */
+} ppss;
+
+/*------------------------------------------------------------------------------
+    4. Function prototypes
+------------------------------------------------------------------------------*/
+int32_t PicParameterSetAlloc(ppss* ppss);
+void PicParameterSetFree(ppss* ppss);
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8picturebuffer.c b/libv4l-rockchip/libvpu/vp8_enc/vp8picturebuffer.c
new file mode 100644
index 0000000..82cb146
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8picturebuffer.c
@@ -0,0 +1,277 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include <memory.h>
+#include <malloc.h>
+#include "enccommon.h"
+#include "vp8picturebuffer.h"
+
+static void Alloc(refPic* refPic, int32_t width, int32_t height);
+static void RefPicListInitialization(picBuffer* ref);
+static void ResetRefPic(refPic* refPic);
+
+void PictureBufferAlloc(picBuffer* picBuffer, int32_t width, int32_t height) {
+  int32_t i;
+
+  /* Be sure that everything is initialized if something goes wrong */
+  memset(picBuffer->refPic, 0, sizeof(picBuffer->refPic));
+  memset(picBuffer->refPicList, 0, sizeof(picBuffer->refPicList));
+
+  /* Reference frame base (lum,cb) and macroblock stuff */
+  for (i = 0; i < BUFFER_SIZE + 1; i++) {
+    Alloc(&picBuffer->refPic[i], width, height);
+    /* Back reference pointer (pointer to itself) */
+    picBuffer->refPic[i].refPic = &picBuffer->refPic[i];
+  }
+  picBuffer->cur_pic = &picBuffer->refPic[0];
+}
+
+void PictureBufferFree(picBuffer* picBuffer) {
+  memset(picBuffer->refPic, 0, sizeof(picBuffer->refPic));
+}
+
+void Alloc(refPic* refPic, int32_t width, int32_t height) {
+  refPic->picture.lumWidth  = width;
+  refPic->picture.lumHeight = height;
+  refPic->picture.chWidth   = width / 2;
+  refPic->picture.chHeight  = height / 2;
+  refPic->picture.lum       = 0;
+  refPic->picture.cb        = 0;
+}
+
+void InitializePictureBuffer(picBuffer* picBuffer) {
+  int32_t i;
+
+  /* I frame (key frame) resets reference pictures */
+  if (picBuffer->cur_pic->i_frame) {
+    picBuffer->cur_pic->p_frame = false;
+    picBuffer->cur_pic->ipf = true;
+    picBuffer->cur_pic->grf = true;
+    picBuffer->cur_pic->arf = true;
+    for (i = 0; i < BUFFER_SIZE + 1; i++) {
+      if (&picBuffer->refPic[i] != picBuffer->cur_pic) {
+        ResetRefPic(&picBuffer->refPic[i]);
+      }
+    }
+  }
+
+  /* Initialize reference picture list, note that API (user) can change
+   * reference picture list */
+  for (i = 0; i < BUFFER_SIZE; i++) {
+    ResetRefPic(&picBuffer->refPicList[i]);
+  }
+  RefPicListInitialization(picBuffer);
+}
+
+void UpdatePictureBuffer(picBuffer* picBuffer) {
+  refPic * cur_pic,*tmp,*refPic,*refPicList;
+  int32_t i, j;
+
+  refPicList = picBuffer->refPicList; /* Reference frame list */
+  refPic     = picBuffer->refPic;     /* Reference frame store */
+  cur_pic    = picBuffer->cur_pic;    /* Reconstructed picture */
+  picBuffer->last_pic = picBuffer->cur_pic;
+
+  /* Reset old marks from reference frame store if user wants to change
+   * current ips/grf/arf frames. */
+
+  /* Input picture marking */
+  for (i = 0; i < picBuffer->size + 1; i++) {
+    if (&refPic[i] == cur_pic) continue;
+    if (cur_pic->ipf) refPic[i].ipf = false;
+    if (cur_pic->grf) refPic[i].grf = false;
+    if (cur_pic->arf) refPic[i].arf = false;
+  }
+
+  /* Reference picture marking */
+  for (i = 0; i < picBuffer->size; i++) {
+    for (j = 0; j < picBuffer->size + 1; j++) {
+      if (refPicList[i].grf) refPic[j].grf = false;
+      if (refPicList[i].arf) refPic[j].arf = false;
+    }
+  }
+
+  /* Reference picture status is changed */
+  for (i = 0; i < picBuffer->size; i++) {
+    if (refPicList[i].grf) refPicList[i].refPic->grf = true;
+    if (refPicList[i].arf) refPicList[i].refPic->arf = true;
+  }
+
+  /* Find new picture not used as reference and set it to new cur_pic */
+  for (i = 0; i < picBuffer->size + 1; i++) {
+    tmp = &refPic[i];
+    if (!tmp->ipf && !tmp->arf && !tmp->grf) {
+      picBuffer->cur_pic = &refPic[i];
+      break;
+    }
+  }
+}
+
+void RefPicListInitialization(picBuffer* picBuffer) {
+  refPic * cur_pic,*refPic,*refPicList;
+  int32_t i, j = 0;
+
+  refPicList = picBuffer->refPicList; /* Reference frame list */
+  refPic     = picBuffer->refPic;     /* Reference frame store */
+  cur_pic    = picBuffer->cur_pic;    /* Reconstructed picture */
+
+  /* The first in the list is immediately previous picture. Note that
+   * cur_pic (the picture under reconstruction) is skipped */
+  for (i = 0; i < picBuffer->size + 1; i++) {
+    if (refPic[i].ipf && (&refPic[i] != cur_pic)) {
+      refPicList[j++] = refPic[i];
+      break;
+    }
+  }
+
+  /* The second in the list is golden frame */
+  for (i = 0; i < picBuffer->size + 1; i++) {
+    if (refPic[i].grf && (&refPic[i] != cur_pic)) {
+      refPicList[j++] = refPic[i];
+      break;
+    }
+  }
+
+  /* The third in the list is alternative reference frame */
+  for (i = 0; i < picBuffer->size + 1; i++) {
+    if (refPic[i].arf && (&refPic[i] != cur_pic)) {
+      refPicList[j] = refPic[i];
+      break;
+    }
+  }
+
+  /* Reset the ipf/grf/arf flags */
+  for (i = 0; i < picBuffer->size; i++) {
+    refPicList[i].ipf = false;
+    refPicList[i].grf = false;
+    refPicList[i].arf = false;
+  }
+}
+
+void ResetRefPic(refPic* refPic) {
+  refPic->poc = -1;
+  refPic->i_frame = false;
+  refPic->p_frame = false;
+  refPic->show = false;
+  refPic->ipf = false;
+  refPic->arf = false;
+  refPic->grf = false;
+  refPic->search = false;
+}
+
+/*------------------------------------------------------------------------------
+    PictureBufferSetRef
+
+        Set the ASIC reference and reconstructed frame buffers based
+        on the user preference and picture buffer.
+------------------------------------------------------------------------------*/
+void PictureBufferSetRef(picBuffer* picBuffer, asicData_s* asic) {
+  int32_t i, refIdx = -1, refIdx2 = -1;
+  refPic* refPicList = picBuffer->refPicList;
+  int32_t noGrf = 0, noArf = 0;
+
+  /* Amount of buffered frames limits grf/arf availability. */
+  if (picBuffer->size < 2) {noGrf = 1;
+    picBuffer->cur_pic->grf = false; }
+  if (picBuffer->size < 3) {noArf = 1;
+    picBuffer->cur_pic->arf = false; }
+
+  /* If current picture shall refresh grf/arf remove marks from ref list */
+  for (i = 0; i < picBuffer->size; i++) {
+    if (picBuffer->cur_pic->grf || noGrf)
+      picBuffer->refPicList[i].grf = false;
+    if (picBuffer->cur_pic->arf || noArf)
+      picBuffer->refPicList[i].arf = false;
+  }
+
+  /* ASIC can use one or two reference frame, use the first ones marked. */
+  for (i = 0; i < BUFFER_SIZE; i++) {
+    if ((i < picBuffer->size) && refPicList[i].search) {
+      if (refIdx == -1)
+        refIdx = i;
+      else if (refIdx2 == -1)
+        refIdx2 = i;
+      else
+        refPicList[i].search = 0;
+    } else {
+      refPicList[i].search = 0;
+    }
+  }
+
+  /* If no reference specified, use ipf */
+  if (refIdx == -1)
+    refIdx = 0;
+
+  asic->regs.mvRefIdx[0] = asic->regs.mvRefIdx[1] = refIdx;
+
+  /* Set the reference buffer for ASIC, no reference for intra frames */
+  if (picBuffer->cur_pic->p_frame) {
+    /* Mark the ref pic that is used */
+    picBuffer->refPicList[refIdx].search = 1;
+
+    /* Check that enough frame buffers is available. */
+    ASSERT(refPicList[refIdx].picture.lum);
+
+    asic->regs.internalImageLumBaseR[0] = refPicList[refIdx].picture.lum;
+    asic->regs.internalImageChrBaseR[0] = refPicList[refIdx].picture.cb;
+    asic->regs.internalImageLumBaseR[1] = refPicList[refIdx].picture.lum;
+    asic->regs.internalImageChrBaseR[1] = refPicList[refIdx].picture.cb;
+
+    asic->regs.mvRefIdx[0] = asic->regs.mvRefIdx[1] = refIdx;
+    asic->regs.ref2Enable = 0;
+
+    /* Enable second reference frame usage */
+    if (refIdx2 != -1) {
+      asic->regs.internalImageLumBaseR[1] = refPicList[refIdx2].picture.lum;
+      asic->regs.internalImageChrBaseR[1] = refPicList[refIdx2].picture.cb;
+      asic->regs.mvRefIdx[1] = refIdx2;
+      asic->regs.ref2Enable = 1;
+    }
+  }
+
+  /* Set the reconstructed frame buffer for ASIC. Luma can be written
+   * to same buffer but chroma read and write buffers must be different. */
+  asic->regs.recWriteDisable = 0;
+  if (!picBuffer->cur_pic->picture.lum) {
+    refPic* cur_pic = picBuffer->cur_pic;
+    refPic* cand;
+    int32_t recIdx = -1;
+
+    /* No free luma buffer so we must "steal" a luma buffer from
+     * some other ref pic that is no longer needed. */
+    for (i = 0; i < picBuffer->size + 1; i++) {
+      cand = &picBuffer->refPic[i];
+      if (cand == cur_pic) continue;
+      if (((cur_pic->ipf | cand->ipf) == cur_pic->ipf) &&
+          ((cur_pic->grf | cand->grf) == cur_pic->grf) &&
+          ((cur_pic->arf | cand->arf) == cur_pic->arf))
+        recIdx = i;
+    }
+
+    if (recIdx >= 0) {
+      /* recIdx is overwritten or unused so steal it */
+      cur_pic->picture.lum = picBuffer->refPic[recIdx].picture.lum;
+      picBuffer->refPic[recIdx].picture.lum = 0;
+    } else {
+      /* No available buffer found, must be no refresh */
+      ASSERT((cur_pic->ipf | cur_pic->grf | cur_pic->arf) == 0);
+      asic->regs.recWriteDisable = 1;
+    }
+  }
+  asic->regs.internalImageLumBaseW = picBuffer->cur_pic->picture.lum;
+  asic->regs.internalImageChrBaseW = picBuffer->cur_pic->picture.cb;
+}
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8picturebuffer.h b/libv4l-rockchip/libvpu/vp8_enc/vp8picturebuffer.h
new file mode 100644
index 0000000..043006b
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8picturebuffer.h
@@ -0,0 +1,70 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _VP8PICTURE_BUFFER_H_
+#define _VP8PICTURE_BUFFER_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "vp8entropytools.h"
+#include "encasiccontroller.h"
+
+#define BUFFER_SIZE 3
+
+typedef struct {
+  int32_t lumWidth;       /* Width of *lum */
+  int32_t lumHeight;      /* Height of *lum */
+  int32_t chWidth;        /* Width of *cb and *cr */
+  int32_t chHeight;       /* Height of *cb and *cr */
+  uint32_t lum;
+  uint32_t cb;
+} picture;
+
+typedef struct refPic {
+  picture picture;    /* Image data */
+  entropy* entropy;   /* Entropy store of picture */
+  int32_t poc;        /* Picture order count */
+
+  bool i_frame;       /* I frame (key frame), only intra mb */
+  bool p_frame;       /* P frame, intra and inter mb */
+  bool show;      /* Frame is for display (showFrame flag) */
+  bool ipf;       /* Frame is immediately previous frame */
+  bool arf;       /* Frame is altref frame */
+  bool grf;       /* Frame is golden frame */
+  bool search;        /* Frame is used for motion estimation */
+  struct refPic* refPic;  /* Back reference pointer to itself */
+} refPic;
+
+typedef struct {
+  int32_t size;       /* Amount of allocated reference pictures */
+  picture input;      /* Input picture */
+  refPic refPic[BUFFER_SIZE + 1]; /* Reference picture store */
+  refPic refPicList[BUFFER_SIZE]; /* Reference picture list */
+  refPic* cur_pic;    /* Pointer to picture under reconstruction */
+  refPic* last_pic;   /* Last picture */
+} picBuffer;
+
+/*------------------------------------------------------------------------------
+    Function prototypes
+------------------------------------------------------------------------------*/
+void PictureBufferAlloc(picBuffer* picBuffer, int32_t width, int32_t height);
+void PictureBufferFree(picBuffer* picBuffer);
+void InitializePictureBuffer(picBuffer* picBuffer);
+void UpdatePictureBuffer(picBuffer* picBuffer);
+void PictureBufferSetRef(picBuffer* picBuffer, asicData_s* asic);
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8putbits.c b/libv4l-rockchip/libvpu/vp8_enc/vp8putbits.c
new file mode 100644
index 0000000..0773e5f
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8putbits.c
@@ -0,0 +1,164 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#include "vp8putbits.h"
+
+#include <stdio.h>
+#include "enccommon.h"
+
+/*------------------------------------------------------------------------------
+    SetBuffer
+    Input   buffer  Pointer to the buffer structure.
+        data    Pointer to data buffer.
+        size    Size of data buffer.
+    Return  ENCHW_OK    Buffer status is OK.
+        ENCHW_NOK   Buffer overflow.
+------------------------------------------------------------------------------*/
+int32_t VP8SetBuffer(vp8buffer* buffer, uint8_t* data, int32_t size) {
+  if ((buffer == NULL) || (data == NULL) || (size < 1)) return ENCHW_NOK;
+
+  buffer->data = data;
+  buffer->pData = data;       /* First position of buffer */
+  buffer->size = size;        /* Buffer size in bytes */
+  buffer->range = 255;
+  buffer->bottom = 0;             /* PutBool bottom */
+  buffer->bitsLeft = 24;
+  buffer->byteCnt = 0;
+
+  return ENCHW_OK;
+}
+
+/*------------------------------------------------------------------------------
+    PutByte write byte literallyt to next place of buffer and advance data
+    pointer to next place
+
+    Input   buffer      Pointer to the buffer stucture
+            value       Byte
+------------------------------------------------------------------------------*/
+void VP8PutByte(vp8buffer* buffer, int32_t byte) {
+  ASSERT((uint32_t)byte < 256);
+  ASSERT(buffer->data < buffer->pData + buffer->size);
+  *buffer->data++ = byte;
+  buffer->byteCnt++;
+}
+
+/*------------------------------------------------------------------------------
+    PutLit write "literal" bits to stream using PutBool() where probability
+    is 128. Note that real bits written to stream are not necessarily same
+    than literal value. Bit write order: MSB...LSB.
+------------------------------------------------------------------------------*/
+void VP8PutLit(vp8buffer* buffer, int32_t value, int32_t number) {
+  ASSERT(number < 32 && number > 0);
+  ASSERT(((value & (-1 << number)) == 0));
+
+  while (number--) {
+    VP8PutBool(buffer, 128, (value >> number) & 0x1);
+  }
+}
+
+/*------------------------------------------------------------------------------
+    PutBool
+------------------------------------------------------------------------------*/
+void VP8PutBool(vp8buffer* buffer, int32_t prob, int32_t boolValue) {
+  int32_t split = 1 + ((buffer->range - 1) * prob >> 8);
+  int32_t lengthBits = 0;
+  int32_t bits = 0;
+
+  if (boolValue) {
+    buffer->bottom += split;
+    buffer->range -= split;
+  } else {
+    buffer->range = split;
+  }
+
+  while (buffer->range < 128) {
+    /* Detect carry and add carry bit to already written
+     * buffer->data if needed */
+    if (buffer->bottom < 0) {
+      uint8_t* data = buffer->data;
+      while (*--data == 255) {
+        *data = 0;
+      }
+      (*data)++;
+    }
+    buffer->range <<= 1;
+    buffer->bottom <<= 1;
+
+    if (!--buffer->bitsLeft) {
+      lengthBits += 8;
+      bits <<= 8;
+      bits |= (buffer->bottom >> 24) & 0xff;
+      TRACE_BIT_STREAM(bits & 0xff, 8);
+      *buffer->data++ = (buffer->bottom >> 24) & 0xff;
+      buffer->byteCnt++;
+      buffer->bottom &= 0xffffff;     /* Keep 3 bytes */
+      buffer->bitsLeft = 8;
+      /* TODO use big enough buffer and check buffer status
+       * for example in the beginning of mb row */
+      ASSERT(buffer->data < buffer->pData + buffer->size - 1);
+    }
+  }
+}
+
+/*------------------------------------------------------------------------------
+    PutTree
+------------------------------------------------------------------------------*/
+void VP8PutTree(vp8buffer* buffer, tree const* tree, int32_t* prob) {
+  int32_t value = tree->value;
+  int32_t number = tree->number;
+  int32_t const* index = tree->index;
+
+  while (number--) {
+    VP8PutBool(buffer, prob[*index++], (value >> number) & 1);
+  }
+}
+
+/*------------------------------------------------------------------------------
+    FlushBuffer put remaining buffer->bottom bits to the stream
+------------------------------------------------------------------------------*/
+void VP8FlushBuffer(vp8buffer* buffer) {
+  int32_t bitsLeft = buffer->bitsLeft;
+  int32_t bottom = buffer->bottom;
+
+  /* Detect (unlikely) carry and add carry bit to already written
+   * buffer->data if needed */
+  if (bottom & (1 << (32 - bitsLeft))) {
+    uint8_t* data = buffer->data;
+    while (*--data == 255) {
+      *data = 0;
+    }
+    (*data)++;
+  }
+
+  /* Move remaining bits to left until byte boundary */
+  bottom <<= (bitsLeft & 0x7);
+
+  /* Move remaining bytes to left until word boundary */
+  bottom <<= (bitsLeft >> 3) * 8;
+
+  /* Write valid (and possibly padded) bits to stream */
+  *buffer->data++ = 0xff & (bottom >> 24);
+  *buffer->data++ = 0xff & (bottom >> 16);
+  *buffer->data++ = 0xff & (bottom >> 8);
+  *buffer->data++ = 0xff & bottom;
+  buffer->byteCnt += 4;
+
+  TRACE_BIT_STREAM(bottom, 32);
+
+  COMMENT("flush");
+
+}
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8putbits.h b/libv4l-rockchip/libvpu/vp8_enc/vp8putbits.h
new file mode 100644
index 0000000..4b4198d
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8putbits.h
@@ -0,0 +1,46 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef VP8PUT_BITS_H
+#define VP8PUT_BITS_H
+
+#include <stdint.h>
+
+typedef struct {
+  uint8_t* data;       /* Pointer to next byte of data buffer */
+  uint8_t* pData;      /* Pointer to beginning of data buffer */
+  int32_t size;        /* Size of *data in bytes */
+  int32_t byteCnt;     /* Data buffer stream byte count */
+
+  int32_t range;       /* Bool encoder range [128, 255] */
+  int32_t bottom;      /* Bool encoder left endpoint */
+  int32_t bitsLeft;    /* Bool encoder bits left before flush bottom */
+} vp8buffer;
+
+typedef struct {
+  int32_t value;       /* Bits describe the bool tree  */
+  int32_t number;      /* Number, valid bit count in above tree */
+  int32_t index[9];    /* Probability table index */
+} tree;
+
+int32_t VP8SetBuffer(vp8buffer*, uint8_t*, int32_t);
+void VP8PutByte(vp8buffer* buffer, int32_t byte);
+void VP8PutLit(vp8buffer*, int32_t, int32_t);
+void VP8PutBool(vp8buffer* buffer, int32_t prob, int32_t boolValue);
+void VP8PutTree(vp8buffer* buffer, tree const* tree, int32_t* prob);
+void VP8FlushBuffer(vp8buffer* buffer);
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8quanttable.h b/libv4l-rockchip/libvpu/vp8_enc/vp8quanttable.h
new file mode 100644
index 0000000..e52c393
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8quanttable.h
@@ -0,0 +1,92 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+#ifndef _VP8QUANT_TABLE_H
+#define _VP8QUANT_TABLE_H
+
+#include <stdint.h>
+
+#define QINDEX_RANGE 128
+
+static const int DcQLookup[QINDEX_RANGE] = {
+  4,   5,   6,   7,   8,   9,   10,  10,  11,  12,
+  13,  14,  15,  16,  17,  17,  18,  19,  20,  20,
+  21,  21,  22,  22,  23,  23,  24,  25,  25,  26,
+  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
+  37,  37,  38,  39,  40,  41,  42,  43,  44,  45,
+  46,  46,  47,  48,  49,  50,  51,  52,  53,  54,
+  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,
+  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
+  75,  76,  76,  77,  78,  79,  80,  81,  82,  83,
+  84,  85,  86,  87,  88,  89,  91,  93,  95,  96,
+  98,  100, 101, 102, 104, 106, 108, 110, 112, 114,
+  116, 118, 122, 124, 126, 128, 130, 132, 134, 136,
+  138, 140, 143, 145, 148, 151, 154, 157
+};
+
+static const int AcQLookup[QINDEX_RANGE] = {
+  4,   5,   6,   7,   8,   9,   10,  11,  12,  13,
+  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,
+  24,  25,  26,  27,  28,  29,  30,  31,  32,  33,
+  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,
+  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,
+  54,  55,  56,  57,  58,  60,  62,  64,  66,  68,
+  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,
+  90,  92,  94,  96,  98,  100, 102, 104, 106, 108,
+  110, 112, 114, 116, 119, 122, 125, 128, 131, 134,
+  137, 140, 143, 146, 149, 152, 155, 158, 161, 164,
+  167, 170, 173, 177, 181, 185, 189, 193, 197, 201,
+  205, 209, 213, 217, 221, 225, 229, 234, 239, 245,
+  249, 254, 259, 264, 269, 274, 279, 284
+};
+
+static const int32_t const QRoundingFactors[QINDEX_RANGE] = {
+  56, 56, 56, 56, 56, 56, 56, 56, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+  48, 48, 48, 48, 48, 48, 48, 48
+};
+
+static const int32_t const QZbinFactors[QINDEX_RANGE] = {
+  64, 64, 64, 64, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+  80, 80, 80, 80, 80, 80, 80, 80
+};
+
+static const int32_t ZbinBoost[16] = {
+  0,   0,  8, 10, 12, 14, 16, 20, 24, 28,
+  32, 36, 40, 44, 44, 44
+};
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8ratecontrol.c b/libv4l-rockchip/libvpu/vp8_enc/vp8ratecontrol.c
new file mode 100644
index 0000000..1eeb845
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8ratecontrol.c
@@ -0,0 +1,673 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+#include "vp8ratecontrol.h"
+
+#include <memory.h>
+
+#include "vp8quanttable.h"
+#include "libvpu/rk_vepu_debug.h"
+
+#define DIV(a, b)               (((a) + (SIGN(a) * (b)) / 2) / (b))
+#define DSCY                    64 /* n * 64 */
+#define I32_MAX                 2147483647 /* 2 ^ 31 - 1 */
+#define QP_DELTA                4
+#define RC_ERROR_RESET          0x7fffffff
+
+static int32_t InitialQp(int32_t bits, int32_t pels);
+static void PicSkip(vp8RateControl_s* rc);
+static void PicQuantLimit(vp8RateControl_s* rc);
+static int32_t VirtualBuffer(vp8VirtualBuffer_s* vb, int32_t timeInc);
+static void PicQuant(vp8RateControl_s* rc);
+static int32_t avg_rc_error(linReg_s* p);
+static void update_rc_error(linReg_s* p, int32_t bits);
+static int32_t gop_avg_qp(vp8RateControl_s* rc);
+static int32_t new_pic_quant(linReg_s* p, int32_t bits, true_e useQpDeltaLimit);
+static void update_tables(linReg_s* p, int32_t qp, int32_t bits);
+static void update_model(linReg_s* p);
+static int32_t lin_sy(int32_t* qp, int32_t* r, int32_t n);
+static int32_t lin_sx(int32_t* qp, int32_t n);
+static int32_t lin_sxy(int32_t* qp, int32_t* r, int32_t n);
+static int32_t lin_nsxx(int32_t* qp, int32_t n);
+
+void VP8InitRc(vp8RateControl_s* rc, uint32_t newStream) {
+  vp8VirtualBuffer_s* vb = &rc->virtualBuffer;
+  int32_t maxBps;
+
+  if (rc->qpMax >= QINDEX_RANGE)
+    rc->qpMax = QINDEX_RANGE - 1;
+
+  if (rc->qpMin < 0)
+    rc->qpMin = 0;
+
+  /* Limit bitrate settings that are way over head.
+   * Maximum limit is half of the uncompressed YUV bitrate (12bpp). */
+  maxBps = rc->mbPerPic * 16 * 16 * 6;   /* Max bits per frame */
+  maxBps = VP8Calculate(maxBps, rc->outRateNum, rc->outRateDenom);
+  if (maxBps < 0)
+    maxBps = I32_MAX;
+  vb->bitRate = MIN(vb->bitRate, maxBps);
+
+  vb->bitPerPic = VP8Calculate(vb->bitRate, rc->outRateDenom, rc->outRateNum);
+
+  /* QP -1: Initial QP estimation done by RC */
+  if (rc->qpHdr == -1)
+    rc->qpHdr = InitialQp(vb->bitPerPic, rc->mbPerPic * 16 * 16);
+
+  PicQuantLimit(rc);
+
+  VPU_PLG_DBG("InitRc:\n  picRc %i\n  picSkip %i\n",
+              rc->picRc, rc->picSkip);
+  VPU_PLG_DBG("  qpHdr %i\n  qpMin,Max %i,%i\n",
+          rc->qpHdr, rc->qpMin, rc->qpMax);
+
+  VPU_PLG_DBG("  BitRate %i\n  BitPerPic %i\n",
+          vb->bitRate, vb->bitPerPic);
+
+  /* If changing QP/bitrate between frames don't reset GOP RC */
+  if (!newStream)
+    return;
+
+  rc->qpHdrPrev       = rc->qpHdr;
+  rc->fixedQp         = rc->qpHdr;
+  rc->frameCoded      = ENCHW_YES;
+  rc->currFrameIntra  = 1;
+  rc->prevFrameIntra  = 0;
+  rc->frameCnt        = 0;
+  rc->gopQpSum        = 0;
+  rc->gopQpDiv        = 0;
+  rc->targetPicSize   = 0;
+  rc->frameBitCnt     = 0;
+
+  memset(&rc->linReg, 0, sizeof(linReg_s));
+  rc->linReg.qs[0]    = AcQLookup[QINDEX_RANGE - 1];
+  rc->linReg.qp_prev  = rc->qpHdr;
+
+  vb->gopRem          = rc->gopLen;
+  vb->timeScale       = rc->outRateNum;
+
+  update_rc_error(&rc->rError, RC_ERROR_RESET);
+}
+
+/*------------------------------------------------------------------------------
+  InitialQp()   Returns sequence initial quantization parameter based on the
+                configured resolution and bitrate.
+------------------------------------------------------------------------------*/
+static int32_t InitialQp(int32_t bits, int32_t pels) {
+  /* Table with resulting average bits/pixel as a function of QP.
+   * The table is calculated by encoding a set of 4CIF resolution video
+   * clips with fixed QP. */
+  const int32_t qp_tbl[2][12] = {
+    { 47, 57, 73, 93, 122, 155, 214, 294, 373, 506, 781, 0x7FFFFFFF },
+    { 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10 } };
+  const int32_t upscale = 8000;
+  int32_t i = -1;
+
+  /* prevents overflow, QP would anyway be 10 with this high bitrate
+     for all resolutions under and including 1920x1088 */
+  if (bits > 1000000)
+    return 10;
+
+  /* Make room for multiplication */
+  pels >>= 8;
+  bits >>= 5;
+
+  /* Adjust the bits value for the current resolution */
+  bits *= pels + 250;
+  ASSERT(pels > 0);
+  ASSERT(bits > 0);
+  bits /= 350 + (3 * pels) / 4;
+  bits = VP8Calculate(bits, upscale, pels << 6);
+
+  while (qp_tbl[0][++i] < bits);
+
+  VPU_PLG_DBG("BPP  %d\n", bits);
+
+  return qp_tbl[1][i];
+}
+
+/*------------------------------------------------------------------------------
+  VirtualBuffer()  Return difference of target and real buffer fullness.
+  Virtual buffer and real bit count grow until one second.  After one second
+  output bit rate per second is removed from virtualBitCnt and realBitCnt. Bit
+  drifting has been taken care.
+
+  If the leaky bucket in VBR mode becomes empty (e.g. underflow), those R * T_e
+  bits are lost and must be decremented from virtualBitCnt. (NOTE: Drift
+  calculation will mess virtualBitCnt up, so the loss is added to realBitCnt)
+------------------------------------------------------------------------------*/
+static int32_t VirtualBuffer(vp8VirtualBuffer_s* vb, int32_t timeInc) {
+  int32_t drift, target;
+
+  /* Saturate realBitCnt, this is to prevent overflows caused by much greater
+     bitrate setting than is really possible to reach */
+  if (vb->realBitCnt > 0x1FFFFFFF)
+    vb->realBitCnt = 0x1FFFFFFF;
+  if (vb->realBitCnt < -0x1FFFFFFF)
+    vb->realBitCnt = -0x1FFFFFFF;
+
+  vb->picTimeInc    += timeInc;
+  vb->virtualBitCnt += VP8Calculate(vb->bitRate, timeInc, vb->timeScale);
+  target = vb->virtualBitCnt - vb->realBitCnt;
+
+  /* Saturate target, prevents rc going totally out of control.
+     This situation should never happen. */
+  if (target > 0x1FFFFFFF)
+    target = 0x1FFFFFFF;
+  if (target < -0x1FFFFFFF)
+    target = -0x1FFFFFFF;
+
+  /* picTimeInc must be in range of [0, timeScale) */
+  while (vb->picTimeInc >= vb->timeScale) {
+    vb->picTimeInc    -= vb->timeScale;
+    vb->virtualBitCnt -= vb->bitRate;
+    vb->realBitCnt    -= vb->bitRate;
+  }
+  drift = VP8Calculate(vb->bitRate, vb->picTimeInc, vb->timeScale);
+  drift -= vb->virtualBitCnt;
+  vb->virtualBitCnt += drift;
+
+  VPU_PLG_DBG("virtualBitCnt: %7i\nrealBitCnt: %7i",
+              vb->virtualBitCnt, vb->realBitCnt);
+  VPU_PLG_DBG("  diff bits: %7i\n", target);
+
+  return target;
+}
+
+/*------------------------------------------------------------------------------
+  VP8BeforePicRc()  Update virtual buffer and calculate picInitQp for current
+  picture.
+------------------------------------------------------------------------------*/
+void VP8BeforePicRc(vp8RateControl_s* rc, uint32_t timeInc,
+                    uint32_t frameTypeIntra) {
+  vp8VirtualBuffer_s* vb = &rc->virtualBuffer;
+  int32_t brDiff = 0;
+
+  rc->frameCoded = ENCHW_YES;
+  rc->currFrameIntra = frameTypeIntra;
+
+  VPU_PLG_DBG("BEFORE PIC RC: pic=%d\n", rc->frameCnt);
+  VPU_PLG_DBG("Frame type: %7i  timeInc: %7i\n", frameTypeIntra, timeInc);
+
+  if (rc->currFrameIntra || vb->gopRem == 1) {
+    vb->gopRem = rc->gopLen;
+  } else {
+    vb->gopRem--;
+  }
+
+  /* Use virtual buffer to calculate the difference of target bitrate
+   * and actual bitrate */
+  brDiff = VirtualBuffer(&rc->virtualBuffer, (int32_t)timeInc);
+
+  /* Calculate target size for this picture */
+  rc->targetPicSize =
+      vb->bitPerPic + DIV(brDiff, MAX(rc->virtualBuffer.gopRem, 3));
+  rc->targetPicSize = MAX(0, rc->targetPicSize);
+
+  if (rc->picSkip)
+    PicSkip(rc);
+
+  /* determine initial quantization parameter for current picture */
+  PicQuant(rc);
+  /* quantization parameter user defined limitations */
+  PicQuantLimit(rc);
+  /* Store the start QP, before any adjustment */
+  rc->qpHdrPrev = rc->qpHdr;
+
+  if (rc->currFrameIntra) {
+    if (rc->fixedIntraQp)
+      rc->qpHdr = rc->fixedIntraQp;
+    else if (!rc->prevFrameIntra)
+      rc->qpHdr += rc->intraQpDelta;
+
+    /* quantization parameter user defined limitations still apply */
+    PicQuantLimit(rc);
+  } else {
+    /* trace the QP over GOP, excluding Intra QP */
+    rc->gopQpSum += rc->qpHdr;
+    rc->gopQpDiv++;
+  }
+
+  VPU_PLG_DBG("Frame coded %7d  ", rc->frameCoded);
+  VPU_PLG_DBG("Frame qpHdr %7d  ", rc->qpHdr);
+  VPU_PLG_DBG("GopRem: %7d  ", vb->gopRem);
+  VPU_PLG_DBG("Target bits: %7d  \n", rc->targetPicSize);
+  VPU_PLG_DBG("Rd:  %7d\n", avg_rc_error(&rc->rError));
+}
+
+/*----------------------------------------------------------------------------
+  VP8AfterPicRc()  Update RC statistics after encoding frame.
+-----------------------------------------------------------------------------*/
+void VP8AfterPicRc(vp8RateControl_s* rc, uint32_t byteCnt) {
+  vp8VirtualBuffer_s* vb = &rc->virtualBuffer;
+  int32_t bitCnt = (int32_t)byteCnt * 8;
+
+  rc->frameCnt++;
+  rc->frameBitCnt     = bitCnt;
+  rc->prevFrameIntra  = rc->currFrameIntra;
+  vb->realBitCnt      += bitCnt;
+
+  VPU_PLG_DBG("AfterPicRc:\n");
+  VPU_PLG_DBG("BitCnt %7d\n", bitCnt);
+  VPU_PLG_DBG("BitErr/avg %6d%%  ",
+          ((bitCnt - vb->bitPerPic) * 100) / (vb->bitPerPic + 1));
+  VPU_PLG_DBG("BitErr/target %6d%%\n",
+              rc->targetPicSize ?
+              (((bitCnt - rc->targetPicSize) * 100) / rc->targetPicSize) : -1);
+
+  /* Needs number of bits used for residual */
+  if ((!rc->currFrameIntra) || (rc->gopLen == 1)) {
+    update_tables(&rc->linReg, rc->qpHdrPrev,
+                  VP8Calculate(bitCnt, 256, rc->mbPerPic));
+
+    if (vb->gopRem == rc->gopLen - 1) {
+      /* First INTER frame of GOP */
+      update_rc_error(&rc->rError, RC_ERROR_RESET);
+      VPU_PLG_DBG("P    ---  I    ---  D    ---\n");
+    } else {
+      /* Store the error between target and actual frame size
+       * Saturate the error to avoid inter frames with
+       * mostly intra MBs to affect too much */
+      update_rc_error(&rc->rError,
+                      MIN(bitCnt - rc->targetPicSize, 2 * rc->targetPicSize));
+    }
+
+    update_model(&rc->linReg);
+  } else {
+    VPU_PLG_DBG("P    xxx  I    xxx  D    xxx\n");
+  }
+
+}
+
+/*----------------------------------------------------------------------------
+  PicSkip()  Decrease framerate if not enough bits available.
+-----------------------------------------------------------------------------*/
+void PicSkip(vp8RateControl_s* rc) {
+  vp8VirtualBuffer_s* vb = &rc->virtualBuffer;
+  int32_t bitAvailable = vb->virtualBitCnt - vb->realBitCnt;
+  int32_t skipIncLimit = -vb->bitPerPic / 3;
+  int32_t skipDecLimit = vb->bitPerPic / 3;
+
+  /* When frameRc is enabled, skipFrameTarget is not allowed to be > 1
+   * This makes sure that not too many frames is skipped and lets
+   * the frameRc adjust QP instead of skipping many frames */
+  if (((rc->picRc == ENCHW_NO) || (vb->skipFrameTarget == 0)) &&
+      (bitAvailable < skipIncLimit))
+    vb->skipFrameTarget++;
+
+  if ((bitAvailable > skipDecLimit) && vb->skipFrameTarget > 0)
+    vb->skipFrameTarget--;
+
+  if (vb->skippedFrames < vb->skipFrameTarget) {
+    vb->skippedFrames++;
+    rc->frameCoded = ENCHW_NO;
+  } else {
+    vb->skippedFrames = 0;
+  }
+}
+
+/*----------------------------------------------------------------------------
+  PicQuant()  Calculate quantization parameter for next frame. In the beginning
+                of GOP use previous GOP average QP and otherwise find new QP
+                using the target size and previous frames QPs and bit counts.
+-----------------------------------------------------------------------------*/
+void PicQuant(vp8RateControl_s* rc) {
+  int32_t qp = 0;
+  int32_t avgRcError, bits;
+  true_e useQpDeltaLimit = ENCHW_YES;
+
+  if (rc->picRc != ENCHW_YES) {
+    rc->qpHdr = rc->fixedQp;
+    VPU_PLG_DBG("R/cx:   xxxx  QP:  xx xx  D:  xxxx  newQP: xx\n");
+    return;
+  }
+
+  /* Determine initial quantization parameter for current picture */
+  if (rc->currFrameIntra) {
+    /* If all frames or every other frame is intra we calculate new QP
+     * for intra the same way as for inter */
+    if (rc->gopLen == 1 || rc->gopLen == 2) {
+      qp = new_pic_quant(&rc->linReg,
+                          VP8Calculate(rc->targetPicSize, 256, rc->mbPerPic),
+                          useQpDeltaLimit);
+    } else {
+      VPU_PLG_DBG("R/cx:   xxxx  QP:  xx xx  D:  xxxx  newQP: xx\n");
+      qp = gop_avg_qp(rc);
+    }
+    if (qp) {
+      rc->qpHdr = qp;
+    }
+  } else if (rc->prevFrameIntra) {
+    /* Previous frame was intra, use the same QP */
+    VPU_PLG_DBG("R/cx:   xxxx  QP:  == ==  D:  ====  newQP: ==\n");
+    rc->qpHdr = rc->qpHdrPrev;
+  } else {
+    /* Calculate new QP by matching to previous frames R-Q curve */
+    avgRcError = avg_rc_error(&rc->rError);
+    bits = VP8Calculate(rc->targetPicSize  - avgRcError, 256, rc->mbPerPic);
+    rc->qpHdr = new_pic_quant(&rc->linReg, bits, useQpDeltaLimit);
+  }
+}
+
+/*----------------------------------------------------------------------------
+  PicQuantLimit()
+-----------------------------------------------------------------------------*/
+void PicQuantLimit(vp8RateControl_s* rc) {
+  rc->qpHdr = MIN(rc->qpMax, MAX(rc->qpMin, rc->qpHdr));
+}
+
+/*------------------------------------------------------------------------------
+  Calculate()  I try to avoid overflow and calculate good enough result of a*b/c
+------------------------------------------------------------------------------*/
+int32_t VP8Calculate(int32_t a, int32_t b, int32_t c) {
+  uint32_t left = 32;
+  uint32_t right = 0;
+  uint32_t shift;
+  int32_t sign = 1;
+  int32_t tmp;
+  uint32_t utmp;
+
+  if (a == 0 || b == 0) {
+    return 0;
+  } else if ((a * b / b) == a && c != 0) {
+    return (a * b / c);
+  }
+  if (a < 0) {
+    sign = -1;
+    a = -a;
+  }
+  if (b < 0) {
+    sign *= -1;
+    b = -b;
+  }
+  if (c < 0) {
+    sign *= -1;
+    c = -c;
+  }
+
+  if (c == 0) {
+    return 0x7FFFFFFF * sign;
+  }
+
+  if (b > a) {
+    tmp = b;
+    b = a;
+    a = tmp;
+  }
+
+  for (--left; (((uint32_t)a << left) >> left) != (uint32_t)a; --left) ;
+  left--; /* unsigned values have one more bit on left,
+             we want signed accuracy. shifting signed values gives
+             lint warnings */
+
+  while (((uint32_t)b >> right) > (uint32_t)c) {
+    right++;
+  }
+
+  if (right > left) {
+    return 0x7FFFFFFF * sign;
+  } else {
+    shift = left - right;
+    utmp = (((uint32_t)a << shift) / (uint32_t)c * (uint32_t)b);
+    utmp = (utmp >> shift) * sign;
+    return (int32_t)utmp;
+  }
+}
+
+/*------------------------------------------------------------------------------
+  avg_rc_error()  PI(D)-control for rate prediction error.
+------------------------------------------------------------------------------*/
+static int32_t avg_rc_error(linReg_s* p) {
+  return DIV(p->bits[2] * 4 + p->bits[1] * 6 + p->bits[0] * 0, 100);
+}
+
+/*------------------------------------------------------------------------------
+  update_rc_error()  Update PI(D)-control values
+------------------------------------------------------------------------------*/
+static void update_rc_error(linReg_s* p, int32_t bits) {
+  p->len = 3;
+
+  if (bits == (int32_t)RC_ERROR_RESET) {
+    /* RESET */
+    p->bits[0] = 0;
+    p->bits[1] = 0;
+    p->bits[2] = 0;
+    return;
+  }
+  p->bits[0] = bits - p->bits[2]; /* Derivative */
+  p->bits[1] = bits + p->bits[1]; /* Integral */
+  p->bits[2] = bits;              /* Proportional */
+
+  VPU_PLG_DBG("P  %7d  I  %7d  D  %7d\n", p->bits[2],  p->bits[1], p->bits[0]);
+}
+
+/*------------------------------------------------------------------------------
+  gop_avg_qp()  Average quantization parameter of P frames of the previous GOP.
+------------------------------------------------------------------------------*/
+int32_t gop_avg_qp(vp8RateControl_s* rc) {
+  int32_t avgQp = 0;
+
+  if (rc->gopQpSum) {
+    avgQp = DIV(rc->gopQpSum, rc->gopQpDiv);
+  }
+  rc->gopQpSum = 0;
+  rc->gopQpDiv = 0;
+
+  return avgQp;
+}
+
+/*------------------------------------------------------------------------------
+  new_pic_quant()  Calculate new quantization parameter from the 2nd degree R-Q
+  equation. Further adjust Qp for "smoother" visual quality.
+------------------------------------------------------------------------------*/
+static int32_t new_pic_quant(linReg_s* p, int32_t bits, true_e useQpDeltaLimit) {
+  int32_t tmp, qp_best = p->qp_prev, qp = p->qp_prev, diff;
+  int32_t diff_prev = 0, qp_prev = 0, diff_best = 0x7FFFFFFF;
+
+  VPU_PLG_DBG("R/cx:  %7d ",bits);
+
+  if (p->a1 == 0 && p->a2 == 0) {
+    VPU_PLG_DBG("  QP:  xx xx  D:   ====  newQP: %2d\n", qp);
+    return qp;
+  }
+
+  /* Target bits is negative => increase QP by maximum allowed */
+  if (bits <= 0) {
+    if (useQpDeltaLimit)
+      qp = MIN(QINDEX_RANGE - 1, MAX(0, qp + QP_DELTA));
+    else
+      qp = MIN(QINDEX_RANGE - 1, MAX(0, qp + 10));
+
+    VPU_PLG_DBG("  QP:  xx xx  D:   ----  newQP: %2d\n", qp);
+    return qp;
+  }
+
+  /* Find the qp that has the best match on fitted curve */
+  do {
+    tmp  = DIV(p->a1, AcQLookup[qp]);
+    tmp += DIV(p->a2, AcQLookup[qp] * AcQLookup[qp]);
+    diff = ABS(tmp - bits);
+
+    if (diff < diff_best) {
+      if (diff_best == 0x7FFFFFFF) {
+        diff_prev = diff;
+        qp_prev   = qp;
+      } else {
+        diff_prev = diff_best;
+        qp_prev   = qp_best;
+      }
+      diff_best = diff;
+      qp_best   = qp;
+      if ((tmp - bits) <= 0) {
+        if (qp < 1) {
+          break;
+        }
+        qp--;
+      } else {
+        if (qp >= QINDEX_RANGE - 1) {
+          break;
+        }
+        qp++;
+      }
+    } else {
+      break;
+    }
+  } while ((qp >= 0) && (qp < QINDEX_RANGE));
+  qp = qp_best;
+
+  VPU_PLG_DBG("  QP:    %2d %2d  D:  %7d", qp, qp_prev, diff_prev - diff_best);
+
+  /* Limit Qp change for smoother visual quality */
+  if (useQpDeltaLimit) {
+    tmp = qp - p->qp_prev;
+    if (tmp > QP_DELTA) {
+      qp = p->qp_prev + QP_DELTA;
+    } else if (tmp < -QP_DELTA) {
+      qp = p->qp_prev - QP_DELTA;
+    }
+  }
+
+  return qp;
+}
+
+/*------------------------------------------------------------------------------
+  update_tables()  only statistics of PSLICE, please.
+------------------------------------------------------------------------------*/
+static void update_tables(linReg_s* p, int32_t qp, int32_t bits) {
+  const int32_t clen = 10;
+  int32_t tmp = p->pos;
+
+  p->qp_prev   = qp;
+  p->qs[tmp] = AcQLookup[qp];
+  p->bits[tmp] = bits;
+
+  if (++p->pos >= clen) {
+    p->pos = 0;
+  }
+  if (p->len < clen) {
+    p->len++;
+  }
+}
+
+/*------------------------------------------------------------------------------
+            update_model()  Update model parameter by Linear Regression.
+------------------------------------------------------------------------------*/
+static void update_model(linReg_s* p) {
+  int32_t* qs = p->qs, *r = p->bits, n = p->len;
+  int32_t i, a1, a2, sx = lin_sx(qs, n), sy = lin_sy(qs, r, n);
+
+  for (i = 0; i < n; i++) {
+    VPU_PLG_DBG("model: qs: %i  r: %i\n",qs[i], r[i]);
+  }
+
+  a1 = lin_sxy(qs, r, n);
+  a1 = a1 < I32_MAX / n ? a1 * n : I32_MAX;
+
+  VPU_PLG_DBG("model: sy: %i  sx: %i\n", sy, sx);
+  if (sy == 0) {
+    a1 = 0;
+  } else {
+    a1 -= (sx < I32_MAX / sy) ? sx * sy : I32_MAX;
+  }
+
+  a2 = (lin_nsxx(qs, n) - (sx * sx));
+  if (a2 == 0) {
+    if (p->a1 == 0) {
+      /* If encountered in the beginning */
+      a1 = 0;
+    } else {
+      a1 = (p->a1 * 2) / 3;
+    }
+  } else {
+    a1 = VP8Calculate(a1, DSCY, a2);
+  }
+
+  /* Value of a1 shouldn't be excessive (small) */
+  a1 = MAX(a1, -4096 * DSCY);
+  a1 = MIN(a1,  4096 * DSCY - 1);
+
+  ASSERT(ABS(a1) * sx >= 0);
+  ASSERT(sx * DSCY >= 0);
+  a2 = DIV(sy * DSCY, n) - DIV(a1 * sx, n);
+
+  VPU_PLG_DBG("model: a2:%9d  a1:%8d\n", a2, a1);
+
+  if (p->len > 0) {
+    p->a1 = a1;
+    p->a2 = a2;
+  }
+}
+
+/*------------------------------------------------------------------------------
+  lin_sy()  calculate value of Sy for n points.
+------------------------------------------------------------------------------*/
+static int32_t lin_sy(int32_t* qp, int32_t* r, int32_t n) {
+  int32_t sum = 0;
+
+  while (n--) {
+    sum += qp[n] * qp[n] * r[n];
+    if (sum < 0) {
+      return I32_MAX / DSCY;
+    }
+  }
+  return DIV(sum, DSCY);
+}
+
+/*------------------------------------------------------------------------------
+  lin_sx()  calculate value of Sx for n points.
+------------------------------------------------------------------------------*/
+static int32_t lin_sx(int32_t* qp, int32_t n) {
+  int32_t tmp = 0;
+
+  while (n--) {
+    ASSERT(qp[n]);
+    tmp += qp[n];
+  }
+  return tmp;
+}
+
+/*------------------------------------------------------------------------------
+  lin_sxy()  calculate value of Sxy for n points.
+------------------------------------------------------------------------------*/
+static int32_t lin_sxy(int32_t* qp, int32_t* r, int32_t n) {
+  int32_t tmp, sum = 0;
+
+  while (n--) {
+    tmp = qp[n] * qp[n] * qp[n];
+    if (tmp > r[n]) {
+      sum += DIV(tmp, DSCY) * r[n];
+    } else {
+      sum += tmp * DIV(r[n], DSCY);
+    }
+    if (sum < 0) {
+      return I32_MAX;
+    }
+  }
+  return sum;
+}
+
+/*------------------------------------------------------------------------------
+  lin_nsxx()  calculate value of n * Sxy for n points.
+------------------------------------------------------------------------------*/
+static int32_t lin_nsxx(int32_t* qp, int32_t n) {
+  int32_t tmp = 0, sum = 0, d = n;
+
+  while (n--) {
+    tmp = qp[n];
+    tmp *= tmp;
+    sum += d * tmp;
+  }
+  return sum;
+}
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8ratecontrol.h b/libv4l-rockchip/libvpu/vp8_enc/vp8ratecontrol.h
new file mode 100644
index 0000000..27ca812
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8ratecontrol.h
@@ -0,0 +1,95 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+#ifndef VP8_RATE_CONTROL_H
+#define VP8_RATE_CONTROL_H
+
+#include <stdint.h>
+
+#include "enccommon.h"
+
+typedef struct {
+  int32_t  a1;               /* model parameter */
+  int32_t  a2;               /* model parameter */
+  int32_t  qp_prev;          /* previous QP */
+  int32_t  qs[15];           /* quantization step size */
+  int32_t  bits[15];         /* Number of bits needed to code residual */
+  int32_t  pos;              /* current position */
+  int32_t  len;              /* current lenght */
+  int32_t  zero_div;         /* a1 divisor is 0 */
+} linReg_s;
+
+/* Virtual buffer */
+typedef struct
+{
+  int32_t bufferSize;          /* size of the virtual buffer */
+  int32_t bitRate;             /* input bit rate per second */
+  int32_t bitPerPic;           /* average number of bits per picture */
+  int32_t picTimeInc;          /* timeInc since last coded picture */
+  int32_t timeScale;           /* input frame rate numerator */
+  int32_t unitsInTic;          /* input frame rate denominator */
+  int32_t virtualBitCnt;       /* virtual (channel) bit count */
+  int32_t realBitCnt;          /* real bit count */
+  int32_t bufferOccupancy;     /* number of bits in the buffer */
+  int32_t skipFrameTarget;     /* how many frames should be skipped in a row */
+  int32_t skippedFrames;       /* how many frames have been skipped in a row */
+  int32_t bucketFullness;      /* Leaky Bucket fullness */
+  int32_t gopRem;              /* Number of frames remaining in this GOP */
+} vp8VirtualBuffer_s;
+
+typedef struct
+{
+  true_e picRc;
+  true_e picSkip;          /* Frame Skip enable */
+  true_e frameCoded;       /* Frame coded or not */
+  int32_t mbPerPic;            /* Number of macroblock per picture */
+  int32_t mbRows;              /* MB rows in picture */
+  int32_t currFrameIntra;      /* Is current frame intra frame? */
+  int32_t prevFrameIntra;      /* Was previous frame intra frame? */
+  int32_t fixedQp;             /* Pic header qp when fixed */
+  int32_t qpHdr;               /* Pic header qp of current voded picture */
+  int32_t qpMin;               /* Pic header minimum qp, user set */
+  int32_t qpMax;               /* Pic header maximum qp, user set */
+  int32_t qpHdrPrev;           /* Pic header qp of previous coded picture */
+  int32_t outRateNum;
+  int32_t outRateDenom;
+  vp8VirtualBuffer_s virtualBuffer;
+  /* for frame QP rate control */
+  linReg_s linReg;       /* Data for R-Q model */
+  linReg_s rError;       /* Rate prediction error (bits) */
+  int32_t targetPicSize;
+  int32_t frameBitCnt;
+  /* for GOP rate control */
+  int32_t gopQpSum;
+  int32_t gopQpDiv;
+  int32_t frameCnt;
+  int32_t gopLen;
+  int32_t intraQpDelta;
+  int32_t fixedIntraQp;
+  int32_t mbQpAdjustment;     /* QP delta for MAD macroblock QP adjustment */
+  int32_t intraPictureRate;
+  int32_t goldenPictureRate;
+  int32_t altrefPictureRate;
+} vp8RateControl_s;
+
+/*------------------------------------------------------------------------------
+    Function prototypes
+------------------------------------------------------------------------------*/
+void VP8InitRc(vp8RateControl_s* rc, uint32_t newStream);
+void VP8BeforePicRc(vp8RateControl_s* rc, uint32_t timeInc, uint32_t frameTypeIntra);
+void VP8AfterPicRc(vp8RateControl_s* rc, uint32_t byteCnt);
+int32_t VP8Calculate(int32_t a, int32_t b, int32_t c);
+#endif /* VP8_RATE_CONTROL_H */
+
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8seqparameterset.h b/libv4l-rockchip/libvpu/vp8_enc/vp8seqparameterset.h
new file mode 100644
index 0000000..a53002c
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8seqparameterset.h
@@ -0,0 +1,53 @@
+/*------------------------------------------------------------------------------
+--                                                                            --
+--       This software is confidential and proprietary and may be used        --
+--        only as expressly authorized by a licensing agreement from          --
+--                                                                            --
+--                            Hantro Products Oy.                             --
+--                                                                            --
+--                   (C) COPYRIGHT 2006 HANTRO PRODUCTS OY                    --
+--                            ALL RIGHTS RESERVED                             --
+--                                                                            --
+--                 The entire notice above must be reproduced                 --
+--                  on all copies and should not be removed.                  --
+--                                                                            --
+--------------------------------------------------------------------------------
+*/
+
+#ifndef _VP8SEQ_PARAMETER_SET_H_
+#define _VP8SEQ_PARAMETER_SET_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef struct {
+  int32_t picWidthInMbs;
+  int32_t picHeightInMbs;
+  int32_t picWidthInPixel;
+  int32_t picHeightInPixel;
+  int32_t horizontalScaling;
+  int32_t verticalScaling;
+  int32_t colorType;
+  int32_t clampType;
+  int32_t dctPartitions;  /* Dct data partitions 0=1, 1=2, 2=4, 3=8 */
+  int32_t partitionCnt;   /* Abbreviation:  2+(1<<prm->dctPartitions) */
+  int32_t profile;
+  int32_t filterType;
+  int32_t filterLevel;
+  int32_t filterSharpness;
+  int32_t quarterPixelMv;
+  int32_t splitMv;
+  int32_t singBias[3];    /* SingBias: 0 = ipf, 1 = grf, 2 = arf */
+
+  int32_t autoFilterLevel;
+  int32_t autoFilterSharpness;
+  bool filterDeltaEnable;
+  int32_t modeDelta[4];
+  int32_t oldModeDelta[4];
+  int32_t refDelta[4];
+  int32_t oldRefDelta[4];
+
+  int32_t refreshEntropy;
+} sps;
+
+#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vpu_mem.c b/libv4l-rockchip/libvpu/vp8_enc/vpu_mem.c
new file mode 100644
index 0000000..eff57dd
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vpu_mem.c
@@ -0,0 +1,27 @@
+/* Copyright 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "vpu_mem.h"
+
+#include <malloc.h>
+#include <memory.h>
+
+#include "libvpu/rk_vepu_debug.h"
+
+int32_t VPUMallocLinear(VPUMemLinear_t* p, uint32_t size) {
+  p->vir_addr = (uint32_t*) calloc(1, size);
+  if (p->vir_addr == NULL) {
+    VPU_PLG_ERR("Fail to malloc.");
+    return -1;
+  }
+  p->size = size;
+  p->phy_addr = 0x0;
+  return 0;
+}
+
+void VPUFreeLinear(VPUMemLinear_t* p) {
+  free(p->vir_addr);
+  memset(p, 0, sizeof(VPUMemLinear_t));
+}
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vpu_mem.h b/libv4l-rockchip/libvpu/vp8_enc/vpu_mem.h
new file mode 100644
index 0000000..40a1e09
--- /dev/null
+++ b/libv4l-rockchip/libvpu/vp8_enc/vpu_mem.h
@@ -0,0 +1,21 @@
+/* Copyright 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __VPU_MEM_H__
+#define __VPU_MEM_H__
+
+#include <stdint.h>
+
+typedef struct VPUMem {
+  uint32_t  phy_addr;
+  uint32_t* vir_addr;
+  uint32_t  size;
+} VPUMemLinear_t;
+
+int32_t VPUMallocLinear(VPUMemLinear_t* p, uint32_t size);
+void VPUFreeLinear(VPUMemLinear_t* p);
+
+#endif /* __VPU_MEM_H__ */
+