update camera source

Signed-off-by: yanghongliang <yang_hongliang@hoperun.com>
This commit is contained in:
yanghongliang
2021-11-08 20:25:39 +08:00
parent 4801a73537
commit 7b37c45074
16 changed files with 3956 additions and 2 deletions
+88
View File
@@ -0,0 +1,88 @@
/*
* 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 __MPI_ENC_UTILS_H__
#define __MPI_ENC_UTILS_H__
#include <stdio.h>
#include "rk_venc_cmd.h"
typedef struct MpiEncTestArgs_t {
MppCodingType type;
MppFrameFormat format;
RK_S32 width;
RK_S32 height;
} MpiEncTestArgs;
typedef struct {
// global flow control flag
RK_U32 frm_eos;
RK_U32 pkt_eos;
RK_S32 frame_count;
RK_U64 stream_size;
// base flow context
MppCtx ctx;
MppApi *mpi;
MppEncCfg cfg;
// input / output
MppBufferGroup buf_grp;
MppBuffer pkt_buf;
MppEncSeiMode sei_mode;
MppEncHeaderMode header_mode;
// paramter for resource malloc
RK_U32 width;
RK_U32 height;
RK_U32 hor_stride;
RK_U32 ver_stride;
MppFrameFormat fmt;
MppCodingType type;
RK_S32 num_frames;
// resources
size_t frame_size;
RK_U32 split_mode;
RK_U32 split_arg;
// rate control runtime parameter
RK_S32 fps_in_flex;
RK_S32 fps_in_den;
RK_S32 fps_in_num;
RK_S32 fps_out_flex;
RK_S32 fps_out_den;
RK_S32 fps_out_num;
RK_S32 bps;
RK_S32 bps_max;
RK_S32 bps_min;
RK_S32 rc_mode;
RK_S32 gop_mode;
RK_S32 gop_len;
RK_S32 vi_len;
} MpiEncTestData;
int hal_mpp_get_sps(void *ctx, unsigned char *buf, size_t *buf_size);
int hal_mpp_encode(void *ctx, int dma_fd, unsigned char *buf, size_t *buf_size);
void *hal_mpp_ctx_create(MpiEncTestArgs *args);
void hal_mpp_ctx_delete(void *ctx);
#endif /*__MPI_ENC_UTILS_H__*/
+886
View File
@@ -0,0 +1,886 @@
/*
* 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 "mpi_enc_utils"
#include <string.h>
#include "mpp_mem.h"
#include "mpp_log.h"
#include "mpp_buffer.h"
#include "rk_mpi.h"
#include "mpp_common.h"
#include "mpi_enc_utils.h"
#if 0
RK_S32 mpi_enc_width_default_stride(RK_S32 width, MppFrameFormat fmt)
{
RK_S32 stride = 0;
switch (fmt & MPP_FRAME_FMT_MASK) {
case MPP_FMT_YUV420SP :
case MPP_FMT_YUV420SP_VU : {
stride = MPP_ALIGN(width, 8);
} break;
case MPP_FMT_YUV420P : {
/* NOTE: 420P need to align to 16 so chroma can align to 8 */
stride = MPP_ALIGN(width, 16);
} break;
case MPP_FMT_YUV422P:
case MPP_FMT_YUV422SP:
case MPP_FMT_YUV422SP_VU: {
/* NOTE: 422 need to align to 8 so chroma can align to 16 */
stride = MPP_ALIGN(width, 8);
} break;
case MPP_FMT_RGB565:
case MPP_FMT_BGR565:
case MPP_FMT_RGB555:
case MPP_FMT_BGR555:
case MPP_FMT_RGB444:
case MPP_FMT_BGR444:
case MPP_FMT_YUV422_YUYV :
case MPP_FMT_YUV422_YVYU :
case MPP_FMT_YUV422_UYVY :
case MPP_FMT_YUV422_VYUY : {
/* NOTE: for vepu limitation */
stride = MPP_ALIGN(width, 8) * 2;
} break;
case MPP_FMT_RGB888 :
case MPP_FMT_BGR888 : {
/* NOTE: for vepu limitation */
stride = MPP_ALIGN(width, 8) * 3;
} break;
case MPP_FMT_RGB101010 :
case MPP_FMT_BGR101010 :
case MPP_FMT_ARGB8888 :
case MPP_FMT_ABGR8888 :
case MPP_FMT_BGRA8888 :
case MPP_FMT_RGBA8888 : {
/* NOTE: for vepu limitation */
stride = MPP_ALIGN(width, 8) * 4;
} break;
default : {
mpp_err_f("do not support type %d\n", fmt);
} break;
}
return stride;
}
#endif
static MPP_RET mpi_enc_gen_ref_cfg(MppEncRefCfg ref, RK_S32 gop_mode)
{
MppEncRefLtFrmCfg lt_ref[4];
MppEncRefStFrmCfg st_ref[16];
RK_S32 lt_cnt = 0;
RK_S32 st_cnt = 0;
MPP_RET ret = 0;
memset(&lt_ref, 0, sizeof(lt_ref));
memset(&st_ref, 0, sizeof(st_ref));
switch (gop_mode) {
case 3 : {
// tsvc4
// /-> P1 /-> P3 /-> P5 /-> P7
// / / / /
// //--------> P2 //--------> P6
// // //
// ///---------------------> P4
// ///
// P0 ------------------------------------------------> P8
lt_cnt = 1;
/* set 8 frame lt-ref gap */
lt_ref[0].lt_idx = 0;
lt_ref[0].temporal_id = 0;
lt_ref[0].ref_mode = REF_TO_PREV_LT_REF;
lt_ref[0].lt_gap = 8;
lt_ref[0].lt_delay = 0;
st_cnt = 9;
/* set tsvc4 st-ref struct */
/* st 0 layer 0 - ref */
st_ref[0].is_non_ref = 0;
st_ref[0].temporal_id = 0;
st_ref[0].ref_mode = REF_TO_TEMPORAL_LAYER;
st_ref[0].ref_arg = 0;
st_ref[0].repeat = 0;
/* st 1 layer 3 - non-ref */
st_ref[1].is_non_ref = 1;
st_ref[1].temporal_id = 3;
st_ref[1].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[1].ref_arg = 0;
st_ref[1].repeat = 0;
/* st 2 layer 2 - ref */
st_ref[2].is_non_ref = 0;
st_ref[2].temporal_id = 2;
st_ref[2].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[2].ref_arg = 0;
st_ref[2].repeat = 0;
/* st 3 layer 3 - non-ref */
st_ref[3].is_non_ref = 1;
st_ref[3].temporal_id = 3;
st_ref[3].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[3].ref_arg = 0;
st_ref[3].repeat = 0;
/* st 4 layer 1 - ref */
st_ref[4].is_non_ref = 0;
st_ref[4].temporal_id = 1;
st_ref[4].ref_mode = REF_TO_PREV_LT_REF;
st_ref[4].ref_arg = 0;
st_ref[4].repeat = 0;
/* st 5 layer 3 - non-ref */
st_ref[5].is_non_ref = 1;
st_ref[5].temporal_id = 3;
st_ref[5].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[5].ref_arg = 0;
st_ref[5].repeat = 0;
/* st 6 layer 2 - ref */
st_ref[6].is_non_ref = 0;
st_ref[6].temporal_id = 2;
st_ref[6].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[6].ref_arg = 0;
st_ref[6].repeat = 0;
/* st 7 layer 3 - non-ref */
st_ref[7].is_non_ref = 1;
st_ref[7].temporal_id = 3;
st_ref[7].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[7].ref_arg = 0;
st_ref[7].repeat = 0;
/* st 8 layer 0 - ref */
st_ref[8].is_non_ref = 0;
st_ref[8].temporal_id = 0;
st_ref[8].ref_mode = REF_TO_TEMPORAL_LAYER;
st_ref[8].ref_arg = 0;
st_ref[8].repeat = 0;
} break;
case 2 : {
// tsvc3
// /-> P1 /-> P3
// / /
// //--------> P2
// //
// P0/---------------------> P4
lt_cnt = 0;
st_cnt = 5;
/* set tsvc4 st-ref struct */
/* st 0 layer 0 - ref */
st_ref[0].is_non_ref = 0;
st_ref[0].temporal_id = 0;
st_ref[0].ref_mode = REF_TO_TEMPORAL_LAYER;
st_ref[0].ref_arg = 0;
st_ref[0].repeat = 0;
/* st 1 layer 2 - non-ref */
st_ref[1].is_non_ref = 1;
st_ref[1].temporal_id = 2;
st_ref[1].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[1].ref_arg = 0;
st_ref[1].repeat = 0;
/* st 2 layer 1 - ref */
st_ref[2].is_non_ref = 0;
st_ref[2].temporal_id = 1;
st_ref[2].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[2].ref_arg = 0;
st_ref[2].repeat = 0;
/* st 3 layer 2 - non-ref */
st_ref[3].is_non_ref = 1;
st_ref[3].temporal_id = 2;
st_ref[3].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[3].ref_arg = 0;
st_ref[3].repeat = 0;
/* st 4 layer 0 - ref */
st_ref[4].is_non_ref = 0;
st_ref[4].temporal_id = 0;
st_ref[4].ref_mode = REF_TO_TEMPORAL_LAYER;
st_ref[4].ref_arg = 0;
st_ref[4].repeat = 0;
} break;
case 1 : {
// tsvc2
// /-> P1
// /
// P0--------> P2
lt_cnt = 0;
st_cnt = 3;
/* set tsvc4 st-ref struct */
/* st 0 layer 0 - ref */
st_ref[0].is_non_ref = 0;
st_ref[0].temporal_id = 0;
st_ref[0].ref_mode = REF_TO_TEMPORAL_LAYER;
st_ref[0].ref_arg = 0;
st_ref[0].repeat = 0;
/* st 1 layer 2 - non-ref */
st_ref[1].is_non_ref = 1;
st_ref[1].temporal_id = 1;
st_ref[1].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[1].ref_arg = 0;
st_ref[1].repeat = 0;
/* st 2 layer 1 - ref */
st_ref[2].is_non_ref = 0;
st_ref[2].temporal_id = 0;
st_ref[2].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[2].ref_arg = 0;
st_ref[2].repeat = 0;
} break;
default : {
mpp_err_f("unsupport gop mode %d\n", gop_mode);
} break;
}
if (lt_cnt || st_cnt) {
ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cnt, st_cnt);
if (lt_cnt)
ret = mpp_enc_ref_cfg_add_lt_cfg(ref, lt_cnt, lt_ref);
if (st_cnt)
ret = mpp_enc_ref_cfg_add_st_cfg(ref, st_cnt, st_ref);
/* check and get dpb size */
ret = mpp_enc_ref_cfg_check(ref);
}
return ret;
}
static MPP_RET mpi_enc_gen_smart_gop_ref_cfg(MppEncRefCfg ref, RK_S32 gop_len, RK_S32 vi_len)
{
MppEncRefLtFrmCfg lt_ref[4];
MppEncRefStFrmCfg st_ref[16];
RK_S32 lt_cnt = 1;
RK_S32 st_cnt = 8;
RK_S32 pos = 0;
MPP_RET ret = 0;
memset(&lt_ref, 0, sizeof(lt_ref));
memset(&st_ref, 0, sizeof(st_ref));
ret = mpp_enc_ref_cfg_set_cfg_cnt(ref, lt_cnt, st_cnt);
/* set 8 frame lt-ref gap */
lt_ref[0].lt_idx = 0;
lt_ref[0].temporal_id = 0;
lt_ref[0].ref_mode = REF_TO_PREV_LT_REF;
lt_ref[0].lt_gap = gop_len;
lt_ref[0].lt_delay = 0;
ret = mpp_enc_ref_cfg_add_lt_cfg(ref, 1, lt_ref);
/* st 0 layer 0 - ref */
st_ref[pos].is_non_ref = 0;
st_ref[pos].temporal_id = 0;
st_ref[pos].ref_mode = REF_TO_PREV_INTRA;
st_ref[pos].ref_arg = 0;
st_ref[pos].repeat = 0;
pos++;
/* st 1 layer 1 - non-ref */
if (vi_len > 1) {
st_ref[pos].is_non_ref = 0;
st_ref[pos].temporal_id = 1;
st_ref[pos].ref_mode = REF_TO_PREV_REF_FRM;
st_ref[pos].ref_arg = 0;
st_ref[pos].repeat = vi_len - 2;
pos++;
}
st_ref[pos].is_non_ref = 0;
st_ref[pos].temporal_id = 0;
st_ref[pos].ref_mode = REF_TO_PREV_INTRA;
st_ref[pos].ref_arg = 0;
st_ref[pos].repeat = 0;
pos++;
ret = mpp_enc_ref_cfg_add_st_cfg(ref, pos, st_ref);
/* check and get dpb size */
ret = mpp_enc_ref_cfg_check(ref);
return ret;
}
/* 除了必须设置的一些参数,如宽高,输入图像格式,输出编码格式等,其他参数不知道直接填0
* test_mpp_enc_cfg_setup函数会自动计算默认的参数如bps, gop等参数
*/
static MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd)
{
MpiEncTestData *p = NULL;
MPP_RET ret = 0;
if (!data || !cmd) {
mpp_err_f("invalid input data %p cmd %p\n", data, cmd);
return MPP_ERR_NULL_PTR;
}
p = mpp_calloc(MpiEncTestData, 1);
if (!p) {
mpp_err_f("create MpiEncTestData failed\n");
ret = MPP_ERR_MALLOC;
goto RET;
}
// get paramter from cmd
p->width = cmd->width;
p->height = cmd->height;
p->hor_stride = MPP_ALIGN(cmd->width, 16);
p->ver_stride = MPP_ALIGN(cmd->height, 16);
p->fmt = cmd->format;
p->type = cmd->type;
// update resource parameter
switch (p->fmt & MPP_FRAME_FMT_MASK) {
case MPP_FMT_YUV420SP:
case MPP_FMT_YUV420P: {
p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 3 / 2;
} break;
case MPP_FMT_YUV422_YUYV :
case MPP_FMT_YUV422_YVYU :
case MPP_FMT_YUV422_UYVY :
case MPP_FMT_YUV422_VYUY :
case MPP_FMT_YUV422P :
case MPP_FMT_YUV422SP :
case MPP_FMT_RGB444 :
case MPP_FMT_BGR444 :
case MPP_FMT_RGB555 :
case MPP_FMT_BGR555 :
case MPP_FMT_RGB565 :
case MPP_FMT_BGR565 : {
p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 2;
} break;
default: {
p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4;
} break;
}
RET:
*data = p;
return ret;
}
static MPP_RET test_ctx_deinit(MpiEncTestData **data)
{
MpiEncTestData *p = NULL;
if (!data) {
mpp_err_f("invalid input data %p\n", data);
return MPP_ERR_NULL_PTR;
}
p = *data;
if (p) {
MPP_FREE(p);
*data = NULL;
}
return MPP_OK;
}
static MPP_RET test_mpp_enc_cfg_setup(MpiEncTestData *p)
{
MPP_RET ret;
MppApi *mpi;
MppCtx ctx;
MppEncCfg cfg;
if (NULL == p)
return MPP_ERR_NULL_PTR;
mpi = p->mpi;
ctx = p->ctx;
cfg = p->cfg;
/* setup default parameter */
if (p->fps_in_den == 0)
p->fps_in_den = 1;
if (p->fps_in_num == 0)
p->fps_in_num = 30;
if (p->fps_out_den == 0)
p->fps_out_den = 1;
if (p->fps_out_num == 0)
p->fps_out_num = 30;
/* 计算默认bps */
if (!p->bps)
p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
mpp_enc_cfg_set_s32(cfg, "prep:width", p->width);
mpp_enc_cfg_set_s32(cfg, "prep:height", p->height);
mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", p->hor_stride);
mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", p->ver_stride);
mpp_enc_cfg_set_s32(cfg, "prep:format", p->fmt);
mpp_enc_cfg_set_s32(cfg, "rc:mode", p->rc_mode);
/* fix input / output frame rate */
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", p->fps_in_flex);
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", p->fps_in_num);
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denorm", p->fps_in_den);
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", p->fps_out_flex);
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num", p->fps_out_num);
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denorm", p->fps_out_den);
mpp_enc_cfg_set_s32(cfg, "rc:gop", p->gop_len ? p->gop_len : p->fps_out_num * 2);
/* drop frame or not when bitrate overflow */
mpp_enc_cfg_set_u32(cfg, "rc:drop_mode", MPP_ENC_RC_DROP_FRM_DISABLED);
mpp_enc_cfg_set_u32(cfg, "rc:drop_thd", 20); /* 20% of max bps */
mpp_enc_cfg_set_u32(cfg, "rc:drop_gap", 1); /* Do not continuous drop frame */
/* setup bitrate for different rc_mode */
mpp_enc_cfg_set_s32(cfg, "rc:bps_target", p->bps);
switch (p->rc_mode) {
case MPP_ENC_RC_MODE_FIXQP : {
/* do not setup bitrate on FIXQP mode */
} break;
case MPP_ENC_RC_MODE_CBR : {
/* CBR mode has narrow bound */
mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
} break;
case MPP_ENC_RC_MODE_VBR :
case MPP_ENC_RC_MODE_AVBR : {
/* VBR mode has wide bound */
mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 1 / 16);
} break;
default : {
/* default use CBR mode */
mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
} break;
}
/* setup qp for different codec and rc_mode */
switch (p->type) {
case MPP_VIDEO_CodingAVC :
case MPP_VIDEO_CodingHEVC : {
switch (p->rc_mode) {
case MPP_ENC_RC_MODE_FIXQP : {
mpp_enc_cfg_set_s32(cfg, "rc:qp_init", 20);
mpp_enc_cfg_set_s32(cfg, "rc:qp_max", 20);
mpp_enc_cfg_set_s32(cfg, "rc:qp_min", 20);
mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", 20);
mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", 20);
mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 2);
} break;
case MPP_ENC_RC_MODE_CBR :
case MPP_ENC_RC_MODE_VBR :
case MPP_ENC_RC_MODE_AVBR : {
mpp_enc_cfg_set_s32(cfg, "rc:qp_init", 26);
mpp_enc_cfg_set_s32(cfg, "rc:qp_max", 51);
mpp_enc_cfg_set_s32(cfg, "rc:qp_min", 10);
mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", 51);
mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", 10);
mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 2);
} break;
default : {
mpp_err_f("unsupport encoder rc mode %d\n", p->rc_mode);
} break;
}
} break;
case MPP_VIDEO_CodingVP8 : {
/* vp8 only setup base qp range */
mpp_enc_cfg_set_s32(cfg, "rc:qp_init", 40);
mpp_enc_cfg_set_s32(cfg, "rc:qp_max", 127);
mpp_enc_cfg_set_s32(cfg, "rc:qp_min", 0);
mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", 127);
mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", 0);
mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 6);
} break;
case MPP_VIDEO_CodingMJPEG : {
/* jpeg use special codec config to control qtable */
mpp_enc_cfg_set_s32(cfg, "jpeg:q_factor", 80);
mpp_enc_cfg_set_s32(cfg, "jpeg:qf_max", 99);
mpp_enc_cfg_set_s32(cfg, "jpeg:qf_min", 1);
} break;
default : {
} break;
}
/* setup codec */
mpp_enc_cfg_set_s32(cfg, "codec:type", p->type);
switch (p->type) {
case MPP_VIDEO_CodingAVC : {
/*
* H.264 profile_idc parameter
* 66 - Baseline profile
* 77 - Main profile
* 100 - High profile
*/
mpp_enc_cfg_set_s32(cfg, "h264:profile", 100);
/*
* H.264 level_idc parameter
* 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
* 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps
* 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps
* 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps
* 50 / 51 / 52 - 4K@30fps
*/
mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
} break;
case MPP_VIDEO_CodingHEVC :
case MPP_VIDEO_CodingMJPEG :
case MPP_VIDEO_CodingVP8 : {
} break;
default : {
mpp_err_f("unsupport encoder coding type %d\n", p->type);
} break;
}
p->split_mode = 0;
p->split_arg = 0;
mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE);
mpp_env_get_u32("split_arg", &p->split_arg, 0);
if (p->split_mode) {
mpp_log("%p split_mode %d split_arg %d\n", ctx, p->split_mode, p->split_arg);
mpp_enc_cfg_set_s32(cfg, "split:mode", p->split_mode);
mpp_enc_cfg_set_s32(cfg, "split:arg", p->split_arg);
}
ret = mpi->control(ctx, MPP_ENC_SET_CFG, cfg);
if (ret) {
mpp_err("mpi control enc set cfg failed ret %d\n", ret);
goto RET;
}
/* optional */
p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
if (ret) {
mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
goto RET;
}
if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode);
if (ret) {
mpp_err("mpi control enc set header mode failed ret %d\n", ret);
goto RET;
}
}
RK_U32 gop_mode = p->gop_mode;
mpp_env_get_u32("gop_mode", &gop_mode, gop_mode);
if (gop_mode) {
MppEncRefCfg ref;
mpp_enc_ref_cfg_init(&ref);
if (p->gop_mode < 4)
mpi_enc_gen_ref_cfg(ref, gop_mode);
else
mpi_enc_gen_smart_gop_ref_cfg(ref, p->gop_len, p->vi_len);
ret = mpi->control(ctx, MPP_ENC_SET_REF_CFG, ref);
if (ret) {
mpp_err("mpi control enc set ref cfg failed ret %d\n", ret);
goto RET;
}
mpp_enc_ref_cfg_deinit(&ref);
}
RET:
return ret;
}
static void test_mpp_frame_set_param(MppFrame frame, MpiEncTestData *p)
{
mpp_frame_set_width(frame, p->width);
mpp_frame_set_height(frame, p->height);
mpp_frame_set_hor_stride(frame, p->hor_stride);
mpp_frame_set_ver_stride(frame, p->ver_stride);
mpp_frame_set_fmt(frame, p->fmt);
mpp_frame_set_eos(frame, p->frm_eos);
}
static void test_mpp_ctx_cleanup(MpiEncTestData *p)
{
if (!p)
return;
p->mpi->reset(p->ctx);
if (p->ctx) {
mpp_destroy(p->ctx);
p->ctx = NULL;
}
if (p->cfg) {
mpp_enc_cfg_deinit(p->cfg);
p->cfg = NULL;
}
if (p->pkt_buf) {
mpp_buffer_put(p->pkt_buf);
p->pkt_buf = NULL;
}
if (p->buf_grp) {
mpp_buffer_group_put(p->buf_grp);
p->buf_grp = NULL;
}
test_ctx_deinit(&p);
}
int hal_mpp_get_sps(void *ctx, unsigned char *buf, size_t *buf_size)
{
int ret;
MppApi *mpi;
MppCtx mpp_ctx;
MppPacket packet = NULL;
MpiEncTestData *p = (MpiEncTestData *)ctx;
mpi = p->mpi;
mpp_ctx = p->ctx;
/*
* Can use packet with normal malloc buffer as input not pkt_buf.
* Please refer to vpu_api_legacy.cpp for normal buffer case.
* Using pkt_buf buffer here is just for simplifing demo.
*/
mpp_packet_init_with_buffer(&packet, p->pkt_buf);
/* NOTE: It is important to clear output packet length!! */
mpp_packet_set_length(packet, 0);
// 设置一下H264,H265专用的一些参数
if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
ret = mpi->control(mpp_ctx, MPP_ENC_GET_HDR_SYNC, packet);
if (ret) {
mpp_err("mpi control enc get extra info failed\n");
ret = MPP_NOK;
goto exit;
}
}
void *ptr = mpp_packet_get_pos(packet);
size_t len = mpp_packet_get_length(packet);
if (*buf_size < len) {
mpp_err("mpi buffer size too small\n");
ret = MPP_NOK;
goto exit;
}
memcpy(buf, ptr, len);
*buf_size = len;
ret = MPP_OK;
exit:
mpp_packet_deinit(&packet);
return MPP_OK;
}
int hal_mpp_encode(void *ctx, int dma_fd, unsigned char *buf, size_t *buf_size)
{
MPP_RET ret = 0;
MppFrame frame = NULL;
MppMeta meta = NULL;
MppPacket packet = NULL;
MpiEncTestData *p = (MpiEncTestData *)ctx;
MppApi *mpi = p->mpi;
RK_U32 eoi = 1;
RK_U32 packet_num = 0;
MppBuffer cam_buf = NULL;
MppBufferInfo info;
memset(&info, 0, sizeof(MppBufferInfo));
info.type = MPP_BUFFER_TYPE_EXT_DMA;
info.fd = dma_fd;
info.size = p->frame_size & 0x07ffffff;
info.index = (p->frame_size & 0xf8000000) >> 27;
ret = mpp_buffer_import(&cam_buf, &info);
if (ret != MPP_SUCCESS) {
mpp_err_f("mpp_buffer_import failed\n");
return MPP_NOK;
}
ret = mpp_frame_init(&frame);
if (ret) {
mpp_err_f("mpp_frame_init failed\n");
return MPP_NOK;
}
/* set frame size info */
test_mpp_frame_set_param(frame, p);
/* set frame data include fd */
mpp_frame_set_buffer(frame, cam_buf);
/* packet init */
mpp_packet_init_with_buffer(&packet, p->pkt_buf);
/* NOTE: It is important to clear output packet length!! */
mpp_packet_set_length(packet, 0);
meta = mpp_frame_get_meta(frame);
mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, packet);
/*
* NOTE: in non-block mode the frame can be resent.
* The default input timeout mode is block.
*
* User should release the input frame to meet the requirements of
* resource creator must be the resource destroyer.
*/
ret = mpi->encode_put_frame(p->ctx, frame);
if (ret) {
mpp_err("mpp encode put frame failed\n");
mpp_frame_deinit(&frame);
goto RET;
}
mpp_frame_deinit(&frame);
packet_num = 0;
do {
ret = mpi->encode_get_packet(p->ctx, &packet);
if (ret) {
mpp_err("mpp encode get packet failed\n");
goto RET;
}
mpp_assert(packet);
if (packet) {
/* for low delay partition encoding */
if (mpp_packet_is_partition(packet)) {
eoi = mpp_packet_is_eoi(packet);
}
p->frame_count += eoi;
packet_num++;
}
} while (!eoi);
void *ptr = mpp_packet_get_pos(packet);
size_t len = mpp_packet_get_length(packet);
if (packet_num != 1) {
mpp_err("packet_num %u != 1\n");
ret = MPP_NOK;
goto RET;
}
if (*buf_size < len) {
mpp_err("mpi buffer size too small\n");
ret = MPP_NOK;
goto RET;
}
memcpy(buf, ptr, len);
*buf_size = len;
ret = MPP_OK;
RET:
if (cam_buf)
mpp_buffer_put(cam_buf);
mpp_packet_deinit(&packet);
return ret;
}
void *hal_mpp_ctx_create(MpiEncTestArgs *args)
{
MPP_RET ret = 0;
MpiEncTestData *p = NULL;
MppPollType timeout = MPP_POLL_BLOCK;
/* 初始化一下常用的参数配置,cmd的配置比较多 */
ret = test_ctx_init(&p, args);
if (ret) {
mpp_err_f("test data init failed ret %d\n", ret);
goto MPP_TEST_OUT;
}
ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_DRM);
if (ret) {
mpp_err_f("failed to get mpp buffer group ret %d\n", ret);
goto MPP_TEST_OUT;
}
/* pkt_buf这个成员需要,是给packet使用的buffer */
ret = mpp_buffer_get(p->buf_grp, &p->pkt_buf, p->frame_size);
if (ret) {
mpp_err_f("failed to get buffer for output packet ret %d\n", ret);
goto MPP_TEST_OUT;
}
// encoder demo
ret = mpp_create(&p->ctx, &p->mpi);
if (ret) {
mpp_err("mpp_create failed ret %d\n", ret);
goto MPP_TEST_OUT;
}
mpp_log("%p mpi_enc_test encoder test start w %d h %d type %d\n",
p->ctx, p->width, p->height, p->type);
ret = p->mpi->control(p->ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
if (MPP_OK != ret) {
mpp_err("mpi control set output timeout %d ret %d\n", timeout, ret);
goto MPP_TEST_OUT;
}
ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type);
if (ret) {
mpp_err("mpp_init failed ret %d\n", ret);
goto MPP_TEST_OUT;
}
ret = mpp_enc_cfg_init(&p->cfg);
if (ret) {
mpp_err_f("mpp_enc_cfg_init failed ret %d\n", ret);
goto MPP_TEST_OUT;
}
ret = test_mpp_enc_cfg_setup(p);
if (ret) {
mpp_err_f("test mpp setup failed ret %d\n", ret);
goto MPP_TEST_OUT;
}
return p;
MPP_TEST_OUT:
mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
return NULL;
}
void hal_mpp_ctx_delete(void *ctx)
{
test_mpp_ctx_cleanup(ctx);
}
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2016 Rockchip Electronics Co., Ltd.
* Authors:
* Zhiqin Wei <wzq@rock-chips.com>
*
* 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 _rk_graphic_buffer_h_
#define _rk_graphic_buffer_h_
#ifdef ANDROID
#include <stdint.h>
#include <vector>
#include <sys/types.h>
#include <system/graphics.h>
#include <utils/Thread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/stddef.h>
#include <utils/Atomic.h>
#include <utils/Errors.h>
#include <android/log.h>
#include <utils/Log.h>
#include <log/log_main.h>
#include "drmrga.h"
#include "rga.h"
// -------------------------------------------------------------------------------
int RkRgaGetHandleFd(buffer_handle_t handle, int *fd);
int RkRgaGetHandleAttributes(buffer_handle_t handle,
std::vector<int> *attrs);
int RkRgaGetHandleMapAddress(buffer_handle_t handle,
void **buf);
#endif //Android
#endif //_rk_graphic_buffer_h_
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2016 Rockchip Electronics Co., Ltd.
* Authors:
* Zhiqin Wei <wzq@rock-chips.com>
*
* 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 _rockchip_rga_c_h_
#define _rockchip_rga_c_h_
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/stddef.h>
#include "drmrga.h"
#include "rga.h"
#ifdef __cplusplus
extern "C"{
#endif
/*
* Compatible with the old version of C interface.The new
* version of the C interface no longer requires users to
* initialize rga, so RgaInit and RgaDeInit are just for
* compatibility with the old C interface, so please do
* not use ctx, because it is usually a NULL.
*/
#define RgaInit(ctx) ({ \
int ret = 0; \
ret = c_RkRgaInit(); \
c_RkRgaGetContext(ctx); \
ret;\
})
#define RgaDeInit(ctx) { \
(void)ctx; /* unused */ \
c_RkRgaDeInit(); \
}
#define RgaBlit(...) c_RkRgaBlit(__VA_ARGS__)
#define RgaCollorFill(...) c_RkRgaColorFill(__VA_ARGS__)
#define RgaFlush() c_RkRgaFlush()
int c_RkRgaInit();
void c_RkRgaDeInit();
void c_RkRgaGetContext(void **ctx);
int c_RkRgaBlit(rga_info_t *src, rga_info_t *dst, rga_info_t *src1);
int c_RkRgaColorFill(rga_info_t *dst);
int c_RkRgaFlush();
#ifndef ANDROID /* linux */
int c_RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp);
int c_RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp);
int c_RkRgaGetMmap(bo_t *bo_info);
int c_RkRgaUnmap(bo_t *bo_info);
int c_RkRgaFree(bo_t *bo_info);
int c_RkRgaGetBufferFd(bo_t *bo_info, int *fd);
#endif /* #ifndef ANDROID */
#ifdef __cplusplus
}
#endif
#endif /* #ifndef _rockchip_rga_c_h_ */
+193
View File
@@ -0,0 +1,193 @@
/*
* Copyright (C) 2020 Rockchip Electronics Co., Ltd.
* Authors:
* PutinLee <putin.lee@rock-chips.com>
*
* 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 _LIBS_RGA_MUTEX_H
#define _LIBS_RGA_MUTEX_H
#ifndef ANDROID
#include <stdint.h>
#include <sys/types.h>
#include <time.h>
#include <pthread.h>
// Enable thread safety attributes only with clang.
// The attributes can be safely erased when compiling with other compilers.
#if defined(__clang__) && (!defined(SWIG))
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif
#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
#define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
#define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
#define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
#define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
#define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
#define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
#define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
#define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
#define TRY_ACQUIRE_SHARED(...) \
THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
#define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
#define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
class Condition;
/*
* NOTE: This class is for code that builds on Win32. Its usage is
* deprecated for code which doesn't build for Win32. New code which
* doesn't build for Win32 should use std::mutex and std::lock_guard instead.
*
* Simple mutex class. The implementation is system-dependent.
*
* The mutex must be unlocked by the thread that locked it. They are not
* recursive, i.e. the same thread can't lock it multiple times.
*/
class CAPABILITY("mutex") Mutex {
public:
enum {
PRIVATE = 0,
SHARED = 1
};
Mutex();
explicit Mutex(const char* name);
explicit Mutex(int type, const char* name = nullptr);
~Mutex();
// lock or unlock the mutex
int32_t lock() ACQUIRE();
void unlock() RELEASE();
// lock if possible; returns 0 on success, error otherwise
int32_t tryLock() TRY_ACQUIRE(0);
int32_t timedLock(int64_t timeoutNs) TRY_ACQUIRE(0);
// Manages the mutex automatically. It'll be locked when Autolock is
// constructed and released when Autolock goes out of scope.
class SCOPED_CAPABILITY Autolock {
public:
inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) {
mLock.lock();
}
inline explicit Autolock(Mutex* mutex) ACQUIRE(mutex) : mLock(*mutex) {
mLock.lock();
}
inline ~Autolock() RELEASE() {
mLock.unlock();
}
private:
Mutex& mLock;
// Cannot be copied or moved - declarations only
Autolock(const Autolock&);
Autolock& operator=(const Autolock&);
};
private:
friend class Condition;
// A mutex cannot be copied
Mutex(const Mutex&);
Mutex& operator=(const Mutex&);
pthread_mutex_t mMutex;
};
// ---------------------------------------------------------------------------
inline Mutex::Mutex() {
pthread_mutex_init(&mMutex, nullptr);
}
inline Mutex::Mutex(__attribute__((unused)) const char* name) {
pthread_mutex_init(&mMutex, nullptr);
}
inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
if (type == SHARED) {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&mMutex, &attr);
pthread_mutexattr_destroy(&attr);
} else {
pthread_mutex_init(&mMutex, nullptr);
}
}
inline Mutex::~Mutex() {
pthread_mutex_destroy(&mMutex);
}
inline int32_t Mutex::lock() {
return -pthread_mutex_lock(&mMutex);
}
inline void Mutex::unlock() {
pthread_mutex_unlock(&mMutex);
}
inline int32_t Mutex::tryLock() {
return -pthread_mutex_trylock(&mMutex);
}
inline int32_t Mutex::timedLock(int64_t timeoutNs) {
timespec now;
clock_gettime(CLOCK_REALTIME, &now);
timeoutNs += now.tv_sec*1000000000 + now.tv_nsec;
const struct timespec ts = {
/* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
/* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),
};
return -pthread_mutex_timedlock(&mMutex, &ts);
}
// ---------------------------------------------------------------------------
/*
* Automatic mutex. Declare one of these at the top of a function.
* When the function returns, it will go out of scope, and release the
* mutex.
*/
typedef Mutex::Autolock AutoMutex;
#endif // __ANDROID_VNDK__
#endif // _LIBS_RGA_MUTEX_H
+70
View File
@@ -0,0 +1,70 @@
/*
* Copyright (C) 2016 Rockchip Electronics Co., Ltd.
* Authors:
* Zhiqin Wei <wzq@rock-chips.com>
*
* 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 _LIBS_RGA_SINGLETON_H
#define _LIBS_RGA_SINGLETON_H
#ifndef ANDROID
#include "RgaMutex.h"
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundefined-var-template"
#endif
template <typename TYPE>
class Singleton {
public:
static TYPE& getInstance() {
Mutex::Autolock _l(sLock);
TYPE* instance = sInstance;
if (instance == nullptr) {
instance = new TYPE();
sInstance = instance;
}
return *instance;
}
static bool hasInstance() {
Mutex::Autolock _l(sLock);
return sInstance != nullptr;
}
protected:
~Singleton() { }
Singleton() { }
private:
Singleton(const Singleton&);
Singleton& operator = (const Singleton&);
static Mutex sLock;
static TYPE* sInstance;
};
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
#define RGA_SINGLETON_STATIC_INSTANCE(TYPE) \
template<> ::Mutex \
(::Singleton< TYPE >::sLock)(::Mutex::PRIVATE); \
template<> TYPE* ::Singleton< TYPE >::sInstance(nullptr); /* NOLINT */ \
template class ::Singleton< TYPE >;
#endif //ANDROID
#endif //_LIBS_RGA_SINGLETON_H
+28
View File
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2016 Rockchip Electronics Co., Ltd.
* Authors:
* Zhiqin Wei <wzq@rock-chips.com>
*
* 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 _rga_utils_h_
#define _rga_utils_h_
// -------------------------------------------------------------------------------
float get_bpp_from_format(int format);
int get_buf_from_file(void *buf, int f, int sw, int sh, int index);
int output_buf_data_to_file(void *buf, int f, int sw, int sh, int index);
const char *translate_format_str(int format);
#endif
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2016 Rockchip Electronics Co., Ltd.
* Authors:
* Zhiqin Wei <wzq@rock-chips.com>
*
* 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 _rockchip_rga_h_
#define _rockchip_rga_h_
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
#include <linux/stddef.h>
#include "drmrga.h"
#include "GrallocOps.h"
#include "RgaUtils.h"
#include "rga.h"
//////////////////////////////////////////////////////////////////////////////////
#ifndef ANDROID
#include "RgaSingleton.h"
#endif
#ifdef ANDROID
#include <utils/Singleton.h>
#include <utils/Thread.h>
#include <hardware/hardware.h>
namespace android {
#endif
class RockchipRga :public Singleton<RockchipRga> {
public:
static inline RockchipRga& get() {
return getInstance();
}
int RkRgaInit();
void RkRgaDeInit();
void RkRgaGetContext(void **ctx);
#ifndef ANDROID /* LINUX */
int RkRgaAllocBuffer(int drm_fd /* input */, bo_t *bo_info,
int width, int height, int bpp, int flags);
int RkRgaFreeBuffer(int drm_fd /* input */, bo_t *bo_info);
int RkRgaGetAllocBuffer(bo_t *bo_info, int width, int height, int bpp);
int RkRgaGetAllocBufferExt(bo_t *bo_info, int width, int height, int bpp, int flags);
int RkRgaGetAllocBufferCache(bo_t *bo_info, int width, int height, int bpp);
int RkRgaGetMmap(bo_t *bo_info);
int RkRgaUnmap(bo_t *bo_info);
int RkRgaFree(bo_t *bo_info);
int RkRgaGetBufferFd(bo_t *bo_info, int *fd);
#else
int RkRgaGetBufferFd(buffer_handle_t handle, int *fd);
int RkRgaGetHandleMapCpuAddress(buffer_handle_t handle, void **buf);
#endif
int RkRgaBlit(rga_info *src, rga_info *dst, rga_info *src1);
int RkRgaCollorFill(rga_info *dst);
int RkRgaCollorPalette(rga_info *src, rga_info *dst, rga_info *lut);
int RkRgaFlush();
void RkRgaSetLogOnceFlag(int log) {
mLogOnce = log;
}
void RkRgaSetAlwaysLogFlag(bool log) {
mLogAlways = log;
}
void RkRgaLogOutRgaReq(struct rga_req rgaReg);
int RkRgaLogOutUserPara(rga_info *rgaInfo);
inline bool RkRgaIsReady() {
return mSupportRga;
}
RockchipRga();
~RockchipRga();
private:
bool mSupportRga;
int mLogOnce;
int mLogAlways;
void * mContext;
friend class Singleton<RockchipRga>;
};
#ifdef ANDROID
}; // namespace android
#endif
#endif
+211
View File
@@ -0,0 +1,211 @@
/*
* Copyright (C) 2016 Rockchip Electronics Co., Ltd.
* Authors:
* Zhiqin Wei <wzq@rock-chips.com>
*
* 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 _rk_drm_rga_
#define _rk_drm_rga_
#include <stdint.h>
//#include <sys/cdefs.h>
#ifdef ANDROID
#define DRMRGA_HARDWARE_MODULE_ID "librga"
#include <hardware/gralloc.h>
#include <hardware/hardware.h>
#include <system/graphics.h>
#include <cutils/native_handle.h>
#endif
#ifndef ANDROID /* LINUX */
/* flip source image horizontally (around the vertical axis) */
#define HAL_TRANSFORM_FLIP_H 0x01
/* flip source image vertically (around the horizontal axis)*/
#define HAL_TRANSFORM_FLIP_V 0x02
/* rotate source image 90 degrees clockwise */
#define HAL_TRANSFORM_ROT_90 0x04
/* rotate source image 180 degrees */
#define HAL_TRANSFORM_ROT_180 0x03
/* rotate source image 270 degrees clockwise */
#define HAL_TRANSFORM_ROT_270 0x07
#endif
#define HAL_TRANSFORM_FLIP_H_V 0x08
/*****************************************************************************/
/* for compatibility */
#define DRM_RGA_MODULE_API_VERSION HWC_MODULE_API_VERSION_0_1
#define DRM_RGA_DEVICE_API_VERSION HWC_DEVICE_API_VERSION_0_1
#define DRM_RGA_API_VERSION HWC_DEVICE_API_VERSION
#define DRM_RGA_TRANSFORM_ROT_MASK 0x0000000F
#define DRM_RGA_TRANSFORM_ROT_0 0x00000000
#define DRM_RGA_TRANSFORM_ROT_90 HAL_TRANSFORM_ROT_90
#define DRM_RGA_TRANSFORM_ROT_180 HAL_TRANSFORM_ROT_180
#define DRM_RGA_TRANSFORM_ROT_270 HAL_TRANSFORM_ROT_270
#define DRM_RGA_TRANSFORM_FLIP_MASK 0x00000003
#define DRM_RGA_TRANSFORM_FLIP_H HAL_TRANSFORM_FLIP_H
#define DRM_RGA_TRANSFORM_FLIP_V HAL_TRANSFORM_FLIP_V
enum {
AWIDTH = 0,
AHEIGHT,
ASTRIDE,
AFORMAT,
ASIZE,
ATYPE,
};
/*****************************************************************************/
#ifndef ANDROID
/* memory type definitions. */
enum drm_rockchip_gem_mem_type {
/* Physically Continuous memory and used as default. */
ROCKCHIP_BO_CONTIG = 1 << 0,
/* cachable mapping. */
ROCKCHIP_BO_CACHABLE = 1 << 1,
/* write-combine mapping. */
ROCKCHIP_BO_WC = 1 << 2,
ROCKCHIP_BO_SECURE = 1 << 3,
ROCKCHIP_BO_MASK = ROCKCHIP_BO_CONTIG | ROCKCHIP_BO_CACHABLE |
ROCKCHIP_BO_WC | ROCKCHIP_BO_SECURE
};
typedef struct bo {
int fd;
void *ptr;
size_t size;
size_t offset;
size_t pitch;
unsigned handle;
} bo_t;
#endif
/*
@value size: user not need care about.For avoid read/write out of memory
*/
typedef struct rga_rect {
int xoffset;
int yoffset;
int width;
int height;
int wstride;
int hstride;
int format;
int size;
} rga_rect_t;
typedef struct rga_nn {
int nn_flag;
int scale_r;
int scale_g;
int scale_b;
int offset_r;
int offset_g;
int offset_b;
} rga_nn_t;
typedef struct rga_dither {
int enable;
int mode;
int lut0_l;
int lut0_h;
int lut1_l;
int lut1_h;
} rga_dither_t;
/*
@value fd: use fd to share memory, it can be ion shard fd,and dma fd.
@value virAddr:userspace address
@value phyAddr:use phy address
@value hnd: use buffer_handle_t
*/
typedef struct rga_info {
int fd;
void *virAddr;
void *phyAddr;
#ifndef ANDROID /* LINUX */
unsigned hnd;
#else /* Android */
buffer_handle_t hnd;
#endif
int format;
rga_rect_t rect;
unsigned int blend;
int bufferSize;
int rotation;
int color;
int testLog;
int mmuFlag;
int colorkey_en;
int colorkey_mode;
int colorkey_max;
int colorkey_min;
int scale_mode;
int color_space_mode;
int sync_mode;
rga_nn_t nn;
rga_dither_t dither;
int rop_code;
int reserve[127];
} rga_info_t;
typedef struct drm_rga {
rga_rect_t src;
rga_rect_t dst;
} drm_rga_t;
/*
@fun rga_set_rect:For use to set the rects esayly
@param rect:The rect user want to set,like setting the src rect:
drm_rga_t rects;
rga_set_rect(rects.src,0,0,1920,1080,1920,NV12);
mean to set the src rect to the value.
*/
static inline int rga_set_rect(rga_rect_t *rect,
int x, int y, int w, int h, int sw, int sh, int f) {
if (!rect)
return -EINVAL;
rect->xoffset = x;
rect->yoffset = y;
rect->width = w;
rect->height = h;
rect->wstride = sw;
rect->hstride = sh;
rect->format = f;
return 0;
}
#ifndef ANDROID /* LINUX */
static inline void rga_set_rotation(rga_info_t *info, int angle) {
if (angle == 90)
info->rotation = HAL_TRANSFORM_ROT_90;
else if (angle == 180)
info->rotation = HAL_TRANSFORM_ROT_180;
else if (angle == 270)
info->rotation = HAL_TRANSFORM_ROT_270;
}
#endif
/*****************************************************************************/
#endif
+892
View File
@@ -0,0 +1,892 @@
/*
* Copyright (C) 2020 Rockchip Electronics Co., Ltd.
* Authors:
* PutinLee <putin.lee@rock-chips.com>
* Cerf Yu <cerf.yu@rock-chips.com>
*
* 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 _im2d_h_
#define _im2d_h_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef IM_API
#define IM_API /* define API export as needed */
#endif
typedef enum {
/* Rotation */
IM_HAL_TRANSFORM_ROT_90 = 1 << 0,
IM_HAL_TRANSFORM_ROT_180 = 1 << 1,
IM_HAL_TRANSFORM_ROT_270 = 1 << 2,
IM_HAL_TRANSFORM_FLIP_H = 1 << 3,
IM_HAL_TRANSFORM_FLIP_V = 1 << 4,
IM_HAL_TRANSFORM_FLIP_H_V = 1 << 5,
IM_HAL_TRANSFORM_MASK = 0x3f,
/*
* Blend
* Additional blend usage, can be used with both source and target configs.
* If none of the below is set, the default "SRC over DST" is applied.
*/
IM_ALPHA_BLEND_SRC_OVER = 1 << 6, /* Default, Porter-Duff "SRC over DST" */
IM_ALPHA_BLEND_SRC = 1 << 7, /* Porter-Duff "SRC" */
IM_ALPHA_BLEND_DST = 1 << 8, /* Porter-Duff "DST" */
IM_ALPHA_BLEND_SRC_IN = 1 << 9, /* Porter-Duff "SRC in DST" */
IM_ALPHA_BLEND_DST_IN = 1 << 10, /* Porter-Duff "DST in SRC" */
IM_ALPHA_BLEND_SRC_OUT = 1 << 11, /* Porter-Duff "SRC out DST" */
IM_ALPHA_BLEND_DST_OUT = 1 << 12, /* Porter-Duff "DST out SRC" */
IM_ALPHA_BLEND_DST_OVER = 1 << 13, /* Porter-Duff "DST over SRC" */
IM_ALPHA_BLEND_SRC_ATOP = 1 << 14, /* Porter-Duff "SRC ATOP" */
IM_ALPHA_BLEND_DST_ATOP = 1 << 15, /* Porter-Duff "DST ATOP" */
IM_ALPHA_BLEND_XOR = 1 << 16, /* Xor */
IM_ALPHA_BLEND_MASK = 0x1ffc0,
IM_ALPHA_COLORKEY_NORMAL = 1 << 17,
IM_ALPHA_COLORKEY_INVERTED = 1 << 18,
IM_ALPHA_COLORKEY_MASK = 0x60000,
IM_SYNC = 1 << 19,
IM_ASYNC = 1 << 26,
IM_CROP = 1 << 20, /* Unused */
IM_COLOR_FILL = 1 << 21,
IM_COLOR_PALETTE = 1 << 22,
IM_NN_QUANTIZE = 1 << 23,
IM_ROP = 1 << 24,
IM_ALPHA_BLEND_PRE_MUL = 1 << 25,
} IM_USAGE;
typedef enum {
IM_ROP_AND = 0x88,
IM_ROP_OR = 0xee,
IM_ROP_NOT_DST = 0x55,
IM_ROP_NOT_SRC = 0x33,
IM_ROP_XOR = 0xf6,
IM_ROP_NOT_XOR = 0xf9,
} IM_ROP_CODE;
typedef enum {
IM_RGA_SUPPORT_FORMAT_ERROR_INDEX = 0,
IM_RGA_SUPPORT_FORMAT_RGB_INDEX,
IM_RGA_SUPPORT_FORMAT_RGB_OTHER_INDEX,
IM_RGA_SUPPORT_FORMAT_BPP_INDEX,
IM_RGA_SUPPORT_FORMAT_YUV_8_INDEX,
IM_RGA_SUPPORT_FORMAT_YUV_10_INDEX,
IM_RGA_SUPPORT_FORMAT_YUYV_420_INDEX,
IM_RGA_SUPPORT_FORMAT_YUYV_422_INDEX,
IM_RGA_SUPPORT_FORMAT_YUV_400_INDEX,
IM_RGA_SUPPORT_FORMAT_Y4_INDEX,
IM_RGA_SUPPORT_FORMAT_MASK_INDEX,
} IM_RGA_SUPPORT_FORMAT_INDEX;
typedef enum {
IM_RGA_SUPPORT_FORMAT_ERROR = 1 << IM_RGA_SUPPORT_FORMAT_ERROR_INDEX,
IM_RGA_SUPPORT_FORMAT_RGB = 1 << IM_RGA_SUPPORT_FORMAT_RGB_INDEX,
IM_RGA_SUPPORT_FORMAT_RGB_OTHER = 1 << IM_RGA_SUPPORT_FORMAT_RGB_OTHER_INDEX,
IM_RGA_SUPPORT_FORMAT_BPP = 1 << IM_RGA_SUPPORT_FORMAT_BPP_INDEX,
IM_RGA_SUPPORT_FORMAT_YUV_8 = 1 << IM_RGA_SUPPORT_FORMAT_YUV_8_INDEX,
IM_RGA_SUPPORT_FORMAT_YUV_10 = 1 << IM_RGA_SUPPORT_FORMAT_YUV_10_INDEX,
IM_RGA_SUPPORT_FORMAT_YUYV_420 = 1 << IM_RGA_SUPPORT_FORMAT_YUYV_420_INDEX,
IM_RGA_SUPPORT_FORMAT_YUYV_422 = 1 << IM_RGA_SUPPORT_FORMAT_YUYV_422_INDEX,
IM_RGA_SUPPORT_FORMAT_YUV_400 = 1 << IM_RGA_SUPPORT_FORMAT_YUV_400_INDEX,
IM_RGA_SUPPORT_FORMAT_Y4 = 1 << IM_RGA_SUPPORT_FORMAT_Y4_INDEX,
IM_RGA_SUPPORT_FORMAT_MASK = ~((~(unsigned int)0x0 << IM_RGA_SUPPORT_FORMAT_MASK_INDEX) | 1),
} IM_RGA_SUPPORT_FORMAT;
typedef enum {
IM_RGA_SUPPORT_FEATURE_ERROR_INDEX = 0,
IM_RGA_SUPPORT_FEATURE_COLOR_FILL_INDEX,
IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE_INDEX,
IM_RGA_SUPPORT_FEATURE_ROP_INDEX,
IM_RGA_SUPPORT_FEATURE_QUANTIZE_INDEX,
IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC_INDEX,
IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC_INDEX,
IM_RGA_SUPPORT_FEATURE_MASK_INDEX,
} IM_RGA_SUPPORT_FEATURE_INDEX;
typedef enum {
IM_RGA_SUPPORT_FEATURE_ERROR = 1 << IM_RGA_SUPPORT_FEATURE_ERROR_INDEX,
IM_RGA_SUPPORT_FEATURE_COLOR_FILL = 1 << IM_RGA_SUPPORT_FEATURE_COLOR_FILL_INDEX,
IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE = 1 << IM_RGA_SUPPORT_FEATURE_COLOR_PALETTE_INDEX,
IM_RGA_SUPPORT_FEATURE_ROP = 1 << IM_RGA_SUPPORT_FEATURE_ROP_INDEX,
IM_RGA_SUPPORT_FEATURE_QUANTIZE = 1 << IM_RGA_SUPPORT_FEATURE_QUANTIZE_INDEX,
IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC = 1 << IM_RGA_SUPPORT_FEATURE_SRC1_R2Y_CSC_INDEX,
IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC = 1 << IM_RGA_SUPPORT_FEATURE_DST_FULL_CSC_INDEX,
IM_RGA_SUPPORT_FEATURE_MASK = ~((~(unsigned int)0x0 << IM_RGA_SUPPORT_FEATURE_MASK_INDEX) | 1),
} IM_RGA_SUPPORT_FEATURE;
/* Status codes, returned by any blit function */
typedef enum {
IM_STATUS_NOERROR = 2,
IM_STATUS_SUCCESS = 1,
IM_STATUS_NOT_SUPPORTED = -1,
IM_STATUS_OUT_OF_MEMORY = -2,
IM_STATUS_INVALID_PARAM = -3,
IM_STATUS_ILLEGAL_PARAM = -4,
IM_STATUS_FAILED = 0,
} IM_STATUS;
/* Status codes, returned by any blit function */
typedef enum {
IM_YUV_TO_RGB_BT601_LIMIT = 1 << 0,
IM_YUV_TO_RGB_BT601_FULL = 2 << 0,
IM_YUV_TO_RGB_BT709_LIMIT = 3 << 0,
IM_YUV_TO_RGB_MASK = 3 << 0,
IM_RGB_TO_YUV_BT601_FULL = 1 << 2,
IM_RGB_TO_YUV_BT601_LIMIT = 2 << 2,
IM_RGB_TO_YUV_BT709_LIMIT = 3 << 2,
IM_RGB_TO_YUV_MASK = 3 << 2,
IM_RGB_TO_Y4 = 1 << 4,
IM_RGB_TO_Y4_DITHER = 2 << 4,
IM_RGB_TO_Y1_DITHER = 3 << 4,
IM_Y4_MASK = 3 << 4,
IM_RGB_FULL = 1 << 8,
IM_RGB_CLIP = 2 << 8,
IM_YUV_BT601_LIMIT_RANGE = 3 << 8,
IM_YUV_BT601_FULL_RANGE = 4 << 8,
IM_YUV_BT709_LIMIT_RANGE = 5 << 8,
IM_YUV_BT709_FULL_RANGE = 6 << 8,
IM_FULL_CSC_MASK = 0xf << 8,
IM_COLOR_SPACE_DEFAULT = 0,
} IM_COLOR_SPACE_MODE;
typedef enum {
IM_UP_SCALE,
IM_DOWN_SCALE,
} IM_SCALE;
typedef enum {
INTER_NEAREST,
INTER_LINEAR,
INTER_CUBIC,
} IM_SCALE_MODE;
/* Get RGA basic information index */
typedef enum {
RGA_VENDOR = 0,
RGA_VERSION,
RGA_MAX_INPUT,
RGA_MAX_OUTPUT,
RGA_SCALE_LIMIT,
RGA_INPUT_FORMAT,
RGA_OUTPUT_FORMAT,
RGA_FEATURE,
RGA_EXPECTED,
RGA_ALL,
} IM_INFORMATION;
/*rga version index*/
typedef enum {
RGA_V_ERR = 0x0,
RGA_1 = 0x1,
RGA_1_PLUS = 0x2,
RGA_2 = 0x3,
RGA_2_LITE0 = 0x4,
RGA_2_LITE1 = 0x5,
RGA_2_ENHANCE = 0x6,
} RGA_VERSION_NUM;
//struct AHardwareBuffer AHardwareBuffer;
typedef struct {
RGA_VERSION_NUM version;
unsigned int input_resolution;
unsigned int output_resolution;
unsigned int scale_limit;
unsigned int performance;
unsigned int input_format;
unsigned int output_format;
unsigned int feature;
char reserved[28];
} rga_info_table_entry;
/* Rectangle definition */
typedef struct {
int x; /* upper-left x */
int y; /* upper-left y */
int width; /* width */
int height; /* height */
} im_rect;
typedef struct {
int max; /* The Maximum value of the color key */
int min; /* The minimum value of the color key */
} im_colorkey_range;
typedef struct im_nn {
int scale_r; /* scaling factor on R channal */
int scale_g; /* scaling factor on G channal */
int scale_b; /* scaling factor on B channal */
int offset_r; /* offset on R channal */
int offset_g; /* offset on G channal */
int offset_b; /* offset on B channal */
} im_nn_t;
/* im_info definition */
typedef struct {
void* vir_addr; /* virtual address */
void* phy_addr; /* physical address */
int fd; /* shared fd */
int width; /* width */
int height; /* height */
int wstride; /* wstride */
int hstride; /* hstride */
int format; /* format */
int color_space_mode; /* color_space_mode */
int color; /* color, used by color fill */
int global_alpha; /* global_alpha */
im_colorkey_range colorkey_range; /* range value of color key */
im_nn_t nn;
int rop_code;
} rga_buffer_t;
/*
* @return error message string
*/
#define imStrError(...) \
({ \
const char* err; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
err = imStrError_t(IM_STATUS_INVALID_PARAM); \
} else if (argc == 1){ \
err = imStrError_t((IM_STATUS)args[0]); \
} else { \
err = ("Fatal error, imStrError() too many parameters\n"); \
printf("Fatal error, imStrError() too many parameters\n"); \
} \
err; \
})
IM_API const char* imStrError_t(IM_STATUS status);
/*
* @return rga_buffer_t
*/
#define wrapbuffer_virtualaddr(vir_addr, width, height, format, ...) \
({ \
rga_buffer_t buffer; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, width, height, format); \
} else if (argc == 2){ \
buffer = wrapbuffer_virtualaddr_t(vir_addr, width, height, args[0], args[1], format); \
} else { \
printf("invalid parameter\n"); \
} \
buffer; \
})
#define wrapbuffer_physicaladdr(phy_addr, width, height, format, ...) \
({ \
rga_buffer_t buffer; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, width, height, format); \
} else if (argc == 2){ \
buffer = wrapbuffer_physicaladdr_t(phy_addr, width, height, args[0], args[1], format); \
} else { \
printf("invalid parameter\n"); \
} \
buffer; \
})
#define wrapbuffer_fd(fd, width, height, format, ...) \
({ \
rga_buffer_t buffer; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
buffer = wrapbuffer_fd_t(fd, width, height, width, height, format); \
} else if (argc == 2){ \
buffer = wrapbuffer_fd_t(fd, width, height, args[0], args[1], format); \
} else { \
printf("invalid parameter\n"); \
} \
buffer; \
})
IM_API rga_buffer_t wrapbuffer_virtualaddr_t(void* vir_addr, int width, int height, int wstride, int hstride, int format);
IM_API rga_buffer_t wrapbuffer_physicaladdr_t(void* phy_addr, int width, int height, int wstride, int hstride, int format);
IM_API rga_buffer_t wrapbuffer_fd_t(int fd, int width, int height, int wstride, int hstride, int format);
/*
* Get RGA basic information, supported resolution, supported format, etc.
*
* @param name
* RGA_VENDOR
* RGA_VERSION
* RGA_MAX_INPUT
* RGA_MAX_OUTPUT
* RGA_INPUT_FORMAT
* RGA_OUTPUT_FORMAT
* RGA_EXPECTED
* RGA_ALL
*
* @returns a usage describing properties of RGA.
*/
//IM_API int rga_get_info(rga_info_table_entry *);
IM_API IM_STATUS rga_get_info(rga_info_table_entry *return_table);
/*
* Query RGA basic information, supported resolution, supported format, etc.
*
* @param name
* RGA_VENDOR
* RGA_VERSION
* RGA_MAX_INPUT
* RGA_MAX_OUTPUT
* RGA_INPUT_FORMAT
* RGA_OUTPUT_FORMAT
* RGA_EXPECTED
* RGA_ALL
*
* @returns a string describing properties of RGA.
*/
IM_API const char* querystring(int name);
/*
* check RGA basic information, supported resolution, supported format, etc.
*
* @param src
* @param dst
* @param src_rect
* @param dst_rect
* @param mode_usage
*
* @returns no error or else negative error code.
*/
#define imcheck(src, dst, src_rect, dst_rect, ...) \
({ \
IM_STATUS ret = IM_STATUS_NOERROR; \
rga_buffer_t pat; \
im_rect pat_rect; \
memset(&pat, 0, sizeof(rga_buffer_t)); \
memset(&pat_rect, 0, sizeof(im_rect)); \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0); \
} else if (argc == 1){ \
ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, args[0]); \
} else { \
ret = IM_STATUS_FAILED; \
printf("check failed\n"); \
} \
ret; \
})
#define imcheck_composite(src, dst, pat, src_rect, dst_rect, pat_rect, ...) \
({ \
IM_STATUS ret = IM_STATUS_NOERROR; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, 0); \
} else if (argc == 1){ \
ret = imcheck_t(src, dst, pat, src_rect, dst_rect, pat_rect, args[0]); \
} else { \
ret = IM_STATUS_FAILED; \
printf("check failed\n"); \
} \
ret; \
})
IM_API IM_STATUS imcheck_t(const rga_buffer_t src, const rga_buffer_t dst, const rga_buffer_t pat,
const im_rect src_rect, const im_rect dst_rect, const im_rect pat_rect, const int mdoe_usage);
/*
* Resize
*
* @param src
* @param dst
* @param fx
* @param fy
* @param interpolation
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imresize(src, dst, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
double args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(double); \
if (argc == 0) { \
ret = imresize_t(src, dst, 0, 0, INTER_LINEAR, 1); \
} else if (argc == 2){ \
ret = imresize_t(src, dst, args[0], args[1], INTER_LINEAR, 1); \
} else if (argc == 3){ \
ret = imresize_t(src, dst, args[0], args[1], (int)args[2], 1); \
} else if (argc == 4){ \
ret = imresize_t(src, dst, args[0], args[1], (int)args[2], (int)args[3]); \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
#define impyramid(src, dst, direction) \
imresize_t(src, \
dst, \
direction == IM_UP_SCALE ? 0.5 : 2, \
direction == IM_UP_SCALE ? 0.5 : 2, \
INTER_LINEAR, 1)
IM_API IM_STATUS imresize_t(const rga_buffer_t src, rga_buffer_t dst, double fx, double fy, int interpolation, int sync);
/*
* Crop
*
* @param src
* @param dst
* @param rect
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imcrop(src, dst, rect, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imcrop_t(src, dst, rect, 1); \
} else if (argc == 1){ \
ret = imcrop_t(src, dst, rect, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imcrop_t(const rga_buffer_t src, rga_buffer_t dst, im_rect rect, int sync);
/*
* rotation
*
* @param src
* @param dst
* @param rotation
* IM_HAL_TRANSFORM_ROT_90
* IM_HAL_TRANSFORM_ROT_180
* IM_HAL_TRANSFORM_ROT_270
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imrotate(src, dst, rotation, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imrotate_t(src, dst, rotation, 1); \
} else if (argc == 1){ \
ret = imrotate_t(src, dst, rotation, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imrotate_t(const rga_buffer_t src, rga_buffer_t dst, int rotation, int sync);
/*
* flip
*
* @param src
* @param dst
* @param mode
* IM_HAL_TRANSFORM_FLIP_H
* IM_HAL_TRANSFORM_FLIP_V
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imflip(src, dst, mode, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imflip_t(src, dst, mode, 1); \
} else if (argc == 1){ \
ret = imflip_t(src, dst, mode, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imflip_t (const rga_buffer_t src, rga_buffer_t dst, int mode, int sync);
/*
* fill/reset/draw
*
* @param src
* @param dst
* @param rect
* @param color
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imfill(buf, rect, color, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imfill_t(buf, rect, color, 1); \
} else if (argc == 1){ \
ret = imfill_t(buf, rect, color, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
#define imreset(buf, rect, color, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imfill_t(buf, rect, color, 1); \
} else if (argc == 1){ \
ret = imfill_t(buf, rect, color, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
#define imdraw(buf, rect, color, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imfill_t(buf, rect, color, 1); \
} else if (argc == 1){ \
ret = imfill_t(buf, rect, color, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imfill_t(rga_buffer_t dst, im_rect rect, int color, int sync);
/*
* palette
*
* @param src
* @param dst
* @param lut
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define impalette(src, dst, lut, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = impalette_t(src, dst, lut, 1); \
} else if (argc == 1){ \
ret = impalette_t(src, dst, lut, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS impalette_t(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t lut, int sync);
/*
* translate
*
* @param src
* @param dst
* @param x
* @param y
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imtranslate(src, dst, x, y, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imtranslate_t(src, dst, x, y, 1); \
} else if (argc == 1){ \
ret = imtranslate_t(src, dst, x, y, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imtranslate_t(const rga_buffer_t src, rga_buffer_t dst, int x, int y, int sync);
/*
* copy
*
* @param src
* @param dst
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imcopy(src, dst, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imcopy_t(src, dst, 1); \
} else if (argc == 1){ \
ret = imcopy_t(src, dst, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imcopy_t(const rga_buffer_t src, rga_buffer_t dst, int sync);
/*
* blend (SRC + DST -> DST or SRCA + SRCB -> DST)
*
* @param srcA
* @param srcB can be NULL.
* @param dst
* @param mode
* IM_ALPHA_BLEND_MODE
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imblend(srcA, dst, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
rga_buffer_t srcB; \
memset(&srcB, 0x00, sizeof(rga_buffer_t)); \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \
} else if (argc == 1){ \
ret = imblend_t(srcA, srcB, dst, args[0], 1); \
} else if (argc == 2){ \
ret = imblend_t(srcA, srcB, dst, args[0], args[1]); \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
#define imcomposite(srcA, srcB, dst, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imblend_t(srcA, srcB, dst, IM_ALPHA_BLEND_SRC_OVER, 1); \
} else if (argc == 1){ \
ret = imblend_t(srcA, srcB, dst, args[0], 1); \
} else if (argc == 2){ \
ret = imblend_t(srcA, srcB, dst, args[0], args[1]); \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imblend_t(const rga_buffer_t srcA, const rga_buffer_t srcB, rga_buffer_t dst, int mode, int sync);
/*
* color key
*
* @param src
* @param dst
* @param colorkey_range
* max color
* min color
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imcolorkey(src, dst, range, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imcolorkey_t(src, dst, range, IM_ALPHA_COLORKEY_NORMAL, 1); \
} else if (argc == 1){ \
ret = imcolorkey_t(src, dst, range, args[0], 1); \
} else if (argc == 2){ \
ret = imcolorkey_t(src, dst, range, args[0], args[1]); \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imcolorkey_t(const rga_buffer_t src, rga_buffer_t dst, im_colorkey_range range, int mode, int sync);
/*
* format convert
*
* @param src
* @param dst
* @param sfmt
* @param dfmt
* @param mode
* color space mode: IM_COLOR_SPACE_MODE
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imcvtcolor(src, dst, sfmt, dfmt, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imcvtcolor_t(src, dst, sfmt, dfmt, IM_COLOR_SPACE_DEFAULT, 1); \
} else if (argc == 1){ \
ret = imcvtcolor_t(src, dst, sfmt, dfmt, args[0], 1); \
} else if (argc == 2){ \
ret = imcvtcolor_t(src, dst, sfmt, dfmt, args[0], args[1]); \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imcvtcolor_t(rga_buffer_t src, rga_buffer_t dst, int sfmt, int dfmt, int mode, int sync);
/*
* nn quantize
*
* @param src
* @param dst
* @param nninfo
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imquantize(src, dst, nn_info, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imquantize_t(src, dst, nn_info, 1); \
} else if (argc == 1){ \
ret = imquantize_t(src, dst, nn_info, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imquantize_t(const rga_buffer_t src, rga_buffer_t dst, im_nn_t nn_info, int sync);
/*
* ROP
*
* @param src
* @param dst
* @param rop_code
* @param sync
* wait until operation complete
*
* @returns success or else negative error code.
*/
#define imrop(src, dst, rop_code, ...) \
({ \
IM_STATUS ret = IM_STATUS_SUCCESS; \
int args[] = {__VA_ARGS__}; \
int argc = sizeof(args)/sizeof(int); \
if (argc == 0) { \
ret = imrop_t(src, dst, rop_code, 1); \
} else if (argc == 1){ \
ret = imrop_t(src, dst, rop_code, args[0]);; \
} else { \
ret = IM_STATUS_INVALID_PARAM; \
printf("invalid parameter\n"); \
} \
ret; \
})
IM_API IM_STATUS imrop_t(const rga_buffer_t src, rga_buffer_t dst, int rop_code, int sync);
/*
* process
*
* @param src
* @param dst
* @param usage
* @param ...
* wait until operation complete
*
* @returns success or else negative error code.
*/
IM_API IM_STATUS improcess(rga_buffer_t src, rga_buffer_t dst, rga_buffer_t pat, im_rect srect, im_rect drect, im_rect prect, int usage);
/*
* block until all execution is complete
*
* @returns success or else negative error code.
*/
IM_API IM_STATUS imsync(void);
#ifdef __cplusplus
}
#endif
#endif /* _im2d_h_ */
+121
View File
@@ -0,0 +1,121 @@
/*
* Copyright (C) 2017-2018 RockChip Limited. All rights reserved.
*
* 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.
*/
/* --------------------------------------------------------------------------------------------------------
* File: platform_gralloc4.h
*
* Desc: 声明对 buffer_handle_t 实例的 get metadata, import_buffer/free_buffer, lock_buffer/unlock_buffer 等接口.
* 这些接口都将基于 IMapper 4.0 (gralloc 4.0) 实现.
*
* -----------------------------------------------------------------------------------
* < 习语 和 缩略语 > :
*
* -----------------------------------------------------------------------------------
* Usage:
*
* Note:
*
* Author: ChenZhen
*
* Log:
* init.
----Fri Aug 28 10:10:14 2020
*
* --------------------------------------------------------------------------------------------------------
*/
#ifndef __PLATFORM_GRALLOC4_H__
#define __PLATFORM_GRALLOC4_H__
/* ---------------------------------------------------------------------------------------------------------
* Include Files
* ---------------------------------------------------------------------------------------------------------
*/
// #include <linux/kernel.h>
#include <stdint.h>
#include <cutils/native_handle.h>
#include <utils/Errors.h>
#include <ui/PixelFormat.h>
/* ---------------------------------------------------------------------------------------------------------
* Macros Definition
* ---------------------------------------------------------------------------------------------------------
*/
namespace gralloc4 {
/* ---------------------------------------------------------------------------------------------------------
* Types and Structures Definition
* ---------------------------------------------------------------------------------------------------------
*/
/* ---------------------------------------------------------------------------------------------------------
* Global Functions' Prototype
* ---------------------------------------------------------------------------------------------------------
*/
/*
* 获取 'handle' 引用的 graphic_buffer 的 internal_format.
*/
uint64_t get_internal_format(buffer_handle_t handle);
int get_width(buffer_handle_t handle, uint64_t* width);
int get_height(buffer_handle_t handle, uint64_t* height);
int get_pixel_stride(buffer_handle_t handle, int* pixel_stride);
int get_byte_stride(buffer_handle_t handle, int* byte_stride);
int get_format_requested(buffer_handle_t handle, int* format_requested);
int get_usage(buffer_handle_t handle, uint64_t* usage);
int get_allocation_size(buffer_handle_t handle, uint64_t* usage);
int get_share_fd(buffer_handle_t handle, int* share_fd);
using android::status_t;
status_t importBuffer(buffer_handle_t rawHandle, buffer_handle_t* outHandle);
void freeBuffer(buffer_handle_t handle);
status_t lock(buffer_handle_t bufferHandle,
uint64_t usage,
int x,
int y,
int w,
int h,
void** outData);
void unlock(buffer_handle_t bufferHandle);
/* ---------------------------------------------------------------------------------------------------------
* Inline Functions Implementation
* ---------------------------------------------------------------------------------------------------------
*/
}
#endif /* __PLATFORM_GRALLOC4_H__ */
+795
View File
@@ -0,0 +1,795 @@
/*
* Copyright (C) 2016 Rockchip Electronics Co., Ltd.
* Authors:
* Zhiqin Wei <wzq@rock-chips.com>
*
* 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 _RGA_DRIVER_H_
#define _RGA_DRIVER_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#define RGA_BLIT_SYNC 0x5017
#define RGA_BLIT_ASYNC 0x5018
#define RGA_FLUSH 0x5019
#define RGA_GET_RESULT 0x501a
#define RGA_GET_VERSION 0x501b
#define RGA2_BLIT_SYNC 0x6017
#define RGA2_BLIT_ASYNC 0x6018
#define RGA2_FLUSH 0x6019
#define RGA2_GET_RESULT 0x601a
#define RGA2_GET_VERSION 0x601b
#define RGA2_GET_VERSION 0x601b
#define RGA_REG_CTRL_LEN 0x8 /* 8 */
#define RGA_REG_CMD_LEN 0x1c /* 28 */
#define RGA_CMD_BUF_SIZE 0x700 /* 16*28*4 */
#ifndef ENABLE
#define ENABLE 1
#endif
#ifndef DISABLE
#define DISABLE 0
#endif
/* RGA process mode enum */
enum {
bitblt_mode = 0x0,
color_palette_mode = 0x1,
color_fill_mode = 0x2,
line_point_drawing_mode = 0x3,
blur_sharp_filter_mode = 0x4,
pre_scaling_mode = 0x5,
update_palette_table_mode = 0x6,
update_patten_buff_mode = 0x7,
};
enum {
rop_enable_mask = 0x2,
dither_enable_mask = 0x8,
fading_enable_mask = 0x10,
PD_enbale_mask = 0x20,
};
enum {
yuv2rgb_mode0 = 0x0, /* BT.601 MPEG */
yuv2rgb_mode1 = 0x1, /* BT.601 JPEG */
yuv2rgb_mode2 = 0x2, /* BT.709 */
rgb2yuv_601_full = 0x1 << 8,
rgb2yuv_709_full = 0x2 << 8,
yuv2yuv_601_limit_2_709_limit = 0x3 << 8,
yuv2yuv_601_limit_2_709_full = 0x4 << 8,
yuv2yuv_709_limit_2_601_limit = 0x5 << 8,
yuv2yuv_709_limit_2_601_full = 0x6 << 8, //not support
yuv2yuv_601_full_2_709_limit = 0x7 << 8,
yuv2yuv_601_full_2_709_full = 0x8 << 8, //not support
yuv2yuv_709_full_2_601_limit = 0x9 << 8, //not support
yuv2yuv_709_full_2_601_full = 0xa << 8, //not support
full_csc_mask = 0xf00,
};
/* RGA rotate mode */
enum {
rotate_mode0 = 0x0, /* no rotate */
rotate_mode1 = 0x1, /* rotate */
rotate_mode2 = 0x2, /* x_mirror */
rotate_mode3 = 0x3, /* y_mirror */
};
enum {
color_palette_mode0 = 0x0, /* 1K */
color_palette_mode1 = 0x1, /* 2K */
color_palette_mode2 = 0x2, /* 4K */
color_palette_mode3 = 0x3, /* 8K */
};
enum {
BB_BYPASS = 0x0, /* no rotate */
BB_ROTATE = 0x1, /* rotate */
BB_X_MIRROR = 0x2, /* x_mirror */
BB_Y_MIRROR = 0x3 /* y_mirror */
};
enum {
nearby = 0x0, /* no rotate */
bilinear = 0x1, /* rotate */
bicubic = 0x2, /* x_mirror */
};
/*
// Alpha Red Green Blue
{ 4, 32, {{32,24, 8, 0, 16, 8, 24,16 }}, GGL_RGBA }, // RK_FORMAT_RGBA_8888
{ 4, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGBX_8888
{ 3, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGB_888
{ 4, 32, {{32,24, 24,16, 16, 8, 8, 0 }}, GGL_BGRA }, // RK_FORMAT_BGRA_8888
{ 2, 16, {{ 0, 0, 16,11, 11, 5, 5, 0 }}, GGL_RGB }, // RK_FORMAT_RGB_565
{ 2, 16, {{ 1, 0, 16,11, 11, 6, 6, 1 }}, GGL_RGBA }, // RK_FORMAT_RGBA_5551
{ 2, 16, {{ 4, 0, 16,12, 12, 8, 8, 4 }}, GGL_RGBA }, // RK_FORMAT_RGBA_4444
{ 3, 24, {{ 0, 0, 24,16, 16, 8, 8, 0 }}, GGL_BGR }, // RK_FORMAT_BGB_888
*/
/* In order to be compatible with RK_FORMAT_XX and HAL_PIXEL_FORMAT_XX,
* RK_FORMAT_XX is shifted to the left by 8 bits to distinguish. */
typedef enum _Rga_SURF_FORMAT {
RK_FORMAT_RGBA_8888 = 0x0 << 8,
RK_FORMAT_RGBX_8888 = 0x1 << 8,
RK_FORMAT_RGB_888 = 0x2 << 8,
RK_FORMAT_BGRA_8888 = 0x3 << 8,
RK_FORMAT_RGB_565 = 0x4 << 8,
RK_FORMAT_RGBA_5551 = 0x5 << 8,
RK_FORMAT_RGBA_4444 = 0x6 << 8,
RK_FORMAT_BGR_888 = 0x7 << 8,
RK_FORMAT_YCbCr_422_SP = 0x8 << 8,
RK_FORMAT_YCbCr_422_P = 0x9 << 8,
RK_FORMAT_YCbCr_420_SP = 0xa << 8,
RK_FORMAT_YCbCr_420_P = 0xb << 8,
RK_FORMAT_YCrCb_422_SP = 0xc << 8,
RK_FORMAT_YCrCb_422_P = 0xd << 8,
RK_FORMAT_YCrCb_420_SP = 0xe << 8,
RK_FORMAT_YCrCb_420_P = 0xf << 8,
RK_FORMAT_BPP1 = 0x10 << 8,
RK_FORMAT_BPP2 = 0x11 << 8,
RK_FORMAT_BPP4 = 0x12 << 8,
RK_FORMAT_BPP8 = 0x13 << 8,
RK_FORMAT_Y4 = 0x14 << 8,
RK_FORMAT_YCbCr_400 = 0x15 << 8,
RK_FORMAT_BGRX_8888 = 0x16 << 8,
RK_FORMAT_YVYU_422 = 0x18 << 8,
RK_FORMAT_YVYU_420 = 0x19 << 8,
RK_FORMAT_VYUY_422 = 0x1a << 8,
RK_FORMAT_VYUY_420 = 0x1b << 8,
RK_FORMAT_YUYV_422 = 0x1c << 8,
RK_FORMAT_YUYV_420 = 0x1d << 8,
RK_FORMAT_UYVY_422 = 0x1e << 8,
RK_FORMAT_UYVY_420 = 0x1f << 8,
RK_FORMAT_YCbCr_420_SP_10B = 0x20 << 8,
RK_FORMAT_YCrCb_420_SP_10B = 0x21 << 8,
RK_FORMAT_YCbCr_422_10b_SP = 0x22 << 8,
RK_FORMAT_YCrCb_422_10b_SP = 0x23 << 8,
RK_FORMAT_BGR_565 = 0x24 << 8,
RK_FORMAT_BGRA_5551 = 0x25 << 8,
RK_FORMAT_BGRA_4444 = 0x26 << 8,
RK_FORMAT_UNKNOWN = 0x100 << 8,
} RgaSURF_FORMAT;
typedef struct rga_img_info_t {
#if defined(__arm64__) || defined(__aarch64__)
unsigned long yrgb_addr; /* yrgb mem addr */
unsigned long uv_addr; /* cb/cr mem addr */
unsigned long v_addr; /* cr mem addr */
#else
unsigned int yrgb_addr; /* yrgb mem addr */
unsigned int uv_addr; /* cb/cr mem addr */
unsigned int v_addr; /* cr mem addr */
#endif
unsigned int format; //definition by RK_FORMAT
unsigned short act_w;
unsigned short act_h;
unsigned short x_offset;
unsigned short y_offset;
unsigned short vir_w;
unsigned short vir_h;
unsigned short endian_mode; //for BPP
unsigned short alpha_swap;
}
rga_img_info_t;
typedef struct mdp_img_act {
unsigned short w; // width
unsigned short h; // height
short x_off; // x offset for the vir
short y_off; // y offset for the vir
}
mdp_img_act;
typedef struct RANGE {
unsigned short min;
unsigned short max;
}
RANGE;
typedef struct POINT {
unsigned short x;
unsigned short y;
}
POINT;
typedef struct RECT {
unsigned short xmin;
unsigned short xmax; // width - 1
unsigned short ymin;
unsigned short ymax; // height - 1
} RECT;
typedef struct RGB {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char res;
}RGB;
typedef struct MMU {
unsigned char mmu_en;
#if defined(__arm64__) || defined(__aarch64__)
unsigned long base_addr;
#else
unsigned int base_addr;
#endif
unsigned int mmu_flag; /* [0] mmu enable [1] src_flush [2] dst_flush [3] CMD_flush [4~5] page size*/
} MMU;
typedef struct COLOR_FILL {
short gr_x_a;
short gr_y_a;
short gr_x_b;
short gr_y_b;
short gr_x_g;
short gr_y_g;
short gr_x_r;
short gr_y_r;
//u8 cp_gr_saturation;
}
COLOR_FILL;
typedef struct FADING {
unsigned char b;
unsigned char g;
unsigned char r;
unsigned char res;
}
FADING;
typedef struct line_draw_t {
POINT start_point; /* LineDraw_start_point */
POINT end_point; /* LineDraw_end_point */
unsigned int color; /* LineDraw_color */
unsigned int flag; /* (enum) LineDrawing mode sel */
unsigned int line_width; /* range 1~16 */
}
line_draw_t;
/* color space convert coefficient. */
typedef struct csc_coe_t {
int16_t r_v;
int16_t g_y;
int16_t b_u;
int32_t off;
} csc_coe_t;
typedef struct full_csc_t {
unsigned char flag;
csc_coe_t coe_y;
csc_coe_t coe_u;
csc_coe_t coe_v;
} full_csc_t;
struct rga_req {
unsigned char render_mode; /* (enum) process mode sel */
rga_img_info_t src; /* src image info */
rga_img_info_t dst; /* dst image info */
rga_img_info_t pat; /* patten image info */
#if defined(__arm64__) || defined(__aarch64__)
unsigned long rop_mask_addr; /* rop4 mask addr */
unsigned long LUT_addr; /* LUT addr */
#else
unsigned int rop_mask_addr; /* rop4 mask addr */
unsigned int LUT_addr; /* LUT addr */
#endif
RECT clip; /* dst clip window default value is dst_vir */
/* value from [0, w-1] / [0, h-1]*/
int sina; /* dst angle default value 0 16.16 scan from table */
int cosa; /* dst angle default value 0 16.16 scan from table */
unsigned short alpha_rop_flag; /* alpha rop process flag */
/* ([0] = 1 alpha_rop_enable) */
/* ([1] = 1 rop enable) */
/* ([2] = 1 fading_enable) */
/* ([3] = 1 PD_enable) */
/* ([4] = 1 alpha cal_mode_sel) */
/* ([5] = 1 dither_enable) */
/* ([6] = 1 gradient fill mode sel) */
/* ([7] = 1 AA_enable) */
/* ([8] = 1 nn_quantize) */
/* ([9] = 1 Real color mode) */
unsigned char scale_mode; /* 0 nearst / 1 bilnear / 2 bicubic */
unsigned int color_key_max; /* color key max */
unsigned int color_key_min; /* color key min */
unsigned int fg_color; /* foreground color */
unsigned int bg_color; /* background color */
COLOR_FILL gr_color; /* color fill use gradient */
line_draw_t line_draw_info;
FADING fading;
unsigned char PD_mode; /* porter duff alpha mode sel */
unsigned char alpha_global_value; /* global alpha value */
unsigned short rop_code; /* rop2/3/4 code scan from rop code table*/
unsigned char bsfilter_flag; /* [2] 0 blur 1 sharp / [1:0] filter_type*/
unsigned char palette_mode; /* (enum) color palatte 0/1bpp, 1/2bpp 2/4bpp 3/8bpp*/
unsigned char yuv2rgb_mode; /* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */
unsigned char endian_mode; /* 0/big endian 1/little endian*/
unsigned char rotate_mode; /* (enum) rotate mode */
/* 0x0, no rotate */
/* 0x1, rotate */
/* 0x2, x_mirror */
/* 0x3, y_mirror */
unsigned char color_fill_mode; /* 0 solid color / 1 patten color */
MMU mmu_info; /* mmu information */
unsigned char alpha_rop_mode; /* ([0~1] alpha mode) */
/* ([2~3] rop mode) */
/* ([4] zero mode en) */
/* ([5] dst alpha mode) (RGA1) */
unsigned char src_trans_mode;
unsigned char dither_mode;
full_csc_t full_csc; /* full color space convert */
unsigned char CMD_fin_int_enable;
/* completion is reported through a callback */
void (*complete)(int retval);
};
#if 0
typedef struct TILE_INFO {
int64_t matrix[4];
uint16_t tile_x_num; /* x axis tile num / tile size is 8x8 pixel */
uint16_t tile_y_num; /* y axis tile num */
int16_t dst_x_tmp; /* dst pos x = (xstart - xoff) default value 0 */
int16_t dst_y_tmp; /* dst pos y = (ystart - yoff) default value 0 */
uint16_t tile_w;
uint16_t tile_h;
int16_t tile_start_x_coor;
int16_t tile_start_y_coor;
int32_t tile_xoff;
int32_t tile_yoff;
int32_t tile_temp_xstart;
int32_t tile_temp_ystart;
/* src tile incr */
int32_t x_dx;
int32_t x_dy;
int32_t y_dx;
int32_t y_dy;
mdp_img_act dst_ctrl;
}
TILE_INFO;
#endif
#if 0
#define RGA_BASE 0x10114000
//General Registers
#define RGA_SYS_CTRL 0x000
#define RGA_CMD_CTRL 0x004
#define RGA_CMD_ADDR 0x008
#define RGA_STATUS 0x00c
#define RGA_INT 0x010
#define RGA_AXI_ID 0x014
#define RGA_MMU_STA_CTRL 0x018
#define RGA_MMU_STA 0x01c
//Command code start
#define RGA_MODE_CTRL 0x100
//Source Image Registers
#define RGA_SRC_Y_MST 0x104
#define RGA_SRC_CB_MST 0x108
#define RGA_MASK_READ_MST 0x108 //repeat
#define RGA_SRC_CR_MST 0x10c
#define RGA_SRC_VIR_INFO 0x110
#define RGA_SRC_ACT_INFO 0x114
#define RGA_SRC_X_PARA 0x118
#define RGA_SRC_Y_PARA 0x11c
#define RGA_SRC_TILE_XINFO 0x120
#define RGA_SRC_TILE_YINFO 0x124
#define RGA_SRC_TILE_H_INCR 0x128
#define RGA_SRC_TILE_V_INCR 0x12c
#define RGA_SRC_TILE_OFFSETX 0x130
#define RGA_SRC_TILE_OFFSETY 0x134
#define RGA_SRC_BG_COLOR 0x138
#define RGA_SRC_FG_COLOR 0x13c
#define RGA_LINE_DRAWING_COLOR 0x13c //repeat
#define RGA_SRC_TR_COLOR0 0x140
#define RGA_CP_GR_A 0x140 //repeat
#define RGA_SRC_TR_COLOR1 0x144
#define RGA_CP_GR_B 0x144 //repeat
#define RGA_LINE_DRAW 0x148
#define RGA_PAT_START_POINT 0x148 //repeat
//Destination Image Registers
#define RGA_DST_MST 0x14c
#define RGA_LUT_MST 0x14c //repeat
#define RGA_PAT_MST 0x14c //repeat
#define RGA_LINE_DRAWING_MST 0x14c //repeat
#define RGA_DST_VIR_INFO 0x150
#define RGA_DST_CTR_INFO 0x154
#define RGA_LINE_DRAW_XY_INFO 0x154 //repeat
//Alpha/ROP Registers
#define RGA_ALPHA_CON 0x158
#define RGA_PAT_CON 0x15c
#define RGA_DST_VIR_WIDTH_PIX 0x15c //repeat
#define RGA_ROP_CON0 0x160
#define RGA_CP_GR_G 0x160 //repeat
#define RGA_PRESCL_CB_MST 0x160 //repeat
#define RGA_ROP_CON1 0x164
#define RGA_CP_GR_R 0x164 //repeat
#define RGA_PRESCL_CR_MST 0x164 //repeat
//MMU Register
#define RGA_FADING_CON 0x168
#define RGA_MMU_CTRL 0x168 //repeat
#define RGA_MMU_TBL 0x16c //repeat
#define RGA_BLIT_COMPLETE_EVENT 1
#endif
int
RGA_set_src_act_info(
struct rga_req *req,
unsigned int width, /* act width */
unsigned int height, /* act height */
unsigned int x_off, /* x_off */
unsigned int y_off /* y_off */
);
#if defined(__arm64__) || defined(__aarch64__)
int
RGA_set_src_vir_info(
struct rga_req *req,
unsigned long yrgb_addr, /* yrgb_addr */
unsigned long uv_addr, /* uv_addr */
unsigned long v_addr, /* v_addr */
unsigned int vir_w, /* vir width */
unsigned int vir_h, /* vir height */
unsigned char format, /* format */
unsigned char a_swap_en /* only for 32bit RGB888 format */
);
#else
int
RGA_set_src_vir_info(
struct rga_req *req,
unsigned int yrgb_addr, /* yrgb_addr */
unsigned int uv_addr, /* uv_addr */
unsigned int v_addr, /* v_addr */
unsigned int vir_w, /* vir width */
unsigned int vir_h, /* vir height */
unsigned char format, /* format */
unsigned char a_swap_en /* only for 32bit RGB888 format */
);
#endif
int
RGA_set_dst_act_info(
struct rga_req *req,
unsigned int width, /* act width */
unsigned int height, /* act height */
unsigned int x_off, /* x_off */
unsigned int y_off /* y_off */
);
#if defined(__arm64__) || defined(__aarch64__)
int
RGA_set_dst_vir_info(
struct rga_req *msg,
unsigned long yrgb_addr, /* yrgb_addr */
unsigned long uv_addr, /* uv_addr */
unsigned long v_addr, /* v_addr */
unsigned int vir_w, /* vir width */
unsigned int vir_h, /* vir height */
RECT *clip, /* clip window */
unsigned char format, /* format */
unsigned char a_swap_en
);
#else
int
RGA_set_dst_vir_info(
struct rga_req *msg,
unsigned int yrgb_addr, /* yrgb_addr */
unsigned int uv_addr, /* uv_addr */
unsigned int v_addr, /* v_addr */
unsigned int vir_w, /* vir width */
unsigned int vir_h, /* vir height */
RECT *clip, /* clip window */
unsigned char format, /* format */
unsigned char a_swap_en
);
#endif
int
RGA_set_pat_info(
struct rga_req *msg,
unsigned int width,
unsigned int height,
unsigned int x_off,
unsigned int y_off,
unsigned int pat_format
);
#if defined(__arm64__) || defined(__aarch64__)
int
RGA_set_rop_mask_info(
struct rga_req *msg,
unsigned long rop_mask_addr,
unsigned int rop_mask_endian_mode
);
#else
int
RGA_set_rop_mask_info(
struct rga_req *msg,
unsigned int rop_mask_addr,
unsigned int rop_mask_endian_mode
);
#endif
int RGA_set_alpha_en_info(
struct rga_req *msg,
unsigned int alpha_cal_mode, /* 0:alpha' = alpha + (alpha>>7) | alpha' = alpha */
unsigned int alpha_mode, /* 0 global alpha / 1 per pixel alpha / 2 mix mode */
unsigned int global_a_value,
unsigned int PD_en, /* porter duff alpha mode en */
unsigned int PD_mode,
unsigned int dst_alpha_en ); /* use dst alpha */
int
RGA_set_rop_en_info(
struct rga_req *msg,
unsigned int ROP_mode,
unsigned int ROP_code,
unsigned int color_mode,
unsigned int solid_color
);
int
RGA_set_fading_en_info(
struct rga_req *msg,
unsigned char r,
unsigned char g,
unsigned char b
);
int
RGA_set_src_trans_mode_info(
struct rga_req *msg,
unsigned char trans_mode,
unsigned char a_en,
unsigned char b_en,
unsigned char g_en,
unsigned char r_en,
unsigned char color_key_min,
unsigned char color_key_max,
unsigned char zero_mode_en
);
int
RGA_set_bitblt_mode(
struct rga_req *msg,
unsigned char scale_mode, // 0/near 1/bilnear 2/bicubic
unsigned char rotate_mode, // 0/copy 1/rotate_scale 2/x_mirror 3/y_mirror
unsigned int angle, // rotate angle
unsigned int dither_en, // dither en flag
unsigned int AA_en, // AA flag
unsigned int yuv2rgb_mode
);
int
RGA_set_color_palette_mode(
struct rga_req *msg,
unsigned char palette_mode, /* 1bpp/2bpp/4bpp/8bpp */
unsigned char endian_mode, /* src endian mode sel */
unsigned int bpp1_0_color, /* BPP1 = 0 */
unsigned int bpp1_1_color /* BPP1 = 1 */
);
int
RGA_set_color_fill_mode(
struct rga_req *msg,
COLOR_FILL *gr_color, /* gradient color part */
unsigned char gr_satur_mode, /* saturation mode */
unsigned char cf_mode, /* patten fill or solid fill */
unsigned int color, /* solid color */
unsigned short pat_width, /* pattern width */
unsigned short pat_height, /* pattern height */
unsigned char pat_x_off, /* pattern x offset */
unsigned char pat_y_off, /* pattern y offset */
unsigned char aa_en /* alpha en */
);
int
RGA_set_line_point_drawing_mode(
struct rga_req *msg,
POINT sp, /* start point */
POINT ep, /* end point */
unsigned int color, /* line point drawing color */
unsigned int line_width, /* line width */
unsigned char AA_en, /* AA en */
unsigned char last_point_en /* last point en */
);
int
RGA_set_blur_sharp_filter_mode(
struct rga_req *msg,
unsigned char filter_mode, /* blur/sharpness */
unsigned char filter_type, /* filter intensity */
unsigned char dither_en /* dither_en flag */
);
int
RGA_set_pre_scaling_mode(
struct rga_req *msg,
unsigned char dither_en
);
#if defined(__arm64__) || defined(__aarch64__)
int
RGA_update_palette_table_mode(
struct rga_req *msg,
unsigned long LUT_addr, /* LUT table addr */
unsigned int palette_mode /* 1bpp/2bpp/4bpp/8bpp */
);
#else
int
RGA_update_palette_table_mode(
struct rga_req *msg,
unsigned int LUT_addr, /* LUT table addr */
unsigned int palette_mode /* 1bpp/2bpp/4bpp/8bpp */
);
#endif
int
RGA_set_update_patten_buff_mode(
struct rga_req *msg,
unsigned int pat_addr, /* patten addr */
unsigned int w, /* patten width */
unsigned int h, /* patten height */
unsigned int format /* patten format */
);
#if defined(__arm64__) || defined(__aarch64__)
int
RGA_set_mmu_info(
struct rga_req *msg,
unsigned char mmu_en,
unsigned char src_flush,
unsigned char dst_flush,
unsigned char cmd_flush,
unsigned long base_addr,
unsigned char page_size
);
#else
int
RGA_set_mmu_info(
struct rga_req *msg,
unsigned char mmu_en,
unsigned char src_flush,
unsigned char dst_flush,
unsigned char cmd_flush,
unsigned int base_addr,
unsigned char page_size
);
#endif
void rga_set_fds_offsets(
struct rga_req *rga_request,
unsigned short src_fd,
unsigned short dst_fd,
unsigned int src_offset,
unsigned int dst_offset);
int
RGA_set_src_fence_flag(
struct rga_req *msg,
int acq_fence,
int src_flag
);
int
RGA_set_dst_fence_flag(
struct rga_req *msg,
int dst_flag
);
int
RGA_get_dst_fence(
struct rga_req *msg
);
#ifdef __cplusplus
}
#endif
#endif /*_RK29_IPP_DRIVER_H_*/
+10 -2
View File
@@ -47,6 +47,7 @@ ohos_shared_library("camera_pipeline_core") {
sources = [
"$camera_path/adapter/platform/v4l2/src/pipeline_core/nodes/uvc_node/uvc_node.cpp",
"$camera_path/adapter/platform/v4l2/src/pipeline_core/nodes/v4l2_source_node/v4l2_source_node.cpp",
"$camera_device_name_path/camera/src/pipeline_core/node/rk_codec_node.cpp",
"$camera_path/pipeline_core/host_stream/src/host_stream_impl.cpp",
"$camera_path/pipeline_core/host_stream/src/host_stream_mgr_impl.cpp",
"$camera_path/pipeline_core/ipp/src/algo_plugin.cpp",
@@ -70,6 +71,7 @@ ohos_shared_library("camera_pipeline_core") {
"$camera_path/pipeline_core/pipeline_impl/src/strategy/stream_pipeline_strategy.cpp",
"$camera_path/pipeline_core/pipeline_impl/src/stream_pipeline_core.cpp",
"$camera_path/pipeline_core/src/pipeline_core.cpp",
"//device/rockchip/hardware/mpp/src/mpi_enc_utils.c",
]
include_dirs = [
"//utils/native/base/include",
@@ -114,7 +116,10 @@ ohos_shared_library("camera_pipeline_core") {
"//foundation/communication/ipc/interfaces/innerkits/ipc_core/include",
"//utils/native/base/include",
"//foundation/multimedia/camera_standard/frameworks/innerkitsimpl/metadata/include",
"$camera_device_name_path/camera/rk",
"$camera_device_name_path/camera/src/pipeline_core/node",
"//device/rockchip/hardware/rga/include",
"//device/rockchip/hardware/mpp/include",
"//third_party/libjpeg",
# hcs parser
"//drivers/framework/include/osal",
@@ -123,12 +128,15 @@ ohos_shared_library("camera_pipeline_core") {
"//system/core/include/cutils",
"//drivers/framework/utils/include",
"//drivers/adapter/uhdf2/osal/include",
]
]
deps = [
"$camera_path/buffer_manager:camera_buffer_manager",
"$camera_path/device_manager:camera_device_manager",
"//foundation/multimedia/camera_standard/frameworks/innerkitsimpl/metadata:metadata",
"//device/rockchip/hardware/rga:librga",
"//device/rockchip/hardware/mpp:libmpp",
"//third_party/libjpeg:libjpeg_static",
# hcs parser
"$hdf_uhdf_path/utils:libhdf_utils",
@@ -0,0 +1,347 @@
/*
* Copyright (c) 2021 Huawei Device 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.
*/
#include "rk_codec_node.h"
#include "securec.h"
namespace OHOS::Camera {
uint32_t RKCodecNode::previewWidth_ = 0;
uint32_t RKCodecNode::previewHeight_ = 0;
RKCodecNode::RKCodecNode(const std::string& name, const std::string& type) : NodeBase(name, type)
{
CAMERA_LOGV("%{public}s enter, type(%{public}s)\n", name_.c_str(), type_.c_str());
}
RKCodecNode::~RKCodecNode()
{
CAMERA_LOGI("~RKCodecNode Node exit.");
}
RetCode RKCodecNode::Start(const int32_t streamId)
{
CAMERA_LOGI("RKCodecNode::Start streamId = %{public}d\n", streamId);
return RC_OK;
}
RetCode RKCodecNode::Stop(const int32_t streamId)
{
CAMERA_LOGI("RKCodecNode::Stop streamId = %{public}d\n", streamId);
if (halCtx_ != nullptr) {
hal_mpp_ctx_delete(halCtx_);
halCtx_ = nullptr;
mppStatus_ = 0;
}
return RC_OK;
}
RetCode RKCodecNode::Flush(const int32_t streamId)
{
CAMERA_LOGI("RKCodecNode::Flush streamId = %{public}d\n", streamId);
return RC_OK;
}
void RKCodecNode::encodeJpegToMemory(unsigned char* image, int width, int height,
const char* comment, size_t* jpegSize, unsigned char** jpegBuf)
{
struct jpeg_compress_struct cInfo;
struct jpeg_error_mgr jErr;
JSAMPROW row_pointer[1];
int row_stride = 0;
constexpr uint32_t colorMap = 3;
constexpr uint32_t compressionRatio = 100;
constexpr uint32_t pixelsThick = 3;
cInfo.err = jpeg_std_error(&jErr);
jpeg_create_compress(&cInfo);
cInfo.image_width = width;
cInfo.image_height = height;
cInfo.input_components = colorMap;
cInfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cInfo);
jpeg_set_quality(&cInfo, compressionRatio, TRUE);
jpeg_mem_dest(&cInfo, jpegBuf, jpegSize);
jpeg_start_compress(&cInfo, TRUE);
if (comment) {
jpeg_write_marker(&cInfo, JPEG_COM, (const JOCTET*)comment, strlen(comment));
}
row_stride = width;
while (cInfo.next_scanline < cInfo.image_height) {
row_pointer[0] = &image[cInfo.next_scanline * row_stride * pixelsThick];
jpeg_write_scanlines(&cInfo, row_pointer, 1);
}
jpeg_finish_compress(&cInfo);
jpeg_destroy_compress(&cInfo);
}
int RKCodecNode::findStartCode(unsigned char *data, size_t dataSz)
{
constexpr uint32_t dataSize = 4;
constexpr uint32_t dataBit2 = 2;
constexpr uint32_t dataBit3 = 3;
if (data == nullptr) {
CAMERA_LOGI("RKCodecNode::findStartCode paramater == nullptr");
return -1;
}
if ((dataSz > dataSize) && (data[0] == 0) && (data[1] == 0) && \
(data[dataBit2] == 0) && (data[dataBit3] == 1)) {
return 4;
}
return -1;
}
static constexpr uint32_t nalBit = 0x1F;
#define NAL_TYPE(value) ((value) & nalBit)
void RKCodecNode::SerchIFps(unsigned char* buf, size_t bufSize, std::shared_ptr<IBuffer>& buffer)
{
size_t nalType = 0;
size_t idx = 0;
size_t size = bufSize;
constexpr uint32_t nalTypeValue = 0x05;
if (buffer == nullptr || buf == nullptr) {
CAMERA_LOGI("RKCodecNode::SerchIFps paramater == nullptr");
return;
}
for (int i = 0; i < bufSize; i++) {
int ret = findStartCode(buf + idx, size);
if (ret == -1) {
idx += 1;
size -= 1;
} else {
nalType = NAL_TYPE(buf[idx + ret]);
CAMERA_LOGI("ForkNode::ForkBuffers nalu == 0x%{public}x buf == 0x%{public}x \n", nalType, buf[idx + ret]);
if (nalType == nalTypeValue) {
buffer->SetEsKeyFrame(1);
CAMERA_LOGI("ForkNode::ForkBuffers SetEsKeyFrame == 1 nalu == 0x%{public}x\n", nalType);
break;
} else {
idx += ret;
size -= ret;
}
}
if (idx >= bufSize) {
break;
}
}
if (idx >= bufSize) {
buffer->SetEsKeyFrame(0);
CAMERA_LOGI("ForkNode::ForkBuffers SetEsKeyFrame == 0 nalu == 0x%{public}x idx = %{public}d\n",
nalType, idx);
}
}
void RKCodecNode::Yuv420ToRGBA8888(std::shared_ptr<IBuffer>& buffer)
{
if (buffer == nullptr) {
CAMERA_LOGI("RKCodecNode::Yuv420ToRGBA8888 buffer == nullptr");
return;
}
int dma_fd = buffer->GetFileDescriptor();
void* temp = malloc(buffer->GetSize());
if (temp == nullptr) {
CAMERA_LOGI("RKCodecNode::Yuv420ToRGBA8888 malloc buffer == nullptr");
return;
}
previewWidth_ = buffer->GetWidth();
previewHeight_ = buffer->GetHeight();
memcpy(temp, (const void *)buffer->GetVirAddress(), buffer->GetSize());
RockchipRga rkRga;
rga_info_t src = {};
rga_info_t dst = {};
src.fd = -1;
src.mmuFlag = 1;
src.rotation = 0;
src.virAddr = (void *)temp;
dst.fd = dma_fd;
dst.mmuFlag = 1;
dst.virAddr = 0;
rga_set_rect(&src.rect, 0, 0, buffer->GetWidth(), buffer->GetHeight(),
buffer->GetWidth(), buffer->GetHeight(),
RK_FORMAT_YCbCr_420_P);
rga_set_rect(&dst.rect, 0, 0, buffer->GetWidth(), buffer->GetHeight(),
buffer->GetWidth(), buffer->GetHeight(),
RK_FORMAT_RGBA_8888);
rkRga.RkRgaBlit(&src, &dst, NULL);
rkRga.RkRgaFlush();
free(temp);
}
void RKCodecNode::Yuv420ToJpeg(std::shared_ptr<IBuffer>& buffer)
{
constexpr uint32_t RGB24Width = 3;
if (buffer == nullptr) {
CAMERA_LOGI("RKCodecNode::Yuv420ToJpeg buffer == nullptr");
return;
}
int dma_fd = buffer->GetFileDescriptor();
unsigned char* jBuf = nullptr;
size_t jpegSize = 0;
uint32_t tempSize = (previewWidth_ * previewHeight_ * RGB24Width);
void* temp = malloc(tempSize);
if (temp == nullptr) {
CAMERA_LOGI("RKCodecNode::Yuv420ToJpeg malloc buffer == nullptr");
return;
}
RockchipRga rkRga;
rga_info_t src = {};
rga_info_t dst = {};
src.mmuFlag = 1;
src.rotation = 0;
src.virAddr = 0;
src.fd = dma_fd;
dst.fd = -1;
dst.mmuFlag = 1;
dst.virAddr = temp;
rga_set_rect(&src.rect, 0, 0, previewWidth_, previewHeight_,
previewWidth_, previewHeight_,
RK_FORMAT_YCbCr_420_P);
rga_set_rect(&dst.rect, 0, 0, previewWidth_, previewHeight_,
previewWidth_, previewHeight_,
RK_FORMAT_RGB_888);
rkRga.RkRgaBlit(&src, &dst, NULL);
rkRga.RkRgaFlush();
encodeJpegToMemory((unsigned char *)temp, previewWidth_, previewHeight_, NULL, &jpegSize, &jBuf);
memcpy((unsigned char*)buffer->GetVirAddress(), jBuf, jpegSize);
buffer->SetEsFrameSize(jpegSize);
free(jBuf);
free(temp);
CAMERA_LOGE("RKCodecNode::Yuv420ToJpeg jpegSize = %{public}d\n", jpegSize);
}
void RKCodecNode::Yuv420ToH264(std::shared_ptr<IBuffer>& buffer)
{
if (buffer == nullptr) {
CAMERA_LOGI("RKCodecNode::Yuv420ToH264 buffer == nullptr");
return;
}
int ret = 0;
size_t buf_size = 0;
struct timespec ts = {};
int64_t timestamp = 0;
int dma_fd = buffer->GetFileDescriptor();
if (mppStatus_ == 0) {
MpiEncTestArgs args = {};
args.width = previewWidth_;
args.height = previewHeight_;
args.format = MPP_FMT_YUV420P;
args.type = MPP_VIDEO_CodingAVC;
halCtx_ = hal_mpp_ctx_create(&args);
mppStatus_ = 1;
buf_size = ((MpiEncTestData *)halCtx_)->frame_size;
ret = hal_mpp_encode(halCtx_, dma_fd, (unsigned char *)buffer->GetVirAddress(), &buf_size);
SerchIFps((unsigned char *)buffer->GetVirAddress(), buf_size, buffer);
buffer->SetEsFrameSize(buf_size);
clock_gettime(CLOCK_REALTIME, &ts);
timestamp = ts.tv_sec & 0xFFFFFF;
timestamp *= 1000000000;
timestamp += ts.tv_nsec;
buffer->SetEsTimestamp(timestamp);
CAMERA_LOGI("RKCodecNode::Yuv420ToH264 video capture on\n");
} else {
buf_size = ((MpiEncTestData *)halCtx_)->frame_size;
ret = hal_mpp_encode(halCtx_, dma_fd, (unsigned char *)buffer->GetVirAddress(), &buf_size);
SerchIFps((unsigned char *)buffer->GetVirAddress(), buf_size, buffer);
buffer->SetEsFrameSize(buf_size);
clock_gettime(CLOCK_REALTIME, &ts);
timestamp = ts.tv_sec & 0xFFFFFF;
timestamp *= 1000000000;
timestamp += ts.tv_nsec;
buffer->SetEsTimestamp(timestamp);
}
CAMERA_LOGI("ForkNode::ForkBuffers H264 size = %{public}d ret = %{public}d timestamp = %{public}lld\n",
buf_size, ret, timestamp);
}
void RKCodecNode::DeliverBuffer(std::shared_ptr<IBuffer>& buffer)
{
if (buffer == nullptr) {
CAMERA_LOGE("RKCodecNode::DeliverBuffer frameSpec is null");
return;
}
int32_t id = buffer->GetStreamId();
CAMERA_LOGE("RKCodecNode::DeliverBuffer StreamId %{public}d", id);
if (buffer->GetEncodeType() == ENCODE_TYPE_JPEG) {
Yuv420ToJpeg(buffer);
} else if (buffer->GetEncodeType() == ENCODE_TYPE_H264) {
Yuv420ToH264(buffer);
} else {
Yuv420ToRGBA8888(buffer);
}
outPutPorts_ = GetOutPorts();
for (auto& it : outPutPorts_) {
if (it->format_.streamId_ == id) {
it->DeliverBuffer(buffer);
CAMERA_LOGI("RKCodecNode deliver buffer streamid = %{public}d", it->format_.streamId_);
return;
}
}
}
RetCode RKCodecNode::Capture(const int32_t streamId, const int32_t captureId)
{
CAMERA_LOGV("RKCodecNode::Capture");
return RC_OK;
}
RetCode RKCodecNode::CancelCapture(const int32_t streamId)
{
CAMERA_LOGI("RKCodecNode::CancelCapture streamid = %{public}d", streamId);
if (halCtx_ != nullptr) {
hal_mpp_ctx_delete(halCtx_);
halCtx_ = nullptr;
mppStatus_ = 0;
}
return RC_OK;
}
REGISTERNODE(RKCodecNode, {"RKCodec"})
} // namespace OHOS::Camera
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2021 Huawei Device 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 HOS_CAMERA_RKCODEC_NODE_H
#define HOS_CAMERA_RKCODEC_NODE_H
#include <vector>
#include <condition_variable>
#include <ctime>
#include <jpeglib.h>
#include "device_manager_adapter.h"
#include "utils.h"
#include "camera.h"
#include "source_node.h"
#include "RockchipRga.h"
#include "RgaUtils.h"
#include "RgaApi.h"
#include "rk_mpi.h"
#include "mpp_env.h"
#include "mpp_mem.h"
#include "mpp_log.h"
#include "mpp_common.h"
extern "C" {
#include "mpi_enc_utils.h"
}
namespace OHOS::Camera {
class RKCodecNode : public NodeBase {
public:
RKCodecNode(const std::string& name, const std::string& type);
~RKCodecNode() override;
RetCode Start(const int32_t streamId) override;
RetCode Stop(const int32_t streamId) override;
void DeliverBuffer(std::shared_ptr<IBuffer>& buffer) override;
virtual RetCode Capture(const int32_t streamId, const int32_t captureId) override;
RetCode CancelCapture(const int32_t streamId) override;
RetCode Flush(const int32_t streamId);
private:
void encodeJpegToMemory(unsigned char* image, int width, int height,
const char* comment, size_t* jpegSize, unsigned char** jpegBuf);
int findStartCode(unsigned char *data, size_t dataSz);
void SerchIFps(unsigned char* buf, size_t bufSize, std::shared_ptr<IBuffer>& buffer);
void Yuv420ToRGBA8888(std::shared_ptr<IBuffer>& buffer);
void Yuv420ToJpeg(std::shared_ptr<IBuffer>& buffer);
void Yuv420ToH264(std::shared_ptr<IBuffer>& buffer);
static uint32_t previewWidth_;
static uint32_t previewHeight_;
std::vector<std::shared_ptr<IPort>> outPutPorts_;
void* halCtx_ = nullptr;
int mppStatus_ = 0;
};
}// namespace OHOS::Camera
#endif
Binary file not shown.