714 lines
20 KiB
C
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;
|
|
}
|