/* Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd. */ #include #include #include #include #include #include #include #include #include #include #include "sample_comm.h" #define VB_NUM_PRE_CHN 8 #define SAMPLE_CHN_NUM 4 static int g_sample_vio_exit = 0; static void sample_vio_handle_sig(td_s32 signo) { if (signo == SIGINT || signo == SIGTERM) { g_sample_vio_exit = 1; } } static int sample_vio_getchar(td_void) { int c; if (g_sample_vio_exit == 1) { sample_comm_sys_exit(); printf("\033[0;31mprogram termination abnormally!\033[0;39m\n"); exit(-1); } c = getchar(); if (g_sample_vio_exit == 1) { sample_comm_sys_exit(); printf("\033[0;31mprogram termination abnormally!\033[0;39m\n"); exit(-1); } return c; } static td_s32 sample_vio_get_vb_type(sample_vi_mode vi_mode) { td_s32 vb_type; switch (vi_mode) { case SAMPLE_VI_MODE_720P_1X4: case SAMPLE_VI_MODE_960H_4X4: case SAMPLE_VI_MODE_720P_4X4: vb_type = 0; break; case SAMPLE_VI_MODE_720P_2X2: case SAMPLE_VI_MODE_1080P_1X2: case SAMPLE_VI_MODE_1080P_2X2: case SAMPLE_VI_MODE_1080P_2X1: case SAMPLE_VI_MODE_4K_1X8: vb_type = 1; break; default: sample_print("vi_mode invalid !\n"); return TD_FAILURE; } return vb_type; } static td_s32 sample_vio_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 = sample_vio_get_vb_type(vi_mode); if (vb_type == TD_FAILURE) { return TD_FAILURE; } if (vb_type == 0) { vb_cfg->max_pool_cnt = 2; /* 2: max vb pool */ 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 = vi_param->vi_chn_cnt * 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; vb_cfg->common_pool[1].blk_cnt = vi_param->vi_chn_cnt * VB_NUM_PRE_CHN; } else if (vb_type == 1) { vb_cfg->max_pool_cnt = 3; /* 3: max vb pool */ 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 = SAMPLE_CHN_NUM * 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; vb_cfg->common_pool[1].blk_cnt = vi_param->vi_chn_cnt * VB_NUM_PRE_CHN; pic_buf_attr.width = vi_param->minor_dst_size.width; pic_buf_attr.height = 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; /* 2 : 2nd vb pool */ vb_cfg->common_pool[2].blk_cnt = vi_param->vi_chn_cnt * VB_NUM_PRE_CHN; /* 2 : 2nd vb pool */ } return TD_SUCCESS; } static td_s32 sample_vio_start_vpss(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn, const ot_size *size) { td_s32 ret; ot_vpss_grp_attr grp_attr = { 0 }; ot_vpss_chn_attr chn_attr[OT_VPSS_MAX_PHYS_CHN_NUM] = { 0 }; td_bool chn_enable[OT_VPSS_MAX_PHYS_CHN_NUM] = { 0 }; if (vpss_chn >= OT_VPSS_MAX_PHYS_CHN_NUM) { sample_print("vpss_chn:%d invalid!\n", vpss_chn); return TD_FAILURE; } grp_attr.nr_en = TD_TRUE; grp_attr.ie_en = TD_TRUE; grp_attr.dci_en = TD_TRUE; grp_attr.nr_attr.compress_mode = OT_COMPRESS_MODE_FRAME; 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.max_width = size->width; grp_attr.max_height = size->height; chn_enable[vpss_chn] = TD_TRUE; chn_attr[vpss_chn].chn_mode = OT_VPSS_CHN_MODE_AUTO; chn_attr[vpss_chn].width = size->width; chn_attr[vpss_chn].height = size->height; chn_attr[vpss_chn].pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420; chn_attr[vpss_chn].frame_rate.src_frame_rate = -1; chn_attr[vpss_chn].frame_rate.dst_frame_rate = -1; chn_attr[vpss_chn].border_en = TD_TRUE; chn_attr[vpss_chn].border_attr.color = COLOR_RGB_BLUE; chn_attr[vpss_chn].border_attr.top_width = 2; /* 2 : border top width */ chn_attr[vpss_chn].border_attr.bottom_width = 2; /* 2 : border bottom width */ chn_attr[vpss_chn].border_attr.left_width = 2; /* 2 : border left width */ chn_attr[vpss_chn].border_attr.right_width = 2; /* 2 : border right width */ ret = sample_common_vpss_start(vpss_grp, chn_enable, &grp_attr, chn_attr, 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_vio_stop_vpss(ot_vpss_grp vpss_grp, ot_vpss_chn vpss_chn) { td_s32 ret; td_bool chn_enable[OT_VPSS_MAX_PHYS_CHN_NUM] = {0}; if (vpss_chn >= OT_VPSS_MAX_PHYS_CHN_NUM) { sample_print("vpss_chn:%d invalid!\n", vpss_chn); return TD_FAILURE; } chn_enable[vpss_chn] = TD_TRUE; ret = sample_common_vpss_stop(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_vio_start_vpss_4_1080p(td_s32 vpss_grp_cnt, const ot_size *venc_size, const ot_size *vo_size) { td_s32 ret; ot_vpss_grp vpss_grp; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { if (vpss_grp % 2 == 0) { /* 2: odd-even */ ret = sample_vio_start_vpss(vpss_grp, OT_VPSS_CHN0, venc_size); } else { ret = sample_vio_start_vpss(vpss_grp, OT_VPSS_CHN2, vo_size); } if (ret != TD_SUCCESS) { sample_print("failed with %#x!\n", ret); return TD_FAILURE; } } return TD_SUCCESS; } static td_s32 sample_vio_stop_vpss_4_1080p(td_s32 vpss_grp_cnt) { td_s32 ret; ot_vpss_grp vpss_grp; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { if (vpss_grp % 2 == 0) { /* 2: odd-even */ ret = sample_vio_stop_vpss(vpss_grp, OT_VPSS_CHN0); } else { ret = sample_vio_stop_vpss(vpss_grp, OT_VPSS_CHN2); } if (ret != TD_SUCCESS) { sample_print("failed with %#x!\n", ret); return TD_FAILURE; } } return TD_SUCCESS; } static td_s32 sample_vio_start_vpss_hd_zoom_in(td_s32 vpss_grp_cnt, const ot_size *vo_size) { td_s32 ret; ot_vpss_grp vpss_grp; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { ret = sample_vio_start_vpss(vpss_grp, OT_VPSS_CHN2, vo_size); if (ret != TD_SUCCESS) { sample_print("failed with %#x!\n", ret); return TD_FAILURE; } } return TD_SUCCESS; } static td_void sample_vio_stop_vpss_hd_zoom_in(td_s32 vpss_grp_cnt) { td_s32 ret; ot_vpss_grp vpss_grp; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { ret = sample_vio_stop_vpss(vpss_grp, OT_VPSS_CHN2); if (ret != TD_SUCCESS) { sample_print("failed with %#x!\n", ret); return; } } } static td_s32 sample_vio_vi_bind_multi_vpss(td_s32 vpss_grp_cnt) { td_s32 ret; ot_vi_chn vi_chn; ot_vpss_grp vpss_grp; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { vi_chn = vpss_grp; /* one vi chn bind to two vpss group */ ret = sample_comm_vi_bind_vpss(0, vi_chn, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } } return TD_SUCCESS; } static td_s32 sample_vio_vi_unbind_multi_vpss(td_s32 vpss_grp_cnt) { td_s32 ret; ot_vi_chn vi_chn; ot_vpss_grp vpss_grp; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { vi_chn = vpss_grp; /* one vi chn unbind to two vpss group */ ret = sample_comm_vi_un_bind_vpss(0, vi_chn, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } } return TD_SUCCESS; } static td_s32 sample_vio_vi_bind_multi_vpss_with_pip(td_s32 vpss_grp_cnt) { td_s32 ret; ot_vi_chn vi_chn; ot_vi_chn vi_chn_for_pip; ot_vpss_grp vpss_grp; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt - 1; vpss_grp++) { vi_chn = vpss_grp; /* one vi chn bind to two vpss group */ ret = sample_comm_vi_bind_vpss(0, vi_chn, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } } vi_chn_for_pip = (vpss_grp - 1 > 0) ? (vpss_grp - 1) : 0; /* vi chn1 bind to 2rd group for pip */ ret = sample_comm_vi_bind_vpss(0, vi_chn_for_pip, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } return TD_SUCCESS; } static td_s32 sample_vio_vi_unbind_multi_vpss_with_pip(td_s32 vpss_grp_cnt) { td_s32 ret; ot_vi_chn vi_chn; ot_vi_chn vi_chn_for_pip; ot_vpss_grp vpss_grp; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt - 1; vpss_grp++) { vi_chn = vpss_grp; /* one vi chn unbind to two vpss group */ ret = sample_comm_vi_un_bind_vpss(0, vi_chn, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } } vi_chn_for_pip = (vpss_grp - 1 > 0) ? (vpss_grp - 1) : 0; /* vi chn1 bind to 2rd group for pip */ ret = sample_comm_vi_un_bind_vpss(0, vi_chn_for_pip, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } return TD_SUCCESS; } static td_s32 sample_vio_vpss_bind_multi_vo(td_s32 vpss_grp_cnt, ot_vpss_chn vpss_chn, td_s32 vo_layer) { td_s32 ret; ot_vpss_grp vpss_grp; ot_vo_chn vo_chn = 0; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { /* this type group is sent to venc */ if (vpss_grp % 2 == 0) { /* 2 : odd-even */ continue; } /* this type group is sent to vo */ ret = sample_comm_vpss_bind_vo(vpss_grp, vpss_chn, vo_layer, vo_chn); if (ret != TD_SUCCESS) { sample_print("vpss bind vo failed!\n"); return ret; } vo_chn++; } return TD_SUCCESS; } static td_s32 sample_vio_vpss_unbind_multi_vo(td_s32 vpss_grp_cnt, ot_vpss_chn vpss_chn, td_s32 vo_layer) { td_s32 ret; ot_vpss_grp vpss_grp; ot_vo_chn vo_chn = 0; for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { /* this type group is sent to venc */ if (vpss_grp % 2 == 0) { /* 2 : odd-even */ continue; } /* this type group is sent to vo */ ret = sample_comm_vpss_un_bind_vo(vpss_grp, vpss_chn, vo_layer, vo_chn); if (ret != TD_SUCCESS) { sample_print("vpss unbind vo failed!\n"); return ret; } vo_chn++; } return TD_SUCCESS; } static td_s32 sample_vio_do_switch_window(ot_vo_layer layer, sample_vo_mode pre_vo_mode, sample_vo_mode tmp_vo_mode) { td_s32 ret; ret = ss_mpi_vo_batch_begin(layer); if (ret != TD_SUCCESS) { sample_print("vo batch begin failed!\n"); return ret; } ret = sample_comm_vo_stop_chn(layer, pre_vo_mode); if (ret != TD_SUCCESS) { sample_print("vo stop chn failed!\n"); return ret; } ret = sample_comm_vo_start_chn(layer, tmp_vo_mode); if (ret != TD_SUCCESS) { sample_print("vo start chn failed!\n"); return ret; } ret = ss_mpi_vo_batch_end(layer); if (ret != TD_SUCCESS) { sample_print("vo batch end failed!\n"); return ret; } return TD_SUCCESS; } static td_s32 sample_vio_vo_check_preview_mode(td_s32 *char_var) { td_s32 char_val[2] = {'\0'}; /* 2:char */ char_val[0] = sample_vio_getchar(); if ((char_val[0] == 10) || /* 10 : enter */ ((char_val[0] != '0') && (char_val[0] != '1') && (char_val[0] != 'q'))) { sample_print("invalid input! please try again.\n"); while (sample_vio_getchar() != 10) { /* 10 : enter */ } return TD_FAILURE; } char_val[1] = sample_vio_getchar(); if (char_val[1] != 10) { /* 10 : enter */ sample_print("invalid input! please try again.\n"); while (sample_vio_getchar() != 10) { /* 10 : enter */ } return TD_FAILURE; } *char_var = char_val[0]; return TD_SUCCESS; } static td_s32 sample_vio_vo_switch_window(td_s32 dev, td_s32 vo_window_num, sample_vo_mode vo_mode) { td_s32 ret; ot_vo_layer layer = dev; sample_vo_mode pre_vo_mode; sample_vo_mode tmp_vo_mode = vo_mode; td_s32 pre_vo_window_num; td_s32 tmp_vo_window_num = vo_window_num; td_s32 char_var = 'q'; //while (1) { pre_vo_mode = tmp_vo_mode; pre_vo_window_num = tmp_vo_window_num; printf("please choose preview mode, press 'q' to exit this sample.\n"); printf("\t0) 1 preview\n"); printf("\t1) %d preview\n", vo_window_num); printf("\tq) quit\n"); #if 0 ret = sample_vio_vo_check_preview_mode(&char_var); if (ret != TD_SUCCESS) { continue; } if (char_var == '0') { tmp_vo_window_num = 1; tmp_vo_mode = VO_MODE_1MUX; } else if (char_var == '1') { tmp_vo_window_num = vo_window_num; tmp_vo_mode = VO_MODE_4MUX; } else if (char_var == 'q') { break; } else { sample_print("preview mode invalid! please try again.\n"); continue; } #endif sample_print("vo dev(%d) switch from %d to %d window\n", dev, pre_vo_window_num, tmp_vo_window_num); ret = sample_vio_do_switch_window(layer, pre_vo_mode, tmp_vo_mode); if (ret != TD_SUCCESS) { return ret; } //} return TD_SUCCESS; } static td_s32 sample_vio_init(sample_vi_mode vi_mode, sample_vi_param *vi_param, ot_size *size) { td_s32 ret; ot_pic_size pic_size; ot_vb_cfg vb_cfg; /* get parameter from vi mode */ ret = sample_common_vi_mode_to_param(vi_mode, vi_param); if (ret != TD_SUCCESS) { sample_print("vi get param failed!\n"); return ret; } ret = sample_common_vi_get_size_by_mode(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; } ret = sample_vio_set_vb_cfg(vi_mode, size, 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); return ret; } return TD_SUCCESS; } static td_s32 sample_vio_2_1080p_init_vo(ot_vo_dev vo_dev_dhd0, sample_vo_mode vo_mode, sample_vo_cfg *vo_config_dhd0, td_s32 vpss_grp_cnt, ot_vpss_chn vpss_chn) { td_s32 ret; ot_vo_intf_sync intf_sync = OT_VO_OUT_1080P60; ot_vo_intf_type intf_type_dhd0 = OT_VO_INTF_BT1120; /* start vo DHD0 (BT1120+HDMI), multi-screen, you can switch mode */ printf("start vo DHD0.\n"); sample_comm_vo_get_def_config(vo_config_dhd0); vo_config_dhd0->vo_dev = vo_dev_dhd0; vo_config_dhd0->vo_intf_type = intf_type_dhd0; vo_config_dhd0->intf_sync = intf_sync; vo_config_dhd0->vo_mode = vo_mode; vo_config_dhd0->vo_part_mode = OT_VO_PARTITION_MODE_MULTI; vo_config_dhd0->compress_mode = OT_COMPRESS_MODE_LINE; vo_config_dhd0->dis_buf_len = 4; /* 4 : display buffer length */ ret = sample_comm_vo_start_vo(vo_config_dhd0); if (ret != TD_SUCCESS) { sample_print("start vo failed with 0x%x!\n", ret); return TD_FAILURE; } ot_vpss_grp vpss_grp=2; ot_vo_chn vo_chn = 0; /* this type group is sent to vo */ ret = sample_comm_vpss_bind_vo(vpss_grp, vpss_chn, vo_dev_dhd0, vo_chn); if (ret != TD_SUCCESS) { sample_print("vpss bind vo failed!\n"); return ret; } return TD_SUCCESS; exit_vo_dhd0_bind: ret = sample_comm_vo_stop_vo(vo_config_dhd0); if (ret != TD_SUCCESS) { sample_print("stop vo failed with 0x%x!\n", ret); } return TD_FAILURE; } static td_s32 sample_vio_4_1080p_init_vo(ot_vo_dev vo_dev_dhd0, sample_vo_mode vo_mode, sample_vo_cfg *vo_config_dhd0, td_s32 vpss_grp_cnt, ot_vpss_chn vpss_chn) { td_s32 ret; ot_vo_intf_sync intf_sync = OT_VO_OUT_1080P60; ot_vo_intf_type intf_type_dhd0 = OT_VO_INTF_HDMI; /* start vo DHD0 (BT1120+HDMI), multi-screen, you can switch mode */ printf("start vo DHD0.\n"); sample_comm_vo_get_def_config(vo_config_dhd0); vo_config_dhd0->vo_dev = vo_dev_dhd0; vo_config_dhd0->vo_intf_type = intf_type_dhd0; vo_config_dhd0->intf_sync = intf_sync; vo_config_dhd0->vo_mode = vo_mode; vo_config_dhd0->vo_part_mode = OT_VO_PARTITION_MODE_MULTI; vo_config_dhd0->compress_mode = OT_COMPRESS_MODE_LINE; vo_config_dhd0->dis_buf_len = 4; /* 4 : display buffer length */ ret = sample_comm_vo_start_vo(vo_config_dhd0); if (ret != TD_SUCCESS) { sample_print("start vo failed with 0x%x!\n", ret); return TD_FAILURE; } ret = sample_vio_vpss_bind_multi_vo(vpss_grp_cnt, vpss_chn, vo_dev_dhd0); if (ret != TD_SUCCESS) { sample_print("vpss bind vo vo failed with 0x%x!\n", ret); goto exit_vo_dhd0_bind; } return TD_SUCCESS; exit_vo_dhd0_bind: ret = sample_comm_vo_stop_vo(vo_config_dhd0); if (ret != TD_SUCCESS) { sample_print("stop vo failed with 0x%x!\n", ret); } return TD_FAILURE; } static td_s32 sample_vio_hd_zoom_in_init_vo(ot_vo_dev vo_dev_dhd0, sample_vo_mode vo_mode, sample_vo_cfg *vo_config_dhd0, td_s32 vpss_grp_dhd0, ot_vpss_chn vpss_chn_dhd0) { td_s32 ret; ot_vo_intf_sync intf_sync = OT_VO_OUT_1080P60; ot_vo_intf_type intf_type_dhd0 = OT_VO_INTF_HDMI; /* start vo DHD0 (BT1120+HDMI), multi-screen, you can switch mode */ printf("start vo DHD0.\n"); sample_comm_vo_get_def_config(vo_config_dhd0); vo_config_dhd0->vo_dev = vo_dev_dhd0; vo_config_dhd0->vo_intf_type = intf_type_dhd0; vo_config_dhd0->intf_sync = intf_sync; vo_config_dhd0->bg_color = COLOR_RGB_BLUE; vo_config_dhd0->vo_mode = vo_mode; vo_config_dhd0->vo_part_mode = OT_VO_PARTITION_MODE_MULTI; vo_config_dhd0->compress_mode = OT_COMPRESS_MODE_LINE; vo_config_dhd0->dis_buf_len = 4; /* 4 : display buffer length */ ret = sample_comm_vo_start_vo(vo_config_dhd0); if (ret != TD_SUCCESS) { sample_print("start vo failed with 0x%x!\n", ret); return TD_FAILURE; } ret = sample_comm_vpss_bind_vo(vpss_grp_dhd0, vpss_chn_dhd0, 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 TD_SUCCESS; exit_vo_dhd0_bind: ret = sample_comm_vo_stop_vo(vo_config_dhd0); if (ret != TD_SUCCESS) { sample_print("stop vo failed with 0x%x!\n", ret); } return TD_FAILURE; } static td_s32 sample_vio_2_1080p_init_vpss(const sample_vi_param *vi_param, td_s32 vpss_grp_cnt, const ot_size *size) { td_s32 ret; ret = sample_vio_start_vpss_4_1080p(vpss_grp_cnt, size, &vi_param->minor_dst_size); if (ret != TD_SUCCESS) { sample_print("start vpss failed with 0x%x!\n", ret); return ret; } // td_s32 ret; ot_vi_chn vi_chn; ot_vpss_grp vpss_grp; // for (vpss_grp = 0; vpss_grp < vpss_grp_cnt; vpss_grp++) { vi_chn = vpss_grp = 0; /* one vi chn bind to two vpss group */ ret = sample_comm_vi_bind_vpss(0, vi_chn, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } // } vi_chn = vpss_grp = 1; /* one vi chn bind to two vpss group */ ret = sample_comm_vi_bind_vpss(0, vi_chn, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } vi_chn = 8; vpss_grp =2; /* one vi chn bind to two vpss group */ ret = sample_comm_vi_bind_vpss(0, vi_chn, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } vi_chn = 9; vpss_grp =3; /* one vi chn bind to two vpss group */ ret = sample_comm_vi_bind_vpss(0, vi_chn, vpss_grp, 0); if (ret != TD_SUCCESS) { sample_print("vi bind vpss failed!\n"); return ret; } return TD_SUCCESS; ret = sample_vio_vi_bind_multi_vpss(vpss_grp_cnt); if (ret != TD_SUCCESS) { sample_print("vi_bind_multi_vpss 0x%x!\n", ret); goto exit_vpss_bind; } return TD_SUCCESS; exit_vpss_bind: ret = sample_vio_stop_vpss_4_1080p(vpss_grp_cnt); if (ret != TD_SUCCESS) { sample_print("stop_vpss_4_1080p 0x%x!\n", ret); } return TD_FAILURE; } static td_s32 sample_vio_4_1080p_init_vpss(const sample_vi_param *vi_param, td_s32 vpss_grp_cnt, const ot_size *size) { td_s32 ret; ret = sample_vio_start_vpss_4_1080p(vpss_grp_cnt, size, &vi_param->minor_dst_size); if (ret != TD_SUCCESS) { sample_print("start vpss failed with 0x%x!\n", ret); return ret; } ret = sample_vio_vi_bind_multi_vpss(vpss_grp_cnt); if (ret != TD_SUCCESS) { sample_print("vi_bind_multi_vpss 0x%x!\n", ret); goto exit_vpss_bind; } return TD_SUCCESS; exit_vpss_bind: ret = sample_vio_stop_vpss_4_1080p(vpss_grp_cnt); if (ret != TD_SUCCESS) { sample_print("stop_vpss_4_1080p 0x%x!\n", ret); } return TD_FAILURE; } static td_s32 sample_vio_zoom_in_init_vpss(const sample_vi_param *vi_param, td_s32 vpss_grp_cnt) { td_s32 ret; ot_vpss_crop_info vpss_crop_info; const ot_vpss_chn vpss_grp_dhd0 = 1; ret = sample_vio_start_vpss_hd_zoom_in(vpss_grp_cnt, &vi_param->minor_dst_size); if (ret != TD_SUCCESS) { sample_print("start vpss failed with 0x%x!\n", ret); return ret; } ret = sample_vio_vi_bind_multi_vpss_with_pip(vpss_grp_cnt); if (ret != TD_SUCCESS) { sample_print("vi_bind_multi_vpss 0x%x!\n", ret); goto exit_vpss_bind; } vpss_crop_info.enable = TD_TRUE; vpss_crop_info.crop_mode = OT_COORD_ABS; vpss_crop_info.crop_rect.x = 200; /* 200 : crop x coordinate */ vpss_crop_info.crop_rect.y = 300; /* 300 : crop y coordinate */ vpss_crop_info.crop_rect.width = 500; /* 500 : crop width */ vpss_crop_info.crop_rect.height = 500; /* 500 : crop height */ ret = ss_mpi_vpss_set_grp_crop(vpss_grp_dhd0, &vpss_crop_info); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vpss_set_grp_crop failed with 0x%x!\n", ret); } return TD_SUCCESS; exit_vpss_bind: sample_vio_stop_vpss_hd_zoom_in(vpss_grp_cnt); return TD_FAILURE; } static td_s32 sample_vio_zoom_in_start_pip(sample_vo_cfg *vo_config_dhd0, ot_vpss_chn vpss_grp_pip, ot_vpss_chn vpss_chn_pip) { td_s32 ret; /************************************************** start vo PIP (HDMI), multi-screen, you can switch mode **************************************************/ printf("start vo PIP.\n"); vo_config_dhd0->vo_part_mode = OT_VO_PARTITION_MODE_SINGLE; vo_config_dhd0->dis_buf_len = 3; /* 3 : display buffer length */ ret = sample_comm_vo_start_pip(vo_config_dhd0); if (ret != TD_SUCCESS) { sample_print("start vo failed with 0x%x!\n", ret); return TD_FAILURE; } ret = sample_comm_vpss_bind_vo(vpss_grp_pip, vpss_chn_pip, SAMPLE_VO_LAYER_PIP, 0); if (ret != TD_SUCCESS) { sample_print("vpss bind vo failed with 0x%x!\n", ret); goto exit_vo_pip_bind; } return TD_SUCCESS; exit_vo_pip_bind: (td_void)sample_comm_vo_stop_pip(vo_config_dhd0); return TD_FAILURE; } static td_void sample_vio_deinit_vpss(td_s32 vpss_grp_cnt) { td_s32 ret; ret = sample_vio_vi_unbind_multi_vpss(vpss_grp_cnt); if (ret != TD_SUCCESS) { sample_print("stop vo failed with 0x%x!\n", ret); } ret = sample_vio_stop_vpss_4_1080p(vpss_grp_cnt); if (ret != TD_SUCCESS) { sample_print("stop vo failed with 0x%x!\n", ret); } } static td_void sample_vio_zoom_in_deinit_vpss(td_s32 vpss_grp_cnt) { td_s32 ret; ret = sample_vio_vi_unbind_multi_vpss_with_pip(vpss_grp_cnt); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vpss_set_grp_crop failed with 0x%x!\n", ret); } sample_vio_stop_vpss_hd_zoom_in(vpss_grp_cnt); } static td_void sample_vio_deinit_vo(ot_vpss_grp vpss_grp_dhd0, ot_vpss_chn vpss_chn_dhd0, const sample_vo_cfg *vo_config_dhd0) { td_s32 ret; sample_comm_vpss_un_bind_vo(vpss_grp_dhd0, vpss_chn_dhd0, SAMPLE_VO_LAYER_VHD0, 0); ret = sample_comm_vo_stop_vo(vo_config_dhd0); if (ret != TD_SUCCESS) { sample_print("ample_comm_vo_stop_vo failed with 0x%x!\n", ret); } } static td_void sample_vio_deinit_vo_pip(ot_vpss_grp vpss_grp_pip, ot_vpss_chn vpss_chn_pip, const sample_vo_cfg *vo_config_dhd0) { sample_comm_vpss_un_bind_vo(vpss_grp_pip, vpss_chn_pip, SAMPLE_VO_LAYER_PIP, 0); sample_comm_vo_stop_pip(vo_config_dhd0); } static td_s32 sample_vio_2_1080p(td_void) { sample_vi_mode vi_mode = SAMPLE_VI_MODE_1080P_2X1; sample_video_encoding video_encoding = SAMPLE_VIDEO_ENCODING_NTSC; const td_s32 vpss_grp_cnt = 4; sample_vo_mode vo_mode = VO_MODE_1MUX; const td_s32 vo_window_num = 1; ot_vo_dev vo_dev_dhd0 = SAMPLE_VO_DEV_DHD0; ot_vpss_chn vpss_chn_dhd0 = OT_VPSS_CHN0; sample_vo_cfg vo_config_dhd0; td_s32 ret; ot_size size; sample_vi_param vi_param; ret = sample_vio_init(vi_mode, &vi_param, &size); if (ret != TD_SUCCESS) { return ret; } ret = sample_common_vi_start_vi(vi_mode, video_encoding, &vi_param); if (ret != TD_SUCCESS) { sample_print("start vi failed with 0x%x!\n", ret); goto exit_vi; } ret = sample_vio_2_1080p_init_vpss(&vi_param, vpss_grp_cnt, &size); if (ret != TD_SUCCESS) { goto exit_vpss; } ret = sample_vio_2_1080p_init_vo(vo_dev_dhd0, vo_mode, &vo_config_dhd0, vpss_grp_cnt, vpss_chn_dhd0); if (ret != TD_SUCCESS) { goto exit_vo; } ret = sample_vio_vo_switch_window(vo_dev_dhd0, vo_window_num, vo_mode); if (ret != TD_SUCCESS) { sample_print("vo switch window failed with 0x%x!\n", ret); } while(1){ sleep(5) ; } ret = sample_vio_vpss_unbind_multi_vo(vpss_grp_cnt, vpss_chn_dhd0, vo_dev_dhd0); if (ret != TD_SUCCESS) { sample_print("vpss unbind vo failed with 0x%x!\n", ret); } exit_vo: sample_vio_deinit_vpss(vpss_grp_cnt); exit_vpss: sample_common_vi_stop(vi_mode, &vi_param); exit_vi: sample_comm_sys_exit(); return ret; } static td_s32 sample_vio_4_1080p(td_void) { sample_vi_mode vi_mode = SAMPLE_VI_MODE_1080P_1X2; sample_video_encoding video_encoding = SAMPLE_VIDEO_ENCODING_NTSC; const td_s32 vpss_grp_cnt = 8; sample_vo_mode vo_mode = VO_MODE_4MUX; const td_s32 vo_window_num = 4; ot_vo_dev vo_dev_dhd0 = SAMPLE_VO_DEV_DHD0; ot_vpss_chn vpss_chn_dhd0 = OT_VPSS_CHN2; sample_vo_cfg vo_config_dhd0; td_s32 ret; ot_size size; sample_vi_param vi_param; ret = sample_vio_init(vi_mode, &vi_param, &size); if (ret != TD_SUCCESS) { return ret; } ret = sample_common_vi_start_vi(vi_mode, video_encoding, &vi_param); if (ret != TD_SUCCESS) { sample_print("start vi failed with 0x%x!\n", ret); goto exit_vi; } ret = sample_vio_4_1080p_init_vpss(&vi_param, vpss_grp_cnt, &size); if (ret != TD_SUCCESS) { goto exit_vpss; } ret = sample_vio_4_1080p_init_vo(vo_dev_dhd0, vo_mode, &vo_config_dhd0, vpss_grp_cnt, vpss_chn_dhd0); if (ret != TD_SUCCESS) { goto exit_vo; } ret = sample_vio_vo_switch_window(vo_dev_dhd0, vo_window_num, vo_mode); if (ret != TD_SUCCESS) { sample_print("vo switch window failed with 0x%x!\n", ret); } ret = sample_vio_vpss_unbind_multi_vo(vpss_grp_cnt, vpss_chn_dhd0, vo_dev_dhd0); if (ret != TD_SUCCESS) { sample_print("vpss unbind vo failed with 0x%x!\n", ret); } exit_vo: sample_vio_deinit_vpss(vpss_grp_cnt); exit_vpss: sample_common_vi_stop(vi_mode, &vi_param); exit_vi: sample_comm_sys_exit(); return ret; } static td_s32 sample_vio_hd_zoom_in(td_void) { sample_vi_mode vi_mode = SAMPLE_VI_MODE_1080P_1X2; sample_video_encoding video_encoding = SAMPLE_VIDEO_ENCODING_NTSC; const td_s32 vpss_grp_cnt = 3; /* 3 : number of grp */ const ot_vpss_chn vpss_grp_dhd0 = 1; const ot_vpss_chn vpss_chn_dhd0 = OT_VPSS_CHN2; const ot_vpss_chn vpss_grp_pip = 2; /* 2: grp pip */ const ot_vpss_chn vpss_chn_pip = OT_VPSS_CHN2; sample_vo_mode vo_mode = VO_MODE_1MUX; ot_vo_dev vo_dev_dhd0 = SAMPLE_VO_DEV_DHD0; sample_vo_cfg vo_config_dhd0; td_s32 ret; ot_size size; sample_vi_param vi_param; ret = sample_vio_init(vi_mode, &vi_param, &size); if (ret != TD_SUCCESS) { return ret; } ret = sample_common_vi_start_vi(vi_mode, video_encoding, &vi_param); if (ret != TD_SUCCESS) { sample_print("start vi failed with 0x%x!\n", ret); goto exit_vi; } ret = sample_vio_zoom_in_init_vpss(&vi_param, vpss_grp_cnt); if (ret != TD_SUCCESS) { goto exit_vpss; } ret = sample_vio_hd_zoom_in_init_vo(vo_dev_dhd0, vo_mode, &vo_config_dhd0, vpss_grp_dhd0, vpss_chn_dhd0); if (ret != TD_SUCCESS) { goto exit_vo; } printf("press any key to show hd zoom.\n"); sample_vio_getchar(); ret = sample_vio_zoom_in_start_pip(&vo_config_dhd0, vpss_grp_pip, vpss_chn_pip); if (ret != TD_SUCCESS) { goto exit_vo_pip; } printf("\npress enter stop sample ... ... \n"); sample_vio_getchar(); sample_vio_deinit_vo_pip(vpss_grp_pip, vpss_chn_pip, &vo_config_dhd0); exit_vo_pip: sample_vio_deinit_vo(vpss_grp_dhd0, vpss_chn_dhd0, &vo_config_dhd0); exit_vo: sample_vio_zoom_in_deinit_vpss(vpss_grp_cnt); exit_vpss: sample_common_vi_stop(vi_mode, &vi_param); exit_vi: sample_comm_sys_exit(); return ret; } static void sample_vio_usage(const char *s_prg_nm) { printf("usage : %s \n", s_prg_nm); printf("index:\n"); printf("\t0: VI 1080P input, HD0(HDMI) output, window switch \n"); printf("\t1: VI 1080P input, HD0(HDMI) output, ZoomIn\n"); return; } td_s32 main(td_s32 argc, td_char *argv[]) { td_s32 ret; char index; if (argc != 2) { /* 2: 2 arg num */ sample_vio_usage(argv[0]); return TD_FAILURE; } if (!strncmp(argv[1], "-h", 2)) { /* 2: 2 chars */ sample_vio_usage(argv[0]); return TD_SUCCESS; } sample_sys_signal(&sample_vio_handle_sig); if (strlen(argv[1]) > 1) { sample_vio_usage(argv[0]); return TD_FAILURE; } index = *argv[1]; switch (index) { case '0': ret = sample_vio_2_1080p(); break; case '1': /* 1: index 1 */ ret = sample_vio_hd_zoom_in(); break; default: sample_print("the index is invalid!\n"); sample_vio_usage(argv[0]); return TD_FAILURE; } if (ret == TD_SUCCESS) { sample_print("sample_vio exit success!\n"); } else { sample_print("sample_vio exit abnormally!\n"); } return ret; }