363 lines
12 KiB
C
Executable File
363 lines
12 KiB
C
Executable File
/*
|
|
* Copyright (c) XMEDIA. All rights reserved.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
|
|
#include "sample_comm.h"
|
|
#include "sample_comm_sys.h"
|
|
#include "sample_comm_vi.h"
|
|
#include "sample_comm_isp.h"
|
|
|
|
static sample_comm_sensor_type g_sample_fpn_sensor_type[MAX_SENSOR_NUM] = { SENSOR0_TYPE, SENSOR1_TYPE, SENSOR2_TYPE,
|
|
SENSOR3_TYPE, SENSOR4_TYPE };
|
|
|
|
static xmedia_bool g_force_exit = XMEDIA_FALSE;
|
|
|
|
xmedia_void sample_fpn_usage(xmedia_char *args)
|
|
{
|
|
printf("\n"
|
|
"***************************************************************\n"
|
|
"Usage: %s [work_mode] [stream_mode]\n"
|
|
"work_mode: \n"
|
|
" 0: vi offline fpn calibrate\n"
|
|
"e.g: %s 0\n"
|
|
"***************************************************************\n"
|
|
"\n",
|
|
args, args);
|
|
return;
|
|
}
|
|
|
|
xmedia_s32 sample_fpn_sys_init(sample_sys_config *sys_config)
|
|
{
|
|
xmedia_s32 ret = 0;
|
|
|
|
ret = sample_comm_sys_init(sys_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("sample_comm_sys_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
// in online-online mode,vi and vpss must be reset at the same time
|
|
ret = sample_comm_vi_init();
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("sample_comm_vi_init failed!\n");
|
|
return ret;
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
xmedia_void sample_fpn_sys_exit(void)
|
|
{
|
|
sample_comm_vi_exit();
|
|
sample_comm_sys_exit();
|
|
}
|
|
|
|
xmedia_void sample_fpn_handle_sig(xmedia_s32 signo)
|
|
{
|
|
if (SIGINT == signo || SIGTSTP == signo || SIGTERM == signo) {
|
|
g_force_exit = XMEDIA_TRUE;
|
|
}
|
|
}
|
|
|
|
xmedia_s32 sample_fpn_calibrate(xmedia_s32 pipe, xmedia_u32 width, xmedia_u32 height)
|
|
{
|
|
xmedia_char string[8] = { 0 };
|
|
xmedia_u16 calibrate_frame = 256;
|
|
xmedia_handle vb_block = VB_INVALID_HANDLE;
|
|
xmedia_s8 *vb_vir_addr = { XMEDIA_NULL };
|
|
xmedia_u64 phy_addr;
|
|
FILE *file = XMEDIA_NULL;
|
|
xmedia_u64 start, end;
|
|
xmedia_s32 ret;
|
|
xmedia_u32 blk_size = 0;
|
|
|
|
xmedia_isp_fpn_calibrate_attr fpn_calibrate_attr = { 0 };
|
|
xmedia_isp_blc_attr blc_attr = { 0 };
|
|
|
|
fflush(stdin);
|
|
SAMPLE_PRT("input number to set calibrate frame and press enter to confirm!\n");
|
|
SAMPLE_PRT("calibrate frame: \n");
|
|
fgets(string, sizeof string, stdin);
|
|
calibrate_frame = (xmedia_u16)atoi(string);
|
|
fflush(stdin);
|
|
|
|
while (calibrate_frame > 256 || calibrate_frame < 1) {
|
|
SAMPLE_PRT("calibrate frame supported range is [1, 256] and power of 2. please input number again!\n");
|
|
fgets(string, sizeof string, stdin);
|
|
calibrate_frame = (xmedia_u16)atoi(string);
|
|
fflush(stdin);
|
|
}
|
|
|
|
SAMPLE_PRT("press enter to start fpn calibrate.\n");
|
|
getchar();
|
|
|
|
xmedia_sys_get_cur_pts(&start);
|
|
|
|
blk_size = (width * 8 + 63) / 64 * 8 * height;
|
|
vb_block = xmedia_vb_get_block(VB_INVALID_POOLID, blk_size, XMEDIA_NULL);
|
|
if (vb_block == VB_INVALID_HANDLE) {
|
|
SAMPLE_PRT("get block failed!\n");
|
|
goto exit;
|
|
}
|
|
|
|
phy_addr = xmedia_vb_handle_to_phy_addr(vb_block);
|
|
if (phy_addr == 0) {
|
|
SAMPLE_PRT("get phy_addr failed!\n");
|
|
goto exit;
|
|
}
|
|
|
|
vb_vir_addr = (xmedia_s8 *)xmedia_mmz_map(phy_addr, blk_size, XMEDIA_FALSE);
|
|
if (vb_vir_addr == XMEDIA_NULL) {
|
|
SAMPLE_PRT("mmz map failed!\n");
|
|
goto exit;
|
|
}
|
|
|
|
memset(vb_vir_addr, 0x63, blk_size); // 初始化为一个特殊的值,方便debug定位问题
|
|
|
|
ret = xmedia_isp_get_black_level_attr(pipe, &blc_attr);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("get black level failed!\n");
|
|
goto exit;
|
|
}
|
|
fpn_calibrate_attr.offset = blc_attr.manual_attr.black_level[0];
|
|
fpn_calibrate_attr.frame_num = calibrate_frame;
|
|
fpn_calibrate_attr.fpn_frame.frame.addr.y_phy_addr = phy_addr;
|
|
ret = xmedia_isp_set_fpn_calibrate(pipe, &fpn_calibrate_attr);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("set fpn calibrate failed!\n");
|
|
goto exit;
|
|
}
|
|
|
|
xmedia_sys_get_cur_pts(&end);
|
|
SAMPLE_PRT("fpn calibrate finish. cost time: %llu us.\n", end - start);
|
|
|
|
file = fopen("FPN.bin", "w");
|
|
chmod("FPN.bin", 0666);
|
|
if (file == XMEDIA_NULL) {
|
|
SAMPLE_PRT("open file failed!\n");
|
|
goto exit;
|
|
}
|
|
|
|
SAMPLE_PRT("start save calibrate result to FPN.bin.\n");
|
|
xmedia_sys_get_cur_pts(&start);
|
|
fwrite(vb_vir_addr, blk_size, 1, file);
|
|
|
|
fclose(file);
|
|
xmedia_sys_get_cur_pts(&end);
|
|
SAMPLE_PRT("save FPN.bin finish. cost time: %llu us.\n", end - start);
|
|
|
|
exit:
|
|
if (vb_block != VB_INVALID_HANDLE) {
|
|
xmedia_vb_release_block(vb_block);
|
|
}
|
|
|
|
if (vb_vir_addr != XMEDIA_NULL) {
|
|
xmedia_mmz_unmap(vb_vir_addr);
|
|
}
|
|
|
|
return XMEDIA_SUCCESS;
|
|
}
|
|
|
|
xmedia_s32 sample_fpn_vi_offline_fpn_calibrate()
|
|
{
|
|
xmedia_s32 ret = XMEDIA_SUCCESS;
|
|
xmedia_s32 blk_size = 0;
|
|
xmedia_video_size pic_size = { 0 };
|
|
sample_comm_video_param video_param = { 0 };
|
|
sample_sys_config sys_config = { 0 };
|
|
xmedia_ae_exposure_attr exposure_attr = { 0 };
|
|
|
|
xmedia_s32 vi_dev = 0;
|
|
xmedia_s32 vi_pipe = 0;
|
|
xmedia_s32 vi_chn = 0;
|
|
sample_vi_config vi_config = { 0 };
|
|
|
|
xmedia_s32 sensor_type = g_sample_fpn_sensor_type[0];
|
|
xmedia_u32 framerate = 0;
|
|
vi_sensor_info sensor_info = { 0 };
|
|
sample_isp_param isp_param = { 0 };
|
|
xmedia_isp_config isp_config = { 0 };
|
|
xmedia_bool mirror = XMEDIA_FALSE;
|
|
xmedia_bool flip = XMEDIA_FALSE;
|
|
|
|
video_param.video_fmt = XMEDIA_VIDEO_FMT_LINEAR;
|
|
video_param.pixel_fmt = XMEDIA_VIDEO_PIXEL_FMT_YVU_SEMIPLANAR_420;
|
|
video_param.data_width = XMEDIA_VIDEO_DATA_WIDTH_8;
|
|
video_param.compress_mode = XMEDIA_VIDEO_COMPRESS_MODE_NONE;
|
|
|
|
sample_comm_vi_get_sensor_info(sensor_type, &sensor_info);
|
|
sample_comm_vi_get_framerate_by_sensor(sensor_type, &framerate);
|
|
|
|
// sys init
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].vicap_viproc_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].viproc_vpss_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
sys_config.sys_conf.pipe_mode[vi_pipe].gdc_vpss_mode = XMEDIA_WORK_MODE_OFFLINE;
|
|
|
|
sys_config.vb_conf.max_pool_cnt = 25;
|
|
|
|
pic_size.width = sensor_info.width;
|
|
pic_size.height = sensor_info.height;
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size, video_param.video_fmt, sensor_info.pixel_format,
|
|
sensor_info.bit_width, video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[0].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[0].block_cnt = 2;
|
|
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size, video_param.video_fmt, video_param.pixel_fmt,
|
|
video_param.data_width, video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[1].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[1].block_cnt = 2;
|
|
|
|
blk_size = sample_comm_sys_get_buffer_size(pic_size, video_param.video_fmt, sensor_info.pixel_format,
|
|
video_param.data_width, video_param.compress_mode);
|
|
sys_config.vb_conf.common_pool[2].block_size = blk_size;
|
|
sys_config.vb_conf.common_pool[2].block_cnt = 4;
|
|
|
|
sys_config.vb_conf.supplement_config = 1;
|
|
|
|
ret = sample_fpn_sys_init(&sys_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("sys init failed !\n");
|
|
return ret;
|
|
}
|
|
|
|
vi_config.dev_info[vi_dev].dev_en = XMEDIA_TRUE;
|
|
vi_config.dev_info[vi_dev].dev_no = vi_dev;
|
|
vi_config.dev_info[vi_dev].sensor_type = sensor_type;
|
|
vi_config.pipe_info[vi_pipe].pipe_en = XMEDIA_TRUE;
|
|
vi_config.pipe_info[vi_pipe].pipe_no = vi_pipe;
|
|
vi_config.pipe_info[vi_pipe].chn_info[vi_chn].chn_en = XMEDIA_TRUE;
|
|
vi_config.pipe_info[vi_pipe].chn_info[vi_chn].chn_no = vi_chn;
|
|
vi_config.dev_bind_pipe[vi_dev].pipe[0] = vi_pipe;
|
|
vi_config.dev_bind_pipe[vi_dev].pipe[1] = -1;
|
|
|
|
isp_config.fps = framerate;
|
|
isp_config.mode_config.work_mode = XMEDIA_ISP_WORK_MODE_MASTER;
|
|
isp_config.mode_config.master_mode.blend_stat_enable = XMEDIA_FALSE;
|
|
isp_config.mode_config.master_mode.slave_num = 0;
|
|
isp_config.pixel_fmt = sensor_info.pixel_format;
|
|
isp_config.size.height = sensor_info.height;
|
|
isp_config.size.width = sensor_info.width;
|
|
isp_config.wdr_mode = sensor_info.wdr_mode;
|
|
|
|
// isp pipe init
|
|
isp_param.pipe[vi_pipe] = vi_pipe;
|
|
isp_param.isp_info[vi_pipe].isp_pipe_en = XMEDIA_TRUE;
|
|
isp_param.isp_info[vi_pipe].isp_sensor_en = XMEDIA_TRUE;
|
|
isp_param.isp_info[vi_pipe].sensor_type = sensor_type;
|
|
isp_param.isp_info[vi_pipe].mirror = mirror;
|
|
isp_param.isp_info[vi_pipe].flip = flip;
|
|
|
|
memcpy(&(isp_param.isp_info[vi_pipe].isp_config), &isp_config, sizeof(xmedia_isp_config));
|
|
|
|
// isp init
|
|
ret = sample_comm_isp_init(&isp_param, &vi_config);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("isp init failed!\n");
|
|
goto exit0;
|
|
}
|
|
|
|
// vi start
|
|
ret = sample_comm_vi_start(&vi_config, &video_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("start vi failed!\n");
|
|
goto exit1;
|
|
}
|
|
|
|
// isp start
|
|
ret = sample_comm_isp_start(&isp_param);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("start isp failed!\n");
|
|
goto exit2;
|
|
}
|
|
|
|
xmedia_ae_get_exposure_attr(vi_pipe, &exposure_attr);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("get_exposure failed!\n");
|
|
goto exit2;
|
|
}
|
|
|
|
exposure_attr.auto_attr.dgain_range.max = 1024;
|
|
exposure_attr.auto_attr.dgain_range.min = 1024;
|
|
xmedia_ae_set_exposure_attr(vi_pipe, &exposure_attr);
|
|
if (ret != XMEDIA_SUCCESS) {
|
|
SAMPLE_PRT("set_exposure failed!\n");
|
|
goto exit2;
|
|
}
|
|
|
|
while (1) {
|
|
xmedia_char c, a;
|
|
|
|
SAMPLE_PRT("input cmd: 'q' - quit; 'f' - fpn calibrate.\n");
|
|
c = getchar();
|
|
while ((a = getchar()) != '\n' && a != EOF) {
|
|
}
|
|
if (c == 'q') {
|
|
break;
|
|
} else if (c == 'f') {
|
|
sample_fpn_calibrate(vi_pipe, sensor_info.width, sensor_info.height);
|
|
}
|
|
}
|
|
|
|
exit2:
|
|
sample_comm_isp_stop(&isp_param);
|
|
|
|
exit1:
|
|
sample_comm_vi_stop(&vi_config);
|
|
|
|
exit0:
|
|
sample_comm_isp_exit(&isp_param);
|
|
sample_fpn_sys_exit();
|
|
|
|
return ret;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
xmedia_s32 ret = XMEDIA_SUCCESS;
|
|
xmedia_s32 work_mode = 0;
|
|
|
|
signal(SIGINT, sample_fpn_handle_sig);
|
|
signal(SIGTERM, sample_fpn_handle_sig);
|
|
|
|
if (argc == 2) {
|
|
if (!strncmp(argv[1], "-h", 2)) {
|
|
sample_fpn_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
} else {
|
|
sample_fpn_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
work_mode = atoi(argv[1]);
|
|
|
|
switch (work_mode) {
|
|
case 0:
|
|
ret = sample_fpn_vi_offline_fpn_calibrate();
|
|
break;
|
|
|
|
default:
|
|
sample_fpn_usage(argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
if (XMEDIA_SUCCESS == ret) {
|
|
SAMPLE_PRT("program exit normally!\n");
|
|
} else {
|
|
SAMPLE_PRT("program exit abnormally!\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|