mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-11-02 05:24:15 +08:00
[jpegd]: Add RKV jpegd implementation
Change-Id: I10497fea20a0a4bbd5bd32a4d3a3e398f6e1aa95 Signed-off-by: Johnson Ding <johnson.ding@rock-chips.com>
This commit is contained in:
committed by
Herman Chen
parent
533ccf5546
commit
149bb3d090
@@ -53,6 +53,7 @@
|
||||
#define JPEGD_DBG_PARSER_INFO (0x00000020) /* parser information */
|
||||
#define JPEGD_DBG_SYNTAX_ERR (0x00000040) /* syntax error */
|
||||
#define JPEGD_DBG_HAL_INFO (0x00000080) /* hal information */
|
||||
#define JPEGD_DBG_HAL_TBL (0x00000100) /* hal information */
|
||||
|
||||
extern RK_U32 jpegd_debug;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ set(HAL_JPEGD_SRC
|
||||
hal_jpegd_common.c
|
||||
hal_jpegd_vdpu2.c
|
||||
hal_jpegd_vdpu1.c
|
||||
hal_jpegd_rkv.c
|
||||
)
|
||||
|
||||
add_library(hal_jpegd STATIC
|
||||
|
||||
@@ -49,14 +49,12 @@ typedef struct JpegdHalCtx {
|
||||
RK_U32 hal_debug_enable;
|
||||
RK_U32 frame_count;
|
||||
RK_U32 output_yuv_count;
|
||||
RK_U8 scale;
|
||||
|
||||
RK_S32 pkt_fd; /* input stream's physical address(fd) */
|
||||
RK_S32 frame_fd; /* output picture's physical address(fd) */
|
||||
|
||||
PPInfo pp_info;
|
||||
|
||||
FILE *fp_reg_in;
|
||||
FILE *fp_reg_out;
|
||||
} JpegdHalCtx;
|
||||
|
||||
#endif /* __HAL_JPEGD_COMMON_H__ */
|
||||
|
||||
777
mpp/hal/vpu/jpegd/hal_jpegd_rkv.c
Normal file
777
mpp/hal/vpu/jpegd/hal_jpegd_rkv.c
Normal file
@@ -0,0 +1,777 @@
|
||||
/*
|
||||
* Copyright 2020 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_jpegd_rkv"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpp_env.h"
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_frame.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
#include "jpegd_syntax.h"
|
||||
#include "hal_jpegd_common.h"
|
||||
#include "hal_jpegd_rkv.h"
|
||||
#include "hal_jpegd_rkv_reg.h"
|
||||
|
||||
// Support 8-bit precision only
|
||||
#define NB_COMPONENTS (3)
|
||||
#define RKD_QUANTIZATION_TBL_SIZE (8*8*2*NB_COMPONENTS)
|
||||
#define RKD_HUFFMAN_MINCODE_TBL_SIZE (16*3*2*NB_COMPONENTS)
|
||||
#define RKD_HUFFMAN_VALUE_TBL_SIZE (16*12*NB_COMPONENTS)
|
||||
#define RKD_HUFFMAN_MINCODE_TBL_OFFSET (RKD_QUANTIZATION_TBL_SIZE)
|
||||
#define RKD_HUFFMAN_VALUE_TBL_OFFSET (RKD_HUFFMAN_MINCODE_TBL_OFFSET + MPP_ALIGN(RKD_HUFFMAN_MINCODE_TBL_SIZE, 64))
|
||||
#define RKD_TABLE_SIZE (RKD_HUFFMAN_VALUE_TBL_OFFSET + RKD_HUFFMAN_VALUE_TBL_SIZE)
|
||||
|
||||
MPP_RET jpegd_write_rkv_qtbl(JpegdHalCtx *ctx, JpegdSyntax *syntax)
|
||||
{
|
||||
jpegd_dbg_func("enter\n");
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdSyntax *s = syntax;
|
||||
RK_U16 *base = (RK_U16 *)mpp_buffer_get_ptr(ctx->pTableBase);
|
||||
RK_U16 table_tmp[QUANTIZE_TABLE_LENGTH] = {0};
|
||||
RK_U32 i, j , idx;
|
||||
|
||||
for (j = 0; j < s->nb_components; j++) {
|
||||
idx = s->quant_index[j];
|
||||
|
||||
//turn zig-zag order to raster-scan order
|
||||
for (i = 0; i < QUANTIZE_TABLE_LENGTH; i++) {
|
||||
table_tmp[zzOrder[i]] = s->quant_matrixes[idx][i];
|
||||
}
|
||||
|
||||
memcpy(base + j * QUANTIZE_TABLE_LENGTH, table_tmp, sizeof(RK_U16) * QUANTIZE_TABLE_LENGTH);
|
||||
}
|
||||
|
||||
if (jpegd_debug & JPEGD_DBG_HAL_TBL) {
|
||||
RK_U8 *data = (RK_U8 *)mpp_buffer_get_ptr(ctx->pTableBase);
|
||||
|
||||
mpp_log("--------------Quant tbl----------------------\n");
|
||||
for (i = 0; i < RKD_QUANTIZATION_TBL_SIZE; i += 8) {
|
||||
mpp_log("%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
data[i + 7], data[i + 6], data[i + 5], data[i + 4],
|
||||
data[i + 3], data[i + 2], data[i + 1], data[i + 0]);
|
||||
}
|
||||
}
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
MPP_RET jpegd_write_rkv_htbl(JpegdHalCtx *ctx, JpegdSyntax *jpegd_syntax)
|
||||
{
|
||||
jpegd_dbg_func("enter\n");
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
JpegdSyntax *s = jpegd_syntax;
|
||||
AcTable *ac_ptr0 = NULL, *ac_ptr1 = NULL;
|
||||
DcTable *dc_ptr0 = NULL, *dc_ptr1 = NULL;
|
||||
void * htbl_ptr[6] = {NULL};
|
||||
RK_U32 i, j, k = 0;
|
||||
RK_U8 *p_htbl_value = (RK_U8 *)mpp_buffer_get_ptr(ctx->pTableBase) + RKD_HUFFMAN_VALUE_TBL_OFFSET;
|
||||
RK_U16 *p_htbl_mincode = (RK_U16 *)mpp_buffer_get_ptr(ctx->pTableBase) + RKD_HUFFMAN_MINCODE_TBL_OFFSET / 2;
|
||||
RK_U16 min_code_ac[16] = {0};
|
||||
RK_U16 min_code_dc[16] = {0};
|
||||
RK_U16 acc_addr_ac[16] = {0};
|
||||
RK_U16 acc_addr_dc[16] = {0};
|
||||
RK_U8 htbl_value[192] = {0};
|
||||
RK_U16 code = 0;
|
||||
RK_S32 addr = 0;
|
||||
RK_U32 len = 0;
|
||||
AcTable *ac_ptr;
|
||||
DcTable *dc_ptr;
|
||||
|
||||
if (s->ac_index[0] == HUFFMAN_TABLE_ID_ZERO) {
|
||||
/* Luma's AC uses Huffman table zero */
|
||||
ac_ptr0 = &(s->ac_table[HUFFMAN_TABLE_ID_ZERO]);
|
||||
ac_ptr1 = &(s->ac_table[HUFFMAN_TABLE_ID_ONE]);
|
||||
} else {
|
||||
ac_ptr0 = &(s->ac_table[HUFFMAN_TABLE_ID_ONE]);
|
||||
ac_ptr1 = &(s->ac_table[HUFFMAN_TABLE_ID_ZERO]);
|
||||
}
|
||||
|
||||
if (s->dc_index[0] == HUFFMAN_TABLE_ID_ZERO) {
|
||||
/* Luma's DC uses Huffman table zero */
|
||||
dc_ptr0 = &(s->dc_table[HUFFMAN_TABLE_ID_ZERO]);
|
||||
dc_ptr1 = &(s->dc_table[HUFFMAN_TABLE_ID_ONE]);
|
||||
} else {
|
||||
dc_ptr0 = &(s->dc_table[HUFFMAN_TABLE_ID_ONE]);
|
||||
dc_ptr1 = &(s->dc_table[HUFFMAN_TABLE_ID_ZERO]);
|
||||
}
|
||||
|
||||
htbl_ptr[0] = dc_ptr0;
|
||||
htbl_ptr[1] = ac_ptr0;
|
||||
htbl_ptr[2] = dc_ptr1;
|
||||
htbl_ptr[3] = ac_ptr1;
|
||||
htbl_ptr[4] = dc_ptr1;
|
||||
htbl_ptr[5] = ac_ptr1;
|
||||
|
||||
for (k = 0; k < s->nb_components; k++) {
|
||||
dc_ptr = (DcTable *)htbl_ptr[k * 2];
|
||||
ac_ptr = (AcTable *)htbl_ptr[k * 2 + 1];
|
||||
|
||||
len = dc_ptr->bits[0];
|
||||
code = addr = 0;
|
||||
min_code_dc[0] = 0;
|
||||
acc_addr_dc[0] = 0;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
len = dc_ptr->bits[j];
|
||||
|
||||
if (len == 0 && j > 0) {
|
||||
if (code > (min_code_dc[j - 1] << 1))
|
||||
min_code_dc[j] = code;
|
||||
else
|
||||
min_code_dc[j] = min_code_dc[j - 1] << 1;
|
||||
} else {
|
||||
min_code_dc[j] = code;
|
||||
}
|
||||
|
||||
code += len;
|
||||
addr += len;
|
||||
acc_addr_dc[j] = addr;
|
||||
code <<= 1;
|
||||
|
||||
}
|
||||
|
||||
if (dc_ptr->bits[15])
|
||||
min_code_dc[0] = min_code_dc[15] + dc_ptr->bits[15] - 1;
|
||||
else
|
||||
min_code_dc[0] = min_code_dc[15];
|
||||
|
||||
len = ac_ptr->bits[0];
|
||||
code = addr = 0;
|
||||
min_code_ac[0] = 0;
|
||||
acc_addr_ac[0] = 0;
|
||||
for (j = 0; j < 16; j++) {
|
||||
len = ac_ptr->bits[j];
|
||||
|
||||
if (len == 0 && j > 0) {
|
||||
if (code > (min_code_ac[j - 1] << 1))
|
||||
min_code_ac[j] = code;
|
||||
else
|
||||
min_code_ac[j] = min_code_ac[j - 1] << 1;
|
||||
} else {
|
||||
min_code_ac[j] = code;
|
||||
}
|
||||
|
||||
code += len;
|
||||
addr += len;
|
||||
acc_addr_ac[j] = addr;
|
||||
code <<= 1;
|
||||
}
|
||||
|
||||
if (ac_ptr->bits[15])
|
||||
min_code_ac[0] = min_code_ac[15] + ac_ptr->bits[15] - 1;
|
||||
else
|
||||
min_code_ac[0] = min_code_ac[15];
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
*p_htbl_mincode++ = min_code_dc[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
*p_htbl_mincode++ = acc_addr_dc[2 * i] | acc_addr_dc[2 * i + 1] << 8;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
*p_htbl_mincode++ = min_code_ac[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
*p_htbl_mincode++ = acc_addr_ac[2 * i] | acc_addr_ac[2 * i + 1] << 8;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_DC_HUFFMAN_TABLE_LENGTH; i++) {
|
||||
htbl_value[i] = dc_ptr->vals[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_AC_HUFFMAN_TABLE_LENGTH; i++) {
|
||||
htbl_value[i + 16] = ac_ptr->vals[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < 12 * 16; i++) {
|
||||
*p_htbl_value++ = htbl_value[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (jpegd_debug & JPEGD_DBG_HAL_TBL) {
|
||||
RK_U8 *data = (RK_U8 *)mpp_buffer_get_ptr(ctx->pTableBase) + RKD_HUFFMAN_VALUE_TBL_OFFSET;
|
||||
|
||||
mpp_log("--------------huffman value tbl----------------------\n");
|
||||
for (i = 0; i < RKD_HUFFMAN_VALUE_TBL_SIZE; i += 8) {
|
||||
mpp_log("%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
data[i + 7], data[i + 6], data[i + 5], data[i + 4],
|
||||
data[i + 3], data[i + 2], data[i + 1], data[i + 0]);
|
||||
}
|
||||
|
||||
data = NULL;
|
||||
data = (RK_U8 *)mpp_buffer_get_ptr(ctx->pTableBase) + RKD_HUFFMAN_MINCODE_TBL_OFFSET;
|
||||
|
||||
mpp_log("--------------huffman mincode tbl----------------------\n");
|
||||
for (i = 0; i < RKD_HUFFMAN_MINCODE_TBL_SIZE; i += 8) {
|
||||
mpp_log("%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
data[i + 7], data[i + 6], data[i + 5], data[i + 4],
|
||||
data[i + 3], data[i + 2], data[i + 1], data[i + 0]);
|
||||
}
|
||||
}
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET hal_jpegd_rkv_init(void *hal, MppHalCfg *cfg)
|
||||
{
|
||||
jpegd_dbg_func("enter\n");
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdHalCtx *ctx = (JpegdHalCtx *)hal;
|
||||
if (NULL == ctx) {
|
||||
ctx = (JpegdHalCtx *)mpp_calloc(JpegdHalCtx, 1);
|
||||
if (NULL == ctx) {
|
||||
mpp_err_f("NULL pointer");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->packet_slots = cfg->packet_slots;
|
||||
ctx->frame_slots = cfg->frame_slots;
|
||||
|
||||
ret = mpp_dev_init(&ctx->dev, VPU_CLIENT_JPEG_DEC);
|
||||
if (ret) {
|
||||
mpp_err("mpp_device_init failed. ret: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* allocate regs buffer */
|
||||
if (ctx->regs == NULL) {
|
||||
ctx->regs = mpp_calloc_size(void, sizeof(JpegRegSet));
|
||||
if (ctx->regs == NULL) {
|
||||
mpp_err("hal jpegd reg alloc failed\n");
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return MPP_ERR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->group == NULL) {
|
||||
ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_ION);
|
||||
if (ret) {
|
||||
mpp_err_f("mpp_buffer_group_get failed ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = mpp_buffer_get(ctx->group, &ctx->frame_buf,
|
||||
JPEGD_STREAM_BUFF_SIZE);
|
||||
if (ret) {
|
||||
mpp_err_f("Get frame buffer failed ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mpp_buffer_get(ctx->group, &ctx->pTableBase, RKD_TABLE_SIZE);
|
||||
if (ret) {
|
||||
mpp_err_f("Get table buffer failed, ret %d\n", ret);
|
||||
}
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MPP_RET setup_output_fmt(JpegdHalCtx *ctx, JpegdSyntax *syntax, RK_S32 out_idx)
|
||||
{
|
||||
|
||||
jpegd_dbg_func("enter\n");
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdSyntax *s = syntax;
|
||||
JpegRegSet *regs = (JpegRegSet *)ctx->regs;
|
||||
MppFrame frm = NULL;
|
||||
|
||||
mpp_buf_slot_get_prop(ctx->frame_slots, out_idx, SLOT_FRAME_PTR, &frm);
|
||||
|
||||
if (ctx->scale) {
|
||||
if (ctx->scale == 2)
|
||||
regs->reg2_sys.scaledown_mode = SCALEDOWN_HALF;
|
||||
if (ctx->scale == 4)
|
||||
regs->reg2_sys.scaledown_mode = SCALEDOWN_QUARTER;
|
||||
if (ctx->scale == 8)
|
||||
regs->reg2_sys.scaledown_mode = SCALEDOWN_ONE_EIGHTS;
|
||||
} else {
|
||||
regs->reg2_sys.scaledown_mode = SCALEDOWN_DISABLE;
|
||||
}
|
||||
|
||||
if (ctx->set_output_fmt_flag && (ctx->output_fmt != s->output_fmt)) { // PP enable
|
||||
if (MPP_FRAME_FMT_IS_YUV(ctx->output_fmt) && s->output_fmt != MPP_FMT_YUV400) {
|
||||
if (ctx->output_fmt == MPP_FMT_YUV420SP)
|
||||
regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_NV12;
|
||||
else if (ctx->output_fmt == MPP_FMT_YUV422_YUYV)
|
||||
/* Only support yuv422 and yuv444.
|
||||
* Other format transformation won't report hardware irq error,
|
||||
* and won't get a correct YUV image.
|
||||
*/
|
||||
regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_YUYV;
|
||||
else if (ctx->output_fmt == MPP_FMT_YUV422_YVYU) {
|
||||
regs->reg2_sys.out_cbcr_swap = 1;
|
||||
regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_YUYV;
|
||||
}
|
||||
} else if (MPP_FRAME_FMT_IS_RGB(ctx->output_fmt)) {
|
||||
if (ctx->output_fmt == MPP_FMT_RGB888) {
|
||||
regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_RGB888;
|
||||
} else if (ctx->output_fmt == MPP_FMT_BGR565) { //bgr565le
|
||||
regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_RGB565;
|
||||
} else {
|
||||
mpp_err_f("unsupported output format %d\n", ctx->output_fmt);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
MppFrameColorRange color_range = MPP_FRAME_RANGE_UNSPECIFIED;
|
||||
color_range = mpp_frame_get_color_range(frm);
|
||||
if (color_range != MPP_FRAME_RANGE_MPEG)
|
||||
regs->reg2_sys.yuv2rgb_range = YUV_TO_RGB_FULL_RANGE;
|
||||
else
|
||||
regs->reg2_sys.yuv2rgb_range = YUV_TO_RGB_LIMIT_RANGE;
|
||||
}
|
||||
} else { //keep original format
|
||||
regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_NO_TRANS;
|
||||
}
|
||||
|
||||
jpegd_dbg_hal("convert format %d to format %d\n", s->output_fmt, ctx->output_fmt);
|
||||
|
||||
regs->reg2_sys.fill_down_e = s->fill_bottom;
|
||||
regs->reg2_sys.fill_right_e = s->fill_right;
|
||||
|
||||
mpp_frame_set_fmt(frm, ctx->output_fmt);
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MPP_RET jpegd_gen_regs(JpegdHalCtx *ctx, JpegdSyntax *syntax)
|
||||
{
|
||||
jpegd_dbg_func("enter\n");
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdSyntax *s = syntax;
|
||||
JpegRegSet *regs = (JpegRegSet *)ctx->regs;
|
||||
|
||||
regs->reg1_int.dec_e = 1;
|
||||
regs->reg1_int.dec_timeout_e = 1;
|
||||
regs->reg1_int.buf_empty_e = 1;
|
||||
|
||||
regs->reg3_pic_size.pic_width_m1 = s->width - 1;
|
||||
regs->reg3_pic_size.pic_height_m1 = s->height - 1;
|
||||
|
||||
//TODO: Get these value from parser
|
||||
/*
|
||||
* a. only support 8 bit precision currently
|
||||
* b. quantization/huffman table should be parsed from parser when decoding
|
||||
* markes, syntax->qtable_cnt is not correct match qtable_sel
|
||||
*/
|
||||
regs->reg4_pic_fmt.pixel_depth = BIT_DEPTH_8;
|
||||
if (s->nb_components == 1) {
|
||||
regs->reg4_pic_fmt.htables_sel = TBL_ENTRY_1;
|
||||
regs->reg4_pic_fmt.qtables_sel = TBL_ENTRY_1;
|
||||
} else {
|
||||
regs->reg4_pic_fmt.htables_sel = TBL_ENTRY_2;
|
||||
regs->reg4_pic_fmt.qtables_sel = TBL_ENTRY_2;
|
||||
}
|
||||
|
||||
if (s->restart_interval) {
|
||||
regs->reg4_pic_fmt.dri_e = RST_ENABLE;
|
||||
regs->reg4_pic_fmt.dri_mcu_num_m1 = s->restart_interval - 1;
|
||||
}
|
||||
|
||||
//TODO: map format together with vdpu1 and vdpu2 at parser layer
|
||||
switch (s->yuv_mode) {
|
||||
case JPEGDEC_YUV400:
|
||||
case JPEGDEC_YUV420:
|
||||
case JPEGDEC_YUV422:
|
||||
regs->reg4_pic_fmt.jpeg_mode = s->yuv_mode;
|
||||
break;
|
||||
case JPEGDEC_YUV411:
|
||||
regs->reg4_pic_fmt.jpeg_mode = YUV_MODE_411;
|
||||
break;
|
||||
case JPEGDEC_YUV440:
|
||||
regs->reg4_pic_fmt.jpeg_mode = YUV_MODE_440;
|
||||
break;
|
||||
case JPEGDEC_YUV444:
|
||||
regs->reg4_pic_fmt.jpeg_mode = YUV_MODE_444;
|
||||
break;
|
||||
default:
|
||||
mpp_err_f("unsupported yuv mode %d\n", s->yuv_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
RK_U32 out_width = MPP_ALIGN(s->width, 16);
|
||||
RK_U32 out_height = s->height;
|
||||
out_width = out_width >> regs->reg2_sys.scaledown_mode;
|
||||
out_width = MPP_ALIGN(out_width, 16);
|
||||
out_height = regs->reg2_sys.fill_down_e ? MPP_ALIGN(out_height, 16) : MPP_ALIGN(out_height, 8);
|
||||
out_height = out_height >> regs->reg2_sys.scaledown_mode;
|
||||
jpegd_dbg_hal("output scale %d, width %d, height %d\n", regs->reg2_sys.scaledown_mode, out_width, out_height);
|
||||
|
||||
RK_U32 y_hor_stride = out_width >> 4;
|
||||
RK_U32 y_virstride = 0;
|
||||
RK_U32 uv_hor_virstride = 0;
|
||||
|
||||
switch (regs->reg2_sys.yuv_out_format) {
|
||||
case YUV_OUT_FMT_2_RGB888:
|
||||
y_hor_stride *= 3;
|
||||
break;
|
||||
case YUV_OUT_FMT_2_RGB565:
|
||||
case YUV_OUT_FMT_2_YUYV:
|
||||
y_hor_stride *= 2;
|
||||
break;
|
||||
case YUV_OUT_FMT_NO_TRANS:
|
||||
switch (regs->reg4_pic_fmt.jpeg_mode) {
|
||||
case YUV_MODE_440:
|
||||
case YUV_MODE_444:
|
||||
uv_hor_virstride = y_hor_stride * 2;
|
||||
break;
|
||||
case YUV_MODE_411:
|
||||
uv_hor_virstride = y_hor_stride >> 1;
|
||||
break;
|
||||
case YUV_MODE_400:
|
||||
uv_hor_virstride = 0;
|
||||
break;
|
||||
default:
|
||||
uv_hor_virstride = y_hor_stride;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case YUV_OUT_FMT_2_NV12:
|
||||
uv_hor_virstride = y_hor_stride;
|
||||
break;
|
||||
}
|
||||
|
||||
y_virstride = y_hor_stride * out_height;
|
||||
if (regs->reg2_sys.dec_out_sequence == OUTPUT_TILE) {
|
||||
y_hor_stride <<= 3;
|
||||
uv_hor_virstride <<= 3;
|
||||
}
|
||||
|
||||
regs->reg5_hor_virstride.y_hor_virstride = y_hor_stride & 0xffff;
|
||||
regs->reg5_hor_virstride.uv_hor_virstride = uv_hor_virstride & 0xffff;
|
||||
regs->reg6_y_virstride.y_virstride = y_virstride;
|
||||
|
||||
regs->reg7_tbl_len.y_hor_virstride_h = (y_hor_stride >> 16) & 1;
|
||||
|
||||
if (s->qtable_cnt)
|
||||
regs->reg7_tbl_len.qtbl_len = regs->reg4_pic_fmt.qtables_sel * 8 - 1;
|
||||
else
|
||||
regs->reg7_tbl_len.qtbl_len = 0;
|
||||
|
||||
// 8 bit precision 12, 12 bit precision 16;
|
||||
regs->reg7_tbl_len.htbl_value_len = regs->reg4_pic_fmt.htables_sel * (regs->reg4_pic_fmt.pixel_depth ? 16 : 12) - 1;
|
||||
|
||||
switch (regs->reg4_pic_fmt.htables_sel) {
|
||||
case TBL_ENTRY_0 :
|
||||
regs->reg7_tbl_len.htbl_mincode_len = 0;
|
||||
regs->reg7_tbl_len.htbl_value_len = 0;
|
||||
break;
|
||||
case TBL_ENTRY_2 :
|
||||
regs->reg7_tbl_len.htbl_mincode_len = (s->nb_components - 1) * 6 - 1;
|
||||
break;
|
||||
case TBL_ENTRY_1 :
|
||||
case TBL_ENTRY_3 :
|
||||
regs->reg7_tbl_len.htbl_mincode_len = s->nb_components * 6 - 1;
|
||||
break;
|
||||
default :
|
||||
mpp_err_f("unsupported htable_sel %d\n", regs->reg4_pic_fmt.htables_sel);
|
||||
break;
|
||||
}
|
||||
|
||||
RK_U32 strm_offset = 0;
|
||||
RK_U32 hw_strm_offset = 0;
|
||||
RK_U8 start_byte = 0;
|
||||
RK_U32 table_fd = mpp_buffer_get_fd(ctx->pTableBase);
|
||||
|
||||
strm_offset = s->strm_offset;
|
||||
hw_strm_offset = strm_offset - strm_offset % 16;
|
||||
start_byte = strm_offset % 16;
|
||||
|
||||
regs->reg8_strm_len.stream_len = (MPP_ALIGN((s->pkt_len - hw_strm_offset), 16) - 1) >> 4;
|
||||
regs->reg8_strm_len.strm_start_byte = start_byte;
|
||||
|
||||
regs->reg9_qtbl_base = table_fd;
|
||||
regs->reg10_htbl_mincode_base = table_fd;
|
||||
regs->reg11_htbl_value_base = table_fd;
|
||||
regs->reg13_dec_out_base = ctx->frame_fd;
|
||||
regs->reg12_strm_base = ctx->pkt_fd;
|
||||
|
||||
MppDevRegOffsetCfg trans_cfg_10;
|
||||
MppDevRegOffsetCfg trans_cfg_11;
|
||||
MppDevRegOffsetCfg trans_cfg_12;
|
||||
|
||||
trans_cfg_12.reg_idx = 12;
|
||||
trans_cfg_12.offset = hw_strm_offset;
|
||||
mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFSET, &trans_cfg_12);
|
||||
|
||||
trans_cfg_10.reg_idx = 10;
|
||||
trans_cfg_10.offset = RKD_HUFFMAN_MINCODE_TBL_OFFSET;
|
||||
mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFSET, &trans_cfg_10);
|
||||
|
||||
trans_cfg_11.reg_idx = 11;
|
||||
trans_cfg_11.offset = RKD_HUFFMAN_VALUE_TBL_OFFSET;
|
||||
mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFSET, &trans_cfg_11);
|
||||
|
||||
regs->reg14_strm_error.error_prc_mode = 1;
|
||||
regs->reg14_strm_error.strm_ffff_err_mode = 2;
|
||||
regs->reg14_strm_error.strm_other_mark_mode = 2;
|
||||
regs->reg14_strm_error.strm_dri_seq_err_mode = 0;
|
||||
|
||||
regs->reg16_clk_gate.val = 0xff;
|
||||
|
||||
regs->reg30_perf_latency_ctrl0.axi_per_work_e = 1;
|
||||
regs->reg30_perf_latency_ctrl0.axi_per_clr_e = 1;
|
||||
regs->reg30_perf_latency_ctrl0.axi_cnt_type = 1;
|
||||
regs->reg30_perf_latency_ctrl0.rd_latency_id = 0xa;
|
||||
|
||||
jpegd_write_rkv_htbl(ctx, s);
|
||||
|
||||
jpegd_write_rkv_qtbl(ctx, s);
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET hal_jpegd_rkv_deinit(void *hal)
|
||||
{
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdHalCtx *ctx = (JpegdHalCtx *)hal;
|
||||
|
||||
jpegd_dbg_func("enter\n");
|
||||
|
||||
if (ctx->dev) {
|
||||
mpp_dev_deinit(ctx->dev);
|
||||
ctx->dev = NULL;
|
||||
}
|
||||
|
||||
if (ctx->frame_buf) {
|
||||
ret = mpp_buffer_put(ctx->frame_buf);
|
||||
if (ret) {
|
||||
mpp_err_f("put buffer failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->pTableBase) {
|
||||
ret = mpp_buffer_put(ctx->pTableBase);
|
||||
if (ret) {
|
||||
mpp_err_f("put buffer failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->group) {
|
||||
ret = mpp_buffer_group_put(ctx->group);
|
||||
if (ret) {
|
||||
mpp_err_f("group free buffer failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->regs) {
|
||||
mpp_free(ctx->regs);
|
||||
ctx->regs = NULL;
|
||||
}
|
||||
|
||||
ctx->output_fmt = MPP_FMT_YUV420SP;
|
||||
ctx->set_output_fmt_flag = 0;
|
||||
ctx->hal_debug_enable = 0;
|
||||
ctx->frame_count = 0;
|
||||
ctx->output_yuv_count = 0;
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET hal_jpegd_rkv_gen_regs(void *hal, HalTaskInfo *syn)
|
||||
{
|
||||
jpegd_dbg_func("enter\n");
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdHalCtx *ctx = (JpegdHalCtx *)hal;
|
||||
JpegdSyntax *s = (JpegdSyntax *)syn->dec.syntax.data;
|
||||
|
||||
MppBuffer strm_buf = NULL;
|
||||
MppBuffer output_buf = NULL;
|
||||
|
||||
mpp_buf_slot_get_prop(ctx->packet_slots, syn->dec.input, SLOT_BUFFER, & strm_buf);
|
||||
mpp_buf_slot_get_prop(ctx->frame_slots, syn->dec.output, SLOT_BUFFER, &output_buf);
|
||||
|
||||
ctx->pkt_fd = mpp_buffer_get_fd(strm_buf);
|
||||
ctx->frame_fd = mpp_buffer_get_fd(output_buf);
|
||||
|
||||
memset(ctx->regs, 0, sizeof(JpegRegSet));
|
||||
|
||||
setup_output_fmt(ctx, s, syn->dec.output);
|
||||
|
||||
ret = jpegd_gen_regs(ctx, s);
|
||||
|
||||
if (ret != MPP_OK) {
|
||||
mpp_err_f("generate registers failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
syn->dec.valid = 1;
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET hal_jpegd_rkv_start(void *hal, HalTaskInfo *task)
|
||||
{
|
||||
jpegd_dbg_func("enter\n");
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdHalCtx * ctx = (JpegdHalCtx *)hal;
|
||||
RK_U32 *regs = (RK_U32 *)ctx->regs;
|
||||
|
||||
MppDevRegWrCfg wr_cfg;
|
||||
MppDevRegRdCfg rd_cfg;
|
||||
RK_U32 reg_size = JPEGD_REG_NUM * sizeof(RK_U32);
|
||||
RK_U8 i = 0;
|
||||
|
||||
wr_cfg.reg = regs;
|
||||
wr_cfg.size = reg_size;
|
||||
wr_cfg.offset = 0;
|
||||
|
||||
if (jpegd_debug & JPEGD_DBG_HAL_INFO) {
|
||||
for (i = 0; i < JPEGD_REG_NUM; i++) {
|
||||
mpp_log_f("send reg[%d]=0x%08x\n", i, regs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
|
||||
|
||||
if (ret) {
|
||||
mpp_err_f("set register write failed %d\n", ret);
|
||||
goto __RETURN;
|
||||
}
|
||||
|
||||
rd_cfg.reg = regs;
|
||||
rd_cfg.size = reg_size;
|
||||
rd_cfg.offset = 0;
|
||||
|
||||
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
|
||||
|
||||
if (ret) {
|
||||
mpp_err_f("set register read failed %d\n", ret);
|
||||
goto __RETURN;
|
||||
}
|
||||
|
||||
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
|
||||
|
||||
if (ret) {
|
||||
mpp_err_f("send cmd failed %d\n", ret);
|
||||
goto __RETURN;
|
||||
}
|
||||
|
||||
__RETURN:
|
||||
(void)task;
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET hal_jpegd_rkv_wait(void *hal, HalTaskInfo *task)
|
||||
{
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdHalCtx *ctx = (JpegdHalCtx *)hal;
|
||||
JpegRegSet *reg_out = ctx->regs;
|
||||
RK_U32 errinfo = 0;
|
||||
MppFrame tmp = NULL;
|
||||
RK_U8 i = 0;
|
||||
|
||||
jpegd_dbg_func("enter\n");
|
||||
|
||||
ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
|
||||
|
||||
if (ret)
|
||||
mpp_err_f("poll cmd failed %d\n", ret);
|
||||
|
||||
if (jpegd_debug & JPEGD_DBG_HAL_INFO) {
|
||||
for (i = 0; i < JPEGD_REG_NUM; i++) {
|
||||
mpp_log_f("read regs[%d]=0x%08x\n", i, ((RK_U32*)reg_out)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
jpegd_dbg_hal("decode one frame in cycles: %d\n", reg_out->reg39_perf_working_cnt);
|
||||
|
||||
if (!reg_out->reg1_int.dec_irq || !reg_out->reg1_int.dec_rdy_sta
|
||||
|| reg_out->reg1_int.dec_bus_sta || reg_out->reg1_int.dec_error_sta
|
||||
|| reg_out->reg1_int.dec_timeout_sta
|
||||
|| reg_out->reg1_int.dec_buf_empty_sta) {
|
||||
mpp_err("decode result: failed, irq 0x%08x\n", ((RK_U32 *)reg_out)[1]);
|
||||
errinfo = 1;
|
||||
}
|
||||
|
||||
mpp_buf_slot_get_prop(ctx->frame_slots, task->dec.output, SLOT_FRAME_PTR, &tmp);
|
||||
mpp_frame_set_errinfo(tmp, errinfo);
|
||||
|
||||
if (jpegd_debug & JPEGD_DBG_IO) {
|
||||
FILE *jpg_file;
|
||||
char name[32];
|
||||
MppBuffer outputBuf = NULL;
|
||||
void *base = NULL;
|
||||
mpp_buf_slot_get_prop(ctx->frame_slots, task->dec.output, SLOT_BUFFER, &outputBuf);
|
||||
base = mpp_buffer_get_ptr(outputBuf);
|
||||
|
||||
snprintf(name, sizeof(name), "/data/tmp/output%02d.yuv", ctx->output_yuv_count);
|
||||
jpg_file = fopen(name, "wb+");
|
||||
if (jpg_file) {
|
||||
JpegdSyntax *s = (JpegdSyntax *) task->dec.syntax.data;
|
||||
RK_U32 width = s->hor_stride;
|
||||
RK_U32 height = s->ver_stride;
|
||||
|
||||
fwrite(base, width * height * 3, 1, jpg_file);
|
||||
jpegd_dbg_io("frame_%02d output YUV(%d*%d) saving to %s\n", ctx->output_yuv_count,
|
||||
width, height, name);
|
||||
fclose(jpg_file);
|
||||
ctx->output_yuv_count++;
|
||||
}
|
||||
}
|
||||
|
||||
memset(®_out->reg1_int, 0, sizeof(RK_U32));
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET hal_jpegd_rkv_control(void *hal, MpiCmd cmd_type, void *param)
|
||||
{
|
||||
jpegd_dbg_func("enter\n");
|
||||
MPP_RET ret = MPP_OK;
|
||||
JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
|
||||
|
||||
if (NULL == JpegHalCtx) {
|
||||
mpp_err_f("NULL pointer");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
switch (cmd_type) {
|
||||
case MPP_DEC_SET_OUTPUT_FORMAT: {
|
||||
JpegHalCtx->output_fmt = *((MppFrameFormat *)param);
|
||||
JpegHalCtx->set_output_fmt_flag = 1;
|
||||
jpegd_dbg_hal("output_format:%d\n", JpegHalCtx->output_fmt);
|
||||
} break;
|
||||
//TODO support scale and tile output
|
||||
default :
|
||||
ret = MPP_NOK;
|
||||
break;
|
||||
}
|
||||
|
||||
jpegd_dbg_func("exit\n");
|
||||
return ret;
|
||||
}
|
||||
28
mpp/hal/vpu/jpegd/hal_jpegd_rkv.h
Normal file
28
mpp/hal/vpu/jpegd/hal_jpegd_rkv.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2020 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_JPEGD_RKV_H__
|
||||
#define __HAL_JPEGD_RKV_H__
|
||||
|
||||
#include "rk_type.h"
|
||||
|
||||
MPP_RET hal_jpegd_rkv_init(void *hal, MppHalCfg *cfg);
|
||||
MPP_RET hal_jpegd_rkv_deinit(void *hal);
|
||||
MPP_RET hal_jpegd_rkv_gen_regs(void *hal, HalTaskInfo *syn);
|
||||
MPP_RET hal_jpegd_rkv_start(void *hal, HalTaskInfo *task);
|
||||
MPP_RET hal_jpegd_rkv_wait(void *hal, HalTaskInfo *task);
|
||||
MPP_RET hal_jpegd_rkv_control(void *hal, MpiCmd cmd_type, void *param);
|
||||
|
||||
#endif /* __HAL_JPEGD_RKV_H__ */
|
||||
Reference in New Issue
Block a user