/* Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ot_common.h" #include "ot_mipi_rx.h" #include "sample_comm.h" #if SAMPLE_AD_TYPE == AD_NVP6158 #include "common.h" #include "video.h" #elif SAMPLE_AD_TYPE == AD_TP2854B #include "tp2854.h" #elif SAMPLE_AD_TYPE == AD_TP2856 #include "tp2856.h" #endif #define MIPI_DEV_NODE "/dev/ot_mipi" #define MAX_FRAME_WIDTH 8192 #define CHN_NUM_PRE_CHIP 4 ot_vi_dev_attr g_sample_vi_dev_attr = { /* interface mode */ OT_VI_MODE_MIPI_YUV422, /* work mode, 1/2/4 multiplex */ OT_VI_WORK_MODE_MULTIPLEX_1, /* r_mask g_mask b_mask */ { 0xFF000000, 0x0 }, /* for single/double edge, must be set when double edge */ OT_VI_CLK_EDGE_SINGLE_UP, /* enDataSeq, just support yuv */ OT_VI_IN_DATA_YVYU, /* sync info */ { /* port_vsync port_vsync_neg port_hsync port_hsync_neg */ OT_VI_VSYNC_FIELD, OT_VI_VSYNC_NEG_HIGH, OT_VI_HSYNC_VALID_SIG, OT_VI_HSYNC_NEG_HIGH, OT_VI_VSYNC_VALID_SIG, OT_VI_VSYNC_VALID_NEG_HIGH, /* * timing info: * hsync_hfb hsync_act hsync_hhb * vsync0_vhb vsync0_act vsync0_hhb * vsync1_vhb vsync1_act vsync1_hhb */ { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, /* data_reverse_en */ TD_FALSE, /* mixed_capture_en */ TD_FALSE, }; ot_vi_chn_attr g_sample_vi_chn_attr = { /* crop_x crop_y, crop_w crop_h */ { 0, 0, 1920, 1080 }, /* dest_w dest_h */ { 1920, 1080 }, /* capture_select */ OT_VI_CAPTURE_SELECT_BOTH, /* scan mode */ OT_VI_SCAN_PROGRESSIVE, /* pixel_format */ OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420, /* mirror_en flip_en */ 0, 0, /* compress mode */ OT_COMPRESS_MODE_SEG_COMPACT, /* src_frame_rate dst_frame_rate */ -1, -1 }; td_s32 sample_common_vi_get_size_by_mode(sample_vi_mode vi_mode, ot_pic_size *pic_size) { if (pic_size == TD_NULL) { return TD_FAILURE; } switch (vi_mode) { case SAMPLE_VI_MODE_960H_4X4: *pic_size = PIC_960H; break; case SAMPLE_VI_MODE_720P_1X4: case SAMPLE_VI_MODE_720P_2X2: case SAMPLE_VI_MODE_720P_4X4: case SAMPLE_VI_MODE_720P_2X1: *pic_size = PIC_720P; break; case SAMPLE_VI_MODE_1080P_1X2: case SAMPLE_VI_MODE_1080P_2X2: case SAMPLE_VI_MODE_1080P_2X1: *pic_size = PIC_1080P; break; case SAMPLE_VI_MODE_4K_1X8: case SAMPLE_VI_MODE_4K_2X1: *pic_size = PIC_3840X2160; break; default: *pic_size = PIC_3840X2160; break; } return TD_SUCCESS; } td_void sample_common_vi_set_param_4x4(sample_vi_mode vi_mode, sample_vi_param *vi_param) { vi_param->vi_dev_cnt = 4; /* 4 : number of dev */ vi_param->vi_dev_interval = 1; vi_param->vi_chn_cnt = 16; /* 16 : number of chn */ vi_param->vi_chn_interval = 1; vi_param->minor_attr_en = TD_FALSE; if (vi_mode == SAMPLE_VI_MODE_960H_4X4) { vi_param->scan_mode = OT_VI_SCAN_INTERLACED; vi_param->minor_dst_size.width = _960H_WIDTH; vi_param->minor_dst_size.height = _960H_HEIGHT_PAL; } else if (SAMPLE_VI_MODE_720P_4X4) { vi_param->scan_mode = OT_VI_SCAN_PROGRESSIVE; vi_param->minor_dst_size.width = HD_WIDTH; vi_param->minor_dst_size.height = HD_HEIGHT; } } td_void sample_common_vi_set_param_1x4(sample_vi_param *vi_param) { vi_param->vi_dev_cnt = 4; /* 4 : number of dev */ vi_param->vi_dev_interval = 1; vi_param->vi_chn_cnt = 4; /* 4 : number of chn */ vi_param->vi_chn_interval = 4; /* 4 : chn interval */ vi_param->scan_mode = OT_VI_SCAN_PROGRESSIVE; vi_param->minor_attr_en = TD_TRUE; vi_param->minor_dst_size.width = D1_WIDTH; vi_param->minor_dst_size.height = D1_HEIGHT_NTSC; } td_void sample_common_vi_set_param_2x2(sample_vi_mode vi_mode, sample_vi_param *vi_param) { vi_param->vi_dev_cnt = 2; /* 2 : number of dev */ vi_param->vi_dev_interval = 1; vi_param->vi_chn_cnt = 4; /* 4 : number of chn */ vi_param->vi_chn_interval = 2; /* 2 : chn interval */ vi_param->scan_mode = OT_VI_SCAN_PROGRESSIVE; vi_param->minor_attr_en = TD_TRUE; if (vi_mode == SAMPLE_VI_MODE_720P_2X2) { vi_param->minor_dst_size.width = D1_WIDTH; vi_param->minor_dst_size.height = D1_HEIGHT_NTSC; } else if (SAMPLE_VI_MODE_1080P_2X2) { vi_param->minor_dst_size.width = HD_WIDTH; vi_param->minor_dst_size.height = HD_HEIGHT; } } td_void sample_common_vi_set_param_1x2(sample_vi_param *vi_param) { /* use chn 0,2 */ vi_param->vi_dev_cnt = 1; vi_param->vi_dev_interval = 1; vi_param->vi_chn_cnt = 2; /* 2 : number of chn */ vi_param->vi_chn_interval = 2; /* 2 : chn interval */ vi_param->scan_mode = OT_VI_SCAN_PROGRESSIVE; vi_param->minor_attr_en = TD_TRUE; vi_param->minor_dst_size.width = HD_WIDTH; vi_param->minor_dst_size.height = HD_HEIGHT; } td_void sample_common_vi_set_param_2x1(sample_vi_param *vi_param) { /* use chn 0,8 */ vi_param->vi_dev_cnt = 2; vi_param->vi_dev_interval = 2; vi_param->vi_chn_cnt = 2; /* 2 : number of chn */ vi_param->vi_chn_interval = 8; /* 2 : chn interval */ vi_param->scan_mode = OT_VI_SCAN_PROGRESSIVE; vi_param->minor_attr_en = TD_TRUE; vi_param->minor_dst_size.width = HD_WIDTH; vi_param->minor_dst_size.height = HD_HEIGHT; } td_void sample_common_vi_set_param_1x8(sample_vi_param *vi_param) { vi_param->vi_dev_cnt = 8; /* 8 : number of dev */ vi_param->vi_dev_interval = 1; vi_param->vi_chn_cnt = 8; /* 8 : number of chn */ vi_param->vi_chn_interval = 4; /* 4 : chn interval */ vi_param->scan_mode = OT_VI_SCAN_PROGRESSIVE; vi_param->minor_attr_en = TD_TRUE; vi_param->minor_dst_size.width = HD_WIDTH; vi_param->minor_dst_size.height = HD_HEIGHT; } td_s32 sample_common_vi_mode_to_param(sample_vi_mode vi_mode, sample_vi_param *vi_param) { switch (vi_mode) { case SAMPLE_VI_MODE_960H_4X4: case SAMPLE_VI_MODE_720P_4X4: sample_common_vi_set_param_4x4(vi_mode, vi_param); break; case SAMPLE_VI_MODE_720P_1X4: sample_common_vi_set_param_1x4(vi_param); break; case SAMPLE_VI_MODE_720P_2X2: case SAMPLE_VI_MODE_1080P_2X2: sample_common_vi_set_param_2x2(vi_mode, vi_param); break; case SAMPLE_VI_MODE_1080P_1X2: sample_common_vi_set_param_1x2(vi_param); break; case SAMPLE_VI_MODE_1080P_2X1: case SAMPLE_VI_MODE_720P_2X1: case SAMPLE_VI_MODE_4K_2X1: sample_common_vi_set_param_2x1(vi_param); break; case SAMPLE_VI_MODE_4K_1X8: sample_common_vi_set_param_1x8(vi_param); break; default: sample_print("vi_mode invalid !\n"); return TD_FAILURE; } return TD_SUCCESS; } td_s32 sample_common_vi_mode_to_size(sample_vi_mode vi_mode, sample_video_encoding video_encoding, ot_rect *capture_rect, ot_size *dst_size) { capture_rect->x = 0; capture_rect->y = 0; switch (vi_mode) { case SAMPLE_VI_MODE_960H_4X4: capture_rect->width = _960H_WIDTH; capture_rect->height = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? _960H_HEIGHT_PAL : _960H_HEIGHT_NTSC; dst_size->width = capture_rect->width; dst_size->height = capture_rect->height; break; case SAMPLE_VI_MODE_720P_1X4: case SAMPLE_VI_MODE_720P_2X2: case SAMPLE_VI_MODE_720P_4X4: case SAMPLE_VI_MODE_720P_2X1: capture_rect->width = HD_WIDTH; capture_rect->height = HD_HEIGHT; dst_size->width = capture_rect->width; dst_size->height = capture_rect->height; break; case SAMPLE_VI_MODE_1080P_1X2: case SAMPLE_VI_MODE_1080P_2X2: case SAMPLE_VI_MODE_1080P_2X1: capture_rect->width = FHD_WIDTH; capture_rect->height = FHD_HEIGHT; dst_size->width = capture_rect->width; dst_size->height = capture_rect->height; break; case SAMPLE_VI_MODE_4K_1X8: case SAMPLE_VI_MODE_4K_2X1: capture_rect->width = _4K_WIDTH; capture_rect->height = _4K_HEIGHT; dst_size->width = capture_rect->width; dst_size->height = capture_rect->height; break; default: sample_print("vi mode invalid!\n"); return TD_FAILURE; } return TD_SUCCESS; } #if SAMPLE_AD_TYPE == AD_NVP6158 td_s32 sample_nvp6158_cfg(sample_vi_mode vi_mode, sample_video_encoding video_encoding) { int fd, i, j; int video_mode; nvp6158_opt_mode optmode; nvp6158_chn_mode schnmode; int chip_cnt = 1; fd = open(NVP6158_FILE, O_RDWR); if (fd < 0) { printf("open nvp6158 (%s) fail\n", NVP6158_FILE); return -1; } video_mode = (SAMPLE_VIDEO_ENCODING_PAL == video_encoding) ? 1 : 0; switch (vi_mode) { case SAMPLE_VI_MODE_960H_4X4: schnmode.chmode = (video_mode == 1) ? AHD20_SD_H960_NT : AHD20_SD_H960_PAL; optmode.portmode = NVP6158_OUTMODE_4MUX_SD; break; case SAMPLE_VI_MODE_720P_1X4: schnmode.chmode = (video_mode == 1) ? AHD20_720P_25P : AHD20_720P_30P; optmode.portmode = NVP6158_OUTMODE_1MUX_HD; break; case SAMPLE_VI_MODE_720P_2X2: schnmode.chmode = (video_mode == 1) ? AHD20_720P_25P : AHD20_720P_30P; optmode.portmode = NVP6158_OUTMODE_2MUX_HD; break; case SAMPLE_VI_MODE_1080P_1X2: case SAMPLE_VI_MODE_1080P_2X2: schnmode.chmode = (video_mode == 1) ? AHD20_1080P_25P : AHD20_1080P_30P; optmode.portmode = NVP6158_OUTMODE_2MUX_FHD; break; default: close(fd); sample_print("vi mode invalid!\n"); return TD_FAILURE; } for (i = 0; i < chip_cnt * CHN_NUM_PRE_CHIP; i++) { schnmode.ch = i; schnmode.vformat = video_mode; ioctl(fd, IOC_VDEC_SET_CHNMODE, &schnmode); } for (i = 0; i < chip_cnt; i++) { for (j = 0; j < CHN_NUM_PRE_CHIP; j++) { optmode.chipsel = i; optmode.portsel = j; optmode.chid = j; ioctl(fd, IOC_VDEC_SET_OUTPORTMODE, &optmode); } } close(fd); return TD_SUCCESS; } #elif SAMPLE_AD_TYPE == AD_TP2854B td_s32 sample_tp2854b_cfg(sample_vi_mode vi_mode, sample_video_encoding video_encoding) { int fd, i, j; tp2802_video_mode tp_video_mode; const int chip_cnt = 2; fd = open(TP2854B_FILE, O_RDWR); if (fd < 0) { printf("open tp2854b (%s) fail\n", TP2854B_FILE); return -1; } for (i = 0; i < chip_cnt; i++) { tp_video_mode.chip = i; switch (vi_mode) { case SAMPLE_VI_MODE_720P_1X4: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? TP2802_720P25V2 : TP2802_720P30V2; tp_video_mode.output = MIPI_1CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_720P_2X2: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? TP2802_720P25V2 : TP2802_720P30V2; tp_video_mode.output = MIPI_2CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_720P_4X4: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? TP2802_720P25V2 : TP2802_720P30V2; tp_video_mode.output = MIPI_4CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_1080P_1X2: case SAMPLE_VI_MODE_1080P_2X2: case SAMPLE_VI_MODE_1080P_2X4: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? TP2802_1080P25 : TP2802_1080P30; tp_video_mode.output = MIPI_2CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_4M_1X8: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = TP2802_QHD15; tp_video_mode.output = MIPI_1CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_5M_1X8: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = TP2802_5M12; tp_video_mode.output = MIPI_1CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_4K_1X8: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = TP2802_8M15; tp_video_mode.output = MIPI_1CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; default: printf("vi_mode %d not supported\n", vi_mode); break; } } close(fd); return TD_SUCCESS; } #elif SAMPLE_AD_TYPE == AD_TP2856 td_s32 sample_tp2856_cfg(sample_vi_mode vi_mode, sample_video_encoding video_encoding) { int fd, i, j; tp2802_video_mode tp_video_mode; int chip_cnt = 1; fd = open(TP2856_FILE, O_RDWR); if (fd < 0) { printf("open tp2854b (%s) fail\n", TP2856_FILE); return -1; } for (i = 0; i < chip_cnt; i++) { tp_video_mode.chip = i; switch (vi_mode) { case SAMPLE_VI_MODE_720P_1X4: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? TP2802_720P25V2 : TP2802_720P30V2; tp_video_mode.output = MIPI_1CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_720P_2X2: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? TP2802_720P25V2 : TP2802_720P30V2; tp_video_mode.output = MIPI_2CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_720P_4X4: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? TP2802_720P25V2 : TP2802_720P30V2; tp_video_mode.output = MIPI_4CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_1080P_1X2: case SAMPLE_VI_MODE_1080P_2X2: case SAMPLE_VI_MODE_1080P_2X4: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = (video_encoding == SAMPLE_VIDEO_ENCODING_PAL) ? TP2802_1080P25 : TP2802_1080P30; tp_video_mode.output = MIPI_2CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_4M_1X8: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = TP2802_QHD15; tp_video_mode.output = MIPI_1CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_5M_1X8: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = TP2802_5M12; tp_video_mode.output = MIPI_1CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; case SAMPLE_VI_MODE_4K_1X8: for (j = 0; j < CHANNELS_PER_CHIP; j++) { tp_video_mode.ch = j; tp_video_mode.std = STD_HDA; tp_video_mode.mode = TP2802_8M15; tp_video_mode.output = MIPI_1CH4LANE_297M; ioctl(fd, TP2802_SET_VIDEO_MODE, &tp_video_mode); } break; default: printf("vi_mode %d not supported\n", vi_mode); break; } } close(fd); return TD_SUCCESS; } #endif td_s32 sample_common_vi_start_ad(sample_vi_mode vi_mode, sample_video_encoding video_encoding) { td_s32 ret; #if SAMPLE_AD_TYPE == AD_NVP6158 ret = sample_nvp6158_cfg(vi_mode, video_encoding); if (ret != TD_SUCCESS) { sample_print("nvp6158 config failed!\n"); return ret; } #elif SAMPLE_AD_TYPE == AD_TP2854B ret = sample_tp2854b_cfg(vi_mode, video_encoding); if (ret != TD_SUCCESS) { sample_print("tp2854b config failed!\n"); return ret; } #elif SAMPLE_AD_TYPE == AD_TP2856 ret = sample_tp2856_cfg(vi_mode, video_encoding); if (ret != TD_SUCCESS) { sample_print("tp2854b config failed!\n"); return ret; } #endif return TD_SUCCESS; } #if SAMPLE_AD_TYPE == AD_TP2854B || SAMPLE_AD_TYPE == AD_TP2856 td_s32 sample_common_vi_set_mipi_attr(td_s32 fd, combo_dev_t mipi_dev, ot_rect *capture_rect, sample_vi_param *vi_param) { td_s32 i; td_s32 ret; combo_dev_attr_t mipi_dev_attr; mipi_dev_attr.devno = mipi_dev; mipi_dev_attr.img_rect.x = 0; mipi_dev_attr.img_rect.y = 0; mipi_dev_attr.img_rect.width = capture_rect->width; mipi_dev_attr.img_rect.height = capture_rect->height; mipi_dev_attr.input_mode = INPUT_MODE_MIPI; mipi_dev_attr.mipi_attr.input_data_type = DATA_TYPE_YUV422_8BIT; mipi_dev_attr.scan_mode = (mipi_scan_mode_t)vi_param->scan_mode; for (i = 0; i < MIPI_LANE_NUM_PRE_DEV; i++) { mipi_dev_attr.mipi_attr.lane_id[i] = mipi_dev * MIPI_LANE_NUM_PRE_DEV + i; } ret = ioctl(fd, OT_MIPI_SET_DEV_ATTR, &mipi_dev_attr); if (ret != TD_SUCCESS) { sample_print("OT_MIPI_SET_DEV_ATTR failed\n"); return TD_FAILURE; } return TD_SUCCESS; } td_s32 sample_common_vi_start_mipi(ot_rect *capture_rect, sample_vi_param *vi_param) { td_s32 i; td_s32 ret; td_s32 fd; combo_dev_t mipi_dev; lane_divide_mode_t hs_mode = LANE_DIVIDE_MODE_0; fd = open(MIPI_DEV_NODE, O_RDWR); if (fd < 0) { sample_print("open ot_mipi dev failed\n"); return TD_FAILURE; } ret = ioctl(fd, OT_MIPI_SET_HS_MODE, &hs_mode); if (ret != TD_SUCCESS) { sample_print("OT_MIPI_SET_HS_MODE failed\n"); close(fd); return ret; } for (i = 0; i < vi_param->vi_dev_cnt; i++) { mipi_dev = i * vi_param->vi_dev_interval; ret = ioctl(fd, OT_MIPI_ENABLE_MIPI_CLOCK, &mipi_dev); if (ret != TD_SUCCESS) { sample_print("OT_MIPI_ENABLE_MIPI_CLOCK failed\n"); close(fd); return ret; } ret = ioctl(fd, OT_MIPI_RESET_MIPI, &mipi_dev); if (ret != TD_SUCCESS) { sample_print("OT_MIPI_RESET_MIPI failed\n"); close(fd); return ret; } ret = sample_common_vi_set_mipi_attr(fd, mipi_dev, capture_rect, vi_param); if (ret != TD_SUCCESS) { sample_print("vi set mipi attr failed\n"); close(fd); return ret; } ret = ioctl(fd, OT_MIPI_UNRESET_MIPI, &mipi_dev); if (ret != TD_SUCCESS) { sample_print("OT_MIPI_UNRESET_MIPI failed\n"); close(fd); return ret; } } close(fd); return TD_SUCCESS; } td_s32 sample_common_vi_stop_mipi(sample_vi_param *vi_param) { td_s32 i; td_s32 ret; td_s32 fd; combo_dev_t mipi_dev; fd = open(MIPI_DEV_NODE, O_RDWR); if (fd < 0) { sample_print("open ot_mipi dev failed\n"); return TD_FAILURE; } for (i = 0; i < vi_param->vi_dev_cnt; i++) { mipi_dev = i * vi_param->vi_dev_interval; ret = ioctl(fd, OT_MIPI_RESET_MIPI, &mipi_dev); if (ret != TD_SUCCESS) { sample_print("OT_MIPI_RESET_MIPI failed\n"); close(fd); return TD_FAILURE; } ret = ioctl(fd, OT_MIPI_DISABLE_MIPI_CLOCK, &mipi_dev); if (ret != TD_SUCCESS) { sample_print("OT_MIPI_ENABLE_MIPI_CLOCK failed\n"); close(fd); return TD_FAILURE; } } close(fd); return TD_SUCCESS; } #endif td_void sample_common_vi_set_mask(ot_vi_dev vi_dev, ot_vi_dev_attr *dev_attr) { if (dev_attr->intf_mode == OT_VI_MODE_MIPI_YUV422) { dev_attr->component_mask[0] = 0x00ff0; dev_attr->component_mask[1] = 0xff000; dev_attr->data_seq = OT_VI_IN_DATA_UVUV; } else if (dev_attr->intf_mode == OT_VI_MODE_BT656) { if (vi_dev % 2 == 0) { /* 2 : odd-even judge */ dev_attr->component_mask[0] = 0x00ff0; } else { dev_attr->component_mask[0] = 0xff000; } dev_attr->data_seq = OT_VI_IN_DATA_UYVY; } else if (dev_attr->intf_mode == OT_VI_MODE_BT1120_STANDARD) { dev_attr->component_mask[1] = 0x00ff0; dev_attr->component_mask[0] = 0xff000; dev_attr->data_seq = OT_VI_IN_DATA_VUVU; } } td_s32 sample_common_vi_start_dev(ot_vi_dev vi_dev, sample_vi_mode vi_mode) { td_s32 ret; ot_vi_dev_attr vi_dev_attr; ot_vi_work_mode vi_work_mode; (td_void)memcpy_s(&vi_dev_attr, sizeof(ot_vi_dev_attr), &g_sample_vi_dev_attr, sizeof(ot_vi_dev_attr)); switch (vi_mode) { case SAMPLE_VI_MODE_960H_4X4: vi_work_mode = OT_VI_WORK_MODE_MULTIPLEX_4; break; case SAMPLE_VI_MODE_720P_4X4: vi_work_mode = OT_VI_WORK_MODE_MULTIPLEX_4; break; case SAMPLE_VI_MODE_720P_2X2: case SAMPLE_VI_MODE_1080P_1X2: case SAMPLE_VI_MODE_1080P_2X2: vi_work_mode = OT_VI_WORK_MODE_MULTIPLEX_2; break; case SAMPLE_VI_MODE_720P_1X4: case SAMPLE_VI_MODE_1080P_2X1: case SAMPLE_VI_MODE_720P_2X1: case SAMPLE_VI_MODE_4K_2X1: case SAMPLE_VI_MODE_4K_1X8: vi_work_mode = OT_VI_WORK_MODE_MULTIPLEX_1; break; default: sample_print("vi mode invalid!\n"); return TD_FAILURE; } vi_dev_attr.work_mode = vi_work_mode; #if 1 #if SAMPLE_AD_TYPE == AD_NVP6158 vi_dev_attr.intf_mode = OT_VI_MODE_BT656; if (vi_mode == SAMPLE_VI_MODE_720P_4X4 || vi_mode == SAMPLE_VI_MODE_1080P_1X2 || vi_mode == SAMPLE_VI_MODE_1080P_2X2 || vi_mode == SAMPLE_VI_MODE_4K_1X8) { vi_dev_attr.clk_edge = OT_VI_CLK_EDGE_DOUBLE; } #elif SAMPLE_AD_TYPE == AD_TP2854B || SAMPLE_AD_TYPE == AD_TP2856 vi_dev_attr.intf_mode = OT_VI_MODE_MIPI_YUV422; #elif SAMPLE_AD_TYPE == BT1120 vi_dev_attr.intf_mode = OT_VI_MODE_BT1120_STANDARD; #endif #endif sample_common_vi_set_mask(vi_dev, &vi_dev_attr); #if 0 typedef struct { td_s32 detect_err_frame; td_s32 drop_err_frame; td_s32 int_gap_time; td_s32 min_cas_gap; td_s32 max_cas_gap; td_s32 stop_int_level; td_s32 int_time; td_s32 discard_int; td_s32 yc_reverse; td_s32 compat_mode; td_s32 time_ref_gap; } ot_vi_mod_param; #endif ot_vi_mod_param mod_param; ret = ss_mpi_vi_get_mod_param(&mod_param); if(ret != TD_SUCCESS){ sample_print("ss_mpi_vi_get_mod_param failed 0x%x\n", ret); return ret; } sample_print("ss_mpi_vi_get_mod_param failed 0x%x\n", mod_param.yc_reverse); ss_mpi_vi_disable_dev(vi_dev); #if 1 mod_param.yc_reverse = 0; ret = ss_mpi_vi_set_mod_param(&mod_param); // if(ret != TD_SUCCESS){ // sample_print("ss_mpi_vi_set_mod_param failed 0x%x\n", ret); // return ret; //} #endif ret = ss_mpi_vi_set_dev_attr(vi_dev, &vi_dev_attr); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vi_set_dev_attr failed 0x%x\n", ret); return ret; } ret = ss_mpi_vi_enable_dev(vi_dev); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vi_enable_dev failed 0x%x\n", ret); return ret; } return TD_SUCCESS; } td_s32 sample_common_vi_start_chn(td_s32 vi_chn, ot_rect *capture_rect, ot_size *dst_size, sample_vi_param *vi_param) { td_s32 ret; ot_vi_chn_attr vi_chn_attr; ot_vi_chn_attr minor_chn_attr; (td_void)memcpy_s(&vi_chn_attr, sizeof(ot_vi_chn_attr), &g_sample_vi_chn_attr, sizeof(ot_vi_chn_attr)); (td_void)memcpy_s(&vi_chn_attr.capture_rect, sizeof(ot_rect), capture_rect, sizeof(ot_rect)); (td_void)memcpy_s(&vi_chn_attr.dst_size, sizeof(ot_size), dst_size, sizeof(ot_size)); // vi_chn_attr.compress_mode = OT_COMPRESS_MODE_SEG_COMPACT; vi_chn_attr.compress_mode = OT_COMPRESS_MODE_NONE; vi_chn_attr.pixel_format = SAMPLE_PIXEL_FORMAT; vi_chn_attr.scan_mode = vi_param->scan_mode; vi_chn_attr.src_frame_rate = -1; vi_chn_attr.dst_frame_rate = -1; ret = ss_mpi_vi_set_chn_attr(vi_chn, &vi_chn_attr); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vi_set_chn_attr failed 0x%x\n", ret); return ret; } ret = ss_mpi_vi_enable_chn(vi_chn); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vi_enable_chn failed 0x%x\n", ret); return ret; } if (vi_param->minor_attr_en == TD_TRUE) { (td_void)memcpy_s(&minor_chn_attr, sizeof(ot_vi_chn_attr), &vi_chn_attr, sizeof(ot_vi_chn_attr)); (td_void)memcpy_s(&minor_chn_attr.dst_size, sizeof(ot_size), &vi_param->minor_dst_size, sizeof(ot_size)); minor_chn_attr.src_frame_rate = -1; minor_chn_attr.dst_frame_rate = -1; minor_chn_attr.compress_mode = OT_COMPRESS_MODE_NONE; ret = ss_mpi_vi_set_minor_chn_attr(minor_chn(vi_chn), &minor_chn_attr); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vi_set_minor_chn_attr failed 0x%x\n", ret); return ret; } ret = ss_mpi_vi_enable_chn(minor_chn(vi_chn)); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vi_enable_chn failed 0x%x\n", ret); return ret; } } return TD_SUCCESS; } td_s32 sample_common_vi_set_chn_bind(sample_vi_mode vi_mode, sample_vi_param *vi_param) { #if SAMPLE_AD_TYPE == AD_TP2854B || SAMPLE_AD_TYPE == AD_TP2856 td_s32 i; td_s32 ret; ot_vi_chn vi_chn; ot_vi_dev vi_dev; ot_vi_chn_bind_attr chn_bind_attr; if (vi_mode != SAMPLE_VI_MODE_720P_2X2 && vi_mode != SAMPLE_VI_MODE_1080P_1X2 && vi_mode != SAMPLE_VI_MODE_1080P_2X2) { return TD_SUCCESS; } for (i = 0; i < vi_param->vi_chn_cnt; i++) { vi_chn = i * vi_param->vi_chn_interval; vi_dev = vi_chn / CHN_NUM_PRE_DEV; /* chn 2,6,10,14,18,22,26,30 */ if (vi_chn == CHN_NUM_PRE_DEV * vi_dev + SECOND_CHN_OFFSET_2MUX) { ret = ss_mpi_vi_unbind_chn(vi_chn); if (ret != TD_SUCCESS) { return ret; } chn_bind_attr.vi_dev = vi_dev; chn_bind_attr.vi_way = vi_chn; ret = ss_mpi_vi_bind_chn(vi_chn, &chn_bind_attr); if (ret != TD_SUCCESS) { return ret; } } } #endif return TD_SUCCESS; } td_s32 sample_common_vi_start_vi(sample_vi_mode vi_mode, sample_video_encoding video_encoding, sample_vi_param *vi_param) { ot_vi_dev vi_dev; ot_vi_chn vi_chn; td_s32 i; td_s32 ret; ot_size dst_size; ot_rect capture_rect; ret = sample_common_vi_mode_to_size(vi_mode, video_encoding, &capture_rect, &dst_size); if (ret != TD_SUCCESS) { sample_print("vi get size failed!\n"); return ret; } #if 0 /* start mipi */ #if SAMPLE_AD_TYPE == AD_TP2854B || SAMPLE_AD_TYPE == AD_TP2856 ret = sample_common_vi_start_mipi(&capture_rect, vi_param); if (ret != TD_SUCCESS) { sample_print("vi start mipi failed!\n"); return ret; } #endif /* start ad */ ret = sample_common_vi_start_ad(vi_mode, video_encoding); if (ret != TD_SUCCESS) { sample_print("vi start ad failed!\n"); return ret; } #endif /* start vi dev */ for (i = 0; i < vi_param->vi_dev_cnt; i++) { vi_dev = i * vi_param->vi_dev_interval; ret = sample_common_vi_start_dev(vi_dev, vi_mode); if (ret != TD_SUCCESS) { sample_print("sample_common_vi_start_dev failed with %#x\n", ret); return TD_FAILURE; } } ret = sample_common_vi_set_chn_bind(vi_mode, vi_param); if (ret != TD_SUCCESS) { sample_print("sample_common_vi_set_chn_bind failed with %#x\n", ret); return TD_FAILURE; } /* start vi chn */ for (i = 0; i < vi_param->vi_chn_cnt; i++) { vi_chn = i * vi_param->vi_chn_interval; ret = sample_common_vi_start_chn(vi_chn, &capture_rect, &dst_size, vi_param); if (ret != TD_SUCCESS) { sample_print("sample_common_vi_start_chn failed with %#x\n", ret); return TD_FAILURE; } } return TD_SUCCESS; } td_s32 sample_common_vi_stop(sample_vi_mode vi_mode, sample_vi_param *vi_param) { td_s32 i; td_s32 ret; ot_vi_dev vi_dev; ot_vi_chn vi_chn; ot_unused(vi_mode); /* stop vi chn */ for (i = 0; i < vi_param->vi_chn_cnt; i++) { vi_chn = i * vi_param->vi_chn_interval; ret = ss_mpi_vi_disable_chn(minor_chn(vi_chn)); if (ret != TD_SUCCESS) { sample_print("ss_mpi_vi_disable_chn failed!\n"); return ret; } 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 < vi_param->vi_dev_cnt; i++) { vi_dev = i * 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; } } /* stop mipi */ #if SAMPLE_AD_TYPE == AD_TP2854B || SAMPLE_AD_TYPE == AD_TP2856 ret = sample_common_vi_stop_mipi(vi_param); if (ret != TD_SUCCESS) { sample_print("stop mipi failed!\n"); return ret; } #endif return TD_SUCCESS; }