Files

1234 lines
36 KiB
C

/*
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include "sample_comm.h"
#define MM16_BMP "./res/mm16.bmp"
#define MM_BMP "./res/mm.bmp"
#define STREAM_PATH "res"
#define STREAM_H265_1080P "1080P.h265"
#define VB_NUM_PRE_CHN 8
#define RGN_VPSS_GRP 0
#define RGN_VPSS_CHN 0
#define RGN_VI_CHN 0
#define RGN_VENC_CHN 0
#define RGN_VB_BLK_SIZE_1 2
#define RGN_VB_BLK_SIZE_2 3
#define RGN_VB_BLK_CNT_1 2
#define RGN_VB_BLK_CNT_2 4
#define RGN_HANDLE_NUM_1 1
#define RGN_HANDLE_NUM_2 4
#define RGN_HANDLE_NUM_3 8
#define RGN_VO_CHN 0
#define RGN_VDEC_CHN 0
#define RGN_VDEC_CHN_NUM 1
ot_vpss_grp_attr g_vpss_grp_attr = {0};
td_char *g_path_bmp = TD_NULL;
pthread_t g_vdec_thread[RGN_VDEC_CHN_NUM];
sample_vi_param g_rgn_vi_param;
ot_vo_intf_type g_rgn_vo_intf_type = OT_VO_INTF_VGA | OT_VO_INTF_HDMI;
#ifdef OT_FPGA
ot_vo_intf_sync g_rgn_intf_sync = OT_VO_OUT_720P60;
sample_vi_mode g_rgn_vi_mode = SAMPLE_VI_MODE_720P_2X2;
#else
ot_vo_intf_sync g_rgn_intf_sync = OT_VO_OUT_1080P60;
sample_vi_mode g_rgn_vi_mode = SAMPLE_VI_MODE_1080P_1X2;
#endif
static sample_vdec_attr g_rgn_vdec_cfg = {
.type = OT_PT_H265,
.mode = OT_VDEC_SEND_MODE_FRAME,
.width = FHD_WIDTH,
.height = FHD_HEIGHT,
.sample_vdec_video.dec_mode = OT_VIDEO_DEC_MODE_IP,
.sample_vdec_video.bit_width = OT_DATA_BIT_WIDTH_8,
.sample_vdec_video.ref_frame_num = 2, /* 2:ref_frame_num */
.display_frame_num = 2, /* 2:display_frame_num */
.frame_buf_cnt =5, /* 5:2+2+1 */
};
static vdec_thread_param g_rgn_vdec_thread_param = {
.chn_id = 0,
.type = OT_PT_H265,
.stream_mode = OT_VDEC_SEND_MODE_FRAME,
.interval_time = 1000, /* 1000:interval_time */
.pts_init = 0,
.pts_increase = 0,
.e_thread_ctrl = THREAD_CTRL_START,
.circle_send = TD_TRUE,
.milli_sec = 0,
.min_buf_size = (FHD_WIDTH * FHD_HEIGHT * 3) >> 1, /* 3:buff_size */
.c_file_path = "res",
.c_file_name = STREAM_H265_1080P,
};
static sample_vo_cfg g_rgn_vo_config = {
.vo_dev = SAMPLE_VO_DEV_DHD0,
.vo_intf_type = OT_VO_INTF_VGA | OT_VO_INTF_HDMI,
.intf_sync = OT_VO_OUT_1080P60,
.disp_rect = {0, 0, FHD_WIDTH, FHD_HEIGHT},
.image_size = {FHD_WIDTH, FHD_HEIGHT},
.bg_color = COLOR_RGB_BLUE,
.vo_mode = VO_MODE_1MUX,
.pix_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420,
.vo_part_mode = OT_VO_PARTITION_MODE_SINGLE,
.dis_buf_len = 3, /* 3:buf len */
.dst_dynamic_range = OT_DYNAMIC_RANGE_SDR8,
.compress_mode = OT_COMPRESS_MODE_NONE,
};
/*
* function : show usage
*/
static td_void sample_region_usage(const char *s_prg_nm)
{
printf("usage : %s <index> \n", s_prg_nm);
printf("index:\n");
printf("\t 0)VI COVER.\n");
printf("\t 1)VPSS OVERLAY.\n");
printf("\t 2)VPSS OVERLAYEX.\n");
printf("\t 3)VPSS COVEREX.\n");
printf("\t 4)VPSS COVER.\n");
printf("\t 5)VPSS LINE.\n");
printf("\t 6)VPSS MOSAIC.\n");
printf("\t 7)VPSS MOSAICEX.\n");
printf("\t 8)VO OVERLAYEX.\n");
printf("\t 9)VO COVEREX.\n");
printf("\t 10)VO LINE.\n");
printf("\t 11)VENC OVERLAY.\n");
}
static int g_rgn_sample_exit = 0;
/*
* function: to process abnormal case
*/
static td_void sample_region_handle_sig(td_s32 signo)
{
if ((signo == SIGINT) || (signo == SIGTERM)) {
g_rgn_sample_exit = 1;
}
}
static td_void sample_region_pause(td_void)
{
if (g_rgn_sample_exit == 1) {
return;
}
sample_pause();
if (g_rgn_sample_exit == 1) {
return;
}
}
static td_s32 sample_region_start_venc(td_void)
{
td_s32 ret;
ot_venc_gop_mode gop_mode;
ot_venc_gop_attr gop_attr;
sample_rc rc_mode;
ot_pic_size pic_size;
sample_comm_venc_chnl_param venc_create_param = {0};
rc_mode = SAMPLE_RC_CBR;
gop_mode = OT_VENC_GOP_MODE_NORMAL_P;
sample_common_vi_get_size_by_mode(g_rgn_vi_mode, &pic_size);
ret = sample_comm_venc_get_gop_attr(gop_mode, &gop_attr);
venc_create_param.type = OT_PT_H265;
venc_create_param.size = pic_size;
venc_create_param.rc_mode = rc_mode;
venc_create_param.profile = 0;
venc_create_param.is_rcn_ref_share_buf = 0;
venc_create_param.gop_attr = gop_attr;
ret = sample_comm_venc_start(0, &venc_create_param);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_venc_start_venc failed with %d!\n", ret);
sample_comm_venc_stop(0);
}
return ret;
}
static td_s32 sample_region_stop_venc(td_void)
{
sample_comm_venc_stop(RGN_VENC_CHN);
return TD_SUCCESS;
}
static td_void sample_region_start_get_venc_stream(td_void)
{
td_s32 venc_chn[2] = {0, 1}; /* 2:VENC chn max num */
sample_comm_venc_start_get_stream(venc_chn, 1);
return;
}
static td_void sample_region_stop_get_venc_stream(td_void)
{
sample_comm_venc_stop_get_stream(1);
return;
}
static td_s32 sample_region_mpp_start_vpss(ot_vpss_grp vpss_grp,
td_bool *chn_enable, ot_vpss_grp_attr *vpss_grp_attr, ot_vpss_chn_attr *vpss_chn_attr)
{
td_s32 ret;
td_s32 j;
ot_vpss_chn vpss_chn;
ret = ss_mpi_vpss_create_grp(vpss_grp, vpss_grp_attr);
if (ret != TD_SUCCESS) {
sample_print("ss_mpi_vpss_create_grp(grp:%d) failed with %#x!\n", vpss_grp, ret);
return TD_FAILURE;
}
ret = ss_mpi_vpss_start_grp(vpss_grp);
if (ret != TD_SUCCESS) {
sample_print("ss_mpi_vpss_start_grp failed with %#x\n", ret);
return TD_FAILURE;
}
for (j = 0; j < OT_VPSS_MAX_PHYS_CHN_NUM; j++) {
if (chn_enable[j] == TD_TRUE) {
vpss_chn = j;
ret = ss_mpi_vpss_set_chn_attr(vpss_grp, vpss_chn, &vpss_chn_attr[vpss_chn]);
if (ret != TD_SUCCESS) {
sample_print("ss_mpi_vpss_set_chn_attr failed with %#x\n", ret);
return TD_FAILURE;
}
ret = ss_mpi_vpss_enable_chn(vpss_grp, vpss_chn);
if (ret != TD_SUCCESS) {
sample_print("ss_mpi_vpss_enable_chn failed with %#x\n", ret);
return TD_FAILURE;
}
}
}
return TD_SUCCESS;
}
static td_s32 get_vb_attr(sample_vi_mode vi_mode)
{
switch (vi_mode) {
case SAMPLE_VI_MODE_720P_1X4:
case SAMPLE_VI_MODE_960H_4X4:
case SAMPLE_VI_MODE_720P_4X4:
return 0;
case SAMPLE_VI_MODE_720P_2X2:
case SAMPLE_VI_MODE_1080P_2X2:
case SAMPLE_VI_MODE_1080P_1X2:
case SAMPLE_VI_MODE_4K_1X8:
return 1;
default:
sample_print("vi_mode invalid !\n");
return TD_FAILURE;
}
}
static td_s32 sample_region_set_vb_cfg(sample_vi_mode vi_mode,
ot_size *size, sample_vi_param *vi_param, ot_vb_cfg *vb_cfg)
{
td_s32 vb_type;
td_u32 blk_size;
ot_pic_buf_attr pic_buf_attr;
(td_void)memset_s(vb_cfg, sizeof(ot_vb_cfg), 0, sizeof(ot_vb_cfg));
vb_type = get_vb_attr(vi_mode);
if (vb_type == 0) {
vb_cfg->max_pool_cnt = 2; /* 2:max_pool_cnt */
pic_buf_attr.width = size->width;
pic_buf_attr.height = size->height;
pic_buf_attr.pixel_format = SAMPLE_PIXEL_FORMAT;
pic_buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
pic_buf_attr.compress_mode = OT_COMPRESS_MODE_SEG_COMPACT;
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 * RGN_VB_BLK_SIZE_1;
vb_cfg->common_pool[0].blk_cnt = vi_param->vi_chn_cnt * VB_NUM_PRE_CHN * RGN_VB_BLK_CNT_1;
pic_buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
blk_size = ot_common_get_pic_buf_size(&pic_buf_attr);
vb_cfg->common_pool[1].blk_size = blk_size * RGN_VB_BLK_SIZE_2;
vb_cfg->common_pool[1].blk_cnt = vi_param->vi_chn_cnt * VB_NUM_PRE_CHN * RGN_VB_BLK_CNT_1;
} else if (vb_type == 1) {
vb_cfg->max_pool_cnt = 3; /* 3:max_pool_cnt */
pic_buf_attr.width = size->width;
pic_buf_attr.height = size->height;
pic_buf_attr.pixel_format = SAMPLE_PIXEL_FORMAT;
pic_buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
pic_buf_attr.compress_mode = OT_COMPRESS_MODE_SEG_COMPACT;
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 = RGN_VB_BLK_CNT_2 * VB_NUM_PRE_CHN;
pic_buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
blk_size = ot_common_get_pic_buf_size(&pic_buf_attr);
vb_cfg->common_pool[1].blk_size = blk_size * RGN_VB_BLK_SIZE_1; /* 1:the second blk */
vb_cfg->common_pool[1].blk_cnt = vi_param->vi_chn_cnt * VB_NUM_PRE_CHN; /* 1:the second blk */
pic_buf_attr.width = vi_param->minor_dst_size.width;
pic_buf_attr.width = vi_param->minor_dst_size.height;
blk_size = ot_common_get_pic_buf_size(&pic_buf_attr);
vb_cfg->common_pool[2].blk_size = blk_size * RGN_VB_BLK_SIZE_1; /* 2:the third blk */
vb_cfg->common_pool[2].blk_cnt = vi_param->vi_chn_cnt * VB_NUM_PRE_CHN; /* 2:the third blk */
}
return TD_SUCCESS;
}
static td_s32 sample_region_start_vi(td_void)
{
sample_video_encoding video_encoding = SAMPLE_VIDEO_ENCODING_NTSC;
ot_vb_cfg vb_cfg;
td_s32 ret;
ot_size size;
ot_pic_size pic_size;
ret = sample_common_vi_get_size_by_mode(g_rgn_vi_mode, &pic_size);
if (ret != TD_SUCCESS) {
sample_print("get size by mode failed!\n");
return ret;
}
ret = sample_comm_sys_get_pic_size(pic_size, &size);
if (ret != TD_SUCCESS) {
sample_print("get pic size failed!\n");
return ret;
}
/* get parameter from vi mode */
ret = sample_common_vi_mode_to_param(g_rgn_vi_mode, &g_rgn_vi_param);
if (ret != TD_SUCCESS) {
sample_print("vi get param failed!\n");
return ret;
}
g_rgn_vi_param.minor_attr_en = TD_FALSE;
ret = sample_region_set_vb_cfg(g_rgn_vi_mode, &size, &g_rgn_vi_param, &vb_cfg);
if (ret != TD_SUCCESS) {
sample_print("set vb config failed!\n");
return ret;
}
ret = sample_comm_sys_init(&vb_cfg);
if (ret != TD_SUCCESS) {
sample_print("system init failed with 0x%x!\n", ret);
sample_comm_sys_exit();
return ret;
}
ret = sample_common_vi_start_vi(g_rgn_vi_mode, video_encoding, &g_rgn_vi_param);
if (ret != TD_SUCCESS) {
sample_print("start vi failed with 0x%x!\n", ret);
sample_comm_sys_exit();
return ret;
}
return TD_SUCCESS;
}
static td_s32 sample_region_stop_vi(td_void)
{
td_s32 i;
td_s32 ret;
ot_vi_dev vi_dev;
ot_vi_chn vi_chn;
/* stop vi chn */
for (i = 0; i < g_rgn_vi_param.vi_chn_cnt; i++) {
vi_chn = i * g_rgn_vi_param.vi_chn_interval;
ret = ss_mpi_vi_disable_chn(vi_chn);
if (ret != TD_SUCCESS) {
sample_print("ss_mpi_vi_disable_chn failed!\n");
return ret;
}
}
/* stop vi dev */
for (i = 0; i < g_rgn_vi_param.vi_dev_cnt; i++) {
vi_dev = i * g_rgn_vi_param.vi_dev_interval;
ret = ss_mpi_vi_disable_dev(vi_dev);
if (ret != TD_SUCCESS) {
sample_print("ss_mpi_vi_disable_dev failed!\n");
return ret;
}
}
return TD_SUCCESS;
}
static td_s32 sample_region_start_vdec(td_u32 chn_num, sample_vdec_attr *vdec_attr)
{
td_s32 ret;
ot_pic_buf_attr buf_attr = {0};
ot_vb_cfg vb_cfg;
ot_size disp_size;
ot_pic_size disp_pic_size = PIC_1080P;
ret = sample_comm_sys_get_pic_size(disp_pic_size, &disp_size);
if (ret != TD_SUCCESS) {
sample_print("sys get pic size fail for %#x!\n", ret);
sample_comm_sys_exit();
return ret;
}
buf_attr.align = 0;
buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
buf_attr.height = disp_size.height;
buf_attr.width = disp_size.width;
buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
(td_void)memset_s(&vb_cfg, sizeof(ot_vb_cfg), 0, sizeof(ot_vb_cfg));
vb_cfg.max_pool_cnt = 1; /* 1:vb pool cnt */
vb_cfg.common_pool[0].blk_cnt = 10 * RGN_VDEC_CHN_NUM; /* 10:vb blk cnt */
vb_cfg.common_pool[0].blk_size = ot_common_get_pic_buf_size(&buf_attr);
ret = sample_comm_sys_init(&vb_cfg);
if (ret != TD_SUCCESS) {
sample_print("init sys fail for %#x!\n", ret);
sample_comm_sys_exit();
return ret;
}
ret = sample_comm_vdec_init_vb_pool(chn_num, vdec_attr, OT_VDEC_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
sample_print("vdec init vb_pool fail\n");
sample_comm_sys_exit();
return ret;
}
ret = sample_comm_vdec_start(chn_num, vdec_attr, OT_VDEC_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
sample_print("vdec start fail\n");
sample_comm_vdec_exit_vb_pool();
sample_comm_sys_exit();
}
return ret;
}
static td_s32 sample_region_end_vdec(td_u32 chn_num)
{
td_s32 ret;
ret = sample_comm_vdec_stop(chn_num);
if (ret != TD_SUCCESS) {
printf("vdec stop fail\n");
return TD_FAILURE;
}
sample_comm_vdec_exit_vb_pool();
return TD_SUCCESS;
}
static td_s32 sample_region_common_start_vpss(td_s32 vpss_grp, td_s32 vpss_chn, ot_size *size)
{
td_s32 ret;
ot_vpss_grp_attr grp_attr;
ot_vpss_chn_attr chn_attr[OT_VPSS_MAX_PHYS_CHN_NUM] = {0};
td_bool chn_enable[OT_VPSS_MAX_PHYS_CHN_NUM] = {0};
(td_void)memset_s(&grp_attr, sizeof(ot_vpss_grp_attr), 0, sizeof(ot_vpss_grp_attr));
grp_attr.max_width = size->width;
grp_attr.max_height = size->height;
grp_attr.nr_en = TD_FALSE;
grp_attr.dci_en = TD_FALSE;
grp_attr.ie_en = TD_FALSE;
grp_attr.dei_mode = OT_VPSS_DEI_MODE_OFF;
grp_attr.pixel_format = SAMPLE_PIXEL_FORMAT;
grp_attr.frame_rate.src_frame_rate = -1;
grp_attr.frame_rate.dst_frame_rate = -1;
grp_attr.buf_share_en = TD_FALSE;
(td_void)memset_s(&chn_attr[vpss_chn], sizeof(ot_vpss_chn_attr), 0, sizeof(ot_vpss_chn_attr));
chn_enable[vpss_chn] = TD_TRUE;
chn_attr[vpss_chn].border_en = TD_FALSE;
chn_attr[vpss_chn].width = FHD_WIDTH;
chn_attr[vpss_chn].height = FHD_HEIGHT;
chn_attr[vpss_chn].chn_mode = OT_VPSS_CHN_MODE_AUTO;
chn_attr[vpss_chn].compress_mode = OT_COMPRESS_MODE_SEG;
chn_attr[vpss_chn].pixel_format = SAMPLE_PIXEL_FORMAT;
chn_attr[vpss_chn].frame_rate.src_frame_rate = -1;
chn_attr[vpss_chn].frame_rate.dst_frame_rate = -1;
chn_attr[vpss_chn].depth = 0;
chn_attr[vpss_chn].mirror_en = TD_FALSE;
chn_attr[vpss_chn].flip_en = TD_FALSE;
chn_attr[vpss_chn].aspect_ratio.mode = OT_ASPECT_RATIO_NONE;
ret = sample_region_mpp_start_vpss(vpss_grp, &chn_enable[vpss_chn], &grp_attr, &chn_attr[vpss_chn]);
if (ret != TD_SUCCESS) {
sample_print("failed with %#x!\n", ret);
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_s32 sample_region_stop_vpss(td_void)
{
td_s32 ret;
td_bool chn_enable[OT_VPSS_MAX_PHYS_CHN_NUM] = {0};
ret = sample_comm_vi_un_bind_vpss(0, RGN_VI_CHN, RGN_VPSS_GRP, RGN_VPSS_CHN);
if (ret != TD_SUCCESS) {
sample_print("failed with %#x!\n", ret);
return TD_FAILURE;
}
ret = sample_common_vpss_stop(RGN_VPSS_GRP, chn_enable, OT_VPSS_MAX_PHYS_CHN_NUM);
if (ret != TD_SUCCESS) {
sample_print("failed with %#x!\n", ret);
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_s32 sample_region_start_vpss(td_void)
{
td_s32 ret;
ot_size size;
size.width = FHD_WIDTH;
size.height = FHD_HEIGHT;
ret = sample_region_common_start_vpss(RGN_VPSS_GRP, RGN_VPSS_CHN, &size);
if (ret != TD_SUCCESS) {
sample_print("start vpss failed with 0x%x!\n", ret);
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_s32 sample_region_mpp_vi_vpss_venc_start(td_void)
{
td_s32 ret;
ret = sample_region_start_vi();
if (ret != TD_SUCCESS) {
sample_print("start vi failed with 0x%x!\n", ret);
goto exit_vpss;
}
ret = sample_region_start_vpss();
if (ret != TD_SUCCESS) {
sample_print("start vpss failed with 0x%x!\n", ret);
goto exit_vpss;
}
ret = sample_comm_vi_bind_vpss(0, RGN_VI_CHN, RGN_VPSS_GRP, RGN_VPSS_CHN);
if (ret != TD_SUCCESS) {
sample_print("vi_bind_multi_vpss 0x%x!\n", ret);
goto exit_vpss_bind;
}
ret = sample_comm_vpss_bind_venc(RGN_VPSS_GRP, RGN_VPSS_CHN, RGN_VENC_CHN);
if (ret != TD_SUCCESS) {
sample_print("bind vpss venc failed!\n");
goto bind_vpss_venc_failed;
}
ret = sample_region_start_venc();
if (ret != TD_SUCCESS) {
sample_print("start venc failed!\n");
goto start_venc_failed;
}
sample_region_start_get_venc_stream();
return ret;
bind_vpss_venc_failed:
ret = sample_region_stop_venc();
if (ret != TD_SUCCESS) {
sample_print("stop venc failed!\n");
}
start_venc_failed:
sample_comm_vi_un_bind_vpss(0, RGN_VI_CHN, RGN_VPSS_GRP, RGN_VPSS_CHN);
exit_vpss_bind:
ret = sample_region_stop_vpss();
if (ret != TD_SUCCESS) {
sample_print("stop vpss failed!\n");
}
exit_vpss:
ret = sample_region_stop_vi();
if (ret != TD_SUCCESS) {
sample_print("stop vpss failed!\n");
}
return ret;
}
static td_s32 sample_region_mpp_vi_vpss_venc_end(td_void)
{
td_s32 ret;
sample_region_stop_get_venc_stream();
ret = sample_comm_vpss_un_bind_venc(RGN_VPSS_GRP, RGN_VPSS_CHN, RGN_VENC_CHN);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_vpss_un_bind_venc failed!\n");
return ret;
}
ret = sample_region_stop_venc();
if (ret != TD_SUCCESS) {
sample_print("sample_region_stop_venc failed!\n");
return ret;
}
ret = sample_region_stop_vpss();
if (ret != TD_SUCCESS) {
sample_print("sample_region_stop_vpss failed!\n");
return ret;
}
ret = sample_region_stop_vi();
if (ret != TD_SUCCESS) {
sample_print("sample_region_stop_vi failed!\n");
return ret;
}
sample_comm_sys_exit();
return TD_SUCCESS;
}
static td_s32 sample_region_vi_vpss_venc(td_s32 handle_num, ot_rgn_type type, ot_mpp_chn *chn)
{
td_s32 i;
td_s32 ret;
td_s32 min_handle;
ret = sample_region_mpp_vi_vpss_venc_start();
if (ret != TD_SUCCESS) {
return ret;
}
ret = sample_comm_region_create(handle_num, type);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_create failed!\n");
goto exit1;
}
ret = sample_comm_region_attach_to_chn(handle_num, type, chn);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_attach_to_chn failed!\n");
goto exit2;
}
min_handle = sample_comm_region_get_min_handle(type);
if (type == OT_RGN_OVERLAY || type == OT_RGN_OVERLAYEX) {
for (i = min_handle; i < min_handle + handle_num; i++) {
ret = sample_comm_region_set_bit_map(i, g_path_bmp);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_set_bit_map failed!\n");
goto exit2;
}
}
}
sample_region_pause();
exit2:
ret = sample_comm_region_detach_frm_chn(handle_num, type, chn);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_attach_to_chn failed!\n");
}
exit1:
ret = sample_comm_region_destroy(handle_num, type);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_attach_to_chn failed!\n");
}
ret = sample_region_mpp_vi_vpss_venc_end();
if (ret != TD_SUCCESS) {
sample_print("sample_region_mpp_vi_vpss_venc_end failed!\n");
}
return ret;
}
static td_s32 sample_region_mpp_vi_vpss_vo_start(td_void)
{
td_s32 ret;
ret = sample_region_start_vi();
if (ret != TD_SUCCESS) {
sample_print("start vi failed with 0x%x!\n", ret);
return ret;
}
ret = sample_region_start_vpss();
if (ret != TD_SUCCESS) {
sample_print("start vpss failed with 0x%x!\n", ret);
return ret;
}
ret = sample_comm_vi_bind_vpss(0, RGN_VI_CHN, RGN_VPSS_GRP, RGN_VPSS_CHN);
if (ret != TD_SUCCESS) {
sample_print("vi_bind_multi_vpss 0x%x!\n", ret);
goto EXIT_VO_DHD0;
}
/******************************************
start vo DHD0 (HDMI+VGA), multi-screen, you can switch mode
******************************************/
sample_comm_vo_get_def_config(&g_rgn_vo_config);
g_rgn_vo_config.vo_dev = SAMPLE_VO_DEV_DHD0;
g_rgn_vo_config.vo_intf_type = g_rgn_vo_intf_type;
g_rgn_vo_config.intf_sync = g_rgn_intf_sync;
g_rgn_vo_config.bg_color = COLOR_RGB_BLUE;
g_rgn_vo_config.vo_mode = VO_MODE_1MUX;
ret = sample_comm_vo_start_vo(&g_rgn_vo_config);
if (ret != TD_SUCCESS) {
sample_print("start vo failed with 0x%x!\n", ret);
goto EXIT_VO_DHD0;
}
ret = sample_comm_vpss_bind_vo(RGN_VPSS_GRP, RGN_VPSS_CHN, SAMPLE_VO_LAYER_VHD0, 0);
if (ret != TD_SUCCESS) {
sample_print("vpss bind vo failed with 0x%x!\n", ret);
goto EXIT_VO_DHD0_BIND;
}
return ret;
EXIT_VO_DHD0:
sample_comm_vi_un_bind_vpss(0, RGN_VI_CHN, RGN_VPSS_GRP, RGN_VPSS_CHN);
EXIT_VO_DHD0_BIND:
ret = sample_comm_vo_stop_vo(&g_rgn_vo_config);
if (ret != TD_SUCCESS) {
sample_print("stop vo failed!\n");
}
return ret;
}
static td_s32 sample_region_mpp_vi_vpss_vo_end(td_void)
{
td_s32 ret;
sample_vo_mode vo_mode = VO_MODE_1MUX;
ot_vo_dev vo_dev_dhd0 = SAMPLE_VO_DEV_DHD0;
g_rgn_vo_config.vo_dev = vo_dev_dhd0;
g_rgn_vo_config.vo_intf_type = g_rgn_vo_intf_type;
g_rgn_vo_config.intf_sync = g_rgn_intf_sync;
g_rgn_vo_config.bg_color = COLOR_RGB_BLUE;
g_rgn_vo_config.vo_mode = vo_mode;
ret = sample_comm_vo_stop_vo(&g_rgn_vo_config);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_vo_stop_vo failed!\n");
return ret;
}
ret = sample_region_stop_vi();
if (ret != TD_SUCCESS) {
sample_print("sample_region_stop_vi failed!\n");
return ret;
}
sample_comm_sys_exit();
return ret;
}
static td_s32 sample_region_set_bmp(td_s32 handle_num, ot_rgn_type type)
{
td_s32 min_handle, i, ret;
min_handle = sample_comm_region_get_min_handle(type);
if (type == OT_RGN_OVERLAY) {
for (i = min_handle; i < min_handle + handle_num; i++) {
ret = sample_comm_region_set_bit_map(i, g_path_bmp);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_set_bit_map failed!\n");
return ret;
}
}
} else if (type == OT_RGN_OVERLAYEX) {
for (i = min_handle; i < min_handle + handle_num; i++) {
ret = sample_comm_region_get_up_canvas(i, g_path_bmp);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_get_up_canvas failed!\n");
return ret;
}
}
}
return TD_SUCCESS;
}
static td_s32 sample_region_vi_vpss_vo(td_s32 handle_num, ot_rgn_type type, ot_mpp_chn *chn)
{
td_s32 ret;
ret = sample_region_mpp_vi_vpss_vo_start();
if (ret != TD_SUCCESS) {
sample_print("sample_region_mpp_vi_vpss_vo_start failed!\n");
return ret;
}
ret = sample_comm_region_create(handle_num, type);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_create failed!\n");
goto exit1;
}
ret = sample_comm_region_attach_to_chn(handle_num, type, chn);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_attach_to_chn failed!\n");
goto exit2;
}
ret = sample_region_set_bmp(handle_num, type);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_set_bmp failed!\n");
goto exit2;
}
sample_region_pause();
exit2:
ret = sample_comm_region_detach_frm_chn(handle_num, type, chn);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_detach_frm_chn failed!\n");
}
exit1:
ret = sample_comm_region_destroy(handle_num, type);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_destroy failed!\n");
}
ret = sample_region_mpp_vi_vpss_vo_end();
if (ret != TD_SUCCESS) {
sample_print("sample_region_mpp_vi_vpss_vo_end failed!\n");
}
return ret;
}
static td_s32 sample_region_vdec_vpss_vo_start(td_void)
{
td_s32 ret;
ret = sample_region_start_vdec(RGN_VDEC_CHN_NUM, &g_rgn_vdec_cfg);
if (ret != TD_SUCCESS) {
sample_print("start vdec failed with 0x%x!\n", ret);
return ret;
}
ret = sample_region_start_vpss();
if (ret != TD_SUCCESS) {
sample_print("start vpss failed with 0x%x!\n", ret);
goto EXIT_VDEC;
}
ret = sample_comm_vdec_bind_vpss(RGN_VDEC_CHN, RGN_VPSS_GRP);
if (ret != TD_SUCCESS) {
sample_print("vi_bind_multi_vpss 0x%x!\n", ret);
goto EXIT_VPSS;
}
ret = sample_comm_vo_start_vo(&g_rgn_vo_config);
if (ret != TD_SUCCESS) {
sample_print("start vo failed with 0x%x!\n", ret);
goto EXIT_VDEC_UNBIND_VPSS;
}
ret = sample_comm_vpss_bind_vo(RGN_VPSS_GRP, RGN_VPSS_CHN, SAMPLE_VO_LAYER_VHD0, RGN_VO_CHN);
if (ret != TD_SUCCESS) {
sample_print("vpss bind vo failed with 0x%x!\n", ret);
goto EXIT_STOP_VO;
}
sample_comm_vdec_start_send_stream(RGN_VDEC_CHN_NUM, &g_rgn_vdec_thread_param, &g_vdec_thread[0],
RGN_VDEC_CHN_NUM, RGN_VDEC_CHN_NUM);
return ret;
EXIT_STOP_VO:
sample_comm_vdec_stop_send_stream(RGN_VDEC_CHN_NUM, &g_rgn_vdec_thread_param, &g_vdec_thread[0],
RGN_VDEC_CHN_NUM, RGN_VDEC_CHN_NUM);
sample_comm_vo_stop_vo(&g_rgn_vo_config);
EXIT_VDEC_UNBIND_VPSS:
sample_comm_vdec_un_bind_vpss(RGN_VDEC_CHN, RGN_VPSS_GRP);
EXIT_VPSS:
ret = sample_region_stop_vpss();
if (ret != TD_SUCCESS) {
sample_print("sample_region_stop_vpss failed with 0x%x!\n", ret);
return ret;
}
EXIT_VDEC:
ret = sample_region_end_vdec(RGN_VDEC_CHN_NUM);
if (ret != TD_SUCCESS) {
sample_print("sample_region_stop_vpss failed with 0x%x!\n", ret);
}
return ret;
}
static td_s32 sample_region_vdec_vpss_vo_end(td_void)
{
td_s32 ret;
ret = sample_comm_vpss_un_bind_vo(RGN_VPSS_GRP, RGN_VPSS_CHN, SAMPLE_VO_LAYER_VHD0, RGN_VO_CHN);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_vpss_un_bind_vo failed with 0x%x!\n", ret);
return ret;
}
ret = sample_comm_vo_stop_vo(&g_rgn_vo_config);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_vo_stop_vo failed with 0x%x!\n", ret);
return ret;
}
ret = sample_comm_vdec_un_bind_vpss(RGN_VDEC_CHN, RGN_VPSS_GRP);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_vdec_un_bind_vpss failed with 0x%x!\n", ret);
return ret;
}
sample_comm_vdec_stop_send_stream(1, &g_rgn_vdec_thread_param, &g_vdec_thread[0],
RGN_VDEC_CHN_NUM, RGN_VDEC_CHN_NUM);
ret = sample_region_stop_vpss();
if (ret != TD_SUCCESS) {
sample_print("sample_comm_vdec_un_bind_vpss failed with 0x%x!\n", ret);
return ret;
}
ret = sample_region_end_vdec(RGN_VDEC_CHN_NUM);
if (ret != TD_SUCCESS) {
sample_print("sample_region_end_vdec failed with 0x%x!\n", ret);
return ret;
}
return TD_SUCCESS;
}
static td_s32 sample_region_vdec_vpss_vo(td_s32 handle_num, ot_rgn_type type, ot_mpp_chn *chn)
{
td_s32 ret;
ret = sample_region_vdec_vpss_vo_start();
if (ret != TD_SUCCESS) {
sample_print("sample_region_mpp_vi_vpss_vo_start failed!\n");
return ret;
}
ret = sample_comm_region_create(handle_num, type);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_create failed!\n");
goto exit1;
}
ret = sample_comm_region_attach_to_chn(handle_num, type, chn);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_attach_to_chn failed!\n");
goto exit2;
}
ret = sample_region_set_bmp(handle_num, type);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_set_bmp failed!\n");
goto exit2;
}
sample_region_pause();
exit2:
ret = sample_comm_region_detach_frm_chn(handle_num, type, chn);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_detach_frm_chn failed!\n");
}
exit1:
ret = sample_comm_region_destroy(handle_num, type);
if (ret != TD_SUCCESS) {
sample_print("sample_comm_region_destroy failed!\n");
}
ret = sample_region_vdec_vpss_vo_end();
return ret;
}
static td_s32 sample_region_vi_cover(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 4; /* 4:vi cover num */
type = OT_RGN_COVER;
chn.mod_id = OT_ID_VI;
chn.dev_id = 0;
chn.chn_id = 0;
return sample_region_vi_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vpss_overlay(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 8; /* 8:vpss overlay num */
type = OT_RGN_OVERLAY;
chn.mod_id = OT_ID_VPSS;
chn.dev_id = 0;
chn.chn_id = 0;
g_path_bmp = MM_BMP;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vpss_overlayex(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 8; /* 8:vpss overlayex num */
type = OT_RGN_OVERLAYEX;
chn.mod_id = OT_ID_VPSS;
chn.dev_id = 0;
chn.chn_id = 0;
g_path_bmp = MM_BMP;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vpss_coverex(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 4; /* 4:vpss coverex num */
type = OT_RGN_COVEREX;
chn.mod_id = OT_ID_VPSS;
chn.dev_id = 0;
chn.chn_id = 0;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vpss_cover(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 4; /* 4:vpss cover num */
type = OT_RGN_COVER;
chn.mod_id = OT_ID_VPSS;
chn.dev_id = 0;
chn.chn_id = 0;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vpss_line(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 4; /* 4:vpss line num */
type = OT_RGN_LINE;
chn.mod_id = OT_ID_VPSS;
chn.dev_id = 0;
chn.chn_id = 0;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vpss_mosaic(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 4; /* 4:vpss mosaic num */
type = OT_RGN_MOSAIC;
chn.mod_id = OT_ID_VPSS;
chn.dev_id = 0;
chn.chn_id = 0;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vpss_mosaicex(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 4; /* 4:vpss mosaic num */
type = OT_RGN_MOSAICEX;
chn.mod_id = OT_ID_VPSS;
chn.dev_id = 0;
chn.chn_id = 0;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vo_overlayex(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 1; /* 1:vo overlayex num */
type = OT_RGN_OVERLAYEX;
chn.mod_id = OT_ID_VO;
chn.dev_id = 0;
chn.chn_id = 0;
g_path_bmp = MM_BMP;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vo_coverex(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 1; /* vo coverex num */
type = OT_RGN_COVEREX;
chn.mod_id = OT_ID_VO;
chn.dev_id = 0;
chn.chn_id = 0;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_vo_line(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 1; /* vo line num */
type = OT_RGN_LINE;
chn.mod_id = OT_ID_VO;
chn.dev_id = 0;
chn.chn_id = 0;
return sample_region_vdec_vpss_vo(handle_num, type, &chn);
}
static td_s32 sample_region_venc_overlay(td_void)
{
td_s32 handle_num;
ot_rgn_type type;
ot_mpp_chn chn;
handle_num = 8; /* 8:venc overlay num */
type = OT_RGN_OVERLAY;
chn.mod_id = OT_ID_VENC;
chn.dev_id = 0;
chn.chn_id = 0;
g_path_bmp = MM_BMP;
return sample_region_vi_vpss_venc(handle_num, type, &chn);
}
static td_s32 sample_region_index_start(td_s32 index)
{
td_s32 ret;
switch (index) {
case 0: /* 0 vi cover */
ret = sample_region_vi_cover();
break;
case 1: /* 1 vpss overlay */
ret = sample_region_vpss_overlay();
break;
case 2: /* 2 vpss overlayex */
ret = sample_region_vpss_overlayex();
break;
case 3: /* 3 vpss coverex */
ret = sample_region_vpss_coverex();
break;
case 4: /* 4 vpss cover */
ret = sample_region_vpss_cover();
break;
case 5: /* 5 vpss line */
ret = sample_region_vpss_line();
break;
case 6: /* 6 vpss mosaic */
ret = sample_region_vpss_mosaic();
break;
case 7: /* 7 vpss mosaicex */
ret = sample_region_vpss_mosaicex();
break;
case 8: /* 8 vo overlayex */
ret = sample_region_vo_overlayex();
break;
case 9: /* 9 vo coverex */
ret = sample_region_vo_coverex();
break;
case 10: /* 10 vo line */
ret = sample_region_vo_line();
break;
case 11: /* 11 venc overlay */
ret = sample_region_venc_overlay();
break;
default:
sample_print("the index(%d) is invalid!\n", index);
return TD_FAILURE;
}
return ret;
}
static td_s32 sample_region_get_argv_val(char *argv[], td_u32 index, td_slong *val)
{
td_char *end_ptr = TD_NULL;
td_slong result;
errno = 0;
result = strtol(argv[index], &end_ptr, 10); /* 10:base */
if ((end_ptr == argv[index]) || (*end_ptr != '\0')) {
return TD_FAILURE;
} else if (((result == LONG_MIN) || (result == LONG_MAX)) &&
(errno == ERANGE)) {
return TD_FAILURE;
}
*val = result;
return TD_SUCCESS;
}
#ifdef __LITEOS__
int app_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{
td_s32 ret = TD_FAILURE;
td_s32 index;
td_slong result = 0;
struct sigaction sa;
if (argc != 2) { /* 2: arg num */
sample_region_usage(argv[0]);
return TD_FAILURE;
}
if (strncmp(argv[1], "-h", 2) == 0) { /* 2: arg num */
sample_region_usage(argv[0]);
return TD_SUCCESS;
}
#ifndef __LITEOS__
(td_void)memset_s(&sa, sizeof(struct sigaction), 0, sizeof(struct sigaction));
sa.sa_handler = sample_region_handle_sig;
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
#endif
ret = sample_region_get_argv_val(argv, 1, &result);
if (ret != TD_SUCCESS) {
sample_print("the index is invalid!\n");
sample_region_usage(argv[0]);
return ret;
}
if ((result < 0) || (result > 11)) { /* 11:max index */
sample_print("the index(%ld) is invalid!\n", result);
sample_region_usage(argv[0]);
return TD_FAILURE;
}
index = (td_s32)result;
ret = sample_region_index_start(index);
if ((ret == TD_SUCCESS) && (g_rgn_sample_exit == 0)) {
sample_print("program exit normally!\n");
} else {
sample_print("program exit abnormally!\n");
}
return ret;
}