603 lines
22 KiB
C
603 lines
22 KiB
C
![]() |
/*
|
|||
|
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
|
|||
|
*/
|
|||
|
#include "libapi_common_ive.h"
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
#include <errno.h>
|
|||
|
#include <fcntl.h>
|
|||
|
#include <sys/mman.h>
|
|||
|
#include <sys/stat.h>
|
|||
|
#include <sys/types.h>
|
|||
|
#include <unistd.h>
|
|||
|
#include <signal.h>
|
|||
|
|
|||
|
#include "ot_common.h"
|
|||
|
#include "ot_common_video.h"
|
|||
|
#include "ot_common_sys.h"
|
|||
|
#include "ot_common_vgs.h"
|
|||
|
#include "ot_common_vi.h"
|
|||
|
#include "ot_common_vo.h"
|
|||
|
#include "ss_mpi_sys.h"
|
|||
|
#include <arm_neon.h>
|
|||
|
|
|||
|
#define OT_SAMPLE_IVE_QUERY_SLEEP 100
|
|||
|
#define OT_SAMPLE_IVE_MAX_WIDTH 4096
|
|||
|
#define OT_SAMPLE_IVE_MAX_HEIGHT 4096
|
|||
|
|
|||
|
|
|||
|
// 在一个进程内,MPI初始化是否只能执行一次,如果只能执行一次,那么这里可以设置为全局变量
|
|||
|
// for test
|
|||
|
static td_bool g_is_mpi_init = TD_FALSE;
|
|||
|
|
|||
|
/*
|
|||
|
* function : Mpi check init
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_check_mpi_init(td_void)
|
|||
|
{
|
|||
|
if (g_is_mpi_init == TD_FALSE) {
|
|||
|
if (libapi_common_ive_mpi_init() != TD_SUCCESS) {
|
|||
|
macro_svp_trace_err("Ive mpi init failed!\n");
|
|||
|
return TD_FALSE;
|
|||
|
}
|
|||
|
g_is_mpi_init = TD_TRUE;
|
|||
|
}
|
|||
|
return TD_TRUE;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function :mpi_init
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_mpi_init(td_void)
|
|||
|
{
|
|||
|
td_s32 ret;
|
|||
|
|
|||
|
ss_mpi_sys_exit();
|
|||
|
|
|||
|
ret = ss_mpi_sys_init();
|
|||
|
if (ret != TD_SUCCESS) {
|
|||
|
macro_svp_trace_err("ss_mpi_sys_init fail,Error(%#x)\n", ret);
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function : Mpi exit
|
|||
|
*/
|
|||
|
td_void libapi_common_ive_mpi_exit(td_void)
|
|||
|
{
|
|||
|
if (g_is_mpi_init == TD_TRUE) {
|
|||
|
if (ss_mpi_sys_exit() != TD_SUCCESS) {
|
|||
|
macro_svp_trace_err("Sys exit failed!\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
g_is_mpi_init = TD_FALSE;
|
|||
|
macro_svp_trace_info("ive mpi exit ok!\n");
|
|||
|
}
|
|||
|
|
|||
|
static td_void _comm_ive_get_loop_info(const ot_svp_img *img, ot_struct_rw_image_loop_info *loop_info)
|
|||
|
{
|
|||
|
loop_info->ele_size = 1;
|
|||
|
loop_info->loop_c = 1;
|
|||
|
loop_info->loop_h[0] = img->height;
|
|||
|
switch (img->type) {
|
|||
|
case OT_SVP_IMG_TYPE_U8C1:
|
|||
|
case OT_SVP_IMG_TYPE_S8C1: {
|
|||
|
}
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_YUV420SP: {
|
|||
|
loop_info->ele_size = 1;
|
|||
|
loop_info->loop_c = OT_MACRO_IVE_IMAGE_CHN_TWO;
|
|||
|
loop_info->loop_h[1] = img->height / OT_MACRO_IVE_DIV_TWO;
|
|||
|
}
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_YUV422SP: {
|
|||
|
loop_info->loop_c = OT_MACRO_IVE_IMAGE_CHN_TWO;
|
|||
|
loop_info->loop_h[1] = img->height;
|
|||
|
}
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_U8C3_PACKAGE: {
|
|||
|
loop_info->ele_size = sizeof(td_u8) + sizeof(td_u16);
|
|||
|
}
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_U8C3_PLANAR: {
|
|||
|
loop_info->loop_c = OT_MACRO_IVE_IMAGE_CHN_THREE;
|
|||
|
loop_info->loop_h[1] = img->height;
|
|||
|
loop_info->loop_h[OT_MACRO_IVE_IMAGE_CHN_TWO] = img->height;
|
|||
|
}
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_S16C1:
|
|||
|
case OT_SVP_IMG_TYPE_U16C1: {
|
|||
|
loop_info->ele_size = sizeof(td_u16);
|
|||
|
}
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_U32C1:
|
|||
|
case OT_SVP_IMG_TYPE_S32C1: {
|
|||
|
loop_info->ele_size = sizeof(td_u32);
|
|||
|
}
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_S64C1:
|
|||
|
case OT_SVP_IMG_TYPE_U64C1: {
|
|||
|
loop_info->ele_size = sizeof(td_u64);
|
|||
|
}
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function :Read file
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_read_file(ot_svp_img *img, FILE *fp)
|
|||
|
{
|
|||
|
td_u8 *ptr_tmp = TD_NULL;
|
|||
|
td_u16 c, h;
|
|||
|
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
|||
|
ot_struct_rw_image_loop_info loop_info = {0};
|
|||
|
|
|||
|
macro_svp_check_exps_return(img == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img can't be null\n");
|
|||
|
macro_svp_check_exps_return(fp == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "fp can't be null\n");
|
|||
|
|
|||
|
ret = fgetc(fp);
|
|||
|
macro_svp_check_exps_return(ret == EOF, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "fgetc fp failed!\n");
|
|||
|
if (feof(fp)) {
|
|||
|
macro_svp_trace_err("end of file!\n");
|
|||
|
ret = fseek(fp, 0, SEEK_SET);
|
|||
|
if (ret != 0) {
|
|||
|
macro_svp_trace_err("fseek failed!\n");
|
|||
|
return ret;
|
|||
|
}
|
|||
|
} else {
|
|||
|
ret = fseek(fp, -1, SEEK_CUR);
|
|||
|
if (ret != 0) {
|
|||
|
macro_svp_trace_err("fseek failed!\n");
|
|||
|
return ret;
|
|||
|
}
|
|||
|
}
|
|||
|
_comm_ive_get_loop_info(img, &loop_info);
|
|||
|
for (c = 0; (c < loop_info.loop_c) && (c < OT_SVP_IMG_STRIDE_NUM) && (c < OT_SVP_IMG_ADDR_NUM); c++) {
|
|||
|
ptr_tmp = macro_svp_convert_addr_to_ptr(td_u8, img->virt_addr[c]);
|
|||
|
macro_svp_check_exps_return(ptr_tmp == 0, OT_ERR_IVE_ILLEGAL_PARAM,
|
|||
|
ENUM_SVP_ERR_LEVEL_DEBUG, "ptr_tmp can't be 0\n");
|
|||
|
for (h = 0; h < loop_info.loop_h[c]; h++) {
|
|||
|
if (fread(ptr_tmp, img->width * loop_info.ele_size, 1, fp) != 1) {
|
|||
|
macro_svp_trace_err("Read file fail\n");
|
|||
|
return OT_ERR_IVE_ILLEGAL_PARAM;
|
|||
|
}
|
|||
|
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function :Write file
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_write_file(ot_svp_img *img, FILE *fp)
|
|||
|
{
|
|||
|
td_u16 c, h;
|
|||
|
td_u8 *ptr_tmp = TD_NULL;
|
|||
|
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
|||
|
ot_struct_rw_image_loop_info loop_info = {0};
|
|||
|
|
|||
|
macro_svp_check_exps_return(img == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img can't be null\n");
|
|||
|
macro_svp_check_exps_return(fp == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "fp can't be null\n");
|
|||
|
ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
|||
|
macro_svp_check_exps_return(img->phys_addr == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img->phys_addr can't be 0\n");
|
|||
|
macro_svp_check_exps_return(img->virt_addr == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img->phys_addr can't be 0\n");
|
|||
|
|
|||
|
_comm_ive_get_loop_info(img, &loop_info);
|
|||
|
for (c = 0; (c < loop_info.loop_c) && (c < OT_SVP_IMG_STRIDE_NUM) && (c < OT_SVP_IMG_ADDR_NUM); c++) {
|
|||
|
ptr_tmp = macro_svp_convert_addr_to_ptr(td_u8, img->virt_addr[c]);
|
|||
|
macro_svp_check_exps_return(ptr_tmp == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "ptr_tmp can't be 0\n");
|
|||
|
for (h = 0; h < loop_info.loop_h[c]; h++) {
|
|||
|
if (fwrite(ptr_tmp, img->width * loop_info.ele_size, 1, fp) != 1) {
|
|||
|
macro_svp_trace_err("Write file fail\n");
|
|||
|
return ret;
|
|||
|
}
|
|||
|
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
|||
|
}
|
|||
|
}
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
// static void *memcpy_128(void *dest, void *src, size_t count)
|
|||
|
// {
|
|||
|
// int i;
|
|||
|
// unsigned long *s = (unsigned long *)src;
|
|||
|
// unsigned long *d = (unsigned long *)dest;
|
|||
|
// for (i = 0; i < count / 64; i++) {
|
|||
|
// vst1q_u64(&d[0], vld1q_u64(&s[0]));
|
|||
|
// vst1q_u64(&d[2], vld1q_u64(&s[2]));
|
|||
|
// vst1q_u64(&d[4], vld1q_u64(&s[4]));
|
|||
|
// vst1q_u64(&d[6], vld1q_u64(&s[6]));
|
|||
|
// d += 8; s += 8;
|
|||
|
// }
|
|||
|
// return dest;
|
|||
|
// }
|
|||
|
|
|||
|
/*
|
|||
|
* 先执行
|
|||
|
* ret = libapi_common_ive_create_image(img, img_type, width, height);
|
|||
|
* macro_svp_check_exps_return(ret != TD_SUCCESS, fail, ENUM_SVP_ERR_LEVEL_ERROR, "Error,create src img failed!\n");
|
|||
|
* function :Read os_mem
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_read_os_mem(ot_svp_img *img, td_void *src, td_u32 whidh, td_u32 height, td_u32 img_type)
|
|||
|
{
|
|||
|
td_u8 *ptr_tmp = TD_NULL;
|
|||
|
td_u16 c, h;
|
|||
|
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
|||
|
ot_struct_rw_image_loop_info loop_info = {0};
|
|||
|
|
|||
|
macro_svp_check_exps_return(img == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img can't be null\n");
|
|||
|
macro_svp_check_exps_return(src == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "src can't be null\n");
|
|||
|
|
|||
|
_comm_ive_get_loop_info(img, &loop_info);
|
|||
|
td_void *_tmp_src = src;
|
|||
|
for (c = 0; (c < loop_info.loop_c) && (c < OT_SVP_IMG_STRIDE_NUM) && (c < OT_SVP_IMG_ADDR_NUM); c++) {
|
|||
|
ptr_tmp = macro_svp_convert_addr_to_ptr(td_u8, img->virt_addr[c]);
|
|||
|
macro_svp_check_exps_return(ptr_tmp == 0, OT_ERR_IVE_ILLEGAL_PARAM,
|
|||
|
ENUM_SVP_ERR_LEVEL_DEBUG, "ptr_tmp can't be 0\n");
|
|||
|
td_u32 len = img->width * loop_info.ele_size;
|
|||
|
if (len == img->stride[c] * loop_info.ele_size) {
|
|||
|
memcpy(ptr_tmp, _tmp_src, len * loop_info.loop_h[c]);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
for (h = 0; h < loop_info.loop_h[c]; h++) {
|
|||
|
memcpy(ptr_tmp, _tmp_src, len);
|
|||
|
_tmp_src += len;
|
|||
|
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function :Write os_mem
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_write_os_mem(ot_svp_img *img, td_void *tar)
|
|||
|
{
|
|||
|
td_u16 c, h;
|
|||
|
td_u8 *ptr_tmp = TD_NULL;
|
|||
|
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
|||
|
ot_struct_rw_image_loop_info loop_info = {0};
|
|||
|
|
|||
|
macro_svp_check_exps_return(img == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img can't be null\n");
|
|||
|
macro_svp_check_exps_return(tar == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "tar can't be null\n");
|
|||
|
ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
|||
|
macro_svp_check_exps_return(img->phys_addr == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img->phys_addr can't be 0\n");
|
|||
|
macro_svp_check_exps_return(img->virt_addr == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "img->phys_addr can't be 0\n");
|
|||
|
|
|||
|
_comm_ive_get_loop_info(img, &loop_info);
|
|||
|
td_void *_tmp_tar = tar;
|
|||
|
for (c = 0; (c < loop_info.loop_c) && (c < OT_SVP_IMG_STRIDE_NUM) && (c < OT_SVP_IMG_ADDR_NUM); c++) {
|
|||
|
ptr_tmp = macro_svp_convert_addr_to_ptr(td_u8, img->virt_addr[c]);
|
|||
|
macro_svp_check_exps_return(ptr_tmp == 0, ret, ENUM_SVP_ERR_LEVEL_DEBUG, "ptr_tmp can't be 0\n");
|
|||
|
td_u32 len = img->width * loop_info.ele_size;
|
|||
|
if (len == img->stride[c] * loop_info.ele_size) {
|
|||
|
memcpy(_tmp_tar, ptr_tmp, len * loop_info.loop_h[c]);
|
|||
|
// macro_svp_trace_info("len is %d, len2 is %d\n", len, img->stride[c] * loop_info.ele_size);
|
|||
|
}
|
|||
|
else {
|
|||
|
for (h = 0; h < loop_info.loop_h[c]; h++) {
|
|||
|
memcpy(_tmp_tar, ptr_tmp, len);
|
|||
|
_tmp_tar += len;
|
|||
|
ptr_tmp += img->stride[c] * loop_info.ele_size;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function :Calc stride
|
|||
|
*/
|
|||
|
td_u32 libapi_common_ive_calc_stride(td_u32 width, td_u8 align)
|
|||
|
{
|
|||
|
macro_svp_check_exps_return(align == 0, OT_ERR_IVE_ILLEGAL_PARAM,
|
|||
|
ENUM_SVP_ERR_LEVEL_DEBUG, "align can't be 0\n");
|
|||
|
macro_svp_check_exps_return((width > OT_SAMPLE_IVE_MAX_WIDTH) || (width < 1), OT_ERR_IVE_ILLEGAL_PARAM,
|
|||
|
ENUM_SVP_ERR_LEVEL_DEBUG, "width(%u) must be in [1, %u]", width, OT_SAMPLE_IVE_MAX_WIDTH);
|
|||
|
return (width + (align - width % align) % align);
|
|||
|
}
|
|||
|
|
|||
|
static td_void _comm_ive_get_thresh(ot_ive_ccblob *blob, td_u16 area_thr_step, td_u16 rect_max_num,
|
|||
|
td_u16 *thresh)
|
|||
|
{
|
|||
|
td_u32 i;
|
|||
|
td_u16 num;
|
|||
|
td_u16 thr = blob->info.bits.cur_area_threshold;
|
|||
|
do {
|
|||
|
num = 0;
|
|||
|
thr += area_thr_step;
|
|||
|
for (i = 0; i < blob->info.bits.rgn_num; i++) {
|
|||
|
if (blob->rgn[i].area > thr) {
|
|||
|
num++;
|
|||
|
}
|
|||
|
}
|
|||
|
} while (num > rect_max_num);
|
|||
|
|
|||
|
*thresh = thr;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function : judge if rect is valid
|
|||
|
*/
|
|||
|
static td_void _common_ive_is_rect_valid(ot_struct_svp_rect_info *rect, td_u32 num, td_bool *valid)
|
|||
|
{
|
|||
|
td_u32 j, k;
|
|||
|
for (j = 0; j < (OT_POINT_NUM - 1); j++) {
|
|||
|
for (k = j + 1; k < OT_POINT_NUM; k++) {
|
|||
|
if ((rect->rect[num].point[j].x == rect->rect[num].point[k].x) &&
|
|||
|
(rect->rect[num].point[j].y == rect->rect[num].point[k].y)) {
|
|||
|
*valid = TD_FALSE;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function : Copy blob to rect
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_blob_to_rect(ot_ive_ccblob *blob, ot_struct_svp_rect_info *rect,
|
|||
|
td_u16 rect_max_num, td_u16 area_thr_step, ot_struct_src_dst_size src_dst_size)
|
|||
|
{
|
|||
|
td_u16 num, i;
|
|||
|
td_u16 thr = 0;
|
|||
|
td_bool valid;
|
|||
|
macro_svp_check_exps_return(blob == TD_NULL, OT_ERR_IVE_NULL_PTR,
|
|||
|
ENUM_SVP_ERR_LEVEL_DEBUG, "blob can't be null\n");
|
|||
|
macro_svp_check_exps_return(rect == TD_NULL, OT_ERR_IVE_NULL_PTR,
|
|||
|
ENUM_SVP_ERR_LEVEL_DEBUG, "rect can't be null\n");
|
|||
|
|
|||
|
if (blob->info.bits.rgn_num > rect_max_num) {
|
|||
|
_comm_ive_get_thresh(blob, area_thr_step, rect_max_num, &thr);
|
|||
|
}
|
|||
|
|
|||
|
num = 0;
|
|||
|
for (i = 0; i < blob->info.bits.rgn_num; i++) {
|
|||
|
if (blob->rgn[i].area <= thr) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
macro_svp_check_exps_return(num > (OT_SVP_RECT_NUM - 1), TD_FAILURE,
|
|||
|
ENUM_SVP_ERR_LEVEL_ERROR, "num is larger than %u\n", OT_SVP_RECT_NUM - 1);
|
|||
|
rect->rect[num].point[OT_MACRO_POINT_IDX_ZERO].x = (td_u32)((td_float)blob->rgn[i].left /
|
|||
|
(td_float)src_dst_size.src.width * (td_float)src_dst_size.dst.width) & (~1);
|
|||
|
rect->rect[num].point[OT_MACRO_POINT_IDX_ZERO].y = (td_u32)((td_float)blob->rgn[i].top /
|
|||
|
(td_float)src_dst_size.src.height * (td_float)src_dst_size.dst.height) & (~1);
|
|||
|
|
|||
|
rect->rect[num].point[OT_MACRO_POINT_IDX_ONE].x = (td_u32)((td_float)blob->rgn[i].right /
|
|||
|
(td_float)src_dst_size.src.width * (td_float)src_dst_size.dst.width) & (~1);
|
|||
|
rect->rect[num].point[OT_MACRO_POINT_IDX_ONE].y = (td_u32)((td_float)blob->rgn[i].top /
|
|||
|
(td_float)src_dst_size.src.height * (td_float)src_dst_size.dst.height) & (~1);
|
|||
|
|
|||
|
rect->rect[num].point[OT_MACRO_POINT_IDX_TWO].x = (td_u32)((td_float)blob->rgn[i].right /
|
|||
|
(td_float)src_dst_size.src.width * (td_float)src_dst_size.dst.width) & (~1);
|
|||
|
rect->rect[num].point[OT_MACRO_POINT_IDX_TWO].y = (td_u32)((td_float)blob->rgn[i].bottom /
|
|||
|
(td_float)src_dst_size.src.height * (td_float)src_dst_size.dst.height) & (~1);
|
|||
|
|
|||
|
rect->rect[num].point[OT_MACRO_POINT_IDX_THREE].x = (td_u32)((td_float)blob->rgn[i].left /
|
|||
|
(td_float)src_dst_size.src.width * (td_float)src_dst_size.dst.width) & (~1);
|
|||
|
rect->rect[num].point[OT_MACRO_POINT_IDX_THREE].y = (td_u32)((td_float)blob->rgn[i].bottom /
|
|||
|
(td_float)src_dst_size.src.height * (td_float)src_dst_size.dst.height) & (~1);
|
|||
|
|
|||
|
valid = TD_TRUE;
|
|||
|
_common_ive_is_rect_valid(rect, num, &valid);
|
|||
|
if (valid == TD_TRUE) {
|
|||
|
num++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
rect->num = num;
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static td_s32 _comm_ive_set_image_addr(ot_svp_img *img, const ot_struct_rw_image_loop_info *loop_info,
|
|||
|
td_bool is_mmz_cached)
|
|||
|
{
|
|||
|
td_u32 c;
|
|||
|
td_u32 size = 0;
|
|||
|
td_s32 ret;
|
|||
|
td_void *virt_addr = TD_NULL;
|
|||
|
for (c = 0; (c < loop_info->loop_c) && (c < OT_MAX_LOOP_IMG_H) && (c < OT_SVP_IMG_STRIDE_NUM); c++) {
|
|||
|
size += img->stride[0] * loop_info->loop_h[c] * loop_info->ele_size;
|
|||
|
img->stride[c] = img->stride[0];
|
|||
|
}
|
|||
|
|
|||
|
if (is_mmz_cached == TD_FALSE) {
|
|||
|
ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)&img->phys_addr[0], (td_void **)&virt_addr,
|
|||
|
TD_NULL, TD_NULL, size);
|
|||
|
} else {
|
|||
|
ret = ss_mpi_sys_mmz_alloc_cached((td_phys_addr_t *)&img->phys_addr[0], (td_void **)&virt_addr,
|
|||
|
TD_NULL, TD_NULL, size);
|
|||
|
}
|
|||
|
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR, "mmz malloc fail\n");
|
|||
|
img->virt_addr[OT_MACRO_ADDR_IDX_ZERO] = macro_svp_convert_ptr_to_addr(td_u64, virt_addr);
|
|||
|
|
|||
|
if (img->type != OT_SVP_IMG_TYPE_U8C3_PACKAGE) {
|
|||
|
for (c = 1; (c < loop_info->loop_c) && (c < OT_MAX_LOOP_IMG_H) && (c < OT_SVP_IMG_STRIDE_NUM); c++) {
|
|||
|
img->phys_addr[c] = img->phys_addr[c - 1] + img->stride[c - 1] * img->height;
|
|||
|
img->virt_addr[c] = img->virt_addr[c - 1] + img->stride[c - 1] * img->height;
|
|||
|
}
|
|||
|
} else {
|
|||
|
img->virt_addr[OT_MACRO_ADDR_IDX_ONE] = img->virt_addr[OT_MACRO_ADDR_IDX_ZERO] + 1;
|
|||
|
img->virt_addr[OT_MACRO_ADDR_IDX_TWO] = img->virt_addr[OT_MACRO_ADDR_IDX_ONE] + 1;
|
|||
|
img->phys_addr[OT_MACRO_ADDR_IDX_ONE] = img->phys_addr[OT_MACRO_ADDR_IDX_ZERO] + 1;
|
|||
|
img->phys_addr[OT_MACRO_ADDR_IDX_TWO] = img->phys_addr[OT_MACRO_ADDR_IDX_ONE] + 1;
|
|||
|
}
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function : Create ive image
|
|||
|
*/
|
|||
|
static td_s32 _common_ive_create_image_flag(ot_svp_img *img, ot_svp_img_type type,
|
|||
|
td_u32 width, td_u32 height, td_bool is_mmz_cached)
|
|||
|
{
|
|||
|
td_s32 ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
|||
|
ot_struct_rw_image_loop_info loop_info = {0};
|
|||
|
macro_svp_check_exps_return(img == TD_NULL, OT_ERR_IVE_NULL_PTR, ENUM_SVP_ERR_LEVEL_ERROR, "img can't be null\n");
|
|||
|
macro_svp_check_exps_return((type < 0) || (type >= OT_SVP_IMG_TYPE_BUTT), ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"type(%u) must be in [0, %u)!\n", type, OT_SVP_IMG_TYPE_BUTT);
|
|||
|
macro_svp_check_exps_return(width > OT_SAMPLE_IVE_MAX_WIDTH, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"width(%u) must be in [1, %u]!\n", width, OT_SAMPLE_IVE_MAX_WIDTH);
|
|||
|
macro_svp_check_exps_return(width > OT_SAMPLE_IVE_MAX_HEIGHT, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"width(%u) must be in [1, %u]!\n", width, OT_SAMPLE_IVE_MAX_HEIGHT);
|
|||
|
|
|||
|
img->type = type;
|
|||
|
img->width = width;
|
|||
|
img->height = height;
|
|||
|
img->stride[0] = libapi_common_ive_calc_stride(img->width, OT_IVE_ALIGN);
|
|||
|
|
|||
|
switch (type) {
|
|||
|
case OT_SVP_IMG_TYPE_U8C1:
|
|||
|
case OT_SVP_IMG_TYPE_S8C1:
|
|||
|
case OT_SVP_IMG_TYPE_YUV420SP:
|
|||
|
case OT_SVP_IMG_TYPE_YUV422SP:
|
|||
|
case OT_SVP_IMG_TYPE_S16C1:
|
|||
|
case OT_SVP_IMG_TYPE_U16C1:
|
|||
|
case OT_SVP_IMG_TYPE_U8C3_PACKAGE:
|
|||
|
case OT_SVP_IMG_TYPE_S32C1:
|
|||
|
case OT_SVP_IMG_TYPE_U32C1:
|
|||
|
case OT_SVP_IMG_TYPE_S64C1:
|
|||
|
case OT_SVP_IMG_TYPE_U64C1: {
|
|||
|
_comm_ive_get_loop_info(img, &loop_info);
|
|||
|
ret = _comm_ive_set_image_addr(img, &loop_info, is_mmz_cached);
|
|||
|
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"Err:%#x,_comm_ive_set_image_addr failed\n", ret);
|
|||
|
break;
|
|||
|
}
|
|||
|
case OT_SVP_IMG_TYPE_YUV420P:
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_YUV422P:
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_S8C2_PACKAGE:
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_S8C2_PLANAR:
|
|||
|
break;
|
|||
|
case OT_SVP_IMG_TYPE_U8C3_PLANAR:
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
td_s32 libapi_common_ive_create_image(ot_svp_img *img, ot_svp_img_type type,
|
|||
|
td_u32 width, td_u32 height)
|
|||
|
{
|
|||
|
return _common_ive_create_image_flag(img, type, width, height, TD_FALSE);
|
|||
|
}
|
|||
|
|
|||
|
td_s32 libapi_common_ive_destroy_image(ot_svp_img *img)
|
|||
|
{
|
|||
|
if (TD_NULL != img) macro_svp_mmz_free(img->phys_addr[0], img->virt_addr[0]);
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function : Create memory info
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_create_mem_info(ot_svp_mem_info *mem_info, td_u32 size)
|
|||
|
{
|
|||
|
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
|||
|
td_void *virt_addr = TD_NULL;
|
|||
|
|
|||
|
macro_svp_check_exps_return(mem_info == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "mem_info can't be null\n");
|
|||
|
|
|||
|
mem_info->size = size;
|
|||
|
ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)&mem_info->phys_addr, (td_void **)&virt_addr, TD_NULL, TD_NULL, size);
|
|||
|
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"Mmz Alloc fail,Error(%#x)\n", ret);
|
|||
|
mem_info->virt_addr = macro_svp_convert_ptr_to_addr(td_u64, virt_addr);
|
|||
|
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function : Destroy memory info
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_destroy_mem_info(ot_svp_mem_info *mem_info)
|
|||
|
{
|
|||
|
if (TD_NULL != mem_info) macro_svp_mmz_free(mem_info->phys_addr, mem_info->virt_addr);
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function : Create ive image by cached
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_create_image_by_cached(ot_svp_img *img, ot_svp_img_type type,
|
|||
|
td_u32 width, td_u32 height)
|
|||
|
{
|
|||
|
return _common_ive_create_image_flag(img, type, width, height, TD_TRUE);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* function : Dma frame info to ive image
|
|||
|
*/
|
|||
|
td_s32 libapi_common_ive_dma_image(ot_video_frame_info *frame_info, ot_svp_dst_img *dst,
|
|||
|
td_bool is_instant)
|
|||
|
{
|
|||
|
td_s32 ret = OT_ERR_IVE_NULL_PTR;
|
|||
|
ot_ive_handle handle;
|
|||
|
ot_svp_src_data src_data;
|
|||
|
ot_svp_dst_data dst_data;
|
|||
|
ot_ive_dma_ctrl ctrl = { OT_IVE_DMA_MODE_DIRECT_COPY, 0, 0, 0, 0 };
|
|||
|
td_bool is_finish = TD_FALSE;
|
|||
|
td_bool is_block = TD_TRUE;
|
|||
|
|
|||
|
macro_svp_check_exps_return(frame_info == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "frame_info can't be null\n");
|
|||
|
macro_svp_check_exps_return(dst == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR, "dst can't be null\n");
|
|||
|
macro_svp_check_exps_return(frame_info->video_frame.virt_addr == TD_NULL, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"frame_info->video_frame.virt_addr can't be null\n");
|
|||
|
ret = OT_ERR_IVE_ILLEGAL_PARAM;
|
|||
|
macro_svp_check_exps_return(frame_info->video_frame.phys_addr == 0, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"frame_info->video_frame.virt_addr can't be 0\n");
|
|||
|
macro_svp_check_exps_return(dst->virt_addr == 0, ret, ENUM_SVP_ERR_LEVEL_ERROR, "dst->virt_addr can't be 0\n");
|
|||
|
macro_svp_check_exps_return(dst->phys_addr == 0, ret, ENUM_SVP_ERR_LEVEL_ERROR, "dst->phys_addr can't be 0\n");
|
|||
|
|
|||
|
/* fill src */
|
|||
|
src_data.virt_addr = macro_svp_convert_ptr_to_addr(td_u64, frame_info->video_frame.virt_addr[0]);
|
|||
|
src_data.phys_addr = frame_info->video_frame.phys_addr[0];
|
|||
|
src_data.width = frame_info->video_frame.width;
|
|||
|
src_data.height = frame_info->video_frame.height;
|
|||
|
src_data.stride = frame_info->video_frame.stride[0];
|
|||
|
|
|||
|
/* fill dst */
|
|||
|
dst_data.virt_addr = dst->virt_addr[0];
|
|||
|
dst_data.phys_addr = dst->phys_addr[0];
|
|||
|
dst_data.width = dst->width;
|
|||
|
dst_data.height = dst->height;
|
|||
|
dst_data.stride = dst->stride[0];
|
|||
|
|
|||
|
ret = ss_mpi_ive_dma(&handle, &src_data, &dst_data, &ctrl, is_instant);
|
|||
|
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"Error(%#x),ss_mpi_ive_dma failed!\n", ret);
|
|||
|
|
|||
|
if (is_instant == TD_TRUE) {
|
|||
|
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
|||
|
while (ret == OT_ERR_IVE_QUERY_TIMEOUT) {
|
|||
|
usleep(OT_SAMPLE_IVE_QUERY_SLEEP);
|
|||
|
ret = ss_mpi_ive_query(handle, &is_finish, is_block);
|
|||
|
}
|
|||
|
macro_svp_check_exps_return(ret != TD_SUCCESS, ret, ENUM_SVP_ERR_LEVEL_ERROR,
|
|||
|
"Error(%#x),ss_mpi_ive_query failed!\n", ret);
|
|||
|
}
|
|||
|
|
|||
|
return TD_SUCCESS;
|
|||
|
}
|