/* Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd. */ #include #include #include #include #include #include #include #include #include #include #include #include #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 \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; }