Files
hisi_SS524V100_SDK/mpp/tools/vi_dump.c
T

714 lines
20 KiB
C

/*
Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd.
*/
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include "securec.h"
#include "ss_mpi_sys.h"
#include "ss_mpi_vb.h"
#include "ss_mpi_vi.h"
#include "ss_mpi_vgs.h"
#include "ot_buffer.h"
#define MAX_FRM_CNT 64
#define MAX_FRM_WIDTH 4096
#define FILE_NAME_LENGTH 128
#define PIXEL_FORMAT_NAME_LENGTH 10
#define VI_DUMP_ARG_NUMBER_BASE 10
typedef struct {
ot_vb_blk block;
ot_vb_pool pool;
td_u32 pool_id;
td_phys_addr_t phys_addr;
td_u8 *virt_addr;
td_s32 m_dev;
} dump_mem_buf;
static volatile sig_atomic_t g_quit = TD_FALSE; /* g_quit may be set in the signal handler */
ot_video_frame_info g_frame_info;
dump_mem_buf g_dump_mem = { 0 };
ot_vb_pool g_vb_pool = OT_VB_INVALID_POOL_ID;
ot_vgs_handle g_vgs_handle = -1;
FILE *g_pfd = TD_NULL;
td_u32 g_blk_size = 0;
td_char *g_user_page_addr = TD_NULL;
ot_vi_chn g_vi_chn;
td_s32 g_size;
ot_video_frame_info g_frame[MAX_FRM_CNT];
static td_s32 g_mem_dev = -1;
td_void vi_dump_set_signal(void (*func)(int))
{
#ifndef __LITEOS__
struct sigaction sa = { 0 };
sa.sa_handler = func;
sa.sa_flags = 0;
sigaction(SIGINT, &sa, TD_NULL);
sigaction(SIGTERM, &sa, TD_NULL);
#endif
}
static td_s32 mem_dev_open(td_void)
{
if (g_mem_dev <= 0) {
g_mem_dev = open("/dev/mem", O_CREAT | O_RDWR | O_SYNC, S_IRUSR | S_IWUSR);
if (g_mem_dev < 0) {
perror("Open dev/mem error");
return g_mem_dev;
}
}
return TD_SUCCESS;
}
static td_s32 mem_dev_close(td_void)
{
td_s32 ret = TD_SUCCESS;
if (g_mem_dev > 0) {
ret = close(g_mem_dev);
if (ret != TD_SUCCESS) {
perror("Close mem/dev Fail");
}
g_mem_dev = 0;
}
return ret;
}
static void usage(void)
{
printf("\n"
"*************************************************\n"
"Usage: ./vi_dump [vi_chn] [FrmCnt]\n"
"1)vi_chn: \n"
" which chn to be dump\n"
"Default: 0\n"
"2)FrmCnt: \n"
" the count of frame to be dump\n"
"Default: 1\n"
"*)Example:\n"
"e.g : ./vi_dump 0 1 (dump one YUV)\n"
"*************************************************\n"
"\n");
}
static td_s32 vi_restore(ot_vi_chn vi_chn)
{
td_s32 i;
for (i = 0; i < MAX_FRM_CNT; i++) {
if (g_frame[i].video_frame.phys_addr[0] != 0) {
ss_mpi_vi_release_frame(vi_chn, &g_frame[i]);
g_frame[i].video_frame.phys_addr[0] = 0;
}
}
if (g_vgs_handle != -1) {
ss_mpi_vgs_cancel_job(g_vgs_handle);
g_vgs_handle = -1;
}
if (g_dump_mem.virt_addr != TD_NULL) {
ss_mpi_sys_munmap(g_dump_mem.virt_addr, g_blk_size);
g_dump_mem.phys_addr = TD_NULL;
g_dump_mem.virt_addr = TD_NULL;
}
if (g_dump_mem.pool != OT_VB_INVALID_POOL_ID) {
ss_mpi_vb_release_blk(g_dump_mem.block);
g_dump_mem.pool = OT_VB_INVALID_POOL_ID;
}
if (g_vb_pool != OT_VB_INVALID_POOL_ID) {
ss_mpi_vb_destroy_pool(g_vb_pool);
g_vb_pool = OT_VB_INVALID_POOL_ID;
}
if (g_pfd != TD_NULL) {
fclose(g_pfd);
g_pfd = TD_NULL;
}
return TD_SUCCESS;
}
static void sig_handler(td_s32 signo)
{
if (g_quit == TD_TRUE) {
return;
}
if (signo == SIGINT || signo == SIGTERM) {
g_quit = TD_TRUE;
}
}
static td_s32 vi_dump_get_frame_uv_height(const ot_video_frame *video_buf, td_u32 *uv_height)
{
ot_pixel_format pixel_format = video_buf->pixel_format;
if (pixel_format == OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
g_size = (video_buf->stride[0] * video_buf->height) * 3 / 2; /* 3 / 2 : 420 calc size */
*uv_height = (video_buf->height >> 1);
} else if (pixel_format == OT_PIXEL_FORMAT_YVU_SEMIPLANAR_422) {
g_size = ((video_buf->stride[0] * video_buf->height) << 1);
*uv_height = video_buf->height;
} else if (pixel_format == OT_PIXEL_FORMAT_YUV_400) {
g_size = (video_buf->stride[0] * video_buf->height);
*uv_height = 0;
} else {
printf("not support pixelformat: %d\n", pixel_format);
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_void vi_dump_save_y(const ot_video_frame *video_buf, FILE *pfd)
{
unsigned int h;
char *mem_content = TD_NULL;
char *buf_virt_y = TD_NULL;
buf_virt_y = g_user_page_addr;
(td_void)fprintf(stderr, "saving......Y......");
(td_void)fflush(stderr);
for (h = 0; h < video_buf->height; h++) {
mem_content = buf_virt_y + h * video_buf->stride[0];
(td_void)(td_void)fwrite(mem_content, video_buf->width, 1, pfd);
}
(td_void)fflush(pfd);
}
static td_void vi_dump_save_u(const ot_video_frame *video_buf, FILE *pfd, td_u32 uv_height)
{
unsigned int w, h;
char *buf_virt_y = TD_NULL;
char *buf_virt_c = TD_NULL;
char *mem_content = TD_NULL;
unsigned char temp_buf[MAX_FRM_WIDTH];
buf_virt_y = g_user_page_addr;
buf_virt_c = buf_virt_y + (video_buf->stride[0]) * (video_buf->height);
(td_void)fprintf(stderr, "U......");
(td_void)fflush(stderr);
for (h = 0; h < uv_height; h++) {
mem_content = buf_virt_c + h * video_buf->stride[1];
mem_content += 1;
for (w = 0; w < (video_buf->width >> 1); w++) {
temp_buf[w] = *mem_content;
mem_content += 2; /* 2bytes */
}
(td_void)(td_void)fwrite(temp_buf, video_buf->width >> 1, 1, pfd);
}
(td_void)fflush(pfd);
}
static td_void vi_dump_save_v(const ot_video_frame *video_buf, FILE *pfd, td_u32 uv_height)
{
unsigned int w, h;
char *buf_virt_y = TD_NULL;
char *buf_virt_c = TD_NULL;
char *mem_content = TD_NULL;
unsigned char temp_buf[MAX_FRM_WIDTH];
buf_virt_y = g_user_page_addr;
buf_virt_c = buf_virt_y + (video_buf->stride[0]) * (video_buf->height);
(td_void)fprintf(stderr, "V......");
(td_void)fflush(stderr);
for (h = 0; h < uv_height; h++) {
mem_content = buf_virt_c + h * video_buf->stride[1];
for (w = 0; w < (video_buf->width >> 1); w++) {
temp_buf[w] = *mem_content;
mem_content += 2; /* 2bytes */
}
(td_void)(td_void)fwrite(temp_buf, video_buf->width >> 1, 1, pfd);
}
(td_void)fflush(pfd);
(td_void)fprintf(stderr, "done %d!\n", video_buf->time_ref);
(td_void)fflush(stderr);
}
static td_s32 vi_dump_save_one_frame(const ot_video_frame *video_buf, FILE *pfd)
{
td_phys_addr_t phy_addr;
td_u32 uv_height; /* UV height for planar format */
if (video_buf->width > MAX_FRM_WIDTH) {
printf("Over max frame width: %d, can't support.\n", MAX_FRM_WIDTH);
return TD_FAILURE;
}
if (vi_dump_get_frame_uv_height(video_buf, &uv_height) != TD_SUCCESS) {
return TD_FAILURE;
}
phy_addr = video_buf->phys_addr[0];
g_user_page_addr = (td_char *)ss_mpi_sys_mmap(phy_addr, g_size);
if (g_user_page_addr == TD_NULL) {
return TD_FAILURE;
}
printf("stride: %d,%d\n", video_buf->stride[0], video_buf->stride[1]);
/* save Y ---------------------------------------------------------------- */
vi_dump_save_y(video_buf, pfd);
/* save U ---------------------------------------------------------------- */
vi_dump_save_u(video_buf, pfd, uv_height);
/* save V ---------------------------------------------------------------- */
vi_dump_save_v(video_buf, pfd, uv_height);
if (g_user_page_addr != TD_NULL) {
ss_mpi_sys_munmap(g_user_page_addr, g_size);
g_user_page_addr = TD_NULL;
}
return TD_SUCCESS;
}
static td_s32 vi_dump_create_pool(ot_vi_chn vi_chn, const ot_video_frame_info *video_frame_in, ot_vb_calc_cfg *cal_cfg)
{
const td_u32 align = 0;
ot_compress_mode compress_mode;
ot_pic_buf_attr buf_attr;
ot_pixel_format pixel_format;
ot_data_bit_width bit_width;
ot_vb_pool_cfg vb_pool_cfg;
compress_mode = OT_COMPRESS_MODE_NONE;
pixel_format = video_frame_in->video_frame.pixel_format;
bit_width = (video_frame_in->video_frame.dynamic_range == OT_DYNAMIC_RANGE_SDR8) ? OT_DATA_BIT_WIDTH_8 :
OT_DATA_BIT_WIDTH_10;
buf_attr.width = video_frame_in->video_frame.width;
buf_attr.height = video_frame_in->video_frame.height;
buf_attr.pixel_format = pixel_format;
buf_attr.bit_width = bit_width;
buf_attr.compress_mode = compress_mode;
buf_attr.align = align;
ot_common_get_pic_buf_cfg(&buf_attr, cal_cfg);
g_blk_size = cal_cfg->vb_size;
(td_void)memset_s(&vb_pool_cfg, sizeof(vb_pool_cfg), 0, sizeof(ot_vb_pool_cfg));
vb_pool_cfg.blk_size = g_blk_size;
vb_pool_cfg.blk_cnt = 1;
vb_pool_cfg.remap_mode = OT_VB_REMAP_MODE_NONE;
g_vb_pool = ss_mpi_vb_create_pool(&vb_pool_cfg);
if (g_vb_pool == OT_VB_INVALID_POOL_ID) {
printf("OT_MPI_VB_CreatePool failed! \n");
vi_restore(vi_chn);
return TD_FAILURE;
}
return TD_SUCCESS;
}
static td_s32 vi_dump_set_frame_info(ot_vi_chn vi_chn, ot_video_frame_info *frame_info,
const ot_video_frame_info *video_frame_in, const ot_vb_calc_cfg *cal_cfg)
{
g_dump_mem.pool = g_vb_pool;
g_dump_mem.block = ss_mpi_vb_get_blk(g_dump_mem.pool, g_blk_size, TD_NULL);
if (g_dump_mem.block == OT_VB_INVALID_HANDLE) {
printf("get vb blk fail\n");
return TD_FAILURE;
}
g_dump_mem.phys_addr = ss_mpi_vb_handle_to_phys_addr(g_dump_mem.block);
g_dump_mem.virt_addr = (td_u8 *)ss_mpi_sys_mmap(g_dump_mem.phys_addr, g_blk_size);
if (g_dump_mem.virt_addr == TD_NULL) {
printf("Mem dev may not open\n");
vi_restore(vi_chn);
return TD_FAILURE;
}
(td_void)memset_s(&frame_info->video_frame, sizeof(ot_video_frame), 0, sizeof(ot_video_frame));
frame_info->video_frame.phys_addr[0] = g_dump_mem.phys_addr;
frame_info->video_frame.phys_addr[1] = frame_info->video_frame.phys_addr[0] + cal_cfg->main_y_size;
frame_info->video_frame.virt_addr[0] = (td_void *)(td_uintptr_t)g_dump_mem.virt_addr;
frame_info->video_frame.virt_addr[1] = (frame_info->video_frame.virt_addr[0] + cal_cfg->main_y_size);
frame_info->video_frame.width = video_frame_in->video_frame.width;
frame_info->video_frame.height = video_frame_in->video_frame.height;
frame_info->video_frame.stride[0] = cal_cfg->main_stride;
frame_info->video_frame.stride[1] = cal_cfg->main_stride;
frame_info->video_frame.compress_mode = OT_COMPRESS_MODE_NONE;
frame_info->video_frame.pixel_format = video_frame_in->video_frame.pixel_format;
frame_info->video_frame.video_format = OT_VIDEO_FORMAT_LINEAR;
frame_info->video_frame.dynamic_range = video_frame_in->video_frame.dynamic_range;
frame_info->video_frame.pts = 0;
frame_info->video_frame.time_ref = 0;
frame_info->pool_id = g_vb_pool;
frame_info->mod_id = OT_ID_VGS;
return TD_SUCCESS;
}
td_void vi_dump_destroy_pool(td_void)
{
g_vgs_handle = -1;
ss_mpi_vb_release_blk(g_dump_mem.block);
g_dump_mem.pool = OT_VB_INVALID_POOL_ID;
g_vgs_handle = -1;
if (g_dump_mem.virt_addr != TD_NULL) {
ss_mpi_sys_munmap(g_dump_mem.virt_addr, g_blk_size);
g_dump_mem.phys_addr = TD_NULL;
g_dump_mem.virt_addr = TD_NULL;
}
if (g_vb_pool != OT_VB_INVALID_POOL_ID) {
ss_mpi_vb_destroy_pool(g_vb_pool);
g_vb_pool = OT_VB_INVALID_POOL_ID;
}
}
static td_s32 vi_dump_proc_save_file(ot_vi_chn vi_chn, td_bool send_to_vgs, FILE *pfd,
const ot_video_frame_info *video_frame_in)
{
td_s32 ret;
ot_vgs_task_attr vgs_task;
ot_video_frame_info frame_info;
ot_vb_calc_cfg cal_cfg;
if (send_to_vgs) {
ret = vi_dump_create_pool(vi_chn, video_frame_in, &cal_cfg);
if (ret != TD_SUCCESS) {
return ret;
}
ret = vi_dump_set_frame_info(vi_chn, &frame_info, video_frame_in, &cal_cfg);
if (ret != TD_SUCCESS) {
vi_restore(vi_chn);
return ret;
}
ret = ss_mpi_vgs_begin_job(&g_vgs_handle);
if (ret != TD_SUCCESS) {
printf("OT_MPI_VGS_BeginJob failed\n");
g_vgs_handle = -1;
vi_restore(vi_chn);
return TD_FAILURE;
}
(td_void)memcpy_s(&vgs_task.img_in, sizeof(ot_video_frame_info), video_frame_in, sizeof(ot_video_frame_info));
(td_void)memcpy_s(&vgs_task.img_out, sizeof(ot_video_frame_info), &frame_info, sizeof(ot_video_frame_info));
ret = ss_mpi_vgs_add_scale_task(g_vgs_handle, &vgs_task, OT_VGS_SCALE_COEF_NORM);
if (ret != TD_SUCCESS) {
printf("ss_mpi_vgs_add_scale_task failed\n");
vi_restore(vi_chn);
return TD_FAILURE;
}
ret = ss_mpi_vgs_end_job(g_vgs_handle);
if (ret != TD_SUCCESS) {
printf("ss_mpi_vgs_end_job failed\n");
vi_restore(vi_chn);
return TD_FAILURE;
}
ret = vi_dump_save_one_frame(&frame_info.video_frame, pfd);
if (ret != TD_SUCCESS) {
printf("vi_dump_save_one_frame failed\n");
vi_restore(vi_chn);
return TD_FAILURE;
}
vi_dump_destroy_pool();
} else {
ret = vi_dump_save_one_frame(&video_frame_in->video_frame, pfd);
}
return ret;
}
static td_void sample_misc_prepare_restore_save_fd(td_void)
{
if (g_pfd != TD_NULL) {
fclose(g_pfd);
g_pfd = TD_NULL;
}
}
static td_s32 sample_misc_prepare_save_video_fd(ot_vi_chn vi_chn, td_bool *send_to_vgs, td_u32 cnt)
{
td_char yuv_name[FILE_NAME_LENGTH] = { 0 };
td_char pixel_format[PIXEL_FORMAT_NAME_LENGTH] = {0};
ot_video_frame_info video_frame;
td_s32 ret;
if (g_quit == TD_TRUE) {
return TD_FAILURE;
}
if (ss_mpi_vi_get_frame(vi_chn, &video_frame, 2000) != TD_SUCCESS) { /* 2000 : waiting time */
printf("ss_mpi_vi_get_frame err, vi chn %d \n", vi_chn);
return TD_FAILURE;
}
*send_to_vgs = (video_frame.video_frame.compress_mode != OT_COMPRESS_MODE_NONE);
/* make file name */
if (video_frame.video_frame.pixel_format == OT_PIXEL_FORMAT_YUV_400) {
ret = snprintf_s(pixel_format, PIXEL_FORMAT_NAME_LENGTH, PIXEL_FORMAT_NAME_LENGTH - 1, "single");
} else if (video_frame.video_frame.pixel_format == OT_PIXEL_FORMAT_YVU_SEMIPLANAR_420) {
ret = snprintf_s(pixel_format, PIXEL_FORMAT_NAME_LENGTH, PIXEL_FORMAT_NAME_LENGTH - 1, "p420");
} else {
ret = snprintf_s(pixel_format, PIXEL_FORMAT_NAME_LENGTH, PIXEL_FORMAT_NAME_LENGTH - 1, "p422");
}
if (ret < 0) {
printf("vi chn %d set pixel format fail\n", vi_chn);
(td_void)ss_mpi_vi_release_frame(vi_chn, &video_frame);
return TD_FAILURE;
}
ret = snprintf_s(yuv_name, sizeof(yuv_name), sizeof(yuv_name) - 1, "./vi_chn_%d_%dx%d_%s_%d.yuv", vi_chn,
video_frame.video_frame.width, video_frame.video_frame.height, pixel_format, cnt);
if (ret < 0) {
printf("vi chn %d set yuv name fail\n", vi_chn);
(td_void)ss_mpi_vi_release_frame(vi_chn, &video_frame);
return TD_FAILURE;
}
ret = ss_mpi_vi_release_frame(vi_chn, &video_frame);
if (ret != TD_SUCCESS) {
printf("release frame failed\n");
return TD_FAILURE;
}
/* open file */
g_pfd = fopen(yuv_name, "w+b");
if (g_pfd == TD_NULL) {
printf("open file failed:%d!\n", errno);
return TD_FAILURE;
}
printf("Dump YUV frame of vi chn %d to file: \"%s\"\n", vi_chn, yuv_name);
return TD_SUCCESS;
}
static td_void sample_misc_get_vi_frame(ot_vi_chn vi_chn, td_u32 cnt, td_u32 *frame_cnt)
{
td_u32 j;
const td_s32 milli_sec = 2000; /* 2000 : waiting time */
for (j = 0; j < cnt; j++) {
g_frame[j].video_frame.phys_addr[0] = 0;
}
for (*frame_cnt = 0; (*frame_cnt) < cnt; (*frame_cnt)++) {
if (g_quit == TD_TRUE) {
break;
}
if (ss_mpi_vi_get_frame(vi_chn, &g_frame[*frame_cnt], milli_sec) < 0) {
printf("get vi chn %d frame err\n", vi_chn);
printf("only get %d frame\n", *frame_cnt);
break;
}
}
}
static td_s32 sample_misc_save_frame_to_file(ot_vi_chn vi_chn, td_bool send_to_vgs, td_u32 frame_cnt)
{
td_u32 j;
td_s32 ret;
for (j = 0; j < frame_cnt; j++) {
if (g_quit == TD_TRUE) {
break;
}
ret = vi_dump_proc_save_file(vi_chn, send_to_vgs, g_pfd, &g_frame[j]);
if (ret != TD_SUCCESS) {
printf("save frame %d failed", j);
return TD_FAILURE;
}
/* release frame after using */
ss_mpi_vi_release_frame(vi_chn, &g_frame[j]);
g_frame[j].video_frame.phys_addr[0] = 0;
}
return TD_SUCCESS;
}
td_s32 sample_misc_vi_dump(ot_vi_chn vi_chn, td_u32 cnt)
{
td_u32 frame_cnt, j;
td_s32 ret = TD_SUCCESS;
td_u32 old_depth = -1U;
td_bool send_to_vgs;
if (ss_mpi_vi_get_frame_depth(vi_chn, &old_depth)) {
printf("ss_mpi_vi_get_frame_depth err, vi chn %d \n", vi_chn);
return TD_FAILURE;
}
if (ss_mpi_vi_set_frame_depth(vi_chn, 1) != TD_SUCCESS) {
printf("ss_mpi_vi_set_frame_depth err, vi chn %d \n", vi_chn);
return TD_FAILURE;
}
usleep(90000); /* 90000 : wait depth work */
if (sample_misc_prepare_save_video_fd(vi_chn, &send_to_vgs, cnt) != TD_SUCCESS) {
ret = TD_FAILURE;
goto restore_depth;
}
/* get VI frame */
sample_misc_get_vi_frame(vi_chn, cnt, &frame_cnt);
if ((g_quit == TD_TRUE) || (frame_cnt <= 0)) {
goto restore_fd;
}
if (sample_misc_save_frame_to_file(vi_chn, cnt, frame_cnt) != TD_SUCCESS) {
printf("misc_save_frame_to_file failed!\n");
}
for (j = 0; j < frame_cnt; j++) {
if (g_frame[j].video_frame.phys_addr[0] != 0) {
ss_mpi_vi_release_frame(vi_chn, &g_frame[j]);
g_frame[j].video_frame.phys_addr[0] = 0;
}
}
restore_fd:
sample_misc_prepare_restore_save_fd();
restore_depth:
if (old_depth != -1U) {
ss_mpi_vi_set_frame_depth(vi_chn, old_depth);
}
return ret;
}
static td_s32 vi_dump_get_argv_val(char *argv[], td_s32 index, td_s32 *val)
{
td_char *end_ptr = TD_NULL;
td_s32 result;
result = (td_s32)strtol(argv[index], &end_ptr, VI_DUMP_ARG_NUMBER_BASE);
if (*end_ptr != '\0') {
printf("Failure: input arg[%d] is invalid!\n", index);
usage();
return TD_FAILURE;
}
*val = result;
return TD_SUCCESS;
}
static td_s32 vi_dump_get_chn_num(char *argv[], td_s32 index)
{
td_s32 ret = TD_FAILURE;
td_s32 vi_chn;
ret = vi_dump_get_argv_val(argv, index, &vi_chn);
if (ret != TD_SUCCESS) {
return ret;
}
if (vi_chn < 0 || vi_chn >= OT_VI_MAX_CHN_NUM) {
printf("invalid chn %d, chn range from 0 to %d\n", vi_chn, OT_VI_MAX_CHN_NUM - 1);
return TD_FAILURE;
}
return vi_chn;
}
static td_s32 vi_dump_get_frame_cnt(char *argv[], td_s32 index)
{
td_s32 ret = TD_FAILURE;
td_s32 frame_cnt;
ret = vi_dump_get_argv_val(argv, index, &frame_cnt);
if (ret != TD_SUCCESS) {
return ret;
}
if (frame_cnt < 1 || frame_cnt > MAX_FRM_CNT) {
printf("invalid FrmCnt %d, FrmCnt range from 1 to %d\n", frame_cnt, MAX_FRM_CNT);
return TD_FAILURE;
}
return frame_cnt;
}
td_s32 main(int argc, char *argv[])
{
ot_vi_chn vi_chn;
td_s32 frame_cnt;
printf("\nNOTICE: This tool only can be used for TESTING !!!\n");
printf("\t To see more usage, please enter: ./vi_dump -h\n\n");
if (argc > 1) {
if (!strncmp(argv[1], "-h", 2)) { /* 2 help */
usage();
exit(0);
}
}
if (argc != 3) { /* 3: 3 arg num */
usage();
exit(-1);
}
vi_chn = vi_dump_get_chn_num(argv, 1);
if (vi_chn == TD_FAILURE) {
exit(-1);
}
g_vi_chn = vi_chn;
frame_cnt = vi_dump_get_frame_cnt(argv, 2); /* 2nd arg : frame number that need to capture */
if (frame_cnt == TD_FAILURE) {
exit(-1);
}
if (mem_dev_open()) {
exit(-1);
}
vi_dump_set_signal(&sig_handler);
if (sample_misc_vi_dump(vi_chn, frame_cnt) != TD_SUCCESS) {
printf("sample_misc_vi_dump err!\n");
}
if (g_quit == TD_TRUE) {
fclose(stdin);
vi_restore(g_vi_chn);
(td_void)mem_dev_close();
printf("\033[0;31mprogram exit abnormally!\033[0;39m\n");
exit(-1);
}
if (mem_dev_close()) {
exit(-1);
}
return TD_SUCCESS;
}