/* * V4L2 video capture example * AUTHOT : Jacob Chen * DATA : 2018-02-25 */ #include #include #include #include #include /* getopt_long() */ #include /* low-level i/o */ #include #include #include #include #include #include #include #include #include #include #include "call_fun_ipc.h" #include "drmDsp.h" #include "rk_aiq_user_api_sysctl.h" #include "rk_aiq_user_api_a3dlut.h" // #include "rk_aiq_user_api_ablc.h" #include "rk_aiq_user_api_imgproc.h" #include "config.h" #include #define CLEAR(x) memset(&(x), 0, sizeof(x)) #define FMT_NUM_PLANES 1 #define BUFFER_COUNT 4 #define CAPTURE_RAW_PATH "/tmp" #define CAPTURE_CNT_FILENAME "capture_cnt" struct buffer { void *start; size_t length; int export_fd; int sequence; }; static char out_file[255]; static char dev_name[255]; static int width = 640; static int height = 480; static int format = V4L2_PIX_FMT_NV12; static int fd = -1; static enum v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; struct buffer *buffers; static unsigned int n_buffers; static int frame_count = -1; FILE *fp = NULL; static rk_aiq_sys_ctx_t* aiq_ctx = NULL; static int silent = 0; static int vop = 0; static int rkaiq = 0; static int writeFile = 0; static int writeFileSync = 0; static int pponeframe = 0; static int hdrmode = 0; static char sensor[64]; static int fd_pp_input = -1; static int fd_isp_mp = -1; struct buffer *buffers_mp; static int outputCnt = 3; static int skipCnt = 30; static char yuv_dir_path[64]; static bool _is_yuv_dir_exist = false; static int g_capture_yuv_num = 0x0; static bool _is_capture_yuv; #define DBG(...) do { if(!silent) printf(__VA_ARGS__); } while(0) #define ERR(...) do { fprintf(stderr, __VA_ARGS__); } while (0) static struct termios oldt; //restore terminal settings void restore_terminal_settings(void) { // Apply saved settings tcsetattr(0, TCSANOW, &oldt); } //make terminal read 1 char at a time void disable_terminal_return(void) { struct termios newt; //save terminal settings tcgetattr(0, &oldt); //init new settings newt = oldt; //change settings newt.c_lflag &= ~(ICANON | ECHO); //apply settings tcsetattr(0, TCSANOW, &newt); //make sure settings will be restored when program ends atexit(restore_terminal_settings); } void test_imgproc(const rk_aiq_sys_ctx_t* ctx) { if (ctx == NULL) { return; } int key =getchar(); printf("press key=[%c]\n",key); opMode_t mode; paRange_t range; expPwrLineFreq_t freq; rk_aiq_wb_scene_t scene; rk_aiq_wb_gain_t gain; unsigned int ct; antiFlickerMode_t flicker; switch (key) { case '0': rk_aiq_uapi_setExpMode(ctx, OP_MANUAL); printf("set exp manual\n"); break; case '.': rk_aiq_uapi_setExpMode(ctx, OP_AUTO); printf("set exp auto\n"); break; case '1': rk_aiq_uapi_getExpMode(ctx, &mode); printf("exp mode=%d\n",mode); break; case '2': range.min = 5.0f; range.max = 8.0f; rk_aiq_uapi_setExpGainRange(ctx, &range); printf("set gain range\n"); break; case '3': rk_aiq_uapi_getExpGainRange(ctx, &range); printf("get gain range[%f,%f]\n",range.min,range.max); break; case '4': range.min = 10.0f; range.max = 30.0f; rk_aiq_uapi_setExpTimeRange(ctx, &range); printf("set time range\n"); break; case '5': rk_aiq_uapi_getExpTimeRange(ctx, &range); printf("get time range[%f,%f]\n",range.min,range.max); break; case '6': rk_aiq_uapi_setExpPwrLineFreqMode(ctx, EXP_PWR_LINE_FREQ_50HZ); printf("setExpPwrLineFreqMode 50hz\n"); break; case ',': rk_aiq_uapi_setExpPwrLineFreqMode(ctx, EXP_PWR_LINE_FREQ_60HZ); printf("setExpPwrLineFreqMode 60hz\n"); break; case '7': rk_aiq_uapi_getExpPwrLineFreqMode(ctx, &freq); printf("getExpPwrLineFreqMode=%d\n",freq); break; case '8': rk_aiq_uapi_setWBMode(ctx, OP_MANUAL); printf("setWBMode manual\n"); break; case '/': rk_aiq_uapi_setWBMode(ctx, OP_AUTO); printf("setWBMode auto\n"); break; case '9': rk_aiq_uapi_getWBMode(ctx, &mode); printf("getWBMode=%d\n",mode); break; case 'a': rk_aiq_uapi_lockAWB(ctx); printf("lockAWB\n"); break; case 'b': rk_aiq_uapi_unlockAWB(ctx); printf("unlockAWB\n"); break; case 'c': rk_aiq_uapi_setMWBScene(ctx,RK_AIQ_WBCT_TWILIGHT); printf("setMWBScene\n"); break; case 'd': rk_aiq_uapi_getMWBScene(ctx,&scene); printf("getMWBScene=%d\n",scene); break; case 'e': gain.rgain = 0.5f; gain.grgain = 0.5f; gain.gbgain = 0.5f; gain.bgain = 0.5f; rk_aiq_uapi_setMWBGain(ctx,&gain); printf("setMWBGain\n"); break; case 'f': rk_aiq_uapi_getMWBGain(ctx,&gain); printf("getMWBGain=[%f %f %f %f]\n",gain.rgain,gain.grgain,gain.gbgain,gain.bgain); break; case 'g': ct = 5500; rk_aiq_uapi_setMWBCT(ctx, &ct); printf("setMWBCT\n"); break; case 'h': rk_aiq_uapi_getMWBCT(ctx,&ct); printf("getMWBCT=[%d]\n",ct); break; case 'i': rk_aiq_uapi_setAntiFlickerMode(ctx,ANTIFLICKER_NORMAL_MODE); printf("setAntiFlickerMode normal\n"); break; case 'j': rk_aiq_uapi_setAntiFlickerMode(ctx,ANTIFLICKER_AUTO_MODE); printf("setAntiFlickerMode auto\n"); break; case 'k': rk_aiq_uapi_getAntiFlickerMode(ctx, &flicker); printf("getAntiFlickerMode=%d\n",flicker); break; case 'l': rk_aiq_uapi_setSaturation(ctx, 50); printf("setSaturation\n"); break; case 'm': unsigned int level1; rk_aiq_uapi_getSaturation(ctx, &level1); printf("getSaturation=%f\n",level1); break; case 'n': rk_aiq_uapi_setCrSuppsn(ctx, 50.0); printf("setCrSuppsn\n"); break; case 'o': unsigned int level2; rk_aiq_uapi_getCrSuppsn(ctx, &level2); printf("getCrSuppsn=%d\n",level2); break; case 'p': rk_aiq_uapi_setHDRMode(ctx, OP_AUTO); printf("setHDRMode\n"); break; case 'q': rk_aiq_uapi_setHDRMode(ctx, OP_MANUAL); printf("setHDRMode\n"); break; case 'r': rk_aiq_uapi_getHDRMode(ctx, &mode); printf("getHDRMode=%d\n",mode); break; case 's': rk_aiq_uapi_setNRMode(ctx, OP_MANUAL); printf("setNRMode\n"); break; case 't': rk_aiq_uapi_getNRMode(ctx, &mode); printf("getNRMode=%d\n",mode); break; case 'u': rk_aiq_uapi_setDhzMode(ctx, OP_MANUAL); printf("setDhzMode\n"); break; case 'v': rk_aiq_uapi_getDhzMode(ctx, &mode); printf("getDhzMode=%d\n",mode); break; default: break; } } static void errno_exit(const char *s) { ERR("%s error %d, %s\n", s, errno, strerror(errno)); exit(EXIT_FAILURE); } static int xioctl(int fh, int request, void *arg) { int r; do { r = ioctl(fh, request, arg); } while (-1 == r && EINTR == errno); return r; } bool get_value_from_file(const char* path, int* value) { char buffer[8] = {0}; int fp; fp = open(path, O_RDONLY | O_SYNC); if (fp) { if (read(fp, buffer, sizeof(buffer)) <= 0) printf("%s read %s failed!\n", __func__, path); else *value = atoi(buffer); close(fp); return true; } return false; } static int write_yuv_to_file(const void *p, int size, int sequence) { char file_name[64] = {0}; snprintf(file_name, sizeof(file_name), "%s/frame%d.yuv", yuv_dir_path, sequence); fp = fopen(file_name, "wb+"); if (fp == NULL) { ERR("fopen yuv file %s failed!\n", file_name); return -1; } fwrite(p, size, 1, fp); fflush(fp); if (fp) { fclose(fp); fp = NULL; } for (int i = 0; i < g_capture_yuv_num; i++) printf("<"); printf("\n"); // printf("write frame%d yuv\n", sequence); return 0; } static int creat_yuv_dir(const char* path) { time_t now; struct tm* timenow; if (!path) return -1; time(&now); timenow = localtime(&now); snprintf(yuv_dir_path, sizeof(yuv_dir_path), "%s/yuv_%04d-%02d-%02d_%02d-%02d-%02d", path, timenow->tm_year + 1900, timenow->tm_mon + 1, timenow->tm_mday, timenow->tm_hour, timenow->tm_min, timenow->tm_sec); // printf("mkdir %s for capturing yuv!\n", yuv_dir_path); if(mkdir(yuv_dir_path, 0755) < 0) { printf("mkdir %s error!!!\n", yuv_dir_path); return -1; } _is_yuv_dir_exist = true; return 0; } static void process_image(const void *p, int sequence,int size) { if (fp && sequence >= skipCnt && outputCnt-- > 0) { printf(">\n"); fwrite(p, size, 1, fp); fflush(fp); } else if (writeFileSync) { int ret = 0; if (!_is_capture_yuv) { char file_name[32] = {0}; snprintf(file_name, sizeof(file_name), "%s/%s", CAPTURE_RAW_PATH, CAPTURE_CNT_FILENAME); get_value_from_file(file_name, &g_capture_yuv_num); if (g_capture_yuv_num > 0) _is_capture_yuv = true; if (sequence != 0) return; } if (_is_capture_yuv) { if (!_is_yuv_dir_exist) { creat_yuv_dir(CAPTURE_RAW_PATH); } if (_is_yuv_dir_exist) { write_yuv_to_file(p, size, sequence); } if (--g_capture_yuv_num == 0) { _is_capture_yuv = false; _is_yuv_dir_exist = false; } } } } static int read_frame() { struct v4l2_buffer buf; int i, bytesused; CLEAR(buf); buf.type = buf_type; buf.memory = V4L2_MEMORY_MMAP; struct v4l2_plane planes[FMT_NUM_PLANES]; if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type) { buf.m.planes = planes; buf.length = FMT_NUM_PLANES; } if (-1 == xioctl(fd, VIDIOC_DQBUF, &buf)) errno_exit("VIDIOC_DQBUF"); i = buf.index; if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type) bytesused = buf.m.planes[0].bytesused; else bytesused = buf.bytesused; if (vop) { drmDspFrame(width, height, buffers[i].start, DRM_FORMAT_NV12); } process_image(buffers[i].start, buf.sequence, bytesused); if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); return 1; } static int read_frame_pp_oneframe() { struct v4l2_buffer buf; struct v4l2_buffer buf_pp; int i,ii, bytesused; static int first_time = 1; CLEAR(buf); // dq one buf from isp mp printf("------ dq 1 from isp mp --------------\n"); buf.type = buf_type; buf.memory = V4L2_MEMORY_MMAP; struct v4l2_plane planes[FMT_NUM_PLANES]; if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type) { buf.m.planes = planes; buf.length = FMT_NUM_PLANES; } if (-1 == xioctl(fd_isp_mp, VIDIOC_DQBUF, &buf)) errno_exit("VIDIOC_DQBUF"); i = buf.index; if (first_time ) { printf("------ dq 2 from isp mp --------------\n"); if (-1 == xioctl(fd_isp_mp, VIDIOC_DQBUF, &buf)) errno_exit("VIDIOC_DQBUF"); ii = buf.index; } if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type) bytesused = buf.m.planes[0].bytesused; else bytesused = buf.bytesused; // queue to ispp input printf("------ queue 1 index %d to ispp input --------------\n", i); CLEAR(buf_pp); buf_pp.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; buf_pp.memory = V4L2_MEMORY_DMABUF; buf_pp.index = i; struct v4l2_plane planes_pp[FMT_NUM_PLANES]; memset(planes_pp, 0, sizeof(planes_pp)); buf_pp.m.planes = planes_pp; buf_pp.length = FMT_NUM_PLANES; buf_pp.m.planes[0].m.fd = buffers_mp[i].export_fd; if (-1 == xioctl(fd_pp_input, VIDIOC_QBUF, &buf_pp)) errno_exit("VIDIOC_QBUF"); if (first_time ) { printf("------ queue 2 index %d to ispp input --------------\n", ii); buf_pp.index = ii; buf_pp.m.planes[0].m.fd = buffers_mp[ii].export_fd; if (-1 == xioctl(fd_pp_input, VIDIOC_QBUF, &buf_pp)) errno_exit("VIDIOC_QBUF"); } // read frame from ispp sharp/scale printf("------ readframe from output --------------\n"); read_frame(); // dq from pp input printf("------ dq 1 from ispp input--------------\n"); if (-1 == xioctl(fd_pp_input, VIDIOC_DQBUF, &buf_pp)) errno_exit("VIDIOC_DQBUF"); // queue back to mp printf("------ queue 1 index %d back to isp mp--------------\n", buf_pp.index); buf.index = buf_pp.index; if (-1 == xioctl(fd_isp_mp, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); first_time = 0; return 1; } static void mainloop(void) { bool loop_inf = frame_count == -1 ? true : false; while (loop_inf || (frame_count-- > 0)) { if (pponeframe) read_frame_pp_oneframe(); else read_frame(); } } static void stop_capturing(void) { enum v4l2_buf_type type; type = buf_type; if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type)) errno_exit("VIDIOC_STREAMOFF"); } static void stop_capturing_pp_oneframe(void) { enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; if (-1 == xioctl(fd_pp_input, VIDIOC_STREAMOFF, &type)) errno_exit("VIDIOC_STREAMOFF ppinput"); type = buf_type; if (-1 == xioctl(fd_isp_mp, VIDIOC_STREAMOFF, &type)) errno_exit("VIDIOC_STREAMOFF ispmp"); } static void start_capturing(void) { unsigned int i; enum v4l2_buf_type type; for (i = 0; i < n_buffers; ++i) { struct v4l2_buffer buf; CLEAR(buf); buf.type = buf_type; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type) { struct v4l2_plane planes[FMT_NUM_PLANES]; buf.m.planes = planes; buf.length = FMT_NUM_PLANES; } if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); } type = buf_type; printf("-------- stream on output -------------\n"); if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) errno_exit("VIDIOC_STREAMON"); } static void start_capturing_pp_oneframe(void) { unsigned int i; enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; printf("-------- stream on pp input -------------\n"); if (-1 == xioctl(fd_pp_input, VIDIOC_STREAMON, &type)) errno_exit("VIDIOC_STREAMON pp input"); type = buf_type; for (i = 0; i < n_buffers; ++i) { struct v4l2_buffer buf; CLEAR(buf); buf.type = buf_type; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type) { struct v4l2_plane planes[FMT_NUM_PLANES]; buf.m.planes = planes; buf.length = FMT_NUM_PLANES; } if (-1 == xioctl(fd_isp_mp, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); } printf("-------- stream on isp mp -------------\n"); if (-1 == xioctl(fd_isp_mp, VIDIOC_STREAMON, &type)) errno_exit("VIDIOC_STREAMON ispmp"); } static void uninit_device(void) { unsigned int i; for (i = 0; i < n_buffers; ++i) { if (-1 == munmap(buffers[i].start, buffers[i].length)) errno_exit("munmap"); close(buffers[i].export_fd); } free(buffers); } static void uninit_device_pp_oneframe(void) { unsigned int i; for (i = 0; i < n_buffers; ++i) { if (-1 == munmap(buffers_mp[i].start, buffers_mp[i].length)) errno_exit("munmap"); close(buffers_mp[i].export_fd); } free(buffers_mp); } static void init_mmap(int pp_onframe) { struct v4l2_requestbuffers req; int fd_tmp = -1; CLEAR(req); if (pp_onframe) fd_tmp = fd_isp_mp ; else fd_tmp = fd; req.count = BUFFER_COUNT; req.type = buf_type; req.memory = V4L2_MEMORY_MMAP; struct buffer *tmp_buffers = NULL; if (-1 == xioctl(fd_tmp, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { ERR("%s does not support " "memory mapping\n", dev_name); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_REQBUFS"); } } if (req.count < 2) { ERR("Insufficient buffer memory on %s\n", dev_name); exit(EXIT_FAILURE); } tmp_buffers = (struct buffer*)calloc(req.count, sizeof(struct buffer)); if (!tmp_buffers) { ERR("Out of memory\n"); exit(EXIT_FAILURE); } if (pp_onframe) buffers_mp = tmp_buffers; else buffers = tmp_buffers; for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { struct v4l2_buffer buf; struct v4l2_plane planes[FMT_NUM_PLANES]; CLEAR(buf); CLEAR(planes); buf.type = buf_type; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type) { buf.m.planes = planes; buf.length = FMT_NUM_PLANES; } if (-1 == xioctl(fd_tmp, VIDIOC_QUERYBUF, &buf)) errno_exit("VIDIOC_QUERYBUF"); if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type) { tmp_buffers[n_buffers].length = buf.m.planes[0].length; tmp_buffers[n_buffers].start = mmap(NULL /* start anywhere */, buf.m.planes[0].length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, fd_tmp, buf.m.planes[0].m.mem_offset); } else { tmp_buffers[n_buffers].length = buf.length; tmp_buffers[n_buffers].start = mmap(NULL /* start anywhere */, buf.length, PROT_READ | PROT_WRITE /* required */, MAP_SHARED /* recommended */, fd_tmp, buf.m.offset); } if (MAP_FAILED == tmp_buffers[n_buffers].start) errno_exit("mmap"); // export buf dma fd struct v4l2_exportbuffer expbuf; xcam_mem_clear (expbuf); expbuf.type = buf_type; expbuf.index = n_buffers; expbuf.flags = O_CLOEXEC; if (xioctl(fd_tmp, VIDIOC_EXPBUF, &expbuf) < 0) { errno_exit("get dma buf failed\n"); } else { printf("get dma buf(%d)-fd: %d\n", n_buffers, expbuf.fd); } tmp_buffers[n_buffers].export_fd = expbuf.fd; } } static void init_input_dmabuf_oneframe(void) { struct v4l2_requestbuffers req; CLEAR(req); printf("-------- request pp input buffer -------------\n"); req.count = BUFFER_COUNT; req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; req.memory = V4L2_MEMORY_DMABUF; if (-1 == xioctl(fd_pp_input, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { ERR("does not support " "DMABUF\n"); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_REQBUFS"); } } if (req.count < 2) { ERR("Insufficient buffer memory on %s\n", dev_name); exit(EXIT_FAILURE); } printf("-------- request isp mp buffer -------------\n"); init_mmap(true); } static void init_device(void) { struct v4l2_capability cap; struct v4l2_format fmt; if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { ERR("%s is no V4L2 device\n", dev_name); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_QUERYCAP"); } } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) && !(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)) { ERR("%s is not a video capture device, capabilities: %x\n", dev_name, cap.capabilities); exit(EXIT_FAILURE); } if (!(cap.capabilities & V4L2_CAP_STREAMING)) { ERR("%s does not support streaming i/o\n", dev_name); exit(EXIT_FAILURE); } if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; else if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; CLEAR(fmt); fmt.type = buf_type; fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; fmt.fmt.pix.pixelformat = format; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) errno_exit("VIDIOC_S_FMT"); init_mmap(false); } static void init_device_pp_oneframe(void) { // TODO, set format and link, now do with setup_link.sh init_input_dmabuf_oneframe(); } static void close_device(void) { if (-1 == close(fd)) errno_exit("close"); fd = -1; } static void open_device(void) { printf("-------- open output dev_name -------------\n"); fd = open(dev_name, O_RDWR /* required */ /*| O_NONBLOCK*/, 0); if (-1 == fd) { ERR("Cannot open '%s': %d, %s\n", dev_name, errno, strerror(errno)); exit(EXIT_FAILURE); } } static void close_device_pp_oneframe(void) { if (-1 == close(fd_pp_input)) errno_exit("close"); fd_pp_input = -1; if (-1 == close(fd_isp_mp)) errno_exit("close"); fd_isp_mp = -1; } static void open_device_pp_oneframe(void) { printf("-------- open pp input(video13) -------------\n"); fd_pp_input = open("/dev/video13", O_RDWR /* required */ /*| O_NONBLOCK*/, 0); if (-1 == fd_pp_input) { ERR("Cannot open '%s': %d, %s\n", dev_name, errno, strerror(errno)); exit(EXIT_FAILURE); } printf("-------- open isp mp(video0) -------------\n"); fd_isp_mp = open("/dev/video0", O_RDWR /* required */ /*| O_NONBLOCK*/, 0); if (-1 == fd_isp_mp ) { ERR("Cannot open '%s': %d, %s\n", dev_name, errno, strerror(errno)); exit(EXIT_FAILURE); } } static void uninit_device_pp_onframe(void) { unsigned int i; for (i = 0; i < n_buffers; ++i) { if (-1 == munmap(buffers_mp[i].start, buffers_mp[i].length)) errno_exit("munmap"); close(buffers_mp[i].export_fd); } free(buffers_mp); } void parse_args(int argc, char **argv) { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"width", required_argument, 0, 'w' }, {"height", required_argument, 0, 'h' }, {"format", required_argument, 0, 'f' }, {"device", required_argument, 0, 'd' }, {"stream-to", required_argument, 0, 'o' }, {"stream-count", required_argument, 0, 'n' }, {"stream-skip", required_argument, 0, 'k' }, {"count", required_argument, 0, 'c' }, {"help", no_argument, 0, 'p' }, {"silent", no_argument, 0, 's' }, {"vop", no_argument, 0, 'v' }, {"rkaiq", no_argument, 0, 'r' }, {"pponeframe", no_argument, 0, 'm' }, {"hdr", no_argument, 0, 'a' }, {"sensor", required_argument, 0, 'b' }, {"sync-to-raw", no_argument, 0, 'e' }, {0, 0, 0, 0 } }; //c = getopt_long(argc, argv, "w:h:f:i:d:o:c:ps", c = getopt_long(argc, argv, "w:h:f:i:d:o:c:n:k:m:pse", long_options, &option_index); if (c == -1) break; switch (c) { case 'c': frame_count = atoi(optarg); break; case 'w': width = atoi(optarg); break; case 'h': height = atoi(optarg); break; case 'f': format = v4l2_fourcc(optarg[0], optarg[1], optarg[2], optarg[3]); break; case 'd': strcpy(dev_name, optarg); break; case 'o': strcpy(out_file, optarg); writeFile = 1; break; case 'n': outputCnt = atoi(optarg); break; case 'k': skipCnt = atoi(optarg); break; case 's': silent = 1; break; case 'v': vop = 1; break; case 'r': rkaiq = 1; break; case 'm': pponeframe = 1; break; case 'a': hdrmode = 1; break; case 'b': strcpy(sensor, optarg); break; case 'e': writeFileSync = 1; break; case '?': case 'p': ERR("Usage: %s to capture rkisp1 frames\n" " --width, default 640, optional, width of image\n" " --height, default 480, optional, height of image\n" " --format, default NV12, optional, fourcc of format\n" " --count, default 1000, optional, how many frames to capture\n" " --device, required, path of video device\n" " --stream-to, optional, output file path, if is '-', then the data is written to stdout\n" " --stream-count, default 3 optional, how many frames to write files\n" " --stream-skip, default 30 optional, how many frames to skip befor writing file\n" " --vop, optional, drm display\n" " --rkaiq, optional, auto image quality\n", " --silent, optional, subpress debug log\n", " --pponeframe, optional, pp oneframe readback mode\n", " --hdr, optional, hdr mode\n", " --sensor, default os04a10, optional, sensor names\n", " --sync-to-raw, optional, write yuv files in sync with raw\n", argv[0]); exit(-1); default: ERR("?? getopt returned character code 0%o ??\n", c); } } if (strlen(dev_name) == 0) { ERR("arguments --output and --device are required\n"); exit(-1); } } static void deinit() { stop_capturing(); if (pponeframe) stop_capturing_pp_oneframe(); if (aiq_ctx) { printf("-------- stop aiq -------------\n"); rk_aiq_uapi_sysctl_stop(aiq_ctx, false); printf("-------- deinit aiq -------------\n"); rk_aiq_uapi_sysctl_deinit(aiq_ctx); printf("-------- deinit aiq end -------------\n"); } //stop_capturing(); uninit_device(); if (pponeframe) uninit_device_pp_oneframe(); close_device(); if (pponeframe) close_device_pp_oneframe(); if (fp) fclose(fp); } static void signal_handle(int signo) { printf("force exit signo %d !!!\n",signo); deinit(); exit(0); } static void main_exit(void) { printf("client %s\n", __func__); call_fun_ipc_client_deinit(); } void signal_crash_handler(int sig) { exit(-1); } void signal_exit_handler(int sig) { exit(0); } void* test_thread(void* args) { pthread_detach (pthread_self()); disable_terminal_return(); printf("begin test imgproc\n"); while(1) { test_imgproc(aiq_ctx); } printf("end test imgproc\n"); restore_terminal_settings(); } int main(int argc, char **argv) { signal(SIGINT, signal_handle); atexit(main_exit); signal(SIGTERM, signal_exit_handler); //signal(SIGINT, signal_exit_handler); signal(SIGPIPE, SIG_IGN); signal(SIGBUS, signal_crash_handler); signal(SIGSEGV, signal_crash_handler); signal(SIGFPE, signal_crash_handler); signal(SIGABRT, signal_crash_handler); strcpy(sensor, "os04a10"); parse_args(argc, argv); printf("-------- open output dev -------------\n"); open_device(); if (pponeframe) open_device_pp_oneframe(); init_device(); if (pponeframe) init_device_pp_oneframe(); if (writeFile) { fp = fopen(out_file, "w+"); if (fp == NULL) { ERR("fopen output file %s failed!\n", out_file); exit(-1); } } const char* sns_entity_name = NULL; rk_aiq_working_mode_t work_mode = RK_AIQ_WORKING_MODE_NORMAL; if (strcasecmp(sensor, "ov4689") == 0) { if (hdrmode) work_mode = RK_AIQ_WORKING_MODE_ISP_HDR3; sns_entity_name = "m01_f_ov4689 1-0036"; } else if (strcasecmp(sensor, "os04a10") == 0) { if (hdrmode) work_mode = RK_AIQ_WORKING_MODE_ISP_HDR2; sns_entity_name = "m01_f_os04a10 1-0036"; } else if (strcasecmp(sensor, "gc4c33") == 0) { if (hdrmode) work_mode = RK_AIQ_WORKING_MODE_ISP_HDR2; sns_entity_name = "m01_f_gc4c33 1-0029"; } else if (strcasecmp(sensor, "imx347") == 0) { if (hdrmode) work_mode = RK_AIQ_WORKING_MODE_ISP_HDR2; sns_entity_name = "m01_f_imx347 1-0037"; } printf("sns_entity_name %s\n", sns_entity_name); if (rkaiq) { printf("+++++call_fun_ipc_client_init\n"); //int r = 0xFEFEFEFE; // while (r == 0xFEFEFEFE) { call_fun_ipc_client_init(DBUS_NAME, DBUS_IF, DBUS_PATH, SHARE_PATH, 1); // usleep(1000*1000); // printf("=======call_fun_ipc_client_init, r=0x%x\n",r); // } aiq_ctx = rk_aiq_uapi_sysctl_init(sns_entity_name,NULL, NULL, NULL); if (aiq_ctx) { printf("-------- init mipi tx/rx -------------\n"); XCamReturn ret = rk_aiq_uapi_sysctl_prepare(aiq_ctx, width, height, work_mode); if (ret != XCAM_RETURN_NO_ERROR) ERR("rk_aiq_uapi_sysctl_prepare failed: %d\n", ret); else { /* printf("-------- stream on mipi tx/rx -------------\n"); */ /* ret = rk_aiq_uapi_sysctl_start(aiq_ctx ); */ start_capturing(); if (pponeframe) start_capturing_pp_oneframe(); printf("-------- stream on mipi tx/rx -------------\n"); ret = rk_aiq_uapi_sysctl_start(aiq_ctx); printf("-------------stream on mipi end\n"); } if (vop) { if (initDrmDsp() < 0) { printf("DRM display init failed\n"); exit(0); } } usleep(500 * 1000); } } else { if (vop) { if (initDrmDsp() < 0) { printf("DRM display init failed\n"); exit(0); } } usleep(500 * 1000); start_capturing(); if (pponeframe) start_capturing_pp_oneframe(); } #if ENABLE_TEST pthread_t tid; pthread_create(&tid, NULL, (void*)test_thread, NULL); #endif mainloop(); deinit(); return 0; }