Files
hisi_SS524V100_SDK/mpp/sample/vdec_udp_h265/sample_vdec.c
T

1366 lines
42 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/time.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <math.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <sched.h>
#include <sys/syscall.h>
#include <errno.h>
#include <sys/mman.h>
#include "dqueue.h"
#include "ss_mpi_vb.h"
#include "ss_mpi_sys.h"
#include "ss_mpi_vgs.h"
#include "sample_comm.h"
#ifdef OT_FPGA
#define PIC_SIZE PIC_1080P
#else
#define PIC_SIZE PIC_3840X2160
#endif
#define SAMPLE_STREAM_PATH "./source_file"
#define STREAN_WIDTH 1920
#define STREAM_HEIGHT 1200
#define REF_NUM 2
#define DISPLAY_NUM 2
#if 1
#define NOSIGNAL_YUV_PATH "./nosignal.yuv"
static ot_video_frame_info g_nosignal_src; /* 1920x1200 源图(VGS 输入) */
static ot_vb_pool g_nosignal_src_pool = OT_VB_INVALID_POOL_ID;
static ot_vb_blk g_nosignal_src_blk = OT_VB_INVALID_HANDLE;
static td_bool g_nosignal_src_valid = TD_FALSE;
#endif
static ot_vo_intf_sync g_intf_sync = OT_VO_OUT_3840x2160_30;
static vdec_display_cfg g_vdec_display_cfg = {
.pic_size = PIC_3840X2160,
.intf_sync = OT_VO_OUT_3840x2160_30,
.intf_type = OT_VO_INTF_HDMI,
};
static ot_size g_disp_size;
static td_s32 g_sample_exit = 0;
int fd_fs;
unsigned char buffer_nal[2048];
static int socket_descriptor;
static struct sockaddr_in address;
static struct sockaddr_in clientAddr;
static struct timeval tv;
int sock_len;
extern int socket_descriptor_audio;
extern struct sockaddr_in address_audio;
pthread_attr_t attr;
static pthread_t vid_au_thread;
pthread_cond_t vid_au_cond;
pthread_mutex_t vid_au_mutex;
dqueue vid_au_q;
// static ot_vb_pool g_usrpic_pool = OT_VB_INVALID_POOL_ID;
// static ot_video_frame_info g_usrpic_info;
int do_exit_inner = 0;
int vid_q_len = 0;
int *switch_video;
int *video_switch;
//unsigned int switch_video[10];
#ifndef __LITEOS__
static td_void sample_vdec_handle_sig(td_s32 signo)
{
if ((signo == SIGINT) || (signo == SIGTERM)) {
g_sample_exit = 1;
}
}
#endif
static td_s32 sample_getchar()
{
int c;
if (g_sample_exit == 1) {
return 'e';
}
c = getchar();
if (g_sample_exit == 1) {
return 'e';
}
return c;
}
static td_void sample_vdec_usage(const char *s_prg_nm)
{
printf("\n/************************************/\n");
printf("usage : %s <index> <intf_sync >\n", s_prg_nm);
printf("index:\n");
printf("\t0: VDEC(H265 PLAYBACK)-VPSS-VO\n");
printf("\t1: VDEC(H264 PLAYBACK)-VPSS-VO\n");
printf("\t2: VDEC(H264 PREVIEW)-VPSS-VOPIP\n");
printf("\t3: VDEC(JPEG PLAYBACK)-VPSS-VO\n");
printf("\nintf_sync :\n");
#ifdef OT_FPGA
printf("\t0: VO BT1120 \n");
#else
printf("\t0: VO HDMI \n");
printf("\t1: VO BT1120 \n");
#endif
printf("/************************************/\n\n");
}
static td_void sample_vdec_get_diplay_cfg()
{
#ifdef OT_FPGA
g_vdec_display_cfg.pic_size = PIC_720P;
g_vdec_display_cfg.intf_sync = OT_VO_OUT_720P60;
g_vdec_display_cfg.intf_type = OT_VO_INTF_BT1120;
#else
if (g_intf_sync == OT_VO_OUT_3840x2160_30) {
g_vdec_display_cfg.pic_size = PIC_3840X2160;
g_vdec_display_cfg.intf_sync = OT_VO_OUT_3840x2160_30;
g_vdec_display_cfg.intf_type = OT_VO_INTF_HDMI;
} else {
g_vdec_display_cfg.pic_size = PIC_1920X1200;
//g_vdec_display_cfg.pic_size = PIC_1080P;
g_vdec_display_cfg.intf_sync = OT_VO_OUT_1920x1200_60;
//g_vdec_display_cfg.intf_sync = OT_VO_OUT_1080P60;
//g_vdec_display_cfg.intf_type = OT_VO_INTF_BT1120;
g_vdec_display_cfg.intf_type = OT_VO_INTF_HDMI;
}
#endif
}
static td_s32 sample_init_module_vb(sample_vdec_attr *sample_vdec, td_u32 vdec_chn_num, ot_payload_type type,
td_u32 len)
{
td_u32 i;
td_s32 ret;
for (i = 0; (i < vdec_chn_num) && (i < len); i++) {
sample_vdec[i].type = type;
sample_vdec[i].width = STREAN_WIDTH;
sample_vdec[i].height = STREAM_HEIGHT;
//sample_vdec[i].mode = OT_VDEC_SEND_MODE_STREAM;
sample_vdec[i].mode = OT_VDEC_SEND_MODE_FRAME;
sample_vdec[i].sample_vdec_video.dec_mode = OT_VIDEO_DEC_MODE_IP;
sample_vdec[i].sample_vdec_video.bit_width = OT_DATA_BIT_WIDTH_8;
if (type == OT_PT_JPEG) {
sample_vdec[i].sample_vdec_video.ref_frame_num = 0;
} else {
sample_vdec[i].sample_vdec_video.ref_frame_num = REF_NUM;
}
sample_vdec[i].display_frame_num = DISPLAY_NUM;
sample_vdec[i].frame_buf_cnt = (type == OT_PT_JPEG) ? (sample_vdec[i].display_frame_num + 1) :
(sample_vdec[i].sample_vdec_video.ref_frame_num + sample_vdec[i].display_frame_num + 1);
if (type == OT_PT_JPEG) {
sample_vdec[i].sample_vdec_picture.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
sample_vdec[i].sample_vdec_picture.alpha = 255; /* 255:pic alpha value */
}
}
ret = sample_comm_vdec_init_vb_pool(vdec_chn_num, &sample_vdec[0], len);
if (ret != TD_SUCCESS) {
sample_print("init mod common vb fail for %#x!\n", ret);
return ret;
}
return ret;
}
static td_s32 sample_init_sys_and_vb(sample_vdec_attr *sample_vdec, td_u32 vdec_chn_num, ot_payload_type type,
td_u32 len)
{
ot_vb_cfg vb_cfg;
ot_pic_buf_attr buf_attr = {0};
td_s32 ret;
sample_vdec_get_diplay_cfg();
ret = sample_comm_sys_get_pic_size(g_vdec_display_cfg.pic_size, &g_disp_size);
if (ret != TD_SUCCESS) {
sample_print("sys get pic size fail for %#x!\n", ret);
return ret;
}
buf_attr.align = 0;
buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
buf_attr.compress_mode = OT_COMPRESS_MODE_SEG;
buf_attr.height = g_disp_size.height;
buf_attr.width = g_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;
vb_cfg.common_pool[0].blk_cnt = 10 * vdec_chn_num; /* 10:common vb 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_init_module_vb(&sample_vdec[0], vdec_chn_num, type, len);
if (ret != TD_SUCCESS) {
sample_print("init mod vb fail for %#x!\n", ret);
sample_comm_vdec_exit_vb_pool();
sample_comm_sys_exit();
return ret;
}
return ret;
}
static td_s32 sample_start_vpss_crop(ot_vpss_grp *vpss_grp)
{
ot_vpss_crop_info crop_info;
td_s32 ret;
*vpss_grp = 1;
crop_info.enable = TD_TRUE;
crop_info.crop_mode = OT_COORD_ABS;
crop_info.crop_rect.x = OT_ALIGN_UP(STREAN_WIDTH / 4, 2); /* 4,2:align */
crop_info.crop_rect.y = OT_ALIGN_UP(STREAM_HEIGHT / 4, 2); /* 4,2:align */
crop_info.crop_rect.width = OT_ALIGN_UP(STREAN_WIDTH / 2, 2); /* 2,2:align */
crop_info.crop_rect.height = OT_ALIGN_UP(STREAM_HEIGHT / 2, 2); /* 2,2:align */
ret = ss_mpi_vpss_set_grp_crop(*vpss_grp, &crop_info);
if (ret != TD_SUCCESS) {
sample_print("start VPSS fail for %#x!\n", ret);
return ret;
}
return ret;
}
static td_s32 sample_vdec_bind_vpss(td_u32 vpss_grp_num, td_bool is_pip)
{
td_u32 i;
td_s32 ret = TD_SUCCESS;
for (i = 0; i < vpss_grp_num; i++) {
ret = sample_comm_vdec_bind_vpss(is_pip ? 0 : i, i);
if (ret != TD_SUCCESS) {
sample_print("vdec bind vpss fail for %#x!\n", ret);
return ret;
}
}
return ret;
}
static td_void sample_stop_vpss(ot_vpss_grp vpss_grp, td_bool *vpss_chn_enable, td_u32 chn_array_size)
{
td_s32 i;
for (i = vpss_grp; i >= 0; i--) {
vpss_grp = i;
sample_common_vpss_stop(vpss_grp, &vpss_chn_enable[0], chn_array_size);
}
}
static td_s32 sample_vdec_unbind_vpss(td_u32 vpss_grp_num, td_bool is_pip)
{
td_u32 i;
td_s32 ret = TD_SUCCESS;
for (i = 0; i < vpss_grp_num; i++) {
ret = sample_comm_vdec_un_bind_vpss(is_pip ? 0 : i, i);
if (ret != TD_SUCCESS) {
sample_print("vdec unbind vpss fail for %#x!\n", ret);
}
}
return ret;
}
static td_void sample_config_vpss_grp_attr(ot_vpss_grp_attr *vpss_grp_attr)
{
vpss_grp_attr->max_width = STREAN_WIDTH;
vpss_grp_attr->max_height = STREAM_HEIGHT;
vpss_grp_attr->frame_rate.src_frame_rate = -1;
vpss_grp_attr->frame_rate.dst_frame_rate = -1;
vpss_grp_attr->pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
vpss_grp_attr->nr_en = TD_FALSE;
vpss_grp_attr->ie_en = TD_FALSE;
vpss_grp_attr->dci_en = TD_FALSE;
vpss_grp_attr->dei_mode = OT_VPSS_DEI_MODE_OFF;
vpss_grp_attr->buf_share_en = TD_FALSE;
}
static td_s32 sample_start_vpss(ot_vpss_grp *vpss_grp, td_u32 vpss_grp_num, td_bool *vpss_chn_enable,
td_bool is_pip, td_u32 arr_len)
{
td_u32 i;
td_s32 ret;
ot_vpss_chn_attr vpss_chn_attr[OT_VPSS_MAX_CHN_NUM];
ot_vpss_grp_attr vpss_grp_attr = {0};
sample_config_vpss_grp_attr(&vpss_grp_attr);
(td_void)memset_s(vpss_chn_enable, arr_len * sizeof(td_bool), 0, arr_len * sizeof(td_bool));
if (arr_len > 1) {
vpss_chn_enable[1] = TD_TRUE;
vpss_chn_attr[1].width = is_pip ? (g_disp_size.width / 4) : g_disp_size.width; /* 4:crop */
vpss_chn_attr[1].height = is_pip ? (g_disp_size.height / 4) : g_disp_size.height; /* 4:crop */
vpss_chn_attr[1].chn_mode = OT_VPSS_CHN_MODE_AUTO;
vpss_chn_attr[1].compress_mode = is_pip ? OT_COMPRESS_MODE_NONE : OT_COMPRESS_MODE_SEG;
vpss_chn_attr[1].pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
vpss_chn_attr[1].frame_rate.src_frame_rate = -1;
vpss_chn_attr[1].frame_rate.dst_frame_rate = -1;
vpss_chn_attr[1].depth = 0;
vpss_chn_attr[1].mirror_en = TD_FALSE; //TD_TRUE; //180
vpss_chn_attr[1].flip_en = TD_FALSE; //TD_TRUE; //180
vpss_chn_attr[1].border_en = TD_FALSE;
vpss_chn_attr[1].aspect_ratio.mode = OT_ASPECT_RATIO_NONE;
}
for (i = 0; i < vpss_grp_num; i++) {
*vpss_grp = i;
ret = sample_common_vpss_start(*vpss_grp, &vpss_chn_enable[0],
&vpss_grp_attr, vpss_chn_attr, OT_VPSS_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
sample_print("start VPSS fail for %#x!\n", ret);
sample_stop_vpss(*vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
return ret;
}
}
if (is_pip) {
ret = sample_start_vpss_crop(vpss_grp);
if (ret != TD_SUCCESS) {
sample_stop_vpss(*vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
return ret;
}
}
ret = sample_vdec_bind_vpss(vpss_grp_num, is_pip);
if (ret != TD_SUCCESS) {
sample_vdec_unbind_vpss(vpss_grp_num, is_pip);
sample_stop_vpss(*vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
}
return ret;
}
static td_s32 sample_vpss_unbind_vo(td_u32 vpss_grp_num, sample_vo_cfg vo_config)
{
td_u32 i;
ot_vo_layer vo_layer = vo_config.vo_dev;
td_s32 ret = TD_SUCCESS;
for (i = 0; i < vpss_grp_num; i++) {
ret = sample_comm_vpss_un_bind_vo(i, 1, vo_layer, i);
if (ret != TD_SUCCESS) {
sample_print("vpss unbind vo fail for %#x!\n", ret);
}
}
return ret;
}
static td_s32 sample_vpss_bind_vo(sample_vo_cfg vo_config, td_u32 vpss_grp_num, td_bool is_pip)
{
td_u32 i;
ot_vo_layer vo_layer;
td_s32 ret = TD_SUCCESS;
vo_layer = vo_config.vo_dev;
for (i = 0; i < vpss_grp_num; i++) {
if (is_pip) {
vo_layer = (i == 0) ? 0 : 2; /* 2:layer id */
}
ret = sample_comm_vpss_bind_vo(i, 1, vo_layer, is_pip ? 0 : i);
if (ret != TD_SUCCESS) {
sample_print("vpss bind vo fail for %#x!\n", ret);
return ret;
}
}
return ret;
}
static td_s32 sample_start_vo(sample_vo_cfg *vo_config, td_u32 vpss_grp_num, td_bool is_pip)
{
td_s32 ret;
vo_config->vo_dev = SAMPLE_VO_DEV_UHD;
vo_config->vo_intf_type = g_vdec_display_cfg.intf_type;
vo_config->intf_sync = g_vdec_display_cfg.intf_sync;
vo_config->pic_size = g_vdec_display_cfg.pic_size;
vo_config->bg_color = COLOR_RGB_BLACK;//COLOR_RGB_BLUE;
vo_config->dis_buf_len = 3; /* 3:buf length */
vo_config->dst_dynamic_range = OT_DYNAMIC_RANGE_SDR8;
vo_config->vo_mode = VO_MODE_8MUX;//VO_MODE_4MUX;
vo_config->pix_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
vo_config->disp_rect.x = 0;
vo_config->disp_rect.y = 0;
vo_config->disp_rect.width = g_disp_size.width;
vo_config->disp_rect.height = g_disp_size.height;
vo_config->image_size.width = g_disp_size.width;
vo_config->image_size.height = g_disp_size.height;
vo_config->vo_part_mode = OT_VO_PARTITION_MODE_SINGLE;
vo_config->compress_mode = OT_COMPRESS_MODE_NONE;
ret = sample_comm_vo_start_vo(vo_config);
if (ret != TD_SUCCESS) {
sample_print("start VO fail for %#x!\n", ret);
sample_comm_vo_stop_vo(vo_config);
return ret;
}
if (is_pip == TD_TRUE) {
ret = sample_comm_vo_start_pip(vo_config);
if (ret != TD_SUCCESS) {
sample_print("start VO PIP fail for %#x!\n", ret);
sample_comm_vo_stop_pip(vo_config);
sample_comm_vo_stop_vo(vo_config);
return ret;
}
}
ret = sample_vpss_bind_vo(*vo_config, vpss_grp_num, is_pip);
if (ret != TD_SUCCESS) {
sample_vpss_unbind_vo(vpss_grp_num, *vo_config);
if (is_pip == TD_TRUE) {
sample_comm_vo_stop_pip(vo_config);
}
sample_comm_vo_stop_vo(vo_config);
}
return ret;
}
static td_void sample_vdec_cmd_ctrl(td_u32 chn_num, vdec_thread_param *vdec_send, pthread_t *vdec_thread,
td_u32 send_arr_len, td_u32 thread_arr_len)
{
td_u32 i;
ot_vdec_chn_status status;
td_bool vo_pause = TD_FALSE;
td_s32 c;
for (i = 0; (i < chn_num) && (i < send_arr_len) && (i < thread_arr_len); i++) {
if (vdec_send[i].circle_send == TD_TRUE) {
goto circle_send;
}
}
sample_comm_vdec_cmd_not_circle_send(chn_num, vdec_send, vdec_thread, send_arr_len, thread_arr_len);
return;
circle_send:
while (1) {
printf("\n_sample_test:press 'e' to exit; 'p' to pause; 'r' to resume; 'q' to query; 's' to step;"
" 'a' to add; 'd' to sub!;\n");
c = sample_getchar();
if (c == 'e') {
break;
} else if (c == 'r') {
sample_comm_vdec_cmd_ctrl_resume(chn_num, &vdec_send[0], send_arr_len, thread_arr_len, &vo_pause);
} else if (c == 'p') {
sample_comm_vdec_cmd_ctrl_pause(chn_num, &vdec_send[0], send_arr_len, thread_arr_len, &vo_pause);
} else if (c == 'a') {
sample_comm_vdec_cmd_ctrl_add();
} else if (c == 'd') {
sample_comm_vdec_cmd_ctrl_sub();
} else if (c == 's') {
sample_comm_vdec_cmd_ctrl_step(chn_num, vo_pause);
} else if (c == 'q') {
for (i = 0; (i < chn_num) && (i < send_arr_len) && (i < thread_arr_len); i++) {
ss_mpi_vdec_query_status(vdec_send[i].chn_id, &status);
sample_comm_vdec_print_chn_status(vdec_send[i].chn_id, status);
}
}
}
return;
}
static td_void sample_send_stream_to_vdec(sample_vdec_attr *sample_vdec, td_u32 arr_len, td_u32 vdec_chn_num,
const char *stream_name, td_bool is_pip)
{
td_u32 i;
vdec_thread_param vdec_send[OT_VDEC_MAX_CHN_NUM];
pthread_t vdec_thread[OT_VDEC_MAX_CHN_NUM] = {0}; /* 2:thread */
if (arr_len > OT_VDEC_MAX_CHN_NUM) {
sample_print("array size(%u) of vdec_send need < %u!\n", arr_len, OT_VDEC_MAX_CHN_NUM);
return;
}
for (i = 0; (i < vdec_chn_num) && (i < arr_len); i++) {
if (snprintf_s(vdec_send[i].c_file_name, sizeof(vdec_send[i].c_file_name), sizeof(vdec_send[i].c_file_name) - 1,
stream_name) < 0) {
return;
}
if (snprintf_s(vdec_send[i].c_file_path, sizeof(vdec_send[i].c_file_path), sizeof(vdec_send[i].c_file_path) - 1,
"%s", SAMPLE_STREAM_PATH) < 0) {
return;
}
vdec_send[i].type = sample_vdec[i].type;
vdec_send[i].stream_mode = sample_vdec[i].mode;
vdec_send[i].chn_id = i;
vdec_send[i].interval_time = 1000; /* 1000: interval time */
vdec_send[i].pts_init = 0;
vdec_send[i].pts_increase = 0;
vdec_send[i].e_thread_ctrl = THREAD_CTRL_START;
vdec_send[i].circle_send = TD_TRUE;
vdec_send[i].milli_sec = 0;
vdec_send[i].min_buf_size = (sample_vdec[i].width * sample_vdec[i].height * 3) >> 1; /* 3:yuv */
}
sample_comm_vdec_start_send_stream(vdec_chn_num, &vdec_send[0], &vdec_thread[0],
OT_VDEC_MAX_CHN_NUM, OT_VDEC_MAX_CHN_NUM);
while(1){
sleep(5);
}
if (is_pip) {
printf("\n_sample_test:press any key to exit!\n");
sample_getchar();
} else {
sample_vdec_cmd_ctrl(vdec_chn_num, &vdec_send[0], &vdec_thread[0],
OT_VDEC_MAX_CHN_NUM, OT_VDEC_MAX_CHN_NUM);
}
sample_comm_vdec_stop_send_stream(vdec_chn_num, &vdec_send[0], &vdec_thread[0],
OT_VDEC_MAX_CHN_NUM, OT_VDEC_MAX_CHN_NUM);
}
static td_s32 sample_start_vdec(sample_vdec_attr *sample_vdec, td_u32 vdec_chn_num, td_u32 len, td_bool is_pip)
{
td_s32 ret;
td_u32 i;
ret = sample_comm_vdec_start(vdec_chn_num, &sample_vdec[0], len);
if (ret != TD_SUCCESS) {
sample_print("start VDEC fail for %#x!\n", ret);
sample_comm_vdec_stop(vdec_chn_num);
return ret;
}
if (is_pip == TD_TRUE) {
for (i = 0; i < vdec_chn_num; i++) {
ret = ss_mpi_vdec_set_display_mode(i, OT_VIDEO_DISPLAY_MODE_PREVIEW);
if (ret != TD_SUCCESS) {
sample_print("set VDEC display_mode fail for %#x!\n", ret);
sample_comm_vdec_stop(vdec_chn_num);
}
}
}
return ret;
}
/* ==================== no-signal 占位图 ==================== */
/* 启动时调用:读源图 nosignal.yuv(1920x1200) 到 VB,填成 user pic frame_info */
td_s32 load_nosignal_src(void)
{
td_u32 width = STREAN_WIDTH; /* 1920 */
td_u32 height = STREAM_HEIGHT; /* 1200 */
td_u32 stride = OT_ALIGN_UP(width, 16);
td_u32 y_size = stride * height;
td_u32 frame_size = y_size * 3 / 2;
td_u32 file_size = width * height * 3 / 2;
td_phys_addr_t phys;
td_u8 *virt = TD_NULL;
td_u8 *file_buf = TD_NULL;
td_u32 i;
FILE *fp;
ot_vb_pool_cfg pool_cfg = {0};
/* 建池 */
pool_cfg.blk_size = frame_size;
pool_cfg.blk_cnt = 1;
pool_cfg.remap_mode = OT_VB_REMAP_MODE_NONE;
g_nosignal_src_pool = ss_mpi_vb_create_pool(&pool_cfg);
if (g_nosignal_src_pool == OT_VB_INVALID_POOL_ID) {
printf("[nosignal] create src pool fail\n");
return TD_FAILURE;
}
g_nosignal_src_blk = ss_mpi_vb_get_blk(g_nosignal_src_pool, frame_size, TD_NULL);
if (g_nosignal_src_blk == OT_VB_INVALID_HANDLE) {
printf("[nosignal] get src blk fail\n");
return TD_FAILURE;
}
phys = ss_mpi_vb_handle_to_phys_addr(g_nosignal_src_blk);
virt = (td_u8 *)ss_mpi_sys_mmap(phys, frame_size);
if (virt == TD_NULL) {
printf("[nosignal] mmap src fail\n");
return TD_FAILURE;
}
/* 读源图 */
fp = fopen(NOSIGNAL_YUV_PATH, "rb");
if (fp == TD_NULL) {
printf("[nosignal] open %s fail\n", NOSIGNAL_YUV_PATH);
return TD_FAILURE;
}
file_buf = (td_u8 *)malloc(file_size);
if (file_buf == TD_NULL || fread(file_buf, 1, file_size, fp) != file_size) {
fclose(fp);
printf("[nosignal] read %s fail\n", NOSIGNAL_YUV_PATH);
return TD_FAILURE;
}
fclose(fp);
/* 按行拷贝处理 stride 对齐:Y 平面 + VU 交错平面 */
for (i = 0; i < height; i++) {
memcpy(virt + i * stride, file_buf + i * width, width);
}
{
td_u8 *vu_dst = virt + y_size;
td_u8 *vu_src = file_buf + width * height;
for (i = 0; i < height / 2; i++) {
memcpy(vu_dst + i * stride, vu_src + i * width, width);
}
}
free(file_buf);
/* 填源图 frame_info(VGS 输入) */
memset(&g_nosignal_src, 0, sizeof(g_nosignal_src));
g_nosignal_src.video_frame.field = OT_VIDEO_FIELD_FRAME;
g_nosignal_src.video_frame.width = width;
g_nosignal_src.video_frame.height = height;
g_nosignal_src.video_frame.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
g_nosignal_src.video_frame.video_format = OT_VIDEO_FORMAT_LINEAR;
g_nosignal_src.video_frame.compress_mode = OT_COMPRESS_MODE_NONE;
g_nosignal_src.video_frame.stride[0] = stride;
g_nosignal_src.video_frame.stride[1] = stride;
g_nosignal_src.video_frame.phys_addr[0] = phys;
g_nosignal_src.video_frame.phys_addr[1] = phys + y_size;
g_nosignal_src.video_frame.virt_addr[0] = virt;
g_nosignal_src.video_frame.virt_addr[1] = virt + y_size;
g_nosignal_src.pool_id = ss_mpi_vb_handle_to_pool_id(g_nosignal_src_blk);
g_nosignal_src.mod_id = OT_ID_VDEC;
g_nosignal_src_valid = TD_TRUE;
printf("[nosignal] load src %ux%u ok, stride=%u, pool_id=%u, mod_id=%d\n",
width, height, stride, g_nosignal_src.pool_id, g_nosignal_src.mod_id);
return TD_SUCCESS;
}
/* 停流后 set user pic(共享源图,无需缩放) */
td_s32 vdec_set_nosignal_userpic(ot_vdec_chn chn)
{
printf("[nosignal] pic: w=%u h=%u field=%d pix=%d vidfmt=%d comp=%d dr=%d cg=%d "
"stride0=%u stride1=%u pool=%u mod=%d phys0=%#llx phys1=%#llx\n",
g_nosignal_src.video_frame.width,
g_nosignal_src.video_frame.height,
g_nosignal_src.video_frame.field,
g_nosignal_src.video_frame.pixel_format,
g_nosignal_src.video_frame.video_format,
g_nosignal_src.video_frame.compress_mode,
g_nosignal_src.video_frame.dynamic_range,
g_nosignal_src.video_frame.color_gamut,
g_nosignal_src.video_frame.stride[0],
g_nosignal_src.video_frame.stride[1],
g_nosignal_src.pool_id,
g_nosignal_src.mod_id,
(unsigned long long)g_nosignal_src.video_frame.phys_addr[0],
(unsigned long long)g_nosignal_src.video_frame.phys_addr[1]);
td_s32 ret = ss_mpi_vdec_set_user_pic(chn, &g_nosignal_src);
printf("[nosignal] chn%d set_user_pic ret=%#x\n", chn, ret);
return ret;
}
void* h265_vdec_vpss_vo()
{
td_s32 ret;
td_u32 vdec_chn_num, vpss_grp_num;
sample_vdec_attr sample_vdec[OT_VDEC_MAX_CHN_NUM];
td_bool vpss_chn_enable[OT_VPSS_MAX_CHN_NUM];
sample_vo_cfg vo_config;
ot_vpss_grp vpss_grp;
struct timespec ts;
struct timeval tp;
int len;
ot_vdec_stream stream;
int i;
vdec_chn_num = 8;
vpss_grp_num = vdec_chn_num;
/************************************************
step1: init SYS, init common VB(for VPSS and VO), init module VB(for VDEC)
*************************************************/
ret = sample_init_sys_and_vb(&sample_vdec[0], vdec_chn_num, OT_PT_H265, OT_VDEC_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
return ret;
}
/************************************************
step2: init VDEC
*************************************************/
ret = sample_start_vdec(&sample_vdec[0], vdec_chn_num, OT_VDEC_MAX_CHN_NUM, TD_FALSE);
if (ret != TD_SUCCESS) {
goto stop_sys;
}
/* 新增:启动读源图并 set user pic(set 前必须先 disable) */
if (load_nosignal_src() != TD_SUCCESS) {
printf("[nosignal] load src fail, nosignal disabled\n");
}
/************************************************
step3: start VPSS
*************************************************/
ret = sample_start_vpss(&vpss_grp, vpss_grp_num, &vpss_chn_enable[0], TD_FALSE, OT_VPSS_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
goto stop_vdec;
}
/************************************************
step4: start VO
*************************************************/
ret = sample_start_vo(&vo_config, vpss_grp_num, TD_FALSE);
if (ret != TD_SUCCESS) {
goto stop_vpss;
}
return ret;
stop_vpss:
ret = sample_vdec_unbind_vpss(vpss_grp_num, TD_FALSE);
sample_stop_vpss(vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
stop_vdec:
sample_comm_vdec_stop(vdec_chn_num);
sample_comm_vdec_exit_vb_pool();
stop_sys:
sample_comm_sys_exit();
return ret;
}
static td_s32 sample_h265_vdec_vpss_vo(td_void)
{
td_s32 ret;
td_u32 vdec_chn_num, vpss_grp_num;
sample_vdec_attr sample_vdec[OT_VDEC_MAX_CHN_NUM];
td_bool vpss_chn_enable[OT_VPSS_MAX_CHN_NUM];
sample_vo_cfg vo_config;
ot_vpss_grp vpss_grp;
vdec_chn_num = 1;
vpss_grp_num = vdec_chn_num;
/************************************************
step1: init SYS, init common VB(for VPSS and VO), init module VB(for VDEC)
*************************************************/
ret = sample_init_sys_and_vb(&sample_vdec[0], vdec_chn_num, OT_PT_H265, OT_VDEC_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
return ret;
}
/************************************************
step2: init VDEC
*************************************************/
ret = sample_start_vdec(&sample_vdec[0], vdec_chn_num, OT_VDEC_MAX_CHN_NUM, TD_FALSE);
if (ret != TD_SUCCESS) {
goto stop_sys;
}
/************************************************
step3: start VPSS
*************************************************/
ret = sample_start_vpss(&vpss_grp, vpss_grp_num, &vpss_chn_enable[0], TD_FALSE, OT_VPSS_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
goto stop_vdec;
}
/************************************************
step4: start VO
*************************************************/
ret = sample_start_vo(&vo_config, vpss_grp_num, TD_FALSE);
if (ret != TD_SUCCESS) {
goto stop_vpss;
}
audio_init();
int i;
unsigned char buffer[2048];
ot_vdec_stream stream;
while(1){
i = recvfrom(socket_descriptor, buffer, 1472, 0, (struct sockaddr*)&clientAddr, &sock_len);
if (i > 0){
stream.pts = 0;
stream.addr = &buffer[0];
stream.len = i;
stream.end_of_frame = TD_FALSE;
stream.end_of_stream = TD_FALSE;
stream.need_display = 1;
td_s32 ret;
//do {
ret = ss_mpi_vdec_send_stream(0, &stream, 0);
// usleep(thread_param->interval_time);
//} while ((ret != TD_SUCCESS) && (thread_param->e_thread_ctrl == THREAD_CTRL_START));
}
}
/************************************************
step5: send stream to VDEC
*************************************************/
sample_send_stream_to_vdec(&sample_vdec[0], OT_VDEC_MAX_CHN_NUM, vdec_chn_num, "3840x2160_8bit.h265", TD_FALSE);
ret = sample_vpss_unbind_vo(vpss_grp_num, vo_config);
sample_comm_vo_stop_vo(&vo_config);
stop_vpss:
ret = sample_vdec_unbind_vpss(vpss_grp_num, TD_FALSE);
sample_stop_vpss(vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
stop_vdec:
sample_comm_vdec_stop(vdec_chn_num);
sample_comm_vdec_exit_vb_pool();
stop_sys:
sample_comm_sys_exit();
return ret;
}
static td_s32 sample_h264_vdec_vpss_vo(td_void)
{
td_s32 ret;
td_u32 vdec_chn_num, vpss_grp_num;
ot_vpss_grp vpss_grp;
sample_vdec_attr sample_vdec[OT_VDEC_MAX_CHN_NUM];
sample_vo_cfg vo_config;
td_bool vpss_chn_enable[OT_VPSS_MAX_CHN_NUM];
vdec_chn_num = 1;
vpss_grp_num = vdec_chn_num;
/************************************************
step1: init SYS, init common VB(for VPSS and VO), init module VB(for VDEC)
*************************************************/
ret = sample_init_sys_and_vb(&sample_vdec[0], vdec_chn_num, OT_PT_H264, OT_VDEC_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
return ret;
}
/************************************************
step2: init VDEC
*************************************************/
ret = sample_start_vdec(&sample_vdec[0], vdec_chn_num, OT_VDEC_MAX_CHN_NUM, TD_FALSE);
if (ret != TD_SUCCESS) {
goto stop_sys;
}
/************************************************
step3: start VPSS
*************************************************/
ret = sample_start_vpss(&vpss_grp, vpss_grp_num, &vpss_chn_enable[0], TD_FALSE, OT_VPSS_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
goto stop_vdec;
}
/************************************************
step4: start VO
*************************************************/
ret = sample_start_vo(&vo_config, vpss_grp_num, TD_FALSE);
if (ret != TD_SUCCESS) {
goto stop_vpss;
}
int i;
unsigned char buffer[2048];
ot_vdec_stream stream;
while(1){
i = recvfrom(socket_descriptor, buffer, 1472, 0, (struct sockaddr*)&clientAddr, &sock_len);
if (i > 0){
stream.pts = 0;
stream.addr = &buffer[0];
stream.len = i;
stream.end_of_frame = TD_FALSE;
stream.end_of_stream = TD_FALSE;
stream.need_display = 1;
td_s32 ret;
//do {
ret = ss_mpi_vdec_send_stream(0, &stream, 0);
// usleep(thread_param->interval_time);
//} while ((ret != TD_SUCCESS) && (thread_param->e_thread_ctrl == THREAD_CTRL_START));
}
}
/************************************************
step5: send stream to VDEC
*************************************************/
sample_send_stream_to_vdec(&sample_vdec[0], OT_VDEC_MAX_CHN_NUM, vdec_chn_num, "3840x2160_8bit.h264", TD_FALSE);
ret = sample_vpss_unbind_vo(vpss_grp_num, vo_config);
sample_comm_vo_stop_vo(&vo_config);
stop_vpss:
ret = sample_vdec_unbind_vpss(vpss_grp_num, TD_FALSE);
sample_stop_vpss(vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
stop_vdec:
sample_comm_vdec_stop(vdec_chn_num);
sample_comm_vdec_exit_vb_pool();
stop_sys:
sample_comm_sys_exit();
return ret;
}
static td_s32 sample_h264_vdec_vpss_vo_pip(td_void)
{
td_s32 ret;
td_u32 vdec_chn_num, vpss_grp_num;
ot_vpss_grp vpss_grp;
sample_vdec_attr sample_vdec[OT_VDEC_MAX_CHN_NUM];
sample_vo_cfg vo_config;
td_bool vpss_chn_enable[OT_VPSS_MAX_CHN_NUM];
vdec_chn_num = 1;
vpss_grp_num = 2; /* 2:vpss group cnt */
/************************************************
step1: init SYS, init common VB(for VPSS and VO), init module VB(for VDEC)
*************************************************/
ret = sample_init_sys_and_vb(&sample_vdec[0], vdec_chn_num, OT_PT_H264, OT_VDEC_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
return ret;
}
/************************************************
step2: init VDEC
*************************************************/
ret = sample_start_vdec(&sample_vdec[0], vdec_chn_num, OT_VDEC_MAX_CHN_NUM, TD_TRUE);
if (ret != TD_SUCCESS) {
goto stop_sys;
}
/************************************************
step3: start VPSS
*************************************************/
ret = sample_start_vpss(&vpss_grp, vpss_grp_num, &vpss_chn_enable[0], TD_TRUE, OT_VPSS_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
goto stop_vdec;
}
/************************************************
step4: start VO
*************************************************/
ret = sample_start_vo(&vo_config, vpss_grp_num, TD_TRUE);
if (ret != TD_SUCCESS) {
goto stop_vpss;
}
/************************************************
step5: send stream to VDEC
*************************************************/
sample_send_stream_to_vdec(&sample_vdec[0], OT_VDEC_MAX_CHN_NUM, vdec_chn_num, "3840x2160_8bit.h264", TD_TRUE);
ret = sample_vpss_unbind_vo(vpss_grp_num, vo_config);
sample_comm_vo_stop_pip(&vo_config);
sample_comm_vo_stop_vo(&vo_config);
stop_vpss:
usleep(150000); /* 150000:make sure all frames are decoded before unbind */
ret = sample_vdec_unbind_vpss(vpss_grp_num, TD_TRUE);
sample_stop_vpss(vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
stop_vdec:
sample_comm_vdec_stop(vdec_chn_num);
sample_comm_vdec_exit_vb_pool();
stop_sys:
sample_comm_sys_exit();
return ret;
}
static td_s32 sample_jpeg_vdec_vpss_vo(td_void)
{
td_s32 ret;
td_u32 vdec_chn_num, vpss_grp_num;
ot_vpss_grp vpss_grp;
sample_vdec_attr sample_vdec[OT_VDEC_MAX_CHN_NUM];
sample_vo_cfg vo_config;
td_bool vpss_chn_enable[OT_VPSS_MAX_CHN_NUM];
vdec_chn_num = 1;
vpss_grp_num = vdec_chn_num;
/************************************************
step1: init SYS, init common VB(for VPSS and VO), init module VB(for VDEC)
*************************************************/
ret = sample_init_sys_and_vb(&sample_vdec[0], vdec_chn_num, OT_PT_JPEG, OT_VDEC_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
return ret;
}
/************************************************
step2: init VDEC
*************************************************/
ret = sample_start_vdec(&sample_vdec[0], vdec_chn_num, OT_VDEC_MAX_CHN_NUM, TD_FALSE);
if (ret != TD_SUCCESS) {
goto stop_sys;
}
/************************************************
step3: start VPSS
*************************************************/
ret = sample_start_vpss(&vpss_grp, vpss_grp_num, &vpss_chn_enable[0], TD_FALSE, OT_VPSS_MAX_CHN_NUM);
if (ret != TD_SUCCESS) {
goto stop_vdec;
}
/************************************************
step4: start VO
*************************************************/
ret = sample_start_vo(&vo_config, vpss_grp_num, TD_FALSE);
if (ret != TD_SUCCESS) {
goto stop_vpss;
}
/************************************************
step5: send stream to VDEC
*************************************************/
sample_send_stream_to_vdec(&sample_vdec[0], OT_VDEC_MAX_CHN_NUM, vdec_chn_num, "3840x2160.jpg", TD_FALSE);
ret = sample_vpss_unbind_vo(vpss_grp_num, vo_config);
sample_comm_vo_stop_vo(&vo_config);
stop_vpss:
ret = sample_vdec_unbind_vpss(vpss_grp_num, TD_FALSE);
sample_stop_vpss(vpss_grp, &vpss_chn_enable[0], OT_VPSS_MAX_CHN_NUM);
stop_vdec:
sample_comm_vdec_stop(vdec_chn_num);
sample_comm_vdec_exit_vb_pool();
stop_sys:
sample_comm_sys_exit();
return ret;
}
static td_s32 sample_check_parameter(int argc, const char *argv0, const char *argv1, const char *argv2)
{
if ((argc != 5) || (strlen(argv1) != 1) || (strlen(argv2) != 1)) { /* 3:arg num */
printf("\n_invaild input! for examples:\n");
sample_vdec_usage(argv0);
return TD_FAILURE;
}
if (!strncmp(argv2, "1", 1)) {
g_intf_sync = OT_VO_OUT_1080P60;
} else if (!strncmp(argv2, "0", 1)) {
g_intf_sync = OT_VO_OUT_3840x2160_30;
} else {
printf("\n_invaild input! for examples:\n");
printf("\n argv2 is %s\n", argv2);
sample_vdec_usage(argv0);
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_s32 udp_init(int port){
sock_len = sizeof(clientAddr);
bzero(&address,sizeof(address));
address.sin_family=AF_INET;
address.sin_addr.s_addr=htonl(INADDR_ANY);
address.sin_port=htons(port);
socket_descriptor=socket(AF_INET,SOCK_DGRAM,0);//IPV4
bzero(&address_audio,sizeof(address_audio));
address_audio.sin_family=AF_INET;
address_audio.sin_addr.s_addr=htonl(INADDR_ANY);
address_audio.sin_port=htons(port+1);
socket_descriptor_audio=socket(AF_INET,SOCK_DGRAM,0);//IPV4
tv.tv_sec = 1;
tv.tv_usec = 0;
if (setsockopt(socket_descriptor, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
printf("socket option SO_RCVTIMEO not support\n");
return -1;
}
if (setsockopt(socket_descriptor_audio, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
printf("socket option SO_RCVTIMEO not support\n");
return -1;
}
#if 0
int recvbuf = 5*1024*1024;
int lenbuf = sizeof( recvbuf );
setsockopt( socket_descriptor, SOL_SOCKET, SO_RCVBUF, &recvbuf, sizeof( recvbuf ) );
getsockopt( socket_descriptor, SOL_SOCKET, SO_RCVBUF, &recvbuf, ( socklen_t* )&lenbuf );
printf( "the receive buffer size after settting is %d\n", recvbuf );
#endif
if (bind(socket_descriptor, (struct sockaddr *)&address, sizeof(address)) < 0)
{
printf("bind");
//exit(1);
return -1;
}
if (bind(socket_descriptor_audio, (struct sockaddr *)&address_audio, sizeof(address_audio)) < 0)
{
printf("bind");
//exit(1);
return -1;
}
#if 0
setsockopt( socket_descriptor, SOL_SOCKET, SO_RCVBUF, &recvbuf, sizeof( recvbuf ) );
getsockopt( socket_descriptor, SOL_SOCKET, SO_RCVBUF, &recvbuf, ( socklen_t* )&lenbuf );
printf( "the receive buffer size after settting is %d\n", recvbuf );
#endif
}
static td_s32 sample_choose_case(const char argv1, const char *argv0)
{
td_s32 ret;
switch (argv1) {
case '0': {
ret = sample_h265_vdec_vpss_vo();
break;
}
case '1': {
ret = sample_h264_vdec_vpss_vo();
break;
}
case '2': {
ret = sample_h264_vdec_vpss_vo_pip();
break;
}
case '3': {
ret = sample_jpeg_vdec_vpss_vo();
break;
}
default: {
sample_print("the index is invalid!\n");
sample_vdec_usage(argv0);
ret = TD_FAILURE;
break;
}
}
return ret;
}
#if 0
int *switch_memory_open(void) {
char buf[128];
int fd;
sprintf(buf, "/video_switch");
fd = shm_open(buf, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if(fd < 0) { perror("shm_open"); exit(1); }
if (ftruncate(fd, 4096) == -1) { perror("ftruncate"); exit(1); }
int *retval = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
return retval;
}
#endif
int SAMPLE_VDEC_VPSS_VO_SET_MODE(int mode){
if(mode==1){
sample_comm_vo_stop_chn(SAMPLE_VO_DEV_UHD,VO_MODE_4MUX);
sample_comm_vo_start_chn(SAMPLE_VO_DEV_UHD,VO_MODE_1MUX);
ss_mpi_vdec_stop_recv_stream(1);
ss_mpi_vdec_stop_recv_stream(2);
ss_mpi_vdec_stop_recv_stream(3);
ss_mpi_vdec_reset_chn(1);
ss_mpi_vdec_reset_chn(2);
ss_mpi_vdec_reset_chn(3);
}else if(mode==5){
ss_mpi_vo_clear_chn_buf(0,1,TD_TRUE);
ss_mpi_vo_clear_chn_buf(0,2,TD_TRUE);
ss_mpi_vo_clear_chn_buf(0,3,TD_TRUE);
ss_mpi_vdec_start_recv_stream(1);
ss_mpi_vdec_start_recv_stream(2);
ss_mpi_vdec_start_recv_stream(3);
sleep(2);
sample_comm_vo_stop_chn(SAMPLE_VO_DEV_UHD,VO_MODE_1MUX);
sample_comm_vo_start_chn(SAMPLE_VO_DEV_UHD,VO_MODE_4MUX);
}
}
/******************************************************************************
* function : main()
* description : video vdec sample
******************************************************************************/
#ifdef __LITEOS__
int app_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{
td_s32 ret;
td_s32 i;
int fd_fs;
// int *video_switch;
volatile int switch_mode=0; //默认双屏
volatile int switch_mode_pre=0;
g_intf_sync = OT_VO_OUT_1920x1200_60;
//g_intf_sync = OT_VO_OUT_1080P60;
#ifndef __LITEOS__
sample_sys_signal(sample_vdec_handle_sig);
#endif
h265_vdec_vpss_vo();
init_udp_pthread();
// printf("udp\n");
// switch_video = switch_memory_open();
// video_switch = switch_memory_open();
// switch_mode = video_switch[0];
// switch_video[0]=2;
// switch_mode = switch_video[0];
switch_mode = switch_video[0];
switch_mode_pre = switch_mode;
if(argc==2){
fd_fs = open(argv[1], O_RDWR | O_CREAT);
if(fd_fs < 0) {
printf("open %s failed\n", argv[1]);
return -1;
}
}
//switch_mode=2;
printf("hello\n");
printf("++++++%x \n",switch_mode);
sample_vo_chn_switch(switch_mode);
while(1){
#if 1
switch_mode = switch_video[0];
//switch_mode = video_switch[0];
//printf("--w+++++%x \n",switch_mode);
//sample_comm_vo_stop_chn(SAMPLE_VO_DEV_UHD,VO_MODE_4MUX);
//sample_comm_vo_start_chn(SAMPLE_VO_DEV_UHD,VO_MODE_1MUX);
if(switch_mode != switch_mode_pre){
printf("hello\n");
printf("++++++%x \n",switch_mode);
sample_vo_chn_switch(switch_mode);
// SAMPLE_VDEC_VPSS_VO_SET_MODE(switch_mode);
switch_mode_pre = switch_mode;
}
//sleep(1);
usleep(100 * 1000); /*100ms 轮询一次*/
}
#endif
#if 0
video_switch[0]= 0xAA;
sample_comm_vo_stop_chn(SAMPLE_VO_DEV_UHD,VO_MODE_4MUX);
sample_comm_vo_start_chn(SAMPLE_VO_DEV_UHD,VO_MODE_1MUX);
sleep(10);
video_switch[0]= 0x55;
ss_mpi_vdec_stop_recv_stream(1);
ret=ss_mpi_vdec_reset_chn(1);
//printf("+++++++reset_chn%d\n",ret);
//ret=ss_mpi_vpss_reset_grp(1);
//printf("+++++++reset_vpss%d\n",ret);
ss_mpi_vdec_start_recv_stream(1);
ss_mpi_vo_clear_chn_buf(0,1,TD_TRUE);
sleep(2);
ss_mpi_vo_clear_chn_buf(0,1,TD_TRUE);
sample_comm_vo_stop_chn(SAMPLE_VO_DEV_UHD,VO_MODE_1MUX);
sample_comm_vo_start_chn(SAMPLE_VO_DEV_UHD,VO_MODE_4MUX);
// ss_mpi_vdec_stop_recv_stream(1);
// ss_mpi_vdec_reset_chn(1);
// ss_mpi_vdec_start_recv_stream(1);
#endif
sleep(1);
//}
// return ret;
}