506 lines
16 KiB
C
506 lines
16 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 "sample_comm.h"
|
|
#include "loadbmp.h"
|
|
|
|
#define VDA_WIDTH_ALIGN 16
|
|
#define VDA_HEIGHT_ALIGN 16
|
|
|
|
#define VDA_THREAD_ARRAY_LEN (2 * OT_VDEC_MAX_CHN_NUM)
|
|
#define VDA_SAMPLE_MAX_WIDTH 3840
|
|
#define VDA_SAMPLE_MAX_HEIGHT 2160
|
|
|
|
#define VDA_VPSS_CHN OT_VPSS_CHN0
|
|
|
|
pthread_t g_vdec_thread[VDA_THREAD_ARRAY_LEN];
|
|
td_bool g_exit = TD_FALSE;
|
|
static int g_sample_vda_exit = 0;
|
|
|
|
#define SAMPLE_VDA_STREAM_NAME "D1chn25.h264"
|
|
#define SAMPLE_VDA_STREAM_PATH "./"
|
|
|
|
/* Description : to process abnormal case */
|
|
void sample_vda_handle_sig(td_s32 signo)
|
|
{
|
|
if (signo == SIGINT || signo == SIGTERM) {
|
|
g_sample_vda_exit = 1;
|
|
}
|
|
}
|
|
|
|
static int sample_vda_getchar(td_void)
|
|
{
|
|
int c;
|
|
if (g_sample_vda_exit == 1) {
|
|
sample_common_vda_handle_sig();
|
|
sample_comm_sys_exit();
|
|
printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
|
|
exit(-1);
|
|
}
|
|
|
|
c = getchar();
|
|
|
|
if (g_sample_vda_exit == 1) {
|
|
sample_common_vda_handle_sig();
|
|
sample_comm_sys_exit();
|
|
printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
|
|
exit(-1);
|
|
}
|
|
|
|
return c;
|
|
}
|
|
|
|
/* Description : show usage */
|
|
td_void sample_vda_usage(td_void)
|
|
{
|
|
printf("\n\n/************************************/\n");
|
|
printf("please choose the case which you want to run:\n");
|
|
printf("\t0: MD\n");
|
|
printf("\t1: OD\n");
|
|
printf("sample command:");
|
|
return;
|
|
}
|
|
|
|
static td_s32 sample_vda_init(ot_pic_size disp_pic_size, ot_size *disp_size, td_u32 vdec_chn_num)
|
|
{
|
|
td_s32 ret;
|
|
ot_pic_buf_attr buf_attr = { 0 };
|
|
ot_vb_cfg vb_cfg;
|
|
|
|
/* init SYS, init common VB */
|
|
ret = sample_comm_sys_get_pic_size(disp_pic_size, disp_size);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("sys get pic size fail for %#x!\n", ret);
|
|
return ret;
|
|
}
|
|
buf_attr.align = 0;
|
|
buf_attr.bit_width = OT_DATA_BIT_WIDTH_8;
|
|
buf_attr.compress_mode = OT_COMPRESS_MODE_NONE;
|
|
buf_attr.height = disp_size->height;
|
|
buf_attr.width = disp_size->width;
|
|
buf_attr.pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
|
|
|
(td_void)memset_s(&vb_cfg, sizeof(ot_vb_cfg), 0, sizeof(ot_vb_cfg));
|
|
vb_cfg.max_pool_cnt = 1;
|
|
vb_cfg.common_pool[0].blk_cnt = 10 * vdec_chn_num; /* 10 : 10 vb per chn */
|
|
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);
|
|
return ret;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void sample_vda_deinit(td_void)
|
|
{
|
|
sample_comm_vdec_exit_vb_pool();
|
|
sample_comm_sys_exit();
|
|
}
|
|
|
|
static td_s32 sample_vda_init_vdec(sample_vdec_attr *sample_vdec, td_s32 max_vdec_chn, td_u32 vdec_chn_num)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
|
|
/* step1: init module VB or user VB(for VDEC) */
|
|
for (i = 0; (i < vdec_chn_num) && (i < max_vdec_chn); i++) {
|
|
sample_vdec[i].type = OT_PT_H264;
|
|
sample_vdec[i].width = VDA_SAMPLE_MAX_WIDTH;
|
|
sample_vdec[i].height = VDA_SAMPLE_MAX_HEIGHT;
|
|
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;
|
|
sample_vdec[i].sample_vdec_video.ref_frame_num = 2; /* 2 : reference frame number */
|
|
sample_vdec[i].display_frame_num = 2; /* display_frame number */
|
|
sample_vdec[i].frame_buf_cnt =
|
|
sample_vdec[i].sample_vdec_video.ref_frame_num + sample_vdec[i].display_frame_num + 1;
|
|
}
|
|
ret = sample_comm_vdec_init_vb_pool(vdec_chn_num, &sample_vdec[0], OT_VDEC_MAX_CHN_NUM);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("init mod common vb fail for %#x!\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
/* step2: start VDEC */
|
|
ret = sample_comm_vdec_start(vdec_chn_num, &sample_vdec[0], OT_VDEC_MAX_CHN_NUM);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("start VDEC fail for %#x!\n", ret);
|
|
goto vdec_stop;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
|
|
vdec_stop:
|
|
sample_comm_vdec_exit_vb_pool();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
td_void sample_vda_deinit_vdec(td_u32 vdec_chn_num)
|
|
{
|
|
td_s32 ret;
|
|
ret = sample_comm_vdec_stop(vdec_chn_num);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vdec stop fail for %#x!\n", ret);
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_vda_init_vpss(td_s32 vpss_grp_num, const ot_size *disp_size, td_bool chn_enable[],
|
|
td_s32 vpss_chn_num)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
ot_vpss_chn_attr vpss_chn_attr[OT_VPSS_MAX_CHN_NUM] = { 0 };
|
|
ot_vpss_grp_attr vpss_grp_attr = { 0 };
|
|
|
|
/* start VPSS */
|
|
vpss_grp_attr.max_width = VDA_SAMPLE_MAX_WIDTH;
|
|
vpss_grp_attr.max_height = VDA_SAMPLE_MAX_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.dci_en = TD_FALSE;
|
|
|
|
if (memset_s(chn_enable, vpss_chn_num * sizeof(td_bool), 0, vpss_chn_num * sizeof(td_bool)) != EOK) {
|
|
return TD_FAILURE;
|
|
}
|
|
chn_enable[VDA_VPSS_CHN] = TD_TRUE;
|
|
vpss_chn_attr[VDA_VPSS_CHN].width = disp_size->width;
|
|
vpss_chn_attr[VDA_VPSS_CHN].height = disp_size->height;
|
|
vpss_chn_attr[VDA_VPSS_CHN].chn_mode = OT_VPSS_CHN_MODE_USER;
|
|
vpss_chn_attr[VDA_VPSS_CHN].compress_mode = OT_COMPRESS_MODE_NONE;
|
|
vpss_chn_attr[VDA_VPSS_CHN].pixel_format = OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
|
|
vpss_chn_attr[VDA_VPSS_CHN].frame_rate.src_frame_rate = -1;
|
|
vpss_chn_attr[VDA_VPSS_CHN].frame_rate.dst_frame_rate = -1;
|
|
vpss_chn_attr[VDA_VPSS_CHN].depth = 0;
|
|
vpss_chn_attr[VDA_VPSS_CHN].mirror_en = TD_FALSE;
|
|
vpss_chn_attr[VDA_VPSS_CHN].flip_en = TD_FALSE;
|
|
vpss_chn_attr[VDA_VPSS_CHN].aspect_ratio.mode = OT_ASPECT_RATIO_NONE;
|
|
|
|
for (i = 0; i < vpss_grp_num; i++) {
|
|
ot_vpss_grp vpss_grp = i;
|
|
ret = sample_common_vpss_start(vpss_grp, chn_enable, &vpss_grp_attr, vpss_chn_attr, OT_VPSS_MAX_CHN_NUM);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("start VPSS fail for %#x!\n", ret);
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void sample_vda_deinit_vpss(const td_bool chn_enable[], td_u32 chn_array_size)
|
|
{
|
|
td_s32 ret;
|
|
const ot_vpss_grp vpss_grp = 0;
|
|
|
|
ret = sample_common_vpss_stop(vpss_grp, chn_enable, chn_array_size);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vpss grp %d stop fail for %#x!\n", vpss_grp, ret);
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_vda_init_vo(ot_pic_size disp_pic_size, const ot_size *disp_size, sample_vo_cfg *vo_config)
|
|
{
|
|
td_s32 ret;
|
|
ot_vo_intf_sync intf_sync = OT_VO_OUT_1080P60;
|
|
ot_vo_intf_type vo_intf_type = OT_VO_INTF_HDMI | OT_VO_INTF_VGA;
|
|
|
|
vo_config->vo_dev = SAMPLE_VO_DEV_UHD;
|
|
vo_config->vo_intf_type = vo_intf_type;
|
|
vo_config->intf_sync = intf_sync;
|
|
vo_config->pic_size = disp_pic_size;
|
|
vo_config->bg_color = COLOR_RGB_BLUE;
|
|
vo_config->dis_buf_len = 3; /* 3 : display buffer length */
|
|
vo_config->dst_dynamic_range = OT_DYNAMIC_RANGE_SDR8;
|
|
vo_config->vo_mode = VO_MODE_1MUX;
|
|
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 = disp_size->width;
|
|
vo_config->disp_rect.height = disp_size->height;
|
|
vo_config->image_size.width = disp_size->width;
|
|
vo_config->image_size.height = 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);
|
|
return ret;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void sample_vda_deinit_vo(const sample_vo_cfg *vo_config)
|
|
{
|
|
td_s32 ret;
|
|
ret = sample_comm_vo_stop_vo(vo_config);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vo stop fail for %#x!\n", ret);
|
|
}
|
|
}
|
|
|
|
td_s32 sample_vda_bind_init(td_u32 vdec_chn_num, td_u32 vpss_grp_num, ot_vo_layer vo_layer)
|
|
{
|
|
td_s32 i, j, k;
|
|
td_s32 ret;
|
|
td_s32 vdec_chn_num_tmp = (td_s32)vdec_chn_num;
|
|
|
|
for (i = 0; i < vdec_chn_num_tmp; i++) {
|
|
ret = sample_comm_vdec_bind_vpss(i, i);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vdec bind vpss fail for %#x!\n", ret);
|
|
goto vdec_unbind_vpss;
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < (td_s32)vpss_grp_num; j++) {
|
|
ret = sample_comm_vpss_bind_vo(j, VDA_VPSS_CHN, vo_layer, j);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vpss bind vo fail for %#x!\n", ret);
|
|
goto vpss_unbind_vo;
|
|
}
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
|
|
vpss_unbind_vo:
|
|
for (k = j - 1; k >= 0; k--) {
|
|
ret = sample_comm_vpss_un_bind_vo(k, VDA_VPSS_CHN, vo_layer, k);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vpss unbind vo fail for %#x!\n", ret);
|
|
}
|
|
}
|
|
|
|
vdec_unbind_vpss:
|
|
for (k = i - 1; k >= 0; k--) {
|
|
ret = sample_comm_vdec_un_bind_vpss(k, k);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vdec unbind vpss fail for %#x!\n", ret);
|
|
}
|
|
}
|
|
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
td_void sample_vda_bind_deinit(td_u32 vdec_chn_num, td_u32 vpss_grp_num, ot_vo_layer vo_layer)
|
|
{
|
|
td_u32 i;
|
|
td_s32 ret;
|
|
|
|
for (i = 0; i < vpss_grp_num; i++) {
|
|
ret = sample_comm_vpss_un_bind_vo(i, VDA_VPSS_CHN, vo_layer, i);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vpss unbind vo fail for %#x!\n", ret);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < vdec_chn_num; i++) {
|
|
ret = sample_comm_vdec_un_bind_vpss(i, i);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vdec unbind vpss fail for %#x!\n", ret);
|
|
}
|
|
}
|
|
}
|
|
|
|
static td_s32 sample_vda_send_vdec_stream(vdec_thread_param vdec_send[], td_u32 vdec_max_thread,
|
|
const sample_vdec_attr sample_vdec[], td_u32 vdec_max_chn, td_u32 vdec_chn_num)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
|
|
for (i = 0; ((i < vdec_chn_num) && (i < vdec_max_chn) && (i < vdec_max_thread)); i++) {
|
|
ret = snprintf_s(vdec_send[i].c_file_name, sizeof(vdec_send[i].c_file_name), strlen(SAMPLE_VDA_STREAM_NAME),
|
|
SAMPLE_VDA_STREAM_NAME);
|
|
if (ret == -1) {
|
|
sample_print("set stream name fail!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
ret = snprintf_s(vdec_send[i].c_file_path, sizeof(vdec_send[i].c_file_path), strlen(SAMPLE_VDA_STREAM_PATH),
|
|
"%s", SAMPLE_VDA_STREAM_PATH);
|
|
if (ret == -1) {
|
|
sample_print("set stream path fail!\n");
|
|
return TD_FAILURE;
|
|
}
|
|
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 : send 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/2 : sp420 size cal */
|
|
}
|
|
sample_comm_vdec_start_send_stream(vdec_chn_num, &vdec_send[0], &g_vdec_thread[0],
|
|
OT_VDEC_MAX_CHN_NUM, VDA_THREAD_ARRAY_LEN);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 sample_vda_process(ot_vda_work_mode work_mode)
|
|
{
|
|
td_s32 ret;
|
|
ot_pic_size vda_pic_size = PIC_CIF;
|
|
ot_size vda_size;
|
|
const ot_vda_chn vda_chn = 0;
|
|
|
|
/* start VDA MD process */
|
|
ret = sample_comm_sys_get_pic_size(vda_pic_size, &vda_size);
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("sys get pic size fail for %#x!\n", ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (vda_size.width % 2) { /* 2 : odd-even */
|
|
vda_size.width = (vda_size.width / VDA_WIDTH_ALIGN + 1) * VDA_WIDTH_ALIGN;
|
|
}
|
|
|
|
if (vda_size.height % 2) { /* 2 : odd-even */
|
|
vda_size.height = (vda_size.height / VDA_HEIGHT_ALIGN + 1) * VDA_HEIGHT_ALIGN;
|
|
}
|
|
|
|
if (work_mode == OT_VDA_WORK_MODE_MD) {
|
|
ret = sample_common_vda_md_start(vda_chn, VDA_VPSS_CHN, &vda_size);
|
|
} else if (work_mode == OT_VDA_WORK_MODE_OD) {
|
|
ret = sample_common_vda_od_start(vda_chn, VDA_VPSS_CHN, &vda_size);
|
|
} else {
|
|
sample_print("work_mode(%d) invalid!\n", work_mode);
|
|
return TD_FAILURE;
|
|
}
|
|
if (ret != TD_SUCCESS) {
|
|
sample_print("vda md start fail for %#x!\n", ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
printf("\nPress any key to stop!");
|
|
sample_vda_getchar();
|
|
|
|
if (work_mode == OT_VDA_WORK_MODE_MD) {
|
|
sample_common_vda_md_stop(vda_chn, VDA_VPSS_CHN);
|
|
} else if (work_mode == OT_VDA_WORK_MODE_OD) {
|
|
sample_common_vda_od_stop(vda_chn, VDA_VPSS_CHN);
|
|
} else {
|
|
sample_print("work_mode(%d) invalid!\n", work_mode);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 sample_vda(ot_vda_work_mode work_mode)
|
|
{
|
|
static vdec_thread_param vdec_send[OT_VDEC_MAX_CHN_NUM] = { 0 };
|
|
ot_size disp_size;
|
|
ot_pic_size disp_pic_size = PIC_D1_PAL;
|
|
sample_vdec_attr sample_vdec[OT_VDEC_MAX_CHN_NUM] = { 0 };
|
|
sample_vo_cfg vo_config;
|
|
td_bool chn_enable[OT_VPSS_MAX_CHN_NUM] = { 0 };
|
|
const td_u32 vdec_chn_num = 1;
|
|
td_u32 vpss_grp_num = vdec_chn_num;
|
|
|
|
if (sample_vda_init(disp_pic_size, &disp_size, vdec_chn_num) != TD_SUCCESS) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (sample_vda_init_vdec(sample_vdec, OT_VDEC_MAX_CHN_NUM, vdec_chn_num) != TD_SUCCESS) {
|
|
goto vdec_init_fail;
|
|
}
|
|
|
|
if (sample_vda_init_vpss(vpss_grp_num, &disp_size, chn_enable, OT_VPSS_MAX_CHN_NUM) != TD_SUCCESS) {
|
|
goto vpss_init_fail;
|
|
}
|
|
|
|
if (sample_vda_init_vo(disp_pic_size, &disp_size, &vo_config) != TD_SUCCESS) {
|
|
goto vo_init_fail;
|
|
}
|
|
|
|
if (sample_vda_bind_init(vdec_chn_num, vpss_grp_num, vo_config.vo_dev) != TD_SUCCESS) {
|
|
goto bind_init_fail;
|
|
}
|
|
|
|
if (sample_vda_send_vdec_stream(vdec_send, OT_VDEC_MAX_CHN_NUM, sample_vdec, OT_VDEC_MAX_CHN_NUM,
|
|
vdec_chn_num) != TD_SUCCESS) {
|
|
goto send_stream_fail;
|
|
}
|
|
|
|
if (sample_vda_process(work_mode) != TD_SUCCESS) {
|
|
printf("vda_process fail!\n");
|
|
}
|
|
|
|
sample_comm_vdec_stop_send_stream(vdec_chn_num, &vdec_send[0], &g_vdec_thread[0],
|
|
OT_VDEC_MAX_CHN_NUM, VDA_THREAD_ARRAY_LEN);
|
|
|
|
send_stream_fail:
|
|
sample_vda_bind_deinit(vdec_chn_num, vpss_grp_num, vo_config.vo_dev);
|
|
bind_init_fail:
|
|
sample_vda_deinit_vo(&vo_config);
|
|
vo_init_fail:
|
|
sample_vda_deinit_vpss(chn_enable, OT_VPSS_MAX_CHN_NUM);
|
|
vpss_init_fail:
|
|
sample_vda_deinit_vdec(vdec_chn_num);
|
|
vdec_init_fail:
|
|
sample_vda_deinit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 main(int argc, char *argv[])
|
|
{
|
|
td_s32 ret;
|
|
char index;
|
|
|
|
if (argc != 2) { /* 2: 2 arg num */
|
|
sample_vda_usage();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (!strncmp(argv[1], "-h", 2)) { /* 2: 2 chars */
|
|
sample_vda_usage();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
sample_sys_signal(&sample_vda_handle_sig);
|
|
|
|
if (strlen(argv[1]) > 1) {
|
|
sample_vda_usage();
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
index = *argv[1];
|
|
switch (index) {
|
|
case '0': {
|
|
ret = sample_vda(OT_VDA_WORK_MODE_MD);
|
|
break;
|
|
}
|
|
case '1': {
|
|
ret = sample_vda(OT_VDA_WORK_MODE_OD);
|
|
break;
|
|
}
|
|
default: {
|
|
sample_print("the index is invalid!\n");
|
|
sample_vda_usage();
|
|
return TD_FAILURE;
|
|
}
|
|
}
|
|
|
|
if (ret == TD_SUCCESS) {
|
|
sample_print("sample_vda exit success!\n");
|
|
} else {
|
|
sample_print("sample_vda exit abnormally!\n");
|
|
}
|
|
|
|
return ret;
|
|
}
|