Files

683 lines
26 KiB
C

/*
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
*/
#include "sample_common_svp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "ot_common.h"
#include "ot_common_video.h"
#include "ot_common_sys.h"
#include "ot_common_svp.h"
#include "ss_mpi_vb.h"
#include "sample_comm.h"
#include "sample_common_ive.h"
#define SAMPLE_SVP_BLK_CNT 16
#define SMAPLE_SVP_DISPLAY_BUF_LEN 3
#define SAMPLE_SVP_VI_CHN_INTERVAL 4
#define SAMPLE_SVP_VPSS_BORDER_WIDTH 2
#define SAMPLE_SVP_VO_DIS_BUF_LEN 3
#define SAMPLE_SVP_MAX_WIDTH 32768
#define SAMPLE_SVP_NUM_TWO 2
static td_bool g_sample_svp_init_flag = TD_FALSE;
/* System init */
static td_s32 sample_comm_svp_sys_init(td_void)
{
td_s32 ret;
ot_vb_cfg vb_cfg;
ret = ss_mpi_sys_exit();
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x):ss_mpi_sys_exit failed!\n", ret);
ret = ss_mpi_vb_exit();
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x):ss_mpi_vb_exit failed!\n", ret);
(td_void)memset_s(&vb_cfg, sizeof(ot_vb_cfg), 0, sizeof(ot_vb_cfg));
vb_cfg.max_pool_cnt = SAMPLE_SVP_VB_POOL_NUM;
vb_cfg.common_pool[1].blk_size = SAMPLE_SVP_D1_PAL_WIDTH * SAMPLE_SVP_D1_PAL_HEIGHT * SAMPLE_SVP_VB_POOL_NUM;
vb_cfg.common_pool[1].blk_cnt = 1;
ret = ss_mpi_vb_set_cfg((const ot_vb_cfg *)&vb_cfg);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x):ss_mpi_vb_set_config failed!\n", ret);
ret = ss_mpi_vb_init();
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x):ss_mpi_vb_init failed!\n", ret);
ret = ss_mpi_sys_init();
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x):ss_mpi_sys_init failed!\n", ret);
return ret;
}
/* System exit */
static td_s32 sample_comm_svp_sys_exit(td_void)
{
td_s32 ret;
ret = ss_mpi_sys_exit();
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x):ss_mpi_sys_exit failed!\n", ret);
ret = ss_mpi_vb_exit();
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x):ss_mpi_vb_exit failed!\n", ret);
return TD_SUCCESS;
}
/* System init */
td_s32 sample_common_svp_check_sys_init(td_void)
{
if (g_sample_svp_init_flag == TD_FALSE) {
if (sample_comm_svp_sys_init() != TD_SUCCESS) {
sample_svp_trace_err("Svp mpi init failed!\n");
return TD_FALSE;
}
g_sample_svp_init_flag = TD_TRUE;
}
sample_svp_trace_info("Svp mpi init ok!\n");
return TD_TRUE;
}
/* System exit */
td_void sample_common_svp_check_sys_exit(td_void)
{
td_s32 ret;
if (g_sample_svp_init_flag == TD_TRUE) {
ret = sample_comm_svp_sys_exit();
if (ret != TD_SUCCESS) {
sample_svp_trace_err("svp mpi exit failed!\n");
}
}
g_sample_svp_init_flag = TD_FALSE;
sample_svp_trace_info("Svp mpi exit ok!\n");
}
/* Align */
td_u32 sample_common_svp_align(td_u32 size, td_u16 align)
{
td_u32 stride;
sample_svp_check_exps_return(align == 0, 0, SAMPLE_SVP_ERR_LEVEL_ERROR, "align can't be zero!\n");
sample_svp_check_exps_return((size < 1) || (size > SAMPLE_SVP_MAX_WIDTH), 0, SAMPLE_SVP_ERR_LEVEL_ERROR,
"size(%u) must be [1, %u]\n", size, SAMPLE_SVP_MAX_WIDTH);
stride = size + (align - size % align) % align;
return stride;
}
/* Malloc memory */
td_s32 sample_common_svp_malloc_mem(td_char *mmb, td_char *zone, td_phys_addr_t *phys_addr,
td_void **virt_addr, td_u32 size)
{
td_s32 ret = TD_FAILURE;
sample_svp_check_exps_return(phys_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "phys_addr can't be null\n");
sample_svp_check_exps_return(virt_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "virt_addr can't be null\n");
ret = ss_mpi_sys_mmz_alloc((td_phys_addr_t *)phys_addr, virt_addr, mmb, zone, size);
return ret;
}
/* Malloc memory with cached */
td_s32 sample_common_svp_malloc_cached(td_char *mmb, td_char *zone, td_phys_addr_t *phys_addr,
td_void **virt_addr, td_u32 size)
{
td_s32 ret = TD_FAILURE;
sample_svp_check_exps_return(phys_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "phys_addr can't be null\n");
sample_svp_check_exps_return(virt_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "virt_addr can't be null\n");
ret = ss_mpi_sys_mmz_alloc_cached((td_phys_addr_t *)phys_addr, virt_addr, mmb, zone, size);
return ret;
}
/* Flush cached */
td_s32 sample_common_svp_flush_cache(td_phys_addr_t phys_addr, td_void *virt_addr, td_u32 size)
{
td_s32 ret = TD_FAILURE;
sample_svp_check_exps_return(virt_addr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "virt_addr can't be null\n");
ret = ss_mpi_sys_flush_cache((td_phys_addr_t)phys_addr, virt_addr, size);
return ret;
}
td_s32 sample_common_svp_get_blob_data_byte_num(ot_svp_blob_type type, td_u32 *byte_num)
{
sample_svp_check_exps_return(byte_num == TD_NULL, TD_FAILURE,
SAMPLE_SVP_ERR_LEVEL_ERROR, "byte_num can't be null\n");
switch (type) {
case OT_SVP_BLOB_TYPE_S20Q12:
*byte_num = sizeof(td_s32);
break;
case OT_SVP_BLOB_TYPE_U8:
case OT_SVP_BLOB_TYPE_S8:
case OT_SVP_BLOB_TYPE_YVU420SP:
case OT_SVP_BLOB_TYPE_YVU422SP:
*byte_num = sizeof(td_u8);
break;
case OT_SVP_BLOB_TYPE_VEC_S20Q12:
case OT_SVP_BLOB_TYPE_SEQ_S20Q12:
case OT_SVP_BLOB_TYPE_BBOX_S20Q12:
case OT_SVP_BLOB_TYPE_BSI_SQ32:
case OT_SVP_BLOB_TYPE_S12Q20:
case OT_SVP_BLOB_TYPE_VEC_S12Q20:
case OT_SVP_BLOB_TYPE_S32:
case OT_SVP_BLOB_TYPE_U32:
case OT_SVP_BLOB_TYPE_FP32:
*byte_num = sizeof(td_s32);
break;
case OT_SVP_BLOB_TYPE_FP16:
case OT_SVP_BLOB_TYPE_S16:
case OT_SVP_BLOB_TYPE_U16:
*byte_num = sizeof(td_s16);
break;
default:
sample_svp_check_exps_return(1, OT_INVALID_VALUE, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error: type should be [%d, %d)!\n", OT_SVP_BLOB_TYPE_S20Q12, OT_SVP_BLOB_TYPE_BUTT);
break;
}
return TD_SUCCESS;
}
/*
* function : Init Vb
*/
static td_s32 sample_common_svp_vb_init(ot_pic_size *pic_type, ot_size *pic_size,
td_u32 vpss_chn_num, sample_vi_param *vi_param)
{
td_s32 ret;
td_u32 i;
td_u64 blk_size;
ot_vb_cfg vb_cfg = {0};
ot_pic_buf_attr pic_buf_attr;
vi_param->vi_dev_cnt = 1;
vi_param->vi_dev_interval = 1;
vi_param->vi_chn_cnt = 1;
vi_param->vi_chn_interval = SAMPLE_SVP_VI_CHN_INTERVAL;
vi_param->scan_mode = OT_VI_SCAN_PROGRESSIVE;
vi_param->minor_attr_en = TD_FALSE;
vi_param->minor_dst_size.width = D1_WIDTH;
vi_param->minor_dst_size.height = D1_HEIGHT_NTSC;
vb_cfg.max_pool_cnt = OT_SAMPLE_IVE_MAX_POOL_CNT;
ret = sample_comm_sys_get_pic_size(pic_type[0], &pic_size[0]);
sample_svp_check_exps_goto(ret != TD_SUCCESS, vb_fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
"sample_comm_sys_get_pic_size failed,Error(%#x)!\n", ret);
pic_buf_attr.width = pic_size[0].width;
pic_buf_attr.height = pic_size[0].height;
pic_buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
pic_buf_attr.pixel_format = SAMPLE_PIXEL_FORMAT;
pic_buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
pic_buf_attr.align = OT_DEFAULT_ALIGN;
blk_size = ot_common_get_pic_buf_size(&pic_buf_attr);
vb_cfg.common_pool[0].blk_size = blk_size;
vb_cfg.common_pool[0].blk_cnt = SAMPLE_SVP_BLK_CNT;
for (i = 1; (i < vpss_chn_num) && (i < OT_VB_MAX_COMMON_POOLS); i++) {
ret = sample_comm_sys_get_pic_size(pic_type[i], &pic_size[i]);
sample_svp_check_exps_goto(ret != TD_SUCCESS, vb_fail_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
"sample_comm_sys_get_pic_size failed,Error(%#x)!\n", ret);
pic_buf_attr.width = pic_size[i].width;
pic_buf_attr.height = pic_size[i].height;
pic_buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
pic_buf_attr.align = OT_DEFAULT_ALIGN;
blk_size = ot_common_get_pic_buf_size(&pic_buf_attr);
/* comm video buffer */
vb_cfg.common_pool[i].blk_size = blk_size;
vb_cfg.common_pool[i].blk_cnt = SAMPLE_SVP_BLK_CNT;
}
ret = sample_comm_sys_init(&vb_cfg);
sample_svp_check_exps_goto(ret != TD_SUCCESS, vb_fail_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
"sample_comm_sys_init failed,Error(%#x)!\n", ret);
return ret;
vb_fail_1:
sample_comm_sys_exit();
vb_fail_0:
return ret;
}
td_s32 sample_common_svp_vgs_fill_rect(ot_video_frame_info *frame_info,
ot_sample_svp_rect_info *rect, td_u32 color)
{
ot_vgs_handle vgs_handle = -1;
td_s32 ret = TD_FAILURE;
td_u16 i;
ot_vgs_task_attr vgs_task;
ot_cover vgs_add_cover;
sample_svp_check_exps_return(frame_info == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "frame_info can't be null\n");
sample_svp_check_exps_return(rect == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "rect can't be null\n");
sample_svp_check_exps_return(rect->num > OT_SVP_RECT_NUM, ret,
SAMPLE_SVP_ERR_LEVEL_ERROR, "rect->num can't lager than %u\n", OT_SVP_RECT_NUM);
if (rect->num == 0) {
return TD_SUCCESS;
}
ret = ss_mpi_vgs_begin_job(&vgs_handle);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Vgs begin job fail,Error(%#x)\n", ret);
ret = memcpy_s(&vgs_task.img_in, sizeof(ot_video_frame_info), frame_info, sizeof(ot_video_frame_info));
sample_svp_check_exps_goto(ret != EOK, FAIL, SAMPLE_SVP_ERR_LEVEL_ERROR, "get img_in failed\n");
ret = memcpy_s(&vgs_task.img_out, sizeof(ot_video_frame_info), frame_info, sizeof(ot_video_frame_info));
sample_svp_check_exps_goto(ret != EOK, FAIL, SAMPLE_SVP_ERR_LEVEL_ERROR, "get img_out failed\n");
vgs_add_cover.type = OT_COVER_QUAD;
vgs_add_cover.color = color;
for (i = 0; i < rect->num; i++) {
vgs_add_cover.quad.is_solid = TD_FALSE;
vgs_add_cover.quad.thick = OT_SAMPLE_IVE_DRAW_THICK;
ret = memcpy_s(vgs_add_cover.quad.point, sizeof(rect->rect[i].point),
rect->rect[i].point, sizeof(rect->rect[i].point));
sample_svp_check_exps_goto(ret != EOK, FAIL, SAMPLE_SVP_ERR_LEVEL_ERROR, "get point failed\n");
ret = ss_mpi_vgs_add_cover_task(vgs_handle, &vgs_task, &vgs_add_cover, 1);
sample_svp_check_exps_goto(ret != TD_SUCCESS, FAIL, SAMPLE_SVP_ERR_LEVEL_ERROR,
"ss_mpi_vgs_add_cover_task fail,Error(%#x)\n", ret);
}
ret = ss_mpi_vgs_end_job(vgs_handle);
sample_svp_check_exps_goto(ret != TD_SUCCESS, FAIL, SAMPLE_SVP_ERR_LEVEL_ERROR,
"ss_mpi_vgs_end_job fail,Error(%#x)\n", ret);
return ret;
FAIL:
ss_mpi_vgs_cancel_job(vgs_handle);
return ret;
}
/* function : Start Vpss */
static td_s32 sample_common_svp_start_vpss(const td_s32 vpss_grp_cnt, ot_size *pic_size, td_u32 pic_type_num)
{
td_u32 i;
ot_vpss_chn_attr vpss_chn_attr[OT_VPSS_MAX_CHN_NUM];
ot_vpss_grp_attr vpss_grp_attr;
td_bool chn_enable[OT_VPSS_MAX_CHN_NUM] = { TD_FALSE, TD_FALSE, TD_FALSE, TD_FALSE };
ot_vpss_grp vpss_grp;
td_s32 ret;
(td_void)memset_s(&vpss_grp_attr, sizeof(ot_vpss_grp_attr), 0, sizeof(ot_vpss_grp_attr));
vpss_grp_attr.max_width = OT_SAMPLE_IVE_1080P_WIDTH;
vpss_grp_attr.max_height = OT_SAMPLE_IVE_1080P_HEIGHT;
vpss_grp_attr.frame_rate.src_frame_rate = -1;
vpss_grp_attr.frame_rate.dst_frame_rate = -1;
vpss_grp_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
vpss_grp_attr.nr_en = TD_TRUE;
vpss_grp_attr.dci_en = TD_TRUE;
vpss_grp_attr.dei_mode = OT_VPSS_DEI_MODE_OFF;
for (i = 0; (i < pic_type_num) && (i < OT_VPSS_MAX_CHN_NUM); i++) {
(td_void)memset_s(&vpss_chn_attr[i], sizeof(ot_vpss_chn_attr), 0, sizeof(ot_vpss_chn_attr));
chn_enable[i] = TD_TRUE;
vpss_chn_attr[i].width = pic_size[i].width;
vpss_chn_attr[i].height = pic_size[i].height;
vpss_chn_attr[i].chn_mode = OT_VPSS_CHN_MODE_USER;
vpss_chn_attr[i].compress_mode = OT_COMPRESS_MODE_NONE;
vpss_chn_attr[i].pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
vpss_chn_attr[i].frame_rate.src_frame_rate = -1;
vpss_chn_attr[i].frame_rate.dst_frame_rate = -1;
vpss_chn_attr[i].depth = 1;
vpss_chn_attr[i].mirror_en = TD_FALSE;
vpss_chn_attr[i].flip_en = TD_FALSE;
vpss_chn_attr[i].aspect_ratio.mode = OT_ASPECT_RATIO_NONE;
vpss_chn_attr[i].border_en = TD_TRUE;
vpss_chn_attr[i].border_attr.color = 0xffffff;
vpss_chn_attr[i].border_attr.top_width = SAMPLE_SVP_VPSS_BORDER_WIDTH;
vpss_chn_attr[i].border_attr.bottom_width = SAMPLE_SVP_VPSS_BORDER_WIDTH;
vpss_chn_attr[i].border_attr.left_width = SAMPLE_SVP_VPSS_BORDER_WIDTH;
vpss_chn_attr[i].border_attr.right_width = SAMPLE_SVP_VPSS_BORDER_WIDTH;
}
for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) {
ret = sample_common_vpss_start(vpss_grp, chn_enable, &vpss_grp_attr, vpss_chn_attr, OT_VPSS_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
sample_svp_trace_err("failed with %#x!\n", ret);
return TD_FAILURE;
}
}
return TD_SUCCESS;
}
/* function : Stop Vpss */
static td_void sample_common_svp_stop_vpss(td_s32 vpss_grp_cnt, td_u32 vpss_chn_num)
{
ot_vpss_grp vpss_grp = 0;
td_bool chn_enable[OT_VPSS_MAX_CHN_NUM] = { TD_FALSE, TD_FALSE, TD_FALSE, TD_FALSE };
td_u32 i;
for (i = 0; (i < vpss_chn_num) && (i < OT_VPSS_MAX_CHN_NUM); i++) {
chn_enable[i] = TD_TRUE;
}
for (i = 0; (i < (td_u32)vpss_grp_cnt) && (i < OT_VPSS_MAX_CHN_NUM); i++) {
sample_common_vpss_stop(vpss_grp, chn_enable, OT_VPSS_MAX_CHN_NUM);
vpss_grp++;
}
}
/*
* function : Start Vo
*/
td_s32 sample_common_svp_start_vo(sample_vo_cfg *vo_cfg)
{
sample_svp_check_exps_return(vo_cfg == TD_NULL, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR, "vo_cfg can't be null\n");
return sample_comm_vo_start_vo(vo_cfg);
}
/*
* function : Stop Vo
*/
td_void sample_common_svp_stop_vo(sample_vo_cfg *vo_cfg)
{
sample_svp_check_exps_return_void(vo_cfg == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "vo_cfg can't be null\n");
(td_void)sample_comm_vo_stop_vo(vo_cfg);
}
static td_s32 sample_common_svp_vi_bind_multi_vpss(td_s32 vpss_grp_cnt, sample_vi_param *vi_param)
{
td_s32 ret = TD_FAILURE;
td_s32 loop;
ot_vi_chn vi_chn;
const ot_vpss_chn vpss_chn = 0;
ot_vpss_grp vpss_grp = 0;
sample_svp_check_exps_return(vi_param == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "vi_param can't be null\n");
for (loop = 0; loop < vi_param->vi_chn_cnt && vpss_grp < vpss_grp_cnt; loop++) {
vi_chn = loop * vi_param->vi_chn_interval;
ret = sample_comm_vi_bind_vpss(0, vi_chn, vpss_grp, vpss_chn);
if (ret != TD_SUCCESS) {
sample_svp_trace_err("vi bind vpss failed!\n");
return ret;
}
vpss_grp++;
}
return TD_SUCCESS;
}
static td_s32 sample_common_svp_vi_unbind_multi_vpss(const td_s32 vpss_grp_cnt, sample_vi_param *vi_param)
{
td_s32 ret = TD_FAILURE;
td_s32 loop;
ot_vi_chn vi_chn;
const ot_vpss_chn vpss_chn = 0;
ot_vpss_grp vpss_grp = 0;
sample_svp_check_exps_return(vi_param == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "vi_param can't be null\n");
for (loop = 0; (loop < vi_param->vi_chn_cnt) && (vpss_grp < vpss_grp_cnt); loop++) {
vi_chn = loop * vi_param->vi_chn_interval;
ret = sample_comm_vi_un_bind_vpss(0, vi_chn, vpss_grp, vpss_chn);
if (ret != TD_SUCCESS) {
sample_svp_trace_err("vi bind vpss failed!\n");
return ret;
}
vpss_grp++;
}
return TD_SUCCESS;
}
static td_s32 sample_common_svp_set_vi_cfg(sample_vi_config *vi_config, ot_pic_size *pic_type,
td_u32 pic_type_len, ot_pic_size *ext_pic_size_type)
{
td_s32 ret;
(td_void)memset_s(vi_config, sizeof(sample_vi_config), 0, sizeof(sample_vi_config));
vi_config->video_encoding = SAMPLE_VIDEO_ENCODING_NTSC;
vi_config->vi_mode = SAMPLE_VI_MODE_720P_1X4;
sample_svp_check_exps_return(pic_type_len < SAMPLE_SVP_NUM_TWO, TD_FAILURE, SAMPLE_SVP_ERR_LEVEL_ERROR,
"pic_type_len(%u) must be larger than 2\n", pic_type_len);
ret = sample_common_vi_get_size_by_mode(vi_config->vi_mode, &pic_type[0]);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"sample_common_vi_get_size_by_mode failed!\n");
pic_type[1] = *ext_pic_size_type;
return TD_SUCCESS;
}
static td_s32 sample_common_svp_get_def_vo_cfg(sample_vo_cfg *vo_cfg)
{
ot_rect def_disp_rect = {0, 0, 1920, 1080};
ot_size def_img_size = {1920, 1080};
if (vo_cfg == TD_NULL) {
sample_svp_trace_err("error:argument can not be TD_NULL\n");
return TD_FAILURE;
}
vo_cfg->vo_dev = SAMPLE_VO_DEV_UHD;
#ifdef OT_FPGA
vo_cfg->vo_intf_type = OT_VO_INTF_BT1120;
vo_cfg->intf_sync = OT_VO_OUT_720P60;
#else
vo_cfg->vo_intf_type = OT_VO_INTF_HDMI;
vo_cfg->intf_sync = OT_VO_OUT_1080P60;
#endif
vo_cfg->bg_color = COLOR_RGB_BLACK;
vo_cfg->pix_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
vo_cfg->disp_rect = def_disp_rect;
vo_cfg->image_size = def_img_size;
vo_cfg->vo_part_mode = OT_VO_PARTITION_MODE_SINGLE;
vo_cfg->dis_buf_len = SAMPLE_SVP_VO_DIS_BUF_LEN;
vo_cfg->dst_dynamic_range = OT_DYNAMIC_RANGE_SDR8;
vo_cfg->vo_mode = VO_MODE_1MUX;
vo_cfg->compress_mode = OT_COMPRESS_MODE_NONE;
return TD_SUCCESS;
}
static td_s32 sample_common_svp_set_vi_frame_start_vo(const sample_vi_param *vi_param,
const ot_sample_svp_switch *switch_ptr, sample_vo_cfg *vo_cfg)
{
ot_vi_chn_attr vi_chn_attr;
ot_vi_chn vi_chn;
td_s32 i;
td_s32 ret;
for (i = 0; i < vi_param->vi_chn_cnt; i++) {
vi_chn = i * vi_param->vi_chn_interval;
ret = ss_mpi_vi_get_chn_attr(vi_chn, &vi_chn_attr);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),ss_mpi_vi_get_chn_attr failed!\n", ret);
ret = ss_mpi_vi_set_chn_attr(vi_chn, &vi_chn_attr);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),ss_mpi_vi_set_chn_attr failed!\n", ret);
}
/* Start Vo */
if (switch_ptr->is_vo_open == TD_TRUE) {
ret = sample_common_svp_get_def_vo_cfg(vo_cfg);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_common_svp_get_def_vo_cfg failed!\n", ret);
ret = sample_common_svp_start_vo(vo_cfg);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_common_svp_start_vo failed!\n", ret);
}
return TD_SUCCESS;
}
static td_s32 sample_common_svp_start_venc(const ot_sample_svp_switch *switch_ptr,
sample_vo_cfg *vo_cfg, ot_pic_size *pic_type, td_u32 chn_num)
{
td_s32 ret = TD_FAILURE;
ot_venc_gop_attr gop_attr;
ot_payload_type stream_type = OT_PT_H264;
sample_rc rc_mode = SAMPLE_RC_CBR;
ot_venc_chn h264_chn = 0;
sample_comm_venc_chnl_param venc_create_param = {0};
sample_svp_check_exps_goto(chn_num == 0, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),chn_num(%u) can't be 0!\n", ret, chn_num);
if (switch_ptr->is_venc_open == TD_TRUE) {
ret = sample_comm_venc_get_gop_attr(OT_VENC_GOP_MODE_NORMAL_P, &gop_attr);
sample_svp_check_exps_goto(ret != TD_SUCCESS, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_comm_venc_get_gop_attr failed!\n", ret);
venc_create_param.type = stream_type;
venc_create_param.size = pic_type[0];
venc_create_param.rc_mode = rc_mode;
venc_create_param.profile = 0;
venc_create_param.is_rcn_ref_share_buf = TD_TRUE;
venc_create_param.gop_attr = gop_attr;
ret = sample_comm_venc_start(h264_chn, &venc_create_param);
sample_svp_check_exps_goto(ret != TD_SUCCESS, end_0, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_comm_venc_start failed!\n", ret);
ret = sample_comm_venc_start_get_stream(&h264_chn, 1);
sample_svp_check_exps_goto(ret != TD_SUCCESS, end_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_comm_venc_start_get_stream failed!\n", ret);
}
return TD_SUCCESS;
end_1:
if (switch_ptr->is_venc_open == TD_TRUE) {
sample_comm_venc_stop(h264_chn);
}
end_0:
if (switch_ptr->is_vo_open == TD_TRUE) {
sample_common_svp_stop_vo(vo_cfg);
}
return ret;
}
/*
* function : Start Vi/Vpss/Venc/Vo
*/
td_s32 sample_common_svp_start_vi_vpss_venc_vo(sample_vi_config *vi_config,
ot_sample_svp_switch *switch_ptr, ot_pic_size *ext_pic_size_type)
{
ot_size pic_size[OT_VPSS_CHN_NUM];
ot_pic_size pic_type[OT_VPSS_CHN_NUM];
sample_vi_param vi_param = {0};
sample_vo_cfg vo_cfg;
const td_s32 vpss_grp_cnt = 1;
td_s32 ret = TD_FAILURE;
sample_svp_check_exps_return(vi_config == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "vi_config can't be null\n");
sample_svp_check_exps_return(switch_ptr == TD_NULL, ret, SAMPLE_SVP_ERR_LEVEL_ERROR, "switch_ptr can't be null\n");
sample_svp_check_exps_return(ext_pic_size_type == TD_NULL, ret,
SAMPLE_SVP_ERR_LEVEL_ERROR, "ext_pic_size_type can't be null\n");
ret = sample_common_svp_set_vi_cfg(vi_config, pic_type, OT_VPSS_CHN_NUM, ext_pic_size_type);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"sample_common_svp_set_vi_cfg failed,Error:%#x\n", ret);
/* step 1: Init vb */
ret = sample_common_svp_vb_init(pic_type, pic_size, OT_VPSS_CHN_NUM, &vi_param);
sample_svp_check_exps_return(ret != TD_SUCCESS, ret, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_common_svp_vb_init failed!\n", ret);
/* step 2: Start vi */
ret = sample_common_vi_start_vi(vi_config->vi_mode, vi_config->video_encoding, &vi_param);
sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_1, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_comm_vi_start_vi failed!\n", ret);
/* step 3: Start vpss */
ret = sample_common_svp_start_vpss(vpss_grp_cnt, pic_size, OT_VPSS_CHN_NUM);
sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_2, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_common_svp_start_vpss failed!\n", ret);
/* step 4: Bind vpss to vi */
ret = sample_common_svp_vi_bind_multi_vpss(vpss_grp_cnt, &vi_param);
sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_3, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_common_vi_bind_multi_vpss failed!\n", ret);
/* step 5: Set vi frame, Start Vo */
ret = sample_common_svp_set_vi_frame_start_vo(&vi_param, switch_ptr, &vo_cfg);
sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_4, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_common_svp_set_vi_frame failed!\n", ret);
/* step 6: Start Venc */
ret = sample_common_svp_start_venc(switch_ptr, &vo_cfg, pic_type, OT_VPSS_CHN_NUM);
sample_svp_check_exps_goto(ret != TD_SUCCESS, end_init_4, SAMPLE_SVP_ERR_LEVEL_ERROR,
"Error(%#x),sample_common_svp_start_venc failed!\n", ret);
return TD_SUCCESS;
end_init_4:
ret = sample_common_svp_vi_unbind_multi_vpss(vpss_grp_cnt, &vi_param);
sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "svp_vi_unbind_multi_vpss failed\n");
end_init_3:
sample_common_svp_stop_vpss(vpss_grp_cnt, OT_VPSS_CHN_NUM);
end_init_2:
ret = sample_common_vi_stop(vi_config->vi_mode, &vi_param);
sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "sample_common_vi_stop failed\n");
end_init_1: /* system exit */
sample_comm_sys_exit();
(td_void)memset_s(vi_config, sizeof(sample_vi_config), 0, sizeof(sample_vi_config));
return ret;
}
/*
* function : Stop Vi/Vpss/Venc/Vo
*/
td_void sample_common_svp_stop_vi_vpss_venc_vo(sample_vi_config *vi_config,
ot_sample_svp_switch *switch_ptr)
{
sample_vi_param vi_param = {0};
sample_vo_cfg vo_cfg = {0};
td_s32 ret;
const td_s32 vpss_grp_cnt = 1;
vi_param.vi_dev_cnt = 1;
vi_param.vi_dev_interval = 1;
vi_param.vi_chn_cnt = 1;
vi_param.vi_chn_interval = SAMPLE_SVP_VO_DIS_BUF_LEN;
vi_param.scan_mode = OT_VI_SCAN_PROGRESSIVE;
vi_param.minor_attr_en = TD_FALSE;
vi_param.minor_dst_size.width = D1_WIDTH;
vi_param.minor_dst_size.height = D1_HEIGHT_NTSC;
sample_svp_check_exps_return_void(vi_config == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "vi_config can't be null\n");
sample_svp_check_exps_return_void(switch_ptr == TD_NULL, SAMPLE_SVP_ERR_LEVEL_ERROR, "switch_ptr can't be null\n");
if (switch_ptr->is_venc_open == TD_TRUE) {
sample_comm_venc_stop_get_stream(1);
sample_comm_venc_stop(0);
}
if (switch_ptr->is_vo_open == TD_TRUE) {
(td_void)sample_common_svp_get_def_vo_cfg(&vo_cfg);
sample_common_svp_stop_vo(&vo_cfg);
}
ret = sample_common_svp_vi_unbind_multi_vpss(vpss_grp_cnt, &vi_param);
sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR,
"sample_common_svp_vi_unbind_multi_vpss failed\n");
sample_common_svp_stop_vpss(vpss_grp_cnt, OT_VPSS_CHN_NUM);
ret = sample_common_vi_stop(vi_config->vi_mode, &vi_param);
sample_svp_check_exps_trace(ret != TD_SUCCESS, SAMPLE_SVP_ERR_LEVEL_ERROR, "sample_common_vi_stop failed\n");
sample_comm_sys_exit();
(td_void)memset_s(vi_config, sizeof(sample_vi_config), 0, sizeof(sample_vi_config));
}