mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-07 18:11:02 +08:00
[hal_h264e]: Add new h264 encoder hal module
New hal api will change interface to the following functions: 1. get_task - receive one task from encoder and process hw rate control. 2. gen_regs - generate register set according to different hardware. 3. start - start the hardwara. 4. wait - wait hardware process one task. 5. ret_task - return the processed task back to encoder. NOTE: change some function to v2 to avoid linker conflict. NOTE: vepu2_v2 status 1. Add svc and gop ref implement. 2. Without rc config. The QP is fixed. Change-Id: I5fa890e8e23c0abbc5abb5ce44111c8a10ea1817 Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
@@ -25,15 +25,6 @@ extern "C" {
|
||||
|
||||
extern const MppHalApi hal_api_h264e;
|
||||
|
||||
MPP_RET hal_h264e_init (void *hal, MppHalCfg *cfg);
|
||||
MPP_RET hal_h264e_deinit (void *hal);
|
||||
MPP_RET hal_h264e_gen_regs(void *hal, HalTaskInfo *task);
|
||||
MPP_RET hal_h264e_start (void *hal, HalTaskInfo *task);
|
||||
MPP_RET hal_h264e_wait (void *hal, HalTaskInfo *task);
|
||||
MPP_RET hal_h264e_reset (void *hal);
|
||||
MPP_RET hal_h264e_flush (void *hal);
|
||||
MPP_RET hal_h264e_control (void *hal, MpiCmd cmd_type, void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
76
mpp/hal/inc/mpp_enc_hal.h
Normal file
76
mpp/hal/inc/mpp_enc_hal.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __MPP_ENC_HAL_H__
|
||||
#define __MPP_ENC_HAL_H__
|
||||
|
||||
#include "mpp_hal.h"
|
||||
|
||||
typedef struct MppEncHalCfg_t {
|
||||
// input for encoder
|
||||
MppCodingType coding;
|
||||
MppEncCfgSet *set;
|
||||
MppEncCfgSet *cfg;
|
||||
|
||||
// output for enc_impl
|
||||
HalWorkMode work_mode;
|
||||
MppDeviceId device_id;
|
||||
} MppEncHalCfg;
|
||||
|
||||
typedef struct MppEncHalApi_t {
|
||||
char *name;
|
||||
MppCodingType coding;
|
||||
RK_U32 ctx_size;
|
||||
RK_U32 flag;
|
||||
|
||||
MPP_RET (*init)(void *ctx, MppEncHalCfg *cfg);
|
||||
MPP_RET (*deinit)(void *ctx);
|
||||
|
||||
// configure function
|
||||
MPP_RET (*get_task)(void *ctx, HalEncTask *task);
|
||||
MPP_RET (*gen_regs)(void *ctx, HalEncTask *task);
|
||||
|
||||
// hw operation function
|
||||
MPP_RET (*start)(void *ctx, HalEncTask *task);
|
||||
MPP_RET (*wait)(void *ctx, HalEncTask *task);
|
||||
|
||||
// return function
|
||||
MPP_RET (*ret_task)(void *ctx, HalEncTask *task);
|
||||
} MppEncHalApi;
|
||||
|
||||
typedef void* MppEncHal;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MPP_RET mpp_enc_hal_init(MppEncHal *ctx, MppEncHalCfg *cfg);
|
||||
MPP_RET mpp_enc_hal_deinit(MppEncHal ctx);
|
||||
|
||||
MPP_RET mpp_enc_hal_get_task(MppEncHal ctx, HalEncTask *task);
|
||||
MPP_RET mpp_enc_hal_gen_regs(MppEncHal ctx, HalEncTask *task);
|
||||
|
||||
// start / wait hardware
|
||||
MPP_RET mpp_enc_hal_start(MppEncHal ctx, HalEncTask *task);
|
||||
MPP_RET mpp_enc_hal_wait(MppEncHal ctx, HalEncTask *task);
|
||||
|
||||
MPP_RET mpp_enc_hal_ret_task(MppEncHal ctx, HalEncTask *task);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__MPP_ENC_HAL_H__*/
|
@@ -1,6 +1,7 @@
|
||||
# vim: syntax=cmake
|
||||
include_directories(.)
|
||||
include_directories(../../common/h264/)
|
||||
include_directories(../../../codec/enc/h264/)
|
||||
|
||||
# hal h264 header
|
||||
set(HAL_H264E_HDR
|
||||
@@ -9,6 +10,8 @@ set(HAL_H264E_HDR
|
||||
|
||||
# hal h264 encoder sourse
|
||||
set(HAL_H264E_SRC
|
||||
hal_h264e_vepu2_v2.c
|
||||
hal_h264e_vepu_v2.c
|
||||
hal_h264e_vpu_tbl.c
|
||||
hal_h264e_vepu2.c
|
||||
hal_h264e_vepu1.c
|
||||
|
806
mpp/hal/vpu/h264e/hal_h264e_vepu2_v2.c
Normal file
806
mpp/hal/vpu/h264e/hal_h264e_vepu2_v2.c
Normal file
@@ -0,0 +1,806 @@
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define MODULE_TAG "hal_h264e_vepu2_v2"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mpp_env.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_frame.h"
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_device.h"
|
||||
#include "mpp_rc.h"
|
||||
|
||||
#include "mpp_enc_hal.h"
|
||||
#include "h264e_debug.h"
|
||||
#include "h264e_syntax_new.h"
|
||||
#include "h264e_slice.h"
|
||||
#include "h264e_stream.h"
|
||||
|
||||
#include "hal_h264e_com.h"
|
||||
#include "hal_h264e_vpu_tbl.h"
|
||||
#include "hal_h264e_vepu_v2.h"
|
||||
|
||||
#include "hal_h264e_vepu2_reg_tbl.h"
|
||||
|
||||
typedef struct HalH264eVepu2Ctx_t {
|
||||
MppEncCfgSet *cfg;
|
||||
|
||||
MppDevCtx dev_ctx;
|
||||
RK_S32 frame_cnt;
|
||||
|
||||
/* buffers management */
|
||||
HalH264eVepuBufs hw_bufs;
|
||||
|
||||
/* preprocess config */
|
||||
HalH264eVepuPrep hw_prep;
|
||||
|
||||
/* input / recon / refer address config */
|
||||
HalH264eVepuAddr hw_addr;
|
||||
|
||||
/* macroblock ratecontrol config */
|
||||
HalH264eVepuMbRc hw_mbrc;
|
||||
|
||||
/* syntax for input from enc_impl */
|
||||
RK_U32 updated;
|
||||
SynH264eSps *sps;
|
||||
SynH264ePps *pps;
|
||||
H264eSlice *slice;
|
||||
H264eFrmInfo *frms;
|
||||
H264eReorderInfo *reorder;
|
||||
H264eMarkingInfo *marking;
|
||||
RcSyntax *rc_syn;
|
||||
|
||||
/* special TSVC stream header fixup */
|
||||
size_t buf_size;
|
||||
RK_U8 *src_buf;
|
||||
RK_U8 *dst_buf;
|
||||
|
||||
/* syntax for output to enc_impl */
|
||||
MppRcHalCfg hal_rc_cfg;
|
||||
|
||||
/* vepu2 macroblock ratecontrol context */
|
||||
HalH264eVepuMbRcCtx rc_ctx;
|
||||
|
||||
H264eVpu2RegSet regs_set;
|
||||
H264eVpu2RegSet regs_get;
|
||||
} HalH264eVepu2Ctx;
|
||||
|
||||
static MPP_RET hal_h264e_vepu2_deinit_v2(void *hal)
|
||||
{
|
||||
HalH264eVepu2Ctx *p = (HalH264eVepu2Ctx *)hal;
|
||||
|
||||
hal_h264e_dbg_func("enter %p\n", p);
|
||||
|
||||
if (p->dev_ctx) {
|
||||
mpp_device_deinit(p->dev_ctx);
|
||||
p->dev_ctx = NULL;
|
||||
}
|
||||
|
||||
h264e_vepu_buf_deinit(&p->hw_bufs);
|
||||
|
||||
if (p->rc_ctx) {
|
||||
h264e_vepu_mbrc_deinit(p->rc_ctx);
|
||||
p->rc_ctx = NULL;
|
||||
}
|
||||
|
||||
MPP_FREE(p->src_buf);
|
||||
MPP_FREE(p->dst_buf);
|
||||
|
||||
hal_h264e_dbg_func("leave %p\n", p);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
static MPP_RET hal_h264e_vepu2_init_v2(void *hal, MppEncHalCfg *cfg)
|
||||
{
|
||||
HalH264eVepu2Ctx *p = (HalH264eVepu2Ctx *)hal;
|
||||
MPP_RET ret = MPP_OK;
|
||||
MppDevCfg dev_cfg = {
|
||||
.type = MPP_CTX_ENC, /* type */
|
||||
.coding = MPP_VIDEO_CodingAVC, /* coding */
|
||||
.platform = 0, /* platform */
|
||||
.pp_enable = 0, /* pp_enable */
|
||||
};
|
||||
|
||||
hal_h264e_dbg_func("enter %p\n", p);
|
||||
|
||||
p->cfg = cfg->cfg;
|
||||
|
||||
ret = mpp_device_init(&p->dev_ctx, &dev_cfg);
|
||||
if (ret) {
|
||||
mpp_err_f("mpp_device_init failed ret: %d\n", ret);
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
ret = h264e_vepu_buf_init(&p->hw_bufs);
|
||||
if (ret) {
|
||||
mpp_err_f("init vepu buffer failed ret: %d\n", ret);
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
ret = h264e_vepu_mbrc_init(&p->rc_ctx, &p->hw_mbrc);
|
||||
if (ret) {
|
||||
mpp_err_f("init mb rate control failed ret: %d\n", ret);
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
/* create buffer to TSVC stream */
|
||||
p->buf_size = SZ_128K;
|
||||
p->src_buf = mpp_calloc(RK_U8, p->buf_size);
|
||||
p->dst_buf = mpp_calloc(RK_U8, p->buf_size);
|
||||
|
||||
DONE:
|
||||
if (ret)
|
||||
hal_h264e_vepu2_deinit_v2(hal);
|
||||
|
||||
hal_h264e_dbg_func("leave %p\n", p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RK_U32 update_vepu2_syntax(HalH264eVepu2Ctx *ctx, MppSyntax *syntax)
|
||||
{
|
||||
H264eSyntaxDesc *desc = syntax->data;
|
||||
RK_S32 syn_num = syntax->number;
|
||||
RK_U32 updated = 0;
|
||||
RK_S32 i;
|
||||
|
||||
for (i = 0; i < syn_num; i++, desc++) {
|
||||
switch (desc->type) {
|
||||
case H264E_SYN_CFG : {
|
||||
hal_h264e_dbg_detail("update cfg");
|
||||
ctx->cfg = desc->p;
|
||||
} break;
|
||||
case H264E_SYN_SPS : {
|
||||
hal_h264e_dbg_detail("update sps");
|
||||
ctx->sps = desc->p;
|
||||
} break;
|
||||
case H264E_SYN_PPS : {
|
||||
hal_h264e_dbg_detail("update pps");
|
||||
ctx->pps = desc->p;
|
||||
} break;
|
||||
case H264E_SYN_SLICE : {
|
||||
hal_h264e_dbg_detail("update slice");
|
||||
ctx->slice = desc->p;
|
||||
} break;
|
||||
case H264E_SYN_FRAME : {
|
||||
hal_h264e_dbg_detail("update frames");
|
||||
ctx->frms = desc->p;
|
||||
} break;
|
||||
case H264E_SYN_RC : {
|
||||
hal_h264e_dbg_detail("update rc");
|
||||
ctx->rc_syn = desc->p;
|
||||
} break;
|
||||
case H264E_SYN_ROI :
|
||||
case H264E_SYN_OSD :
|
||||
default : {
|
||||
mpp_log_f("invalid syntax type %d\n", desc->type);
|
||||
} break;
|
||||
}
|
||||
|
||||
updated |= SYN_TYPE_FLAG(desc->type);
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
static MPP_RET hal_h264e_vepu2_get_task_v2(void *hal, HalEncTask *task)
|
||||
{
|
||||
HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
|
||||
RK_U32 updated = update_vepu2_syntax(ctx, &task->syntax);
|
||||
MppEncPrepCfg *prep = &ctx->cfg->prep;
|
||||
HalH264eVepuPrep *hw_prep = &ctx->hw_prep;
|
||||
HalH264eVepuAddr *hw_addr = &ctx->hw_addr;
|
||||
HalH264eVepuBufs *hw_bufs = &ctx->hw_bufs;
|
||||
H264eFrmInfo *frms = ctx->frms;
|
||||
|
||||
hal_h264e_dbg_func("enter %p\n", hal);
|
||||
|
||||
if (updated & SYN_TYPE_FLAG(H264E_SYN_CFG)) {
|
||||
h264e_vepu_buf_set_frame_size(hw_bufs, prep->width, prep->height);
|
||||
|
||||
/* preprocess setup */
|
||||
h264e_vepu_prep_setup(hw_prep, prep);
|
||||
|
||||
h264e_vepu_mbrc_setup(ctx->rc_ctx, ctx->cfg);
|
||||
}
|
||||
|
||||
if (updated & SYN_TYPE_FLAG(H264E_SYN_SLICE)) {
|
||||
H264eSlice *slice = ctx->slice;
|
||||
|
||||
h264e_vepu_buf_set_cabac_idc(hw_bufs, slice->cabac_init_idc);
|
||||
}
|
||||
|
||||
h264e_vepu_prep_get_addr(hw_prep, task->input, &hw_addr->orig);
|
||||
|
||||
MppBuffer recn = h264e_vepu_buf_get_frame_buffer(hw_bufs, frms->curr_idx);
|
||||
MppBuffer refr = h264e_vepu_buf_get_frame_buffer(hw_bufs, frms->refr_idx);
|
||||
EncFrmStatus info = frms->status;
|
||||
size_t yuv_size = hw_bufs->yuv_size;
|
||||
|
||||
hw_addr->recn[0] = mpp_buffer_get_fd(recn);
|
||||
hw_addr->refr[0] = mpp_buffer_get_fd(refr);
|
||||
hw_addr->recn[1] = hw_addr->recn[0] + (yuv_size << 10);
|
||||
hw_addr->refr[1] = hw_addr->refr[0] + (yuv_size << 10);
|
||||
|
||||
// update input rc cfg
|
||||
ctx->hal_rc_cfg = frms->rc_cfg;
|
||||
|
||||
// prepare mb rc config
|
||||
h264e_vepu_mbrc_prepare(ctx->rc_ctx, ctx->rc_syn, &info, &ctx->hw_mbrc);
|
||||
|
||||
hal_h264e_dbg_func("leave %p\n", hal);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
static MPP_RET hal_h264e_vepu2_gen_regs_v2(void *hal, HalEncTask *task)
|
||||
{
|
||||
//MPP_RET ret = MPP_OK;
|
||||
HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
|
||||
HalH264eVepuBufs *hw_bufs = &ctx->hw_bufs;
|
||||
HalH264eVepuPrep *hw_prep = &ctx->hw_prep;
|
||||
HalH264eVepuAddr *hw_addr = &ctx->hw_addr;
|
||||
HalH264eVepuMbRc *hw_mbrc = &ctx->hw_mbrc;
|
||||
SynH264eSps *sps = ctx->sps;
|
||||
SynH264ePps *pps = ctx->pps;
|
||||
H264eSlice *slice = ctx->slice;
|
||||
RK_U32 *reg = ctx->regs_set.val;
|
||||
RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
|
||||
RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
|
||||
RK_U32 val = 0;
|
||||
RK_S32 i = 0;
|
||||
|
||||
// TODO: Fix QP here for debug
|
||||
hw_mbrc->qp_init = 26;
|
||||
hw_mbrc->qp_max = 26;
|
||||
hw_mbrc->qp_min = 26;
|
||||
|
||||
hal_h264e_dbg_func("enter %p\n", hal);
|
||||
|
||||
hal_h264e_dbg_detail("frame %d generate regs now", ctx->frms->seq_idx);
|
||||
|
||||
/* output buffer size is 64 bit address then 8 multiple size */
|
||||
val = mpp_buffer_get_size(task->output);
|
||||
val >>= 3;
|
||||
val &= ~7;
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_STR_BUF_LIMIT, val);
|
||||
|
||||
/*
|
||||
* The hardware needs only the value for luma plane, because
|
||||
* values of other planes are calculated internally based on
|
||||
* format setting.
|
||||
*/
|
||||
val = VEPU_REG_INTRA_AREA_TOP(mb_h)
|
||||
| VEPU_REG_INTRA_AREA_BOTTOM(mb_h)
|
||||
| VEPU_REG_INTRA_AREA_LEFT(mb_w)
|
||||
| VEPU_REG_INTRA_AREA_RIGHT(mb_w);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_AREA_CTRL, val);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_MSB, 0);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_LSB, 0);
|
||||
|
||||
val = VEPU_REG_AXI_CTRL_READ_ID(0);
|
||||
val |= VEPU_REG_AXI_CTRL_WRITE_ID(0);
|
||||
val |= VEPU_REG_AXI_CTRL_BURST_LEN(16);
|
||||
val |= VEPU_REG_AXI_CTRL_INCREMENT_MODE(0);
|
||||
val |= VEPU_REG_AXI_CTRL_BIRST_DISCARD(0);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_AXI_CTRL, val);
|
||||
|
||||
H264E_HAL_SET_REG(reg, VEPU_QP_ADJUST_MAD_DELTA_ROI,
|
||||
hw_mbrc->mad_qp_change);
|
||||
|
||||
val = 0;
|
||||
if (mb_w * mb_h > 3600)
|
||||
val = VEPU_REG_DISABLE_QUARTER_PIXEL_MV;
|
||||
val |= VEPU_REG_CABAC_INIT_IDC(slice->cabac_init_idc);
|
||||
if (pps->entropy_coding_mode)
|
||||
val |= VEPU_REG_ENTROPY_CODING_MODE;
|
||||
if (pps->transform_8x8_mode)
|
||||
val |= VEPU_REG_H264_TRANS8X8_MODE;
|
||||
if (sps->profile_idc > 31)
|
||||
val |= VEPU_REG_H264_INTER4X4_MODE;
|
||||
/*reg |= VEPU_REG_H264_STREAM_MODE;*/
|
||||
val |= VEPU_REG_H264_SLICE_SIZE(hw_mbrc->slice_size_mb_rows);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL0, val);
|
||||
|
||||
RK_U32 scaler = MPP_MAX(1, 200 / (mb_w + mb_h));
|
||||
|
||||
RK_U32 skip_penalty = MPP_MIN(255, h264_skip_sad_penalty[hw_mbrc->qp_init] * scaler);
|
||||
RK_U32 overfill_r = (hw_prep->src_w & 0x0f) ?
|
||||
((16 - (hw_prep->src_w & 0x0f)) / 4) : 0;
|
||||
RK_U32 overfill_b = (hw_prep->src_h & 0x0f) ?
|
||||
(16 - (hw_prep->src_h & 0x0f)) : 0;
|
||||
|
||||
val = VEPU_REG_STREAM_START_OFFSET(0) | /* first_free_bit */
|
||||
VEPU_REG_SKIP_MACROBLOCK_PENALTY(skip_penalty) |
|
||||
VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) |
|
||||
VEPU_REG_IN_IMG_CTRL_OVRFLB(overfill_b);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ENC_OVER_FILL_STRM_OFFSET, val);
|
||||
|
||||
// When offset is zero row length should be total 16 aligned width
|
||||
val = VEPU_REG_IN_IMG_CHROMA_OFFSET(0)
|
||||
| VEPU_REG_IN_IMG_LUMA_OFFSET(0)
|
||||
| VEPU_REG_IN_IMG_CTRL_ROW_LEN(mb_w * 16);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_INPUT_LUMA_INFO, val);
|
||||
|
||||
val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[0])
|
||||
| VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[1]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(0), val);
|
||||
|
||||
val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[2])
|
||||
| VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[3]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(1), val);
|
||||
|
||||
val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[4])
|
||||
| VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[5]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(2), val);
|
||||
|
||||
val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[6])
|
||||
| VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[7]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(3), val);
|
||||
|
||||
val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[8])
|
||||
| VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[9]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(4), val);
|
||||
|
||||
val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[0])
|
||||
| VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[1]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(0), val);
|
||||
|
||||
val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[2])
|
||||
| VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[3]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(1), val);
|
||||
|
||||
val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[4])
|
||||
| VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[5]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(2), val);
|
||||
|
||||
val = VEPU_REG_CHKPT_DELTA_QP_CHK6(hw_mbrc->cp_delta_qp[6])
|
||||
| VEPU_REG_CHKPT_DELTA_QP_CHK5(hw_mbrc->cp_delta_qp[5])
|
||||
| VEPU_REG_CHKPT_DELTA_QP_CHK4(hw_mbrc->cp_delta_qp[4])
|
||||
| VEPU_REG_CHKPT_DELTA_QP_CHK3(hw_mbrc->cp_delta_qp[3])
|
||||
| VEPU_REG_CHKPT_DELTA_QP_CHK2(hw_mbrc->cp_delta_qp[2])
|
||||
| VEPU_REG_CHKPT_DELTA_QP_CHK1(hw_mbrc->cp_delta_qp[1])
|
||||
| VEPU_REG_CHKPT_DELTA_QP_CHK0(hw_mbrc->cp_delta_qp[0]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_DELTA_QP, val);
|
||||
|
||||
val = VEPU_REG_MAD_THRESHOLD(hw_mbrc->mad_threshold)
|
||||
| VEPU_REG_IN_IMG_CTRL_FMT(hw_prep->src_fmt)
|
||||
| VEPU_REG_IN_IMG_ROTATE_MODE(0)
|
||||
| VEPU_REG_SIZE_TABLE_PRESENT; //FIXED
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL1, val);
|
||||
|
||||
val = VEPU_REG_INTRA16X16_MODE(h264_intra16_favor[hw_mbrc->qp_init])
|
||||
| VEPU_REG_INTER_MODE(h264_inter_favor[hw_mbrc->qp_init]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_INTER_MODE, val);
|
||||
|
||||
val = VEPU_REG_PPS_INIT_QP(pps->pic_init_qp)
|
||||
| VEPU_REG_SLICE_FILTER_ALPHA(slice->slice_alpha_c0_offset_div2)
|
||||
| VEPU_REG_SLICE_FILTER_BETA(slice->slice_beta_offset_div2)
|
||||
| VEPU_REG_CHROMA_QP_OFFSET(pps->chroma_qp_index_offset)
|
||||
| VEPU_REG_IDR_PIC_ID(slice->idr_pic_id);
|
||||
|
||||
if (slice->disable_deblocking_filter_idc)
|
||||
val |= VEPU_REG_FILTER_DISABLE;
|
||||
|
||||
if (pps->constrained_intra_pred)
|
||||
val |= VEPU_REG_CONSTRAINED_INTRA_PREDICTION;
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL2, val);
|
||||
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_NEXT_PIC, 0);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_MV_OUT, 0);
|
||||
|
||||
MppBuffer cabac_table = hw_bufs->cabac_table;
|
||||
RK_S32 cabac_table_fd = cabac_table ? mpp_buffer_get_fd(cabac_table) : 0;
|
||||
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_CABAC_TBL, cabac_table_fd);
|
||||
|
||||
val = VEPU_REG_ROI1_TOP_MB(mb_h)
|
||||
| VEPU_REG_ROI1_BOTTOM_MB(mb_h)
|
||||
| VEPU_REG_ROI1_LEFT_MB(mb_w)
|
||||
| VEPU_REG_ROI1_RIGHT_MB(mb_w);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ROI1, val);
|
||||
|
||||
val = VEPU_REG_ROI2_TOP_MB(mb_h)
|
||||
| VEPU_REG_ROI2_BOTTOM_MB(mb_h)
|
||||
| VEPU_REG_ROI2_LEFT_MB(mb_w)
|
||||
| VEPU_REG_ROI2_RIGHT_MB(mb_w);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ROI2, val);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_STABLILIZATION_OUTPUT, 0);
|
||||
|
||||
val = VEPU_REG_RGB2YUV_CONVERSION_COEFB(hw_prep->color_conversion_coeff_b)
|
||||
| VEPU_REG_RGB2YUV_CONVERSION_COEFA(hw_prep->color_conversion_coeff_a);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF1, val);
|
||||
|
||||
val = VEPU_REG_RGB2YUV_CONVERSION_COEFE(hw_prep->color_conversion_coeff_e)
|
||||
| VEPU_REG_RGB2YUV_CONVERSION_COEFC(hw_prep->color_conversion_coeff_c);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF2, val);
|
||||
|
||||
val = VEPU_REG_RGB2YUV_CONVERSION_COEFF(hw_prep->color_conversion_coeff_f);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF3, val);
|
||||
|
||||
val = VEPU_REG_RGB_MASK_B_MSB(hw_prep->b_mask_msb)
|
||||
| VEPU_REG_RGB_MASK_G_MSB(hw_prep->g_mask_msb)
|
||||
| VEPU_REG_RGB_MASK_R_MSB(hw_prep->r_mask_msb);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_RGB_MASK_MSB, val); //FIXED
|
||||
|
||||
{
|
||||
RK_U32 diff_mv_penalty[3] = {0};
|
||||
diff_mv_penalty[0] = h264_diff_mv_penalty4p[hw_mbrc->qp_init];
|
||||
diff_mv_penalty[1] = h264_diff_mv_penalty[hw_mbrc->qp_init];
|
||||
diff_mv_penalty[2] = h264_diff_mv_penalty[hw_mbrc->qp_init];
|
||||
|
||||
val = VEPU_REG_1MV_PENALTY(diff_mv_penalty[1])
|
||||
| VEPU_REG_QMV_PENALTY(diff_mv_penalty[2])
|
||||
| VEPU_REG_4MV_PENALTY(diff_mv_penalty[0]);
|
||||
}
|
||||
|
||||
val |= VEPU_REG_SPLIT_MV_MODE_EN;
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_MV_PENALTY, val);
|
||||
|
||||
val = VEPU_REG_H264_LUMA_INIT_QP(hw_mbrc->qp_init)
|
||||
| VEPU_REG_H264_QP_MAX(hw_mbrc->qp_max)
|
||||
| VEPU_REG_H264_QP_MIN(hw_mbrc->qp_min)
|
||||
| VEPU_REG_H264_CHKPT_DISTANCE(hw_mbrc->cp_distance_mbs);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_QP_VAL, val);
|
||||
|
||||
val = VEPU_REG_ZERO_MV_FAVOR_D2(10);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_MVC_RELATE, val);
|
||||
|
||||
if (hw_prep->src_fmt < H264E_VPU_CSP_RGB565) {
|
||||
val = VEPU_REG_OUTPUT_SWAP32
|
||||
| VEPU_REG_OUTPUT_SWAP16
|
||||
| VEPU_REG_OUTPUT_SWAP8
|
||||
| VEPU_REG_INPUT_SWAP8
|
||||
| VEPU_REG_INPUT_SWAP16
|
||||
| VEPU_REG_INPUT_SWAP32;
|
||||
} else if (hw_prep->src_fmt == H264E_VPU_CSP_ARGB8888) {
|
||||
val = VEPU_REG_OUTPUT_SWAP32
|
||||
| VEPU_REG_OUTPUT_SWAP16
|
||||
| VEPU_REG_OUTPUT_SWAP8
|
||||
| VEPU_REG_INPUT_SWAP32;
|
||||
} else {
|
||||
val = VEPU_REG_OUTPUT_SWAP32
|
||||
| VEPU_REG_OUTPUT_SWAP16
|
||||
| VEPU_REG_OUTPUT_SWAP8
|
||||
| VEPU_REG_INPUT_SWAP16
|
||||
| VEPU_REG_INPUT_SWAP32;
|
||||
}
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_DATA_ENDIAN, val);
|
||||
|
||||
val = VEPU_REG_PPS_ID(pps->pps_id)
|
||||
| VEPU_REG_INTRA_PRED_MODE(h264_prev_mode_favor[hw_mbrc->qp_init])
|
||||
| VEPU_REG_FRAME_NUM(slice->frame_num);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL3, val);
|
||||
|
||||
val = VEPU_REG_INTERRUPT_TIMEOUT_EN;
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_INTERRUPT, val);
|
||||
|
||||
{
|
||||
RK_U8 dmv_penalty[128] = {0};
|
||||
RK_U8 dmv_qpel_penalty[128] = {0};
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
dmv_penalty[i] = i;
|
||||
dmv_qpel_penalty[i] = MPP_MIN(255, exp_golomb_signed(i));
|
||||
}
|
||||
|
||||
for (i = 0; i < 128; i += 4) {
|
||||
val = VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i], 3);
|
||||
val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 1], 2);
|
||||
val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 2], 1);
|
||||
val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 3], 0);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_DMV_PENALTY_TBL(i / 4), val);
|
||||
|
||||
val = VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
|
||||
dmv_qpel_penalty[i], 3);
|
||||
val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
|
||||
dmv_qpel_penalty[i + 1], 2);
|
||||
val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
|
||||
dmv_qpel_penalty[i + 2], 1);
|
||||
val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
|
||||
dmv_qpel_penalty[i + 3], 0);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i / 4), val);
|
||||
}
|
||||
}
|
||||
|
||||
/* set buffers addr */
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_LUMA, hw_addr->orig[0]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CB, hw_addr->orig[1]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CR, hw_addr->orig[2]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_STREAM,
|
||||
mpp_buffer_get_fd(task->output));
|
||||
|
||||
MppBuffer nal_size_table = h264e_vepu_buf_get_nal_size_table(hw_bufs);
|
||||
RK_S32 nal_size_table_fd = nal_size_table ? mpp_buffer_get_fd(nal_size_table) : 0;
|
||||
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_CTRL, nal_size_table_fd);
|
||||
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_LUMA, hw_addr->recn[0]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_CHROMA, hw_addr->recn[1]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_LUMA, hw_addr->refr[0]);
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_CHROMA, hw_addr->refr[1]);
|
||||
|
||||
/* set important encode mode info */
|
||||
val = VEPU_REG_MB_HEIGHT(mb_h)
|
||||
| VEPU_REG_MB_WIDTH(mb_w)
|
||||
| VEPU_REG_PIC_TYPE(slice->idr_flag)
|
||||
| VEPU_REG_ENCODE_FORMAT(3)
|
||||
| VEPU_REG_ENCODE_ENABLE;
|
||||
H264E_HAL_SET_REG(reg, VEPU_REG_ENCODE_START, val);
|
||||
|
||||
ctx->frame_cnt++;
|
||||
|
||||
hal_h264e_dbg_func("leave %p\n", hal);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
static MPP_RET hal_h264e_vepu2_start_v2(void *hal, HalEncTask *task)
|
||||
{
|
||||
MPP_RET ret = MPP_OK;
|
||||
HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
|
||||
(void)task;
|
||||
|
||||
hal_h264e_dbg_func("enter %p\n", hal);
|
||||
|
||||
if (ctx->dev_ctx) {
|
||||
RK_U32 *regs = ctx->regs_set.val;
|
||||
|
||||
hal_h264e_dbg_detail("vpu client is sending %d regs", VEPU2_H264E_NUM_REGS);
|
||||
ret = mpp_device_send_reg(ctx->dev_ctx, regs, VEPU2_H264E_NUM_REGS);
|
||||
if (ret)
|
||||
mpp_err("mpp_device_send_reg failed ret %d", ret);
|
||||
else
|
||||
hal_h264e_dbg_detail("mpp_device_send_reg success!");
|
||||
} else {
|
||||
mpp_err("invalid device ctx: %p", ctx->dev_ctx);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
|
||||
hal_h264e_dbg_func("leave %p\n", hal);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void h264e_vepu2_get_mbrc(HalH264eVepuMbRc *mb_rc, H264eVpu2RegSet *reg)
|
||||
{
|
||||
RK_S32 i = 0;
|
||||
RK_U32 cpt_prev = 0;
|
||||
RK_U32 overflow = 0;
|
||||
RK_U32 cpt_idx = VEPU_REG_CHECKPOINT(0) / 4;
|
||||
RK_U32 *reg_val = reg->val;
|
||||
|
||||
mb_rc->hw_status = reg_val[VEPU_REG_INTERRUPT / 4];
|
||||
mb_rc->out_strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8;
|
||||
mb_rc->qp_sum = ((reg_val[VEPU_REG_QP_SUM_DIV2 / 4] >> 11) & 0x001fffff) * 2;
|
||||
mb_rc->less_mad_count = (reg_val[VEPU_REG_MB_CTRL / 4] >> 16) & 0xffff;
|
||||
mb_rc->rlc_count = reg_val[VEPU_REG_RLC_SUM / 4] & 0x3fffff;
|
||||
|
||||
for (i = 0; i < CHECK_POINTS_MAX; i++) {
|
||||
RK_U32 cpt = VEPU_REG_CHECKPOINT_RESULT(reg_val[cpt_idx]);
|
||||
|
||||
if (cpt < cpt_prev)
|
||||
overflow += (1 << 21);
|
||||
|
||||
cpt_prev = cpt;
|
||||
mb_rc->cp_usage[i] = cpt + overflow;
|
||||
cpt_idx += (i & 1);
|
||||
}
|
||||
}
|
||||
|
||||
static MPP_RET hal_h264e_vepu2_wait_v2(void *hal, HalEncTask *task)
|
||||
{
|
||||
HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
|
||||
HalH264eVepuMbRc *hw_mbrc = &ctx->hw_mbrc;
|
||||
RK_U32 *regs_get = ctx->regs_get.val;
|
||||
(void) task;
|
||||
|
||||
hal_h264e_dbg_func("enter %p\n", hal);
|
||||
|
||||
if (ctx->dev_ctx) {
|
||||
RK_S32 hw_ret = mpp_device_wait_reg(ctx->dev_ctx, (RK_U32 *)regs_get,
|
||||
VEPU2_H264E_NUM_REGS);
|
||||
|
||||
hal_h264e_dbg_detail("mpp_device_wait_reg: ret %d\n", hw_ret);
|
||||
|
||||
if (hw_ret != MPP_OK) {
|
||||
mpp_err("hardware returns error:%d", hw_ret);
|
||||
return MPP_ERR_VPUHW;
|
||||
}
|
||||
} else {
|
||||
mpp_err("invalid device ctx: %p", ctx->dev_ctx);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
h264e_vepu2_get_mbrc(hw_mbrc, &ctx->regs_get);
|
||||
|
||||
h264e_vepu_mbrc_update(ctx->rc_ctx, hw_mbrc);
|
||||
|
||||
/* On TSVC case modify AVC stream to TSVC stream */
|
||||
MppEncCfgSet *cfg = ctx->cfg;
|
||||
H264eSlice *slice = ctx->slice;
|
||||
MppEncGopRef *ref = &cfg->gop_ref;
|
||||
MppEncH264Cfg *h264 = &cfg->codec.h264;
|
||||
|
||||
if (h264->svc || ref->gop_cfg_enable) {
|
||||
H264eSlice hw_slice;
|
||||
MppBuffer buf = task->output;
|
||||
RK_U8 *p = mpp_buffer_get_ptr(buf);
|
||||
RK_U32 len = hw_mbrc->out_strm_size;
|
||||
RK_S32 size = mpp_buffer_get_size(buf);
|
||||
RK_S32 hw_len_bit = 0;
|
||||
RK_S32 sw_len_bit = 0;
|
||||
RK_S32 hw_len_byte = 0;
|
||||
RK_S32 sw_len_byte = 0;
|
||||
RK_S32 diff_size = 0;
|
||||
RK_S32 tail_0bit = 0;
|
||||
RK_U8 tail_byte = 0;
|
||||
RK_U8 tail_tmp = 0;
|
||||
RK_U8 *dst_buf = NULL;
|
||||
RK_S32 buf_size;
|
||||
RK_S32 prefix_bit = 0;
|
||||
RK_S32 prefix_byte = 0;
|
||||
RK_S32 more_buf = 0;
|
||||
|
||||
while (len > ctx->buf_size - 16) {
|
||||
ctx->buf_size *= 2;
|
||||
more_buf = 1;
|
||||
}
|
||||
|
||||
if (more_buf) {
|
||||
MPP_FREE(ctx->src_buf);
|
||||
MPP_FREE(ctx->dst_buf);
|
||||
ctx->src_buf = mpp_malloc(RK_U8, ctx->buf_size);
|
||||
ctx->dst_buf = mpp_malloc(RK_U8, ctx->buf_size);
|
||||
}
|
||||
|
||||
memset(ctx->dst_buf, 0, ctx->buf_size);
|
||||
dst_buf = ctx->dst_buf;
|
||||
buf_size = ctx->buf_size;
|
||||
|
||||
// copy hw stream to stream buffer first
|
||||
memcpy(ctx->src_buf, p, len);
|
||||
|
||||
// prepare hw_slice with some current setup
|
||||
memcpy(&hw_slice, slice, sizeof(hw_slice));
|
||||
// set hw_slice to vepu2 default hardware config
|
||||
hw_slice.max_num_ref_frames = 1;
|
||||
hw_slice.pic_order_cnt_type = 2;
|
||||
hw_slice.log2_max_frame_num = 16;
|
||||
hw_slice.log2_max_poc_lsb = 16;
|
||||
|
||||
hw_len_bit = h264e_slice_read(&hw_slice, ctx->src_buf, size);
|
||||
|
||||
if (h264->svc) {
|
||||
H264ePrefixNal prefix;
|
||||
|
||||
prefix.idr_flag = slice->idr_flag;
|
||||
prefix.nal_ref_idc = slice->nal_reference_idc;
|
||||
prefix.priority_id = 0;
|
||||
prefix.no_inter_layer_pred_flag = 1;
|
||||
prefix.dependency_id = 0;
|
||||
prefix.quality_id = 0;
|
||||
prefix.temporal_id = task->temporal_id;
|
||||
prefix.use_ref_base_pic_flag = 0;
|
||||
prefix.discardable_flag = 0;
|
||||
prefix.output_flag = 1;
|
||||
|
||||
prefix_bit = h264e_slice_write_prefix_nal_unit_svc(&prefix, dst_buf, buf_size);
|
||||
prefix_byte = prefix_bit /= 8;
|
||||
h264e_dbg_slice("prefix_len %d\n", prefix_byte);
|
||||
dst_buf += prefix_byte;
|
||||
buf_size -= prefix_byte;
|
||||
}
|
||||
|
||||
// write new header to header buffer
|
||||
sw_len_bit = h264e_slice_write(slice, dst_buf, buf_size);
|
||||
|
||||
h264e_slice_read(slice, dst_buf, size);
|
||||
|
||||
hw_len_byte = (hw_len_bit + 7) / 8;
|
||||
sw_len_byte = (sw_len_bit + 7) / 8;
|
||||
|
||||
tail_byte = ctx->src_buf[len - 1];
|
||||
tail_tmp = tail_byte;
|
||||
|
||||
while (!(tail_tmp & 1) && tail_0bit < 8) {
|
||||
tail_tmp >>= 1;
|
||||
tail_0bit++;
|
||||
}
|
||||
h264e_dbg_slice("tail_byte %02x bit %d\n", tail_byte, tail_0bit);
|
||||
|
||||
mpp_assert(tail_0bit < 8);
|
||||
|
||||
// move the reset slice data from src buffer to dst buffer
|
||||
diff_size = h264e_slice_move(dst_buf, ctx->src_buf,
|
||||
sw_len_bit, hw_len_bit, len);
|
||||
|
||||
h264e_dbg_slice("tail 0x%02x %d hw_len_bit %d sw_len_bit %d len %d hw_len_byte %d sw_len_byte %d diff %d\n",
|
||||
tail_byte, tail_0bit, hw_len_bit, sw_len_bit, len, hw_len_byte, sw_len_byte, diff_size);
|
||||
|
||||
if (slice->entropy_coding_mode) {
|
||||
memcpy(dst_buf + sw_len_byte, ctx->src_buf + hw_len_byte,
|
||||
len - hw_len_byte);
|
||||
|
||||
len += prefix_byte;
|
||||
|
||||
memcpy(p, ctx->dst_buf, len - hw_len_byte + sw_len_byte);
|
||||
|
||||
// clear the tail data
|
||||
if (sw_len_byte < hw_len_byte)
|
||||
memset(p + len - hw_len_byte + sw_len_byte, 0, hw_len_byte - sw_len_byte);
|
||||
|
||||
len = len - hw_len_byte + sw_len_byte;
|
||||
} else {
|
||||
RK_S32 hdr_diff_bit = sw_len_bit - hw_len_bit;
|
||||
RK_S32 bit_len = len * 8 - tail_0bit + hdr_diff_bit;
|
||||
RK_S32 new_len = (bit_len + diff_size * 8 + 7) / 8;
|
||||
|
||||
dst_buf[new_len] = 0;
|
||||
|
||||
h264e_dbg_slice("frm %d len %d bit hw %d sw %d byte hw %d sw %d diff %d -> %d\n",
|
||||
ctx->frms->seq_idx, len, hw_len_bit, sw_len_bit,
|
||||
hw_len_byte, sw_len_byte, diff_size, new_len);
|
||||
new_len += prefix_byte;
|
||||
memcpy(p, ctx->dst_buf, new_len);
|
||||
p[new_len] = 0;
|
||||
len = new_len;
|
||||
}
|
||||
|
||||
hw_mbrc->out_strm_size = len;
|
||||
}
|
||||
|
||||
hal_h264e_dbg_func("leave %p\n", hal);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
static MPP_RET hal_h264e_vepu2_ret_task_v2(void *hal, HalEncTask *task)
|
||||
{
|
||||
HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
|
||||
RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
|
||||
RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
|
||||
RK_U32 mbs = mb_w * mb_h;
|
||||
|
||||
hal_h264e_dbg_func("enter %p\n", hal);
|
||||
|
||||
task->length = ctx->hw_mbrc.out_strm_size;
|
||||
|
||||
ctx->hal_rc_cfg.bit_real = task->length;
|
||||
ctx->hal_rc_cfg.quality_real = ctx->hw_mbrc.qp_sum / mbs;
|
||||
|
||||
task->hal_ret.data = &ctx->hal_rc_cfg;
|
||||
task->hal_ret.number = 1;
|
||||
|
||||
hal_h264e_dbg_func("leave %p\n", hal);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
const MppEncHalApi hal_h264e_vepu2 = {
|
||||
.name = "hal_h264e_vepu2",
|
||||
.coding = MPP_VIDEO_CodingAVC,
|
||||
.ctx_size = sizeof(HalH264eVepu2Ctx),
|
||||
.flag = 0,
|
||||
.init = hal_h264e_vepu2_init_v2,
|
||||
.deinit = hal_h264e_vepu2_deinit_v2,
|
||||
.get_task = hal_h264e_vepu2_get_task_v2,
|
||||
.gen_regs = hal_h264e_vepu2_gen_regs_v2,
|
||||
.start = hal_h264e_vepu2_start_v2,
|
||||
.wait = hal_h264e_vepu2_wait_v2,
|
||||
.ret_task = hal_h264e_vepu2_ret_task_v2,
|
||||
};
|
24
mpp/hal/vpu/h264e/hal_h264e_vepu2_v2.h
Normal file
24
mpp/hal/vpu/h264e/hal_h264e_vepu2_v2.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_H264E_VEPU2_H__
|
||||
#define __HAL_H264E_VEPU2_H__
|
||||
|
||||
#include "mpp_enc_hal.h"
|
||||
|
||||
extern const MppEncHalApi hal_h264e_vepu2;
|
||||
|
||||
#endif
|
643
mpp/hal/vpu/h264e/hal_h264e_vepu_v2.c
Normal file
643
mpp/hal/vpu/h264e/hal_h264e_vepu_v2.c
Normal file
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright 2015 - 2017 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#define MODULE_TAG "hal_h264e_vepu_v2"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_common.h"
|
||||
#include "mpp_buffer.h"
|
||||
|
||||
#include "hal_h264e_debug.h"
|
||||
#include "hal_h264e_com.h"
|
||||
#include "hal_h264e_vepu_v2.h"
|
||||
#include "hal_h264e_vpu_tbl_v2.h"
|
||||
|
||||
typedef struct HalH264eVepuMbRcImpl_t {
|
||||
RK_S32 width;
|
||||
RK_S32 height;
|
||||
RK_S32 mb_w;
|
||||
RK_S32 mb_h;
|
||||
|
||||
RK_S32 pels;
|
||||
RK_S32 mbs;
|
||||
|
||||
RK_S32 bits_per_pic;
|
||||
|
||||
RK_S32 mb_bit_rc_enable;
|
||||
|
||||
/* frame rate control */
|
||||
RK_S32 fps_in_num;
|
||||
RK_S32 fps_in_denorm;
|
||||
RK_S32 fps_out_num;
|
||||
RK_S32 fps_out_denorm;
|
||||
|
||||
RK_S32 fps_count;
|
||||
RK_S32 fps_step;
|
||||
RK_S32 fps_threshold;
|
||||
|
||||
/*
|
||||
* MAD based QP adjustment
|
||||
* mad_qp_change [-8..7]
|
||||
* mad_threshold MAD threshold div256
|
||||
*/
|
||||
RK_S32 mad_qp_change;
|
||||
RK_S32 mad_threshold;
|
||||
|
||||
/*
|
||||
* check point parameter
|
||||
*/
|
||||
RK_S32 check_point_count;
|
||||
RK_S32 check_point_distance;
|
||||
|
||||
/* estimated first I frame qp */
|
||||
RK_S32 qp_init_est;
|
||||
} HalH264eVepuMbRcImpl;
|
||||
|
||||
static void vepu_swap_endian(RK_U32 *buf, RK_S32 size_bytes)
|
||||
{
|
||||
RK_U32 i = 0;
|
||||
RK_S32 words = size_bytes / 4;
|
||||
RK_U32 val, val2, tmp, tmp2;
|
||||
|
||||
mpp_assert((size_bytes % 8) == 0);
|
||||
|
||||
while (words > 0) {
|
||||
val = buf[i];
|
||||
tmp = 0;
|
||||
|
||||
tmp |= (val & 0xFF) << 24;
|
||||
tmp |= (val & 0xFF00) << 8;
|
||||
tmp |= (val & 0xFF0000) >> 8;
|
||||
tmp |= (val & 0xFF000000) >> 24;
|
||||
{
|
||||
val2 = buf[i + 1];
|
||||
tmp2 = 0;
|
||||
|
||||
tmp2 |= (val2 & 0xFF) << 24;
|
||||
tmp2 |= (val2 & 0xFF00) << 8;
|
||||
tmp2 |= (val2 & 0xFF0000) >> 8;
|
||||
tmp2 |= (val2 & 0xFF000000) >> 24;
|
||||
|
||||
buf[i] = tmp2;
|
||||
words--;
|
||||
i++;
|
||||
}
|
||||
buf[i] = tmp;
|
||||
words--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static void vepu_write_cabac_table(MppBuffer buf, RK_S32 cabac_init_idc)
|
||||
{
|
||||
const RK_S32(*context)[460][2];
|
||||
RK_S32 i, j, qp;
|
||||
RK_U8 table[H264E_CABAC_TABLE_BUF_SIZE] = {0};
|
||||
|
||||
for (qp = 0; qp < 52; qp++) { /* All QP values */
|
||||
for (j = 0; j < 2; j++) { /* Intra/Inter */
|
||||
if (j == 0)
|
||||
/*lint -e(545) */
|
||||
context = &h264_context_init_intra;
|
||||
else
|
||||
/*lint -e(545) */
|
||||
context = &h264_context_init[cabac_init_idc];
|
||||
|
||||
for (i = 0; i < 460; i++) {
|
||||
RK_S32 m = (RK_S32)(*context)[i][0];
|
||||
RK_S32 n = (RK_S32)(*context)[i][1];
|
||||
|
||||
RK_S32 pre_ctx_state = H264E_HAL_CLIP3(((m * (RK_S32)qp) >> 4)
|
||||
+ n, 1, 126);
|
||||
|
||||
if (pre_ctx_state <= 63)
|
||||
table[qp * 464 * 2 + j * 464 + i] =
|
||||
(RK_U8)((63 - pre_ctx_state) << 1);
|
||||
else
|
||||
table[qp * 464 * 2 + j * 464 + i] =
|
||||
(RK_U8)(((pre_ctx_state - 64) << 1) | 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vepu_swap_endian((RK_U32 *)table, H264E_CABAC_TABLE_BUF_SIZE);
|
||||
mpp_buffer_write(buf, 0, table, H264E_CABAC_TABLE_BUF_SIZE);
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_buf_init(HalH264eVepuBufs *bufs)
|
||||
{
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
hal_h264e_dbg_buffer("enter %p\n", bufs);
|
||||
|
||||
memset(bufs, 0, sizeof(*bufs));
|
||||
|
||||
// do not create buffer on cavlc case
|
||||
bufs->cabac_init_idc = -1;
|
||||
ret = mpp_buffer_group_get_internal(&bufs->group, MPP_BUFFER_TYPE_ION);
|
||||
if (ret)
|
||||
mpp_err_f("get buffer group failed ret %d\n", ret);
|
||||
|
||||
hal_h264e_dbg_buffer("leave %p\n", bufs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_buf_deinit(HalH264eVepuBufs *bufs)
|
||||
{
|
||||
RK_S32 i;
|
||||
|
||||
hal_h264e_dbg_buffer("enter %p\n", bufs);
|
||||
|
||||
if (bufs->cabac_table)
|
||||
mpp_buffer_put(bufs->cabac_table);
|
||||
|
||||
if (bufs->nal_size_table)
|
||||
mpp_buffer_put(bufs->nal_size_table);
|
||||
|
||||
for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(bufs->frm_buf); i++) {
|
||||
if (bufs->frm_buf[i])
|
||||
mpp_buffer_put(bufs->frm_buf[i]);
|
||||
}
|
||||
|
||||
if (bufs->group)
|
||||
mpp_buffer_group_put(bufs->group);
|
||||
|
||||
memset(bufs, 0, sizeof(*bufs));
|
||||
bufs->cabac_init_idc = -1;
|
||||
|
||||
hal_h264e_dbg_buffer("leave %p\n", bufs);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_buf_set_cabac_idc(HalH264eVepuBufs *bufs, RK_S32 idc)
|
||||
{
|
||||
hal_h264e_dbg_buffer("enter %p\n", bufs);
|
||||
|
||||
if (idc >= 0 && !bufs->cabac_table)
|
||||
mpp_buffer_get(bufs->group, &bufs->cabac_table, H264E_CABAC_TABLE_BUF_SIZE);
|
||||
|
||||
if (bufs->cabac_table && idc != bufs->cabac_init_idc && idc >= 0)
|
||||
vepu_write_cabac_table(bufs->cabac_table, idc);
|
||||
|
||||
bufs->cabac_init_idc = idc;
|
||||
|
||||
hal_h264e_dbg_buffer("leave %p\n", bufs);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_buf_set_frame_size(HalH264eVepuBufs *bufs, RK_S32 w, RK_S32 h)
|
||||
{
|
||||
RK_S32 aligned_w = MPP_ALIGN(w, 16);
|
||||
RK_S32 aligned_h = MPP_ALIGN(h, 16);
|
||||
size_t yuv_size = aligned_w * aligned_h;
|
||||
size_t frm_size = yuv_size * 3 / 2;
|
||||
RK_S32 i;
|
||||
RK_S32 cnt = (RK_S32)MPP_ARRAY_ELEMS(bufs->frm_buf);
|
||||
|
||||
hal_h264e_dbg_buffer("enter %p\n", bufs);
|
||||
|
||||
mpp_assert(frm_size);
|
||||
|
||||
if (frm_size != bufs->frm_size) {
|
||||
if (bufs->frm_size) {
|
||||
/* reallocate only on larger frame size to save time */
|
||||
mpp_log("new frame size [%d:%d] require buffer %d not equal to %d\n",
|
||||
w, h, frm_size, bufs->frm_size);
|
||||
}
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
if (bufs->frm_buf[i]) {
|
||||
mpp_buffer_put(bufs->frm_buf[i]);
|
||||
bufs->frm_buf[i] = NULL;
|
||||
bufs->frm_cnt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bufs->mb_h = aligned_h >> 4;
|
||||
if (bufs->mb_h)
|
||||
bufs->nal_tab_size = MPP_ALIGN((bufs->mb_h + 1) * sizeof(RK_U32), 8);
|
||||
else
|
||||
bufs->nal_tab_size = 0;
|
||||
|
||||
bufs->yuv_size = yuv_size;
|
||||
bufs->frm_size = frm_size;
|
||||
|
||||
hal_h264e_dbg_buffer("leave %p\n", bufs);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MppBuffer h264e_vepu_buf_get_nal_size_table(HalH264eVepuBufs *bufs)
|
||||
{
|
||||
MppBuffer buf = bufs->nal_size_table;
|
||||
|
||||
hal_h264e_dbg_buffer("enter %p\n", bufs);
|
||||
|
||||
if (NULL == buf) {
|
||||
mpp_buffer_get(bufs->group, &buf, bufs->nal_tab_size);
|
||||
mpp_assert(buf);
|
||||
bufs->nal_size_table = buf;
|
||||
}
|
||||
|
||||
hal_h264e_dbg_buffer("leave %p\n", bufs);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
MppBuffer h264e_vepu_buf_get_frame_buffer(HalH264eVepuBufs *bufs, RK_S32 index)
|
||||
{
|
||||
MppBuffer buf = bufs->frm_buf[index];
|
||||
|
||||
hal_h264e_dbg_buffer("enter\n", bufs);
|
||||
|
||||
if (NULL == buf) {
|
||||
mpp_buffer_get(bufs->group, &buf, bufs->frm_size);
|
||||
mpp_assert(buf);
|
||||
bufs->frm_buf[index] = buf;
|
||||
bufs->frm_cnt++;
|
||||
}
|
||||
|
||||
hal_h264e_dbg_buffer("leave %p\n", bufs);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static H264eVpuCsp fmt_to_vepu_csp_yuv[MPP_FMT_YUV_BUTT] = {
|
||||
H264E_VPU_CSP_YUV420SP, // MPP_FMT_YUV420SP /* YYYY... UV... (NV12) */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV420SP_10BIT ///< Not part of ABI
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV422SP /* YYYY... UVUV... (NV16) */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV422SP_10BIT ///< Not part of ABI
|
||||
H264E_VPU_CSP_YUV420P, // MPP_FMT_YUV420P /* YYYY... U...V... (I420) */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV420SP_VU /* YYYY... VUVUVU... (NV21) */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV422P /* YYYY... UU...VV...(422P) */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV422SP_VU /* YYYY... VUVUVU... (NV61) */
|
||||
H264E_VPU_CSP_YUYV422, // MPP_FMT_YUV422_YUYV /* YUYVYUYV... (YUY2) */
|
||||
H264E_VPU_CSP_UYVY422, // MPP_FMT_YUV422_UYVY /* UYVYUYVY... (UYVY) */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV400 /* YYYY... */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV440SP /* YYYY... UVUV... */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV411SP /* YYYY... UV... */
|
||||
H264E_VPU_CSP_NONE, // MPP_FMT_YUV444SP /* YYYY... UVUVUVUV... */
|
||||
};
|
||||
|
||||
static H264eVpuCsp fmt_to_vepu_csp_rgb[MPP_FMT_RGB_BUTT - MPP_FRAME_FMT_RGB] = {
|
||||
H264E_VPU_CSP_RGB565, // MPP_FMT_RGB565 /* 16-bit RGB */
|
||||
H264E_VPU_CSP_RGB565, // MPP_FMT_BGR565 /* 16-bit RGB */
|
||||
H264E_VPU_CSP_RGB555, // MPP_FMT_RGB555 /* 15-bit RGB */
|
||||
H264E_VPU_CSP_RGB555, // MPP_FMT_BGR555 /* 15-bit RGB */
|
||||
H264E_VPU_CSP_RGB444, // MPP_FMT_RGB444 /* 12-bit RGB */
|
||||
H264E_VPU_CSP_RGB444, // MPP_FMT_BGR444 /* 12-bit RGB */
|
||||
H264E_VPU_CSP_RGB888, // MPP_FMT_RGB888 /* 24-bit RGB */
|
||||
H264E_VPU_CSP_RGB888, // MPP_FMT_BGR888 /* 24-bit RGB */
|
||||
H264E_VPU_CSP_RGB101010, // MPP_FMT_RGB101010 /* 30-bit RGB */
|
||||
H264E_VPU_CSP_RGB101010, // MPP_FMT_BGR101010 /* 30-bit RGB */
|
||||
H264E_VPU_CSP_ARGB8888, // MPP_FMT_ARGB8888 /* 32-bit RGB */
|
||||
H264E_VPU_CSP_ARGB8888, // MPP_FMT_ABGR8888 /* 32-bit RGB */
|
||||
};
|
||||
|
||||
static RK_S32 fmt_to_vepu_mask_msb[MPP_FMT_RGB_BUTT - MPP_FRAME_FMT_RGB][3] = {
|
||||
// R G B // mask msb position
|
||||
{ 15, 10, 4, }, // MPP_FMT_RGB565 /* 16-bit RGB */
|
||||
{ 4, 10, 15, }, // MPP_FMT_BGR565 /* 16-bit RGB */
|
||||
{ 14, 9, 4, }, // MPP_FMT_RGB555 /* 15-bit RGB */
|
||||
{ 4, 9, 14, }, // MPP_FMT_BGR555 /* 15-bit RGB */
|
||||
{ 11, 7, 3, }, // MPP_FMT_RGB444 /* 12-bit RGB */
|
||||
{ 3, 7, 11, }, // MPP_FMT_BGR444 /* 12-bit RGB */
|
||||
{ 23, 15, 7, }, // MPP_FMT_RGB888 /* 24-bit RGB */
|
||||
{ 7, 15, 23, }, // MPP_FMT_BGR888 /* 24-bit RGB */
|
||||
{ 29, 19, 9, }, // MPP_FMT_RGB101010 /* 30-bit RGB */
|
||||
{ 9, 19, 29, }, // MPP_FMT_BGR101010 /* 30-bit RGB */
|
||||
{ 23, 15, 7, }, // MPP_FMT_ARGB8888 /* 32-bit RGB */
|
||||
{ 7, 15, 23, }, // MPP_FMT_ABGR8888 /* 32-bit RGB */
|
||||
};
|
||||
|
||||
MPP_RET h264e_vepu_prep_setup(HalH264eVepuPrep *prep, MppEncPrepCfg *cfg)
|
||||
{
|
||||
MPP_RET ret = MPP_OK;
|
||||
MppFrameFormat format = cfg->format;
|
||||
|
||||
hal_h264e_dbg_buffer("enter\n");
|
||||
|
||||
prep->src_fmt = format;
|
||||
prep->src_w = cfg->width;
|
||||
prep->src_h = cfg->height;
|
||||
|
||||
if (format < MPP_FRAME_FMT_RGB) {
|
||||
// YUV case
|
||||
prep->src_fmt = fmt_to_vepu_csp_yuv[format];
|
||||
if (prep->src_fmt == H264E_VPU_CSP_NONE) {
|
||||
mpp_err("vepu do not support input frame format %d\n", format);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
prep->r_mask_msb = 0;
|
||||
prep->g_mask_msb = 0;
|
||||
prep->b_mask_msb = 0;
|
||||
|
||||
prep->color_conversion_coeff_a = 0;
|
||||
prep->color_conversion_coeff_b = 0;
|
||||
prep->color_conversion_coeff_c = 0;
|
||||
prep->color_conversion_coeff_e = 0;
|
||||
prep->color_conversion_coeff_f = 0;
|
||||
} else {
|
||||
// RGB case
|
||||
RK_S32 rgb_idx = format - MPP_FRAME_FMT_RGB;
|
||||
|
||||
mpp_assert(rgb_idx < MPP_FMT_RGB_BUTT - MPP_FRAME_FMT_RGB);
|
||||
|
||||
prep->src_fmt = fmt_to_vepu_csp_rgb[rgb_idx];
|
||||
if (prep->src_fmt == H264E_VPU_CSP_NONE) {
|
||||
mpp_err("vepu do not support input frame format %d\n", format);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
prep->r_mask_msb = fmt_to_vepu_mask_msb[rgb_idx][0];
|
||||
prep->g_mask_msb = fmt_to_vepu_mask_msb[rgb_idx][1];
|
||||
prep->b_mask_msb = fmt_to_vepu_mask_msb[rgb_idx][2];
|
||||
|
||||
switch (cfg->color) {
|
||||
case MPP_FRAME_SPC_RGB : {
|
||||
/* BT.601 */
|
||||
/* Y = 0.2989 R + 0.5866 G + 0.1145 B
|
||||
* Cb = 0.5647 (B - Y) + 128
|
||||
* Cr = 0.7132 (R - Y) + 128
|
||||
*/
|
||||
prep->color_conversion_coeff_a = 19589;
|
||||
prep->color_conversion_coeff_b = 38443;
|
||||
prep->color_conversion_coeff_c = 7504;
|
||||
prep->color_conversion_coeff_e = 37008;
|
||||
prep->color_conversion_coeff_f = 46740;
|
||||
} break;
|
||||
case MPP_FRAME_SPC_BT709 : {
|
||||
/* BT.709 */
|
||||
/* Y = 0.2126 R + 0.7152 G + 0.0722 B
|
||||
* Cb = 0.5389 (B - Y) + 128
|
||||
* Cr = 0.6350 (R - Y) + 128
|
||||
*/
|
||||
prep->color_conversion_coeff_a = 13933;
|
||||
prep->color_conversion_coeff_b = 46871;
|
||||
prep->color_conversion_coeff_c = 4732;
|
||||
prep->color_conversion_coeff_e = 35317;
|
||||
prep->color_conversion_coeff_f = 41615;
|
||||
} break;
|
||||
default : {
|
||||
prep->color_conversion_coeff_a = 19589;
|
||||
prep->color_conversion_coeff_b = 38443;
|
||||
prep->color_conversion_coeff_c = 7504;
|
||||
prep->color_conversion_coeff_e = 37008;
|
||||
prep->color_conversion_coeff_f = 46740;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
RK_S32 hor_stride = cfg->hor_stride;
|
||||
RK_S32 ver_stride = cfg->ver_stride;
|
||||
prep->offset_cb = 0;
|
||||
prep->offset_cr = 0;
|
||||
|
||||
switch (format) {
|
||||
case MPP_FMT_YUV420SP : {
|
||||
prep->offset_cb = hor_stride * ver_stride;
|
||||
prep->size_y = hor_stride * MPP_ALIGN(prep->src_h, 16);
|
||||
prep->size_c = hor_stride / 2 * MPP_ALIGN(prep->src_h / 2, 8);
|
||||
} break;
|
||||
case MPP_FMT_YUV420P : {
|
||||
prep->offset_cb = hor_stride * ver_stride;
|
||||
prep->offset_cr = prep->offset_cb + ((hor_stride * ver_stride) / 4);
|
||||
prep->size_y = hor_stride * MPP_ALIGN(prep->src_h, 16);
|
||||
prep->size_c = hor_stride / 2 * MPP_ALIGN(prep->src_h / 2, 8);
|
||||
} break;
|
||||
case MPP_FMT_YUV422_YUYV :
|
||||
case MPP_FMT_YUV422_UYVY : {
|
||||
prep->size_y = hor_stride * 2 * MPP_ALIGN(prep->src_h, 16);
|
||||
prep->size_c = 0;
|
||||
} break;
|
||||
case MPP_FMT_RGB565 :
|
||||
case MPP_FMT_BGR444 : {
|
||||
prep->size_y = hor_stride * 2 * MPP_ALIGN(prep->src_h, 16);
|
||||
prep->size_c = 0;
|
||||
} break;
|
||||
case MPP_FMT_BGR888 :
|
||||
case MPP_FMT_RGB888 :
|
||||
case MPP_FMT_ARGB8888 :
|
||||
case MPP_FMT_ABGR8888 :
|
||||
case MPP_FMT_BGR101010 : {
|
||||
prep->size_y = hor_stride * 4 * MPP_ALIGN(prep->src_h, 16);
|
||||
prep->size_c = 0;
|
||||
} break;
|
||||
default: {
|
||||
mpp_err_f("invalid format %d", format);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
}
|
||||
|
||||
hal_h264e_dbg_buffer("leave\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_prep_get_addr(HalH264eVepuPrep *prep, MppBuffer buffer,
|
||||
RK_U32 (*addr)[3])
|
||||
{
|
||||
RK_U32 fd = (RK_U32)mpp_buffer_get_fd(buffer);
|
||||
size_t size = mpp_buffer_get_size(buffer);
|
||||
|
||||
hal_h264e_dbg_buffer("enter\n");
|
||||
|
||||
(*addr)[0] = fd;
|
||||
(*addr)[1] = fd + (prep->offset_cb << 10);
|
||||
(*addr)[2] = fd + (prep->offset_cr << 10);
|
||||
|
||||
if (size < prep->size_y)
|
||||
mpp_err("warnning: input buffer size 0x%x is smaller then required size 0x%x",
|
||||
size, prep->size_y);
|
||||
|
||||
if (prep->size_c && (prep->offset_cb || prep->offset_cr)) {
|
||||
if (prep->offset_cb && (size < prep->offset_cb + prep->size_c))
|
||||
mpp_err("warnning: input buffer size 0x%x is smaller then cb requirement 0x%x + 0x%x",
|
||||
size, prep->offset_cb, prep->size_c);
|
||||
|
||||
if (prep->offset_cr && (size < prep->offset_cr + prep->size_c))
|
||||
mpp_err("warnning: input buffer size 0x%x is smaller then cb requirement 0x%x + 0x%x",
|
||||
size, prep->offset_cr, prep->size_c);
|
||||
}
|
||||
|
||||
hal_h264e_dbg_buffer("leave\n");
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_mbrc_init(HalH264eVepuMbRcCtx *ctx, HalH264eVepuMbRc *mbrc)
|
||||
{
|
||||
MPP_RET ret = MPP_OK;
|
||||
HalH264eVepuMbRcImpl *p = mpp_calloc(HalH264eVepuMbRcImpl, 1);
|
||||
if (!p) {
|
||||
mpp_err_f("failed to alloc rate control context\n");
|
||||
ret = MPP_ERR_NOMEM;
|
||||
}
|
||||
|
||||
memset(mbrc, 0, sizeof(*mbrc));
|
||||
mbrc->qp_init = -1;
|
||||
mbrc->qp_max = 48;
|
||||
mbrc->qp_min = 16;
|
||||
|
||||
*ctx = p;
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_mbrc_deinit(HalH264eVepuMbRcCtx ctx)
|
||||
{
|
||||
MPP_FREE(ctx);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
static RK_S32 qp_tbl[2][13] = {
|
||||
{
|
||||
26, 36, 48, 63, 85, 110, 152, 208, 313, 427, 936,
|
||||
1472, 0x7fffffff
|
||||
},
|
||||
{42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12, 9, 6}
|
||||
};
|
||||
|
||||
MPP_RET h264e_vepu_mbrc_setup(HalH264eVepuMbRcCtx ctx, MppEncCfgSet*cfg)
|
||||
{
|
||||
HalH264eVepuMbRcImpl *p = (HalH264eVepuMbRcImpl *)ctx;
|
||||
MppEncH264Cfg *codec = &cfg->codec.h264;
|
||||
MppEncPrepCfg *prep = &cfg->prep;
|
||||
MppEncRcCfg *rc = &cfg->rc;
|
||||
|
||||
hal_h264e_dbg_rc("enter\n");
|
||||
|
||||
// get necessary parameter from config
|
||||
p->width = prep->width;
|
||||
p->height = prep->height;
|
||||
p->mb_w = MPP_ALIGN(prep->width, 16) / 16;
|
||||
p->mb_h = MPP_ALIGN(prep->height, 16) / 16;
|
||||
p->pels = p->width * p->height;
|
||||
p->mbs = p->mb_w * p->mb_h;
|
||||
p->bits_per_pic = axb_div_c(rc->bps_target, rc->fps_out_denorm,
|
||||
rc->fps_out_num);
|
||||
|
||||
mpp_assert(p->pels);
|
||||
|
||||
// frame rate control
|
||||
mpp_assert(rc->fps_out_num / rc->fps_out_denorm <= rc->fps_in_num / rc->fps_in_denorm);
|
||||
|
||||
p->fps_in_num = rc->fps_in_num;
|
||||
p->fps_in_denorm = rc->fps_in_denorm;
|
||||
p->fps_out_num = rc->fps_out_num;
|
||||
p->fps_out_denorm = rc->fps_out_denorm;
|
||||
|
||||
p->fps_step = rc->fps_in_denorm * rc->fps_out_num;
|
||||
p->fps_threshold = rc->fps_in_num * rc->fps_out_denorm;
|
||||
p->fps_count = p->fps_threshold;
|
||||
|
||||
// if not constant
|
||||
p->mb_bit_rc_enable = !(rc->rc_mode == MPP_ENC_RC_MODE_VBR &&
|
||||
rc->quality == MPP_ENC_RC_QUALITY_CQP);
|
||||
|
||||
// init first frame QP
|
||||
if (p->bits_per_pic > 1000000)
|
||||
p->qp_init_est = codec->qp_min;
|
||||
else {
|
||||
RK_S32 upscale = 8000;
|
||||
RK_S32 i = -1;
|
||||
RK_S32 bits_per_pic = p->bits_per_pic;
|
||||
RK_S32 mbs = p->mbs;
|
||||
|
||||
bits_per_pic >>= 5;
|
||||
|
||||
bits_per_pic *= mbs + 250;
|
||||
bits_per_pic /= 350 + (3 * mbs) / 4;
|
||||
bits_per_pic = axb_div_c(bits_per_pic, upscale, mbs << 6);
|
||||
|
||||
while (qp_tbl[0][++i] < bits_per_pic);
|
||||
|
||||
p->qp_init_est = qp_tbl[1][i];
|
||||
}
|
||||
hal_h264e_dbg_rc("estimated init qp %d\n", p->qp_init_est);
|
||||
|
||||
// init first frame mad parameter
|
||||
p->mad_qp_change = 2;
|
||||
p->mad_threshold = 256 * 6;
|
||||
|
||||
// init check point position
|
||||
if (p->mb_bit_rc_enable) {
|
||||
p->check_point_count = MPP_MIN(p->mb_h - 1, CHECK_POINTS_MAX);
|
||||
p->check_point_distance = p->mbs / (p->check_point_count + 1);
|
||||
} else {
|
||||
p->check_point_count = 0;
|
||||
p->check_point_distance = 0;
|
||||
}
|
||||
|
||||
hal_h264e_dbg_rc("leave\n");
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_mbrc_prepare(HalH264eVepuMbRcCtx ctx, RcSyntax *rc,
|
||||
EncFrmStatus *info, HalH264eVepuMbRc *mbrc)
|
||||
{
|
||||
HalH264eVepuMbRcImpl *p = (HalH264eVepuMbRcImpl *)ctx;
|
||||
RK_S32 target_bits = rc->bit_target;
|
||||
RK_S32 target_step = target_bits / (p->check_point_count + 1);
|
||||
RK_S32 target_sum = 0;
|
||||
RK_S32 tmp;
|
||||
RK_S32 i;
|
||||
|
||||
mpp_assert(target_step >= 0);
|
||||
(void) info;
|
||||
|
||||
for (i = 0; i < VEPU_CHECK_POINTS_MAX; i++) {
|
||||
target_sum += target_step;
|
||||
mbrc->cp_target[i] = mpp_clip(target_sum / 32, -32768, 32767);
|
||||
}
|
||||
|
||||
tmp = target_step / 8;
|
||||
|
||||
mbrc->cp_error[0] = -tmp * 3;
|
||||
mbrc->cp_delta_qp[0] = -3;
|
||||
mbrc->cp_error[1] = -tmp * 2;
|
||||
mbrc->cp_delta_qp[1] = -2;
|
||||
mbrc->cp_error[2] = -tmp * 1;
|
||||
mbrc->cp_delta_qp[2] = -1;
|
||||
mbrc->cp_error[3] = tmp * 1;
|
||||
mbrc->cp_delta_qp[3] = 0;
|
||||
mbrc->cp_error[4] = tmp * 2;
|
||||
mbrc->cp_delta_qp[4] = 1;
|
||||
mbrc->cp_error[5] = tmp * 3;
|
||||
mbrc->cp_delta_qp[5] = 2;
|
||||
mbrc->cp_error[6] = tmp * 4;
|
||||
mbrc->cp_delta_qp[6] = 3;
|
||||
|
||||
mbrc->mad_qp_change = 2;
|
||||
mbrc->mad_threshold = 2;
|
||||
|
||||
mbrc->cp_distance_mbs = p->check_point_distance;
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET h264e_vepu_mbrc_update(HalH264eVepuMbRcCtx ctx, HalH264eVepuMbRc *mbrc)
|
||||
{
|
||||
HalH264eVepuMbRcImpl *p = (HalH264eVepuMbRcImpl *)ctx;
|
||||
(void) p;
|
||||
(void) mbrc;
|
||||
|
||||
hal_h264e_dbg_rc("enter\n");
|
||||
hal_h264e_dbg_rc("leave\n");
|
||||
return MPP_OK;
|
||||
}
|
195
mpp/hal/vpu/h264e/hal_h264e_vepu_v2.h
Normal file
195
mpp/hal/vpu/h264e/hal_h264e_vepu_v2.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2017 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_H264E_VEPU_V2_H__
|
||||
#define __HAL_H264E_VEPU_V2_H__
|
||||
|
||||
#include "mpp_enc_cfg.h"
|
||||
#include "h264e_syntax_new.h"
|
||||
#include "mpp_rc.h"
|
||||
|
||||
typedef enum H264eVpuFrameType_t {
|
||||
H264E_VPU_FRAME_P = 0,
|
||||
H264E_VPU_FRAME_I = 1
|
||||
} H264eVpuFrameType;
|
||||
|
||||
#define VEPU_CTRL_LEVELS 7
|
||||
#define VEPU_CHECK_POINTS_MAX 10
|
||||
|
||||
typedef struct HalH264eVepuInput_t {
|
||||
/* Hardware config format */
|
||||
RK_S32 src_fmt;
|
||||
RK_S32 src_w;
|
||||
RK_S32 src_h;
|
||||
size_t size_y;
|
||||
size_t size_c;
|
||||
|
||||
RK_U32 offset_cb;
|
||||
RK_U32 offset_cr;
|
||||
|
||||
RK_S32 r_mask_msb;
|
||||
RK_S32 g_mask_msb;
|
||||
RK_S32 b_mask_msb;
|
||||
|
||||
RK_U32 color_conversion_coeff_a;
|
||||
RK_U32 color_conversion_coeff_b;
|
||||
RK_U32 color_conversion_coeff_c;
|
||||
RK_U32 color_conversion_coeff_e;
|
||||
RK_U32 color_conversion_coeff_f;
|
||||
} HalH264eVepuPrep;
|
||||
|
||||
typedef struct HalH264eVepuFrmAddr_t {
|
||||
// original frame Y/Cb/Cr/RGB address
|
||||
RK_U32 orig[3];
|
||||
// reconstruction frame
|
||||
RK_U32 recn[2];
|
||||
RK_U32 refr[2];
|
||||
} HalH264eVepuAddr;
|
||||
|
||||
/*
|
||||
* Vepu buffer allocater
|
||||
* There are three internal buffer for Vepu encoder:
|
||||
* 1. cabac table input buffer
|
||||
* 2. nal size table output buffer
|
||||
* 3. recon / refer frame buffer
|
||||
*/
|
||||
typedef struct HalH264eVepuBufs_t {
|
||||
MppBufferGroup group;
|
||||
|
||||
/* cabac table buffer */
|
||||
RK_S32 cabac_init_idc;
|
||||
MppBuffer cabac_table;
|
||||
|
||||
/*
|
||||
* nal size table buffer
|
||||
* table size must be 64-bit multiple, space for zero at the end of table
|
||||
* Atleast 1 macroblock row in every slice
|
||||
*/
|
||||
RK_S32 mb_h;
|
||||
RK_S32 nal_tab_size;
|
||||
MppBuffer nal_size_table;
|
||||
|
||||
/*
|
||||
* recon / refer frame buffer
|
||||
* sync with encoder using slot index
|
||||
*/
|
||||
size_t frm_size;
|
||||
size_t yuv_size;
|
||||
RK_S32 frm_cnt;
|
||||
MppBuffer frm_buf[H264E_MAX_REFS_CNT + 1];
|
||||
} HalH264eVepuBufs;
|
||||
|
||||
typedef struct HalH264eVepuMbRc_t {
|
||||
/* VEPU MB rate control parameter for config to hardware */
|
||||
RK_S32 qp_init;
|
||||
RK_S32 qp_min;
|
||||
RK_S32 qp_max;
|
||||
|
||||
/*
|
||||
* VEPU MB can have max 10 check points (cp).
|
||||
*
|
||||
* On each check point hardware will check the target bit and
|
||||
* error bits and change qp according to delta qp step
|
||||
*
|
||||
* cp_distance_mbs check point distance in mbs (0 = disabled)
|
||||
* cp_target bitrate target at each check point
|
||||
* cp_error error bit level step for each delta qp
|
||||
* cp_delta_qp delta qp applied on when on bit rate error amount
|
||||
*/
|
||||
RK_S32 cp_distance_mbs;
|
||||
RK_S32 cp_target[VEPU_CHECK_POINTS_MAX];
|
||||
RK_S32 cp_error[VEPU_CTRL_LEVELS];
|
||||
RK_S32 cp_delta_qp[VEPU_CTRL_LEVELS];
|
||||
|
||||
/*
|
||||
* MAD based QP adjustment
|
||||
* mad_qp_change [-8..7]
|
||||
* mad_threshold MAD threshold div256
|
||||
*/
|
||||
RK_S32 mad_qp_change;
|
||||
RK_S32 mad_threshold;
|
||||
|
||||
/* slice split by mb row (0 = one slice) */
|
||||
RK_S32 slice_size_mb_rows;
|
||||
|
||||
/* favor and penalty for mode decision */
|
||||
|
||||
/*
|
||||
* VEPU MB rate control parameter which is read from hardware
|
||||
* out_strm_size output stream size (bits)
|
||||
* qp_sum QP Sum div2 output
|
||||
* rlc_count RLC codeword count div4 output max 255*255*384/4
|
||||
*/
|
||||
RK_U32 out_strm_size;
|
||||
RK_S32 qp_sum;
|
||||
RK_S32 rlc_count;
|
||||
|
||||
RK_S32 cp_usage[VEPU_CHECK_POINTS_MAX];
|
||||
/* Macroblock count with MAD value under threshold output */
|
||||
RK_S32 less_mad_count;
|
||||
/* MB count output */
|
||||
RK_S32 mb_count;
|
||||
|
||||
/* hardware encoding status 0 - corret 1 - error */
|
||||
RK_U32 hw_status;
|
||||
} HalH264eVepuMbRc;
|
||||
|
||||
typedef void *HalH264eVepuMbRcCtx;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* buffer management function */
|
||||
MPP_RET h264e_vepu_buf_init(HalH264eVepuBufs *bufs);
|
||||
MPP_RET h264e_vepu_buf_deinit(HalH264eVepuBufs *bufs);
|
||||
|
||||
MPP_RET h264e_vepu_buf_set_cabac_idc(HalH264eVepuBufs *bufs, RK_S32 idc);
|
||||
MPP_RET h264e_vepu_buf_set_frame_size(HalH264eVepuBufs *bufs, RK_S32 w, RK_S32 h);
|
||||
|
||||
MppBuffer h264e_vepu_buf_get_nal_size_table(HalH264eVepuBufs *bufs);
|
||||
MppBuffer h264e_vepu_buf_get_frame_buffer(HalH264eVepuBufs *bufs, RK_S32 index);
|
||||
|
||||
/* preprocess setup function */
|
||||
MPP_RET h264e_vepu_prep_setup(HalH264eVepuPrep *prep, MppEncPrepCfg *cfg);
|
||||
MPP_RET h264e_vepu_prep_get_addr(HalH264eVepuPrep *prep, MppBuffer buffer,
|
||||
RK_U32 (*addr)[3]);
|
||||
|
||||
/* macroblock bitrate control function */
|
||||
MPP_RET h264e_vepu_mbrc_init(HalH264eVepuMbRcCtx *ctx, HalH264eVepuMbRc *mbrc);
|
||||
MPP_RET h264e_vepu_mbrc_deinit(HalH264eVepuMbRcCtx ctx);
|
||||
|
||||
MPP_RET h264e_vepu_mbrc_setup(HalH264eVepuMbRcCtx ctx, MppEncCfgSet *cfg);
|
||||
/*
|
||||
* generate hardware MB rc config by:
|
||||
* 1 - HalH264eVepuMbRcCtx ctx
|
||||
* The previous frame encoding status
|
||||
* 2 - RcSyntax
|
||||
* Provide current frame target bitrate related info
|
||||
* 3 - EncFrmStatus
|
||||
* Provide dpb related info like I / P frame, temporal id, refer distance
|
||||
*
|
||||
* Then output the HalH264eVepuMbRc for register generation
|
||||
*/
|
||||
MPP_RET h264e_vepu_mbrc_prepare(HalH264eVepuMbRcCtx ctx, RcSyntax *rc,
|
||||
EncFrmStatus *info, HalH264eVepuMbRc *mbrc);
|
||||
MPP_RET h264e_vepu_mbrc_update(HalH264eVepuMbRcCtx ctx, HalH264eVepuMbRc *mbrc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
36
mpp/hal/vpu/h264e/hal_h264e_vpu_tbl_v2.h
Normal file
36
mpp/hal/vpu/h264e/hal_h264e_vpu_tbl_v2.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_H264E_VPU_TBL_H__
|
||||
#define __HAL_H264E_VPU_TBL_H__
|
||||
|
||||
#include "rk_type.h"
|
||||
|
||||
#define H264E_CABAC_TABLE_BUF_SIZE (52*2*464)
|
||||
|
||||
/* H.264 motion estimation parameters */
|
||||
extern const RK_U32 h264_prev_mode_favor[52];
|
||||
/* sqrt(2^((qp-12)/3))*8 */
|
||||
extern const RK_U32 h264_diff_mv_penalty[52];
|
||||
/* 31*sqrt(2^((qp-12)/3))/4 */
|
||||
extern const RK_U32 h264_diff_mv_penalty4p[52];
|
||||
extern const RK_U32 h264_intra16_favor[52];
|
||||
extern const RK_U32 h264_inter_favor[52];
|
||||
extern const RK_U32 h264_skip_sad_penalty[52];
|
||||
extern const RK_S32 h264_context_init_intra[460][2];
|
||||
extern const RK_S32 h264_context_init[3][460][2];
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user