Files
hisi_SS524V100_SDK/mpp/sample/vio/sample_vio.c
T

1160 lines
33 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 <sys/ioctl.h>
#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 <index>\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;
}