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__ */
+