1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276 |
- /*
- * Copyright (C) 2021-2022 Alibaba Group Holding Limited
- * Author: LuChongzhi <chongzhi.lcz@alibaba-inc.com>; Minxiong Tian <minxiong.tmx@alibaba-inc.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <pthread.h>
- #include <unistd.h>
- #include <error.h>
- #include <errno.h>
- #include <sys/mman.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <sys/sem.h>
- #include "csi_camera_dev_api.h"
- /* macros for share memory and semaphore */
- #define SHMKEY (key_t)0x39126
- #define SEMKEY (key_t)0x49126
- #define IFLAGS (IPC_CREAT|IPC_EXCL)
- #define LOG_LEVEL 2
- #define LOG_PREFIX "camera_demo1"
- #include <syslog.h>
- #include <csi_frame_ex.h>
- #include <csi_camera.h>
- #ifdef PLATFORM_SIMULATOR
- #include "apputilities.h"
- #endif
- #define PAGE_SIZE 1024
- #define PAGE_ALIGN(addr) (void *)(((int)(addr)+PAGE_SIZE-1)&~( PAGE_SIZE-1))
- /* data store in share-memory */
- struct databuf {
- int d_buf[2];
- };
- static void dump_camera_meta(csi_frame_ex_s *frame, int idx);
- static void* save_camera_img(void *);
- static void* save_camera_stream(void *);
- static int set_properties(csi_cam_handle_t cam_handle, char *pArgs);
- static enum csi_pixel_fmt parse_format(char *fmt);
- // static void handle_dma_buf(csi_frame_s *framei, int cid);
- //extern int csi_camera_frame_unlock(csi_cam_handle_t cam_handle, csi_frame_s *frame);
- extern int csi_camera_put_frame(csi_frame_ex_s *frame);
- static void i_save(csi_frame_ex_s *framei, int cid, FILE *fp, int vmode);
- static void parse_fmt_res(int cindx);
- static void getseg(struct databuf* *pdata);
- static int getsem();
- static void remove_s();
- static void writer(struct databuf *buf, int index, int value);
- static void reader(struct databuf *buf, int index, int * rv);
- static int pr_error(char *mess);
- extern int csi_camera_set_pp_path_param(csi_cam_handle_t cam_handle, uint16_t line_num,uint16_t buf_mode);
- extern void *vi_plink_create(csi_camera_channel_cfg_s *chn_cfg);
- extern void vi_plink_release(void * plink);
- extern void display_camera_frame(void * plink, csi_frame_ex_s *frame);
- #define TEST_DEVICE_NAME "/dev/video0"
- #define CSI_CAMERA_TRUE 1
- #define CSI_CAMERA_FALSE 0
- #define chnMAX 8
- #define fmtMAX 19
- csi_cam_handle_t cam_handle;
- char *prog_name;
- int Soff = 0;
- static char device[CSI_CAMERA_NAME_MAX_LEN]; /* target video device like /dev/video0 */
- static char path[128] = "./"; /* output path */
- static int channelIdx[chnMAX]; /* channel information like 8 */
- enum csi_pixel_fmt fenum[chnMAX];
- int fid[chnMAX] = {0};
- int tframes = 4;
- csi_camera_channel_id_e CAMERA_CHANNEL_ID[chnMAX];
- /* File local Global array to store information which will be used when storig images */
- static int PLANE[chnMAX] = {0};
- static int PBIT[chnMAX] = {0};
- static int PLNS[chnMAX][3] = {0};
- static int LNN[chnMAX][3] = {0};
- static int LSZ[chnMAX][3] = {0};
- static int LNNV[chnMAX][3] = {0}; /* for rotation 90/270 */
- static int LSZV[chnMAX][3] = {0}; /* for rotation 90/270 */
- static int NOSTRD[chnMAX] = {0};
- /* local global array for meta data verify */
- static int cur_metaint[chnMAX] = {-1, -1, -1, -1};
- static int pre_metaint[chnMAX] = {-1, -1, -1, -1};
- static int cur_metasec[chnMAX] = {-1, -1, -1, -1};
- static int pre_metasec[chnMAX] = {-1, -1, -1, -1};
- static int cur_metausec[chnMAX] = {-1, -1, -1, -1};
- static int pre_metausec[chnMAX] = {-1, -1, -1, -1};
- static int shmid, semid;
- struct sembuf p1 = {0, -1, 0}, v1 = {0, 1, 0};
- int meta_mode = -1;
- int flashMode = 0;
- int fNumInc[chnMAX] = {0};
- int fCount = 1;
- int onoffMode = 0;
- int afterOnOff[chnMAX];
- int onoffDrop = 4;
- int onoffFrame = 0;
- int ooNum[chnMAX] = {0};
- int ofTop = 30;
- csi_frame_ex_s frame[chnMAX];
- pthread_t tid[chnMAX]={0};
- int hres[chnMAX], vres[chnMAX]; /* resolution information like 640x480 */
- int idxArray[chnMAX][10]={0};
- static char *dname;
- static int chNum = 0;
- char fmtArray[fmtMAX][50] = {
- "CSI_PIX_FMT_I420",
- "CSI_PIX_FMT_NV12",
- "CSI_PIX_FMT_BGR",
- "CSI_PIX_FMT_RAW_8BIT",
- "CSI_PIX_FMT_RAW_10BIT",
- "CSI_PIX_FMT_RAW_12BIT",
- "CSI_PIX_FMT_RAW_14BIT",
- "CSI_PIX_FMT_RAW_16BIT",
- "CSI_PIX_FMT_RGB_PLANAR_888",
- "CSI_PIX_FMT_RGB_INTEVLEAVED_888",
- "CSI_PIX_FMT_YUV_PLANAR_422",
- "CSI_PIX_FMT_YUV_PLANAR_420",
- "CSI_PIX_FMT_YUV_PLANAR_444",
- "CSI_PIX_FMT_YUV_SEMIPLANAR_422",
- "CSI_PIX_FMT_YUV_SEMIPLANAR_420",
- "CSI_PIX_FMT_YUV_SEMIPLANAR_444",
- "CSI_PIX_FMT_YUV_TEVLEAVED_422",
- "CSI_PIX_FMT_YUV_TEVLEAVED_420",
- "CSI_PIX_FMT_YUV_TEVLEAVED_444"
- };
- void usage()
- {
- fprintf (stderr,
- "usage: %s [options]\n"
- "Options:\n"
- "\t-D dev target video device like /dev/video0\n"
- "\t-R resolution format is like 640x480, use 640x480/1092x1080 for multi channel output\n"
- "\t-F format like NV12, use NV12/NV12 to support multi channel output\n"
- "\t-C channel_index channel index defined in dts, index from 0, use 0/2 for multi channel output\n"
- "\t-M test mode 0: save as image; 1: save as stream file; 2: output to plink; 3. performace test\n"
- "\t-N number for frames 0: record forever; others: the recorded frame numbers, use 30/30 from multi channel output\n"
- "\t-n number of frames to save if not given, 4 is used\n"
- "\t-P Property id:type:value, use id:type:value/id:type:value for multi property setting\n"
- "\t-p output path store output file in the give path\n"
- "\t-S turn off stride mode if given, turn off stride mode\n"
- "\t-t stream turn on/off test if will turn off stream after several streams then turn on\n"
- "\t-s turn off sram mode if given, turn off sram mode between ISP/DSP and DSP/ISP-RY\n"
- "\t-m disable DW DMA-BUF if given, turn off dma-buf mode\n"
- "\t-f enable LED flash mode if given, enable LED flash mode for odd and even frame feature in lightA production board\n"
- "\t-i nubmer of process which needs to do IPC, use for multi-video and mutli-process test scenarios\n"
- "\t-y meta-data test 0 - meta dump all all elements; 1 - meta verify for CAMERA_NAME;\n"
- " 2 - meta verify for CHANNEL_ID; 3 - meta verify for FRAME_ID;\n"
- " 4 - meta verify for TIMESTAMP.\n"
- " 200 - meta verify for all elements\n"
- , prog_name
- );
- }
- int main(int argc, char *argv[])
- {
- bool running = 0;
- csi_camera_info_s camera_info;
- int opt;
- char *resDelim = "xX/";
- int outMode = 0;
- int fNum[chnMAX] = {0};
- char pArgs[500] = {'\0'}; /* store property args */
- char *devDelim = "/";
- char *sCur;
- int idx = 0;
- int ret = 0;
- csi_camera_event_type_e CAMERA_CHANNEL_EVENT_TYPE[chnMAX];
- struct timeval init_time, cur_time;
- memset(&init_time, 0, sizeof(init_time));
- memset(&cur_time, 0, sizeof(cur_time));
- unsigned long video_open = 0;
- unsigned long channel_open = 0;
- unsigned long channel_start = 0;
- unsigned long first_frame = 0;
- unsigned long total_frame = 0;
- float fps = 0.0;
- int sramMode = 1;
- /* data for share-memory */
- struct databuf *buf;
- int mi = 0;
- int srv1 = 0, srv2 = 0;
- prog_name = argv[0];
- while ((opt = getopt(argc, argv, "t:D:R:F:C:M:hN:P:p:Smi:y:fsn:")) != EOF) {
- switch(opt) {
- case 'D':
- strcpy(device, optarg);
- strtok(optarg, devDelim);
- dname=strtok(NULL, devDelim);
- continue;
- case 'p':
- strcpy(path, optarg);
- continue;
- case 'S':
- Soff = 1;
- continue;
- case 't':
- onoffMode = 1;
- onoffFrame = atoi(optarg);
- continue;
- case 's':
- sramMode = 0;
- case 'f':
- flashMode = 1;
- continue;
- case 'P':
- strcpy(pArgs, optarg);
- continue;
- case 'R':
- idx = 0;
- sCur=strtok(optarg, resDelim);
- while (sCur != NULL){
- if (idx % 2 == 0)
- hres[idx/2] = atoi(sCur);
- if (idx % 2 == 1)
- vres[idx/2] = atoi(sCur);
- sCur=strtok(NULL, resDelim);
- idx++;
- }
- continue;
- case 'M':
- outMode = atoi(optarg);
- continue;
- case 'i':
- mi = atoi(optarg);
- continue;
- case 'y':
- meta_mode = atoi(optarg);
- continue;
- case 'N':
- for(int j=0; j<chnMAX; j++)
- fNum[j] = atoi(optarg);
- continue;
- case 'n':
- tframes = atoi(optarg);
- continue;
- case 'F':
- idx = 0;
- sCur=strtok(optarg, devDelim);
- while (sCur != NULL){
- fenum[idx] = parse_format(sCur);
- sCur=strtok(NULL, devDelim);
- idx++;
- }
- continue;
- case 'C':
- idx = 0;
- sCur=strtok(optarg, devDelim);
- while (sCur != NULL){
- channelIdx[idx] = atoi(sCur);
- sCur=strtok(NULL, devDelim);
- idx++;
- }
- chNum = idx;
- continue;
- case '?':
- case 'h':
- default:
- usage();
- return 1;
- }
- }
- /* get semaphore ID and share-memory ID if mi >=2 */
- if(mi >= 2){
- semid = getsem();
- getseg(&buf);
- printf("------IPC mode enable - finish-------\n");
- }
- /* init the target channel ID and channel event type array */
- for (int j=0; j<chNum; j++){
- CAMERA_CHANNEL_ID[j] = CSI_CAMERA_CHANNEL_0 + channelIdx[j];
- CAMERA_CHANNEL_EVENT_TYPE[j] = CSI_CAMERA_EVENT_TYPE_CHANNEL0 + channelIdx[j];
- }
- if (fNum[0] == 0){
- running = 1;
- printf("------running = 1-------\n");
- }
- // 打印HAL接口版本号
- csi_api_version_u version;
- csi_camera_get_version(&version);
- printf("Camera HAL version: %d.%d\n", version.major, version.minor);
- // 获取设备中,所有的Camera
- struct csi_camera_infos camera_infos;
- memset(&camera_infos, 0, sizeof(camera_infos));
- csi_camera_query_list(&camera_infos);
- // 打印所有设备所支持的Camera
- for (int i = 0; i < camera_infos.count; i++) {
- camera_info = camera_infos.info[i];
- printf("Camera[%d]: camera_name='%s', device_name='%s', bus_info='%s', capabilities=0x%08x\n",
- i,
- camera_info.camera_name, camera_info.device_name, camera_info.bus_info,
- camera_info.capabilities);
- printf("Camera[%d] caps are:\n",
- i); /* The caps are: Video capture, metadata capture */
- for (int j = 1; j <= 0x08000000; j = j << 1) {
- switch (camera_info.capabilities & j) {
- case CSI_CAMERA_CAP_VIDEO_CAPTURE:
- printf("\t camera_infos.info[%d]:Video capture,\n", i);
- break;
- case CSI_CAMERA_CAP_META_CAPTURE:
- printf("\t camera_infos.info[%d] metadata capture,\n", i);
- break;
- default:
- if (camera_info.capabilities & j) {
- printf("\t camera_infos.info[%d] unknown capabilities(0x%08x)\n", i,
- camera_info.capabilities & j);
- }
- break;
- }
- }
- }
- // 打开Camera设备获取句柄,作为后续操对象
- strcpy(camera_info.device_name, device);
- gettimeofday(&init_time, 0);
- csi_camera_open(&cam_handle, camera_info.device_name);
- gettimeofday(&cur_time, 0);
- video_open = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
- // 获取Camera支持的工作模式
- struct csi_camera_modes camera_modes;
- csi_camera_get_modes(cam_handle, &camera_modes);
- // 打印camera所支持的所有工作模式
- printf("Camera:'%s' modes are:\n", device);
- printf("{\n");
- for (int i = 0; i < camera_modes.count; i++) {
- printf("\t mode_id=%d: description:'%s'\n",
- camera_modes.modes[i].mode_id, camera_modes.modes[i].description);
- }
- printf("}\n");
- // 设置camera的工作模式及其配置
- csi_camera_mode_cfg_s camera_cfg;
- camera_cfg.mode_id = 1;
- camera_cfg.calibriation = NULL; // 采用系统默认配置
- camera_cfg.lib3a = NULL; // 采用系统默认配置
- csi_camera_set_mode(cam_handle, &camera_cfg);
- // 获取单个可控单元的属性
- csi_camera_property_description_s description;
- // 轮询获取所有可控制的单元
- printf("all properties are:\n");
- description.id = CSI_CAMERA_PID_HFLIP;
- while (!csi_camera_query_property(cam_handle, &description)) {
- switch (description.type) {
- case (CSI_CAMERA_PROPERTY_TYPE_INTEGER):
- printf("id=0x%08x type=%d default=%d value=%d\n",
- description.id, description.type,
- description.default_value.int_value, description.value.int_value);
- break;
- case (CSI_CAMERA_PROPERTY_TYPE_BOOLEAN):
- printf("id=0x%08x type=%d default=%d value=%d\n",
- description.id, description.type,
- description.default_value.bool_value, description.value.bool_value);
- break;
- case (CSI_CAMERA_PROPERTY_TYPE_ENUM):
- printf("id=0x%08x type=%d default=%d value=%d\n",
- description.id, description.type,
- description.default_value.enum_value, description.value.enum_value);
- break;
- case (CSI_CAMERA_PROPERTY_TYPE_STRING):
- printf("id=0x%08x type=%d default=%s value=%s\n",
- description.id, description.type,
- description.default_value.str_value, description.value.str_value);
- break;
- case (CSI_CAMERA_PROPERTY_TYPE_BITMASK):
- printf("id=0x%08x type=%d default=%x value=%x\n",
- description.id, description.type,
- description.default_value.bitmask_value, description.value.bitmask_value);
- break;
- default:
- LOG_E("error type!\n");
- break;
- }
- description.id |= CSI_CAMERA_FLAG_NEXT_CTRL;
- }
- if (pArgs[0] != '\0'){
- set_properties(cam_handle, pArgs);
- }
- // 查询输出channel
- csi_camera_channel_cfg_s chn_cfg[chnMAX];
- for (int j=0; j<chNum; j++){
- chn_cfg[j].chn_id = CAMERA_CHANNEL_ID[j];
- csi_camera_channel_query(cam_handle, &chn_cfg[j]);
- if (chn_cfg[j].status != CSI_CAMERA_CHANNEL_CLOSED) {
- printf("Can't open channel: %d\n", CAMERA_CHANNEL_ID[j]);
- exit(-1);
- }
- }
- // 打开输出channel
- if (sramMode == 1){
- csi_camera_set_pp_path_param(cam_handle,0,1);
- }
- csi_cam_event_handle_t event_handle;
- csi_camera_event_subscription_s subscribe;
- for (int j=0; j<chNum; j++){
- chn_cfg[j].chn_id = CAMERA_CHANNEL_ID[j];
- chn_cfg[j].frm_cnt = fCount;
- chn_cfg[j].img_fmt.width = hres[j];
- chn_cfg[j].img_fmt.height = vres[j];
- chn_cfg[j].img_fmt.pix_fmt = fenum[j];
- chn_cfg[j].img_type = CSI_IMG_TYPE_DMA_BUF;
- chn_cfg[j].meta_fields = CSI_CAMERA_META_DEFAULT_FIELDS;
- chn_cfg[j].capture_type = CSI_CAMERA_CHANNEL_CAPTURE_VIDEO |
- CSI_CAMERA_CHANNEL_CAPTURE_META;
- parse_fmt_res(j);
- gettimeofday(&init_time, 0);
- ret = csi_camera_channel_open(cam_handle, &chn_cfg[j]);
- if (ret) {
- exit(-1);
- }
- gettimeofday(&cur_time, 0);
- channel_open = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
- }
- // 订阅Event
- csi_camera_create_event(&event_handle, cam_handle);
- for (int j=0; j<chNum; j++){
- subscribe.type =
- CSI_CAMERA_EVENT_TYPE_CAMERA; // 订阅Camera的ERROR事件
- subscribe.id = CSI_CAMERA_EVENT_WARNING | CSI_CAMERA_EVENT_ERROR;
- csi_camera_subscribe_event(event_handle, &subscribe);
- subscribe.type =
- CAMERA_CHANNEL_EVENT_TYPE[j]; // 订阅Channel0的FRAME_READY事件
- subscribe.id = CSI_CAMERA_CHANNEL_EVENT_FRAME_READY |
- CSI_CAMERA_CHANNEL_EVENT_OVERFLOW;
- csi_camera_subscribe_event(event_handle, &subscribe);
- }
- if ( flashMode == 1){
- csi_camera_floodlight_led_set_flash_bright(cam_handle, 500); //500ma
- csi_camera_projection_led_set_flash_bright(cam_handle, 500); //500ma
- csi_camera_projection_led_set_mode(cam_handle, LED_IR_ENABLE);
- csi_camera_floodlight_led_set_mode(cam_handle, LED_IR_ENABLE);
- csi_camera_led_enable(cam_handle, LED_FLOODLIGHT_PROJECTION);
- }
- // start all channels
- for (int j=0; j<chNum; j++){
- gettimeofday(&init_time, 0);
- csi_camera_channel_start(cam_handle, CAMERA_CHANNEL_ID[j]);
- gettimeofday(&cur_time, 0);
- channel_start = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
- }
- gettimeofday(&init_time, 0);
- // 处理订阅的Event
- struct csi_camera_event event;
- int fnumTotal = fNum[0] * chNum;
- int frameTotal = fnumTotal;
- while (running || fnumTotal > 0 ) {
- int timeout = -1; // unit: ms, -1 means wait forever, or until error occurs
- csi_camera_get_event(event_handle, &event, timeout);
- printf("%s event.type = %d, event.id = %d\n", __func__, event.type, event.id);
- if(event.type == CSI_CAMERA_EVENT_TYPE_CAMERA){
- switch (event.id) {
- case CSI_CAMERA_EVENT_ERROR:
- // do sth.
- printf("-------get CAMERA EVENT CSI_CAMERA_EVENT_ERROR!----------\n");
- break;
- case CSI_CAMERA_EVENT_WARNING:
- printf("-------get CAMERA EVENT CSI_CAMERA_EVENT_WRN,RC: %s-------\n",event.bin);
- break;
- default:
- break;
- }
- }
- for (int j=0; j<chNum; j++){
- if(event.type == CAMERA_CHANNEL_EVENT_TYPE[j]){
- switch (event.id) {
- case CSI_CAMERA_CHANNEL_EVENT_OVERFLOW:
- printf("-------get channel EVENT CSI_CAMERA_CHANNEL_EVENT_OVERFLOW-------\n");
- break;
- case CSI_CAMERA_CHANNEL_EVENT_FRAME_READY: {
- int read_frame_count = csi_camera_get_frame_count(cam_handle,
- CAMERA_CHANNEL_ID[j]);
- printf("-------read_frame_count=%d-------\n", read_frame_count);
- for (int i = 0; i < fCount; i++) {
- if (tid[j] != 0){
- /* wait for previous image save thread end */
- pthread_join(tid[j], NULL);
- }
- csi_camera_get_frame(cam_handle, CAMERA_CHANNEL_ID[j], &frame[j], timeout);
- if (afterOnOff[j] != 0 ){
- /* drop the first event after on/off operation */
- afterOnOff[j]--;
- csi_camera_put_frame(&frame[j]);
- // csi_frame_release(&frame[j]);
- continue;
- }
- fNum[j]--;
- fNumInc[j]++;
- if (fNum[j] < 0 && running == 0 ){
- //csi_camera_frame_unlock(cam_handle, &frame[j]);
- csi_camera_put_frame(&frame[j]);
- // csi_frame_release(&frame[j]);
- continue;
- }
- #ifdef PLATFORM_SIMULATOR
- show_frame_image(frame[j].img.usr_addr[0], frame[j].img.height, frame.img.width);
- #endif
- fid[j]++;
- fnumTotal--;
- if (outMode == 0){
- int * tIdx = malloc(sizeof(int));
- *tIdx = j;
- /* submit thread to save image for current channel then we can go to handle other channel */
- pthread_create(&tid[j], NULL, save_camera_img, (void *)tIdx);
- }
- else if (outMode == 1){
- int * tIdx = malloc(sizeof(int));
- *tIdx = j;
- pthread_create(&tid[j], NULL, save_camera_stream, (void *)tIdx);
- }
- else if(outMode == 3){
- /* mode 3 only do performance test, no actual image saving */
- gettimeofday(&cur_time, 0);
- if (fid[j] == 1){
- /* first frame */
- first_frame = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec + video_open + channel_open + channel_start;
- }
- if (fnumTotal == 0){
- /* last frame */
- total_frame = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
- fps = (float)frameTotal / total_frame * 1000000.0f;
- printf("\n");
- printf("\n");
- printf("Performance data:\n");
- printf("video_open:%lu ms\n", video_open/1000);
- printf("channel_open:%lu ms\n", channel_open/1000);
- printf("channel_start:%lu ms\n", channel_start/1000);
- printf("first_frame:%lu ms\n", first_frame/1000);
- printf("fps:%f fps\n", fps);
- printf("\n");
- printf("\n");
- }
- /* for mode 3, unlock in this branch, for mode 0,1 unlock in thread */
- //csi_camera_frame_unlock(cam_handle, &frame[j]);
- csi_camera_put_frame(&frame[j]);
-
- }
- else{
- chn_cfg[j].chn_id = j;
- csi_camera_channel_query(cam_handle, &chn_cfg[j]);
- // display_camera_frame(cam_handle, &chn_cfg[j], &frame[j]);
- //csi_camera_frame_unlock(cam_handle, &frame[j]);
- csi_camera_put_frame(&frame[j]);
-
- }
- }
- break;
- }
- default:
- break;
- }
- }
- }
- }
- /* for IPC, update finish status to share-memory */
- if(mi >= 2){
- writer(buf, 0, 1);
- }
- for (int j=0; j<chNum; j++){
- /* for IPC only do stop when share memory value equals mi */
- if(mi >= 2){
- while (1){
- reader(buf, 0, &srv1);
- if (srv1 != mi){
- sleep(2);
- }
- else{
- /* update the second value in share-memory which is used to decide whether to remove share-memory */
- writer(buf, 1, 1);
- reader(buf, 1, &srv2);
- if (srv2 == mi){
- /* I am the last process to update the buf[1], remove the share-memory */
- remove_s();
- printf("------IPC mode: remove-------\n");
- }
- break;
- }
- }
- }
- csi_camera_channel_stop(cam_handle, CAMERA_CHANNEL_ID[j]);
- }
- if ( flashMode == 1){
- csi_camera_led_disable(cam_handle, LED_FLOODLIGHT_PROJECTION);
- }
- usleep (1000000);
- // 取消订阅某一个event, 也可以直接调用csi_camera_destory_event,结束所有的订阅
- for (int j=0; j<chNum; j++){
- subscribe.type = CAMERA_CHANNEL_EVENT_TYPE[j];
- subscribe.id = CSI_CAMERA_CHANNEL_EVENT_FRAME_READY;
- csi_camera_unsubscribe_event(event_handle, &subscribe);
- }
- csi_camera_destory_event(event_handle);
- for (int j=0; j<chNum; j++){
- csi_camera_channel_close(cam_handle, CAMERA_CHANNEL_ID[j]);
- }
- csi_camera_close(cam_handle);
- }
- int pr_error(char *mess){
- perror(mess);
- exit(1);
- }
- /* function: get or create share-memory*/
- void getseg(struct databuf* *pdata){
- /* try to get share-memory */
- if((shmid = shmget(SHMKEY, sizeof(struct databuf), 0600 | IFLAGS)) < 0){
- if(errno == EEXIST){
- /* exist, return its ID */
- shmid = shmget(SHMKEY, sizeof(struct databuf), 0600 | IPC_CREAT);
- if(shmid < 0){
- pr_error("--------share-memory getting: error!!!!!---------");
- }
- }
- else {
- pr_error("--------share-memory getting: other error!!!!!---------");
- }
- }
- if((*pdata = (struct databuf *)(shmat(shmid, 0, 0))) < 0 ){
- /* mapping share-memory */
- pr_error("--------share-memory mapping error!!!!!---------");
- }
- }
- /* function: get semaphore */
- int getsem(){
- /* try to get or create semaphore */
- if((semid = semget(SEMKEY, 1, 0600|IFLAGS)) < 0){
- if(errno == EEXIST){
- /* exist, reurn its ID */
- semid = semget(SEMKEY, 1, 0600 | IPC_CREAT);
- if(semid < 0){
- pr_error("--------semaphore getting ID: error!!!!!---------");
- }
- else{
- /* semaphore already exsit and return ID directly */
- return semid;
- }
- }
- else{
- pr_error("--------semaphore getting: error!!!!!---------");
- }
- }
- /* do semaphore init to 1 once just after semaphore creating */
- if(semctl(semid, 0, SETVAL, 1) < 0){
- pr_error("-----------semctl-----------");
- }
- return semid;
- }
- /* function remove share-memory and semaphore */
- void remove_s(){
- if(shmctl(shmid, IPC_RMID, NULL) < 0)
- pr_error("-----------shmctl when removing-----------");
- if(semctl(semid, 0, IPC_RMID) < 0)
- pr_error("-----------semctl when removing-----------");
- }
- /* function writer to share-memory */
- void writer(struct databuf *buf, int index, int value){
- /* get semaphore before update share-memory */
- semop(semid, &p1, 1);
- /* update share-memory */
- buf->d_buf[index] += value;
- /* release semaphore */
- semop(semid, &v1, 1);
- }
- /* function read to share-memory */
- void reader(struct databuf *buf, int index, int *rv){
- /* get semaphore before update share-memory */
- semop(semid, &p1, 1);
- /* get share-memory value */
- *rv = buf->d_buf[index];
- /* release semaphore */
- semop(semid, &v1, 1);
- }
- static void dump_camera_meta(csi_frame_ex_s *frame, int idx)
- {
- int i;
- //printf("%s\n", __func__);
- if (frame->frame_meta.type != CSI_META_TYPE_CAMERA)
- return;
- csi_camera_meta_s *meta_data = (csi_camera_meta_s *)frame->frame_meta.data;
- int meta_count = meta_data->count;
- csi_camera_meta_unit_s meta_unit;
- csi_camera_meta_id_e meta_id;
- if(meta_mode > 0){
- meta_id = (1<<(meta_mode - 1));
- csi_camera_frame_get_meta_unit(
- &meta_unit, meta_data, meta_id);
- }
- if(meta_mode == 1 || meta_mode == 2){
- /* camera_name and channel_id - which should keep same during testing */
- cur_metaint[idx] = meta_unit.int_value;
- if(pre_metaint[idx] == -1){
- pre_metaint[idx] = cur_metaint[idx];
- }
- else{
- if(cur_metaint[idx] != pre_metaint[idx]){
- pr_error("-----meta test fail: camera_id or channel_id changes during test--------");
- }
- pre_metaint[idx] = cur_metaint[idx];
- printf("-----meta test camera_name or channel_id:%d--------\n", cur_metaint[idx]);
- }
- }
- else if(meta_mode == 3){
- /* frame id - which should increase from 0 */
- if(cur_metaint[idx] == -1 && meta_unit.int_value != 1){
- pr_error("-----meta test fail: first frame ID is not 1--------\n");
- }
- cur_metaint[idx] = meta_unit.int_value;
- if(pre_metaint[idx] == -1){
- pre_metaint[idx] = cur_metaint[idx];
- }
- else{
- if(cur_metaint[idx] != (pre_metaint[idx]+1)){
- pr_error("-----meta test fail: frame_id is not continuous--------\n");
- }
- printf("-----meta test: meta_id: %d, frame_id:%d, previous_id: %d--------\n", meta_unit.id, cur_metaint[idx], pre_metaint[idx]);
- pre_metaint[idx] = cur_metaint[idx];
- }
- }
- else if(meta_mode == 4){
- /* timestamps - which should be larger or equal to previous */
- cur_metasec[idx] = meta_unit.time_value.tv_sec;
- cur_metausec[idx] = meta_unit.time_value.tv_usec;
- if(pre_metasec[idx] == -1){
- pre_metasec[idx] = cur_metasec[idx];
- pre_metausec[idx] = cur_metausec[idx];
- }
- else{
- if(cur_metasec[idx] <= pre_metasec[idx] && cur_metausec[idx] <= pre_metausec[idx]){
- pr_error("-----meta test fail: timestamp decrease--------");
- }
- printf("-----meta test time - second:%d--------\n", cur_metasec[idx]);
- printf("-----meta test time - usecond:%d--------\n", cur_metausec[idx]);
- pre_metasec[idx] = cur_metasec[idx];
- pre_metausec[idx] = cur_metausec[idx];
- }
- }
- else{
- /* means meta_mode = 0 */
- for (i = 0; i < meta_count; i++) {
- meta_id = (1<<i);
- csi_camera_frame_get_meta_unit(
- &meta_unit, meta_data, meta_id);
- printf("meta_id=%d, meta_type=%d, meta_value=%d\n",
- meta_unit.id, meta_unit.type, meta_unit.int_value);
- }
- }
- }
- /*
- function: parse the format and resolution to generate the output information used to save img
- Input args: index of channel will be tested whose order is decided when running
- Below information should be included:
- 1. how may planars which will be store in global int PLANE[] array
- 2. the pix bit which will be store in global int PBIT[] array
- 3. the bytes of each plane for the give channel to store in global int PLNS[][3] array
- 4. the line numbers of each plane for the give channel to store in global int LNN[][3] array
- 5. the bytes to store for each line size in each plane to store in global int LSZ[][3] array
- */
- static void parse_fmt_res(int cindx){
- /* fetch the format the resolution information */
- enum csi_pixel_fmt fmt = fenum[cindx];
- int iw = hres[cindx];
- int ih = vres[cindx];
- /* decide the pixel bit number */
- switch(fmt) {
- case CSI_PIX_FMT_RAW_10BIT:
- PBIT[cindx] = 10;
- break;
- case CSI_PIX_FMT_RAW_12BIT:
- PBIT[cindx] = 12;
- break;
- case CSI_PIX_FMT_RAW_14BIT:
- PBIT[cindx] = 14;
- break;
- case CSI_PIX_FMT_RAW_16BIT:
- PBIT[cindx] = 16;
- break;
- default:
- PBIT[cindx] = 8;
- break;
- }
- /* decide plane numbers, each plane size(byte) and line and line size*/
- switch(fmt) {
- case CSI_PIX_FMT_RAW_8BIT:
- PLNS[cindx][0] = iw * ih;
- LNN[cindx][0] = ih;
- LSZ[cindx][0] = iw * 2 ;
- LNNV[cindx][0] = iw;
- LSZV[cindx][0] = ih * 2 ;
- PLANE[cindx] = 1;
- NOSTRD[cindx] = 0;
- break;
- case CSI_PIX_FMT_RAW_10BIT:
- case CSI_PIX_FMT_RAW_12BIT:
- case CSI_PIX_FMT_RAW_14BIT:
- case CSI_PIX_FMT_RAW_16BIT:
- PLNS[cindx][0] = iw * ih * 2;
- LNN[cindx][0] = ih;
- LSZ[cindx][0] = iw * 2 ;
- LNNV[cindx][0] = iw;
- LSZV[cindx][0] = ih * 2 ;
- PLANE[cindx] = 1;
- NOSTRD[cindx] = 0;
- break;
- case CSI_PIX_FMT_RGB_INTEVLEAVED_888:
- case CSI_PIX_FMT_YUV_TEVLEAVED_444:
- PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8) * 3;
- LNN[cindx][0] = ih;
- LSZ[cindx][0] = (iw * PBIT[cindx] / 8) * 3;
- LNNV[cindx][0] = iw;
- LSZV[cindx][0] = (ih * PBIT[cindx] / 8) * 3;
- PLANE[cindx] = 1;
- break;
- case CSI_PIX_FMT_YUV_TEVLEAVED_422:
- PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8) * 2;
- LNN[cindx][0] = ih;
- LSZ[cindx][0] = (iw * PBIT[cindx] / 8) * 2;
- LNNV[cindx][0] = iw;
- LSZV[cindx][0] = (ih * PBIT[cindx] / 8) * 2;
- PLANE[cindx] = 1;
- break;
- case CSI_PIX_FMT_YUV_TEVLEAVED_420:
- PLNS[cindx][0] = ((iw * ih * PBIT[cindx] / 8) * 3) / 2;
- LNN[cindx][0] = ih;
- LSZ[cindx][0] = ((iw * PBIT[cindx] / 8) * 3) / 2;
- LNNV[cindx][0] = iw;
- LSZV[cindx][0] = ((ih * PBIT[cindx] / 8) * 3) / 2;
- PLANE[cindx] = 1;
- break;
- case CSI_PIX_FMT_BGR:
- case CSI_PIX_FMT_RGB_PLANAR_888:
- case CSI_PIX_FMT_YUV_PLANAR_444:
- PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
- PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8);
- PLNS[cindx][2] = (iw * ih * PBIT[cindx] / 8);
- LNN[cindx][0] = ih;
- LNN[cindx][1] = ih;
- LNN[cindx][2] = ih;
- LSZ[cindx][0] = LSZ[cindx][1] = LSZ[cindx][2] = (iw * PBIT[cindx] / 8);
- LNNV[cindx][0] = iw;
- LNNV[cindx][1] = iw;
- LNNV[cindx][2] = iw;
- LSZV[cindx][0] = LSZV[cindx][1] = LSZV[cindx][2] = (ih * PBIT[cindx] / 8);
- PLANE[cindx] = 3;
- break;
- case CSI_PIX_FMT_YUV_PLANAR_422:
- PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
- PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8) / 2;
- PLNS[cindx][2] = (iw * ih * PBIT[cindx] / 8) / 2;
- LNN[cindx][0] = ih;
- LNN[cindx][1] = ih / 2;
- LNN[cindx][2] = ih / 2;
- LSZ[cindx][0] = (iw * PBIT[cindx] / 8);
- LSZ[cindx][1] = LSZ[cindx][2] = (iw * PBIT[cindx] / 8) / 2;
- LNNV[cindx][0] = iw;
- LNNV[cindx][1] = iw /2;
- LNNV[cindx][2] = iw /2;
- LSZV[cindx][0] = (ih * PBIT[cindx] / 8);
- LSZV[cindx][1] = LSZV[cindx][2] = (ih * PBIT[cindx] / 8) / 2;
- PLANE[cindx] = 3;
- break;
- case CSI_PIX_FMT_YUV_PLANAR_420:
- PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
- PLNS[cindx][1] = PLNS[cindx][2] = (iw * ih * PBIT[cindx] / 8) / 4;
- LNN[cindx][0] = ih;
- LNN[cindx][1] = LNN[cindx][2] = ih / 4;
- LSZ[cindx][0] = (iw * PBIT[cindx] / 8);
- LSZ[cindx][1] = LSZ[cindx][2] = (iw * PBIT[cindx] / 8) / 4;
- LNNV[cindx][0] = iw;
- LNNV[cindx][1] = LNNV[cindx][2] = iw / 4;
- LSZV[cindx][0] = (ih * PBIT[cindx] / 8);
- LSZV[cindx][1] = LSZV[cindx][2] = (ih * PBIT[cindx] / 8) / 4;
- PLANE[cindx] = 3;
- break;
- case CSI_PIX_FMT_I420:
- case CSI_PIX_FMT_NV12:
- case CSI_PIX_FMT_YUV_SEMIPLANAR_420:
- PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
- PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8) / 2;
- LNN[cindx][0] = ih;
- LNN[cindx][1] = ih / 2;
- LSZ[cindx][0] = LSZ[cindx][1] = (iw * PBIT[cindx] / 8);
- LNNV[cindx][0] = iw;
- LNNV[cindx][1] = iw / 2;
- LSZV[cindx][0] = LSZV[cindx][1] = (ih * PBIT[cindx] / 8);
- PLANE[cindx] = 2;
- break;
- case CSI_PIX_FMT_YUV_SEMIPLANAR_422:
- PLNS[cindx][0] = PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8);
- LNN[cindx][0] = ih;
- LNN[cindx][1] = ih;
- LSZ[cindx][0] = LSZ[cindx][0] = (iw * PBIT[cindx] / 8);
- LNNV[cindx][0] = iw;
- LNNV[cindx][1] = iw;
- LSZV[cindx][0] = LSZV[cindx][0] = (ih * PBIT[cindx] / 8);
- PLANE[cindx] = 2;
- break;
- case CSI_PIX_FMT_YUV_SEMIPLANAR_444:
- PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
- PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8) * 2;
- LNN[cindx][0] = ih;
- LNN[cindx][1] = ih * 2;
- LSZ[cindx][0] = (iw * PBIT[cindx] / 8);
- LSZ[cindx][1] = (iw * PBIT[cindx] / 8);
- LNNV[cindx][0] = iw;
- LNNV[cindx][1] = iw * 2;
- LSZV[cindx][0] = (ih * PBIT[cindx] / 8);
- LSZV[cindx][1] = (ih * PBIT[cindx] / 8);
- PLANE[cindx] = 2;
- break;
- default:
- PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
- PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8) / 2;
- LNN[cindx][0] = ih;
- LNN[cindx][1] = ih / 2;
- LSZ[cindx][0] = LSZ[cindx][1] = (iw * PBIT[cindx] / 8);
- LNNV[cindx][0] = iw;
- LNNV[cindx][1] = iw / 2;
- LSZV[cindx][0] = LSZV[cindx][1] = (ih * PBIT[cindx] / 8);
- PLANE[cindx] = 2;
- break;
- }
- }
- /*
- function: store image of each frame
- input1: frame
- input2: channel index
- input3: target file point
- input4: reverse mdoe for rotating 90 and 270 degree
- */
- static void i_save(csi_frame_ex_s *framei, int cid, FILE *fp, int vmode)
- {
- int lindex = 0;
- int smode = 0;
- if( vmode == 0){
- if(framei->frame_data.stride[0] != LSZ[cid][0] && NOSTRD[cid] == 0){
- //if(NOSTRD[cid] == 0){
- smode = 1;
- printf("-------------In Stride mode, framei->img.strides[0]=%d---------------\n", framei->frame_data.stride[0]);
- }
- else{
- printf("-------------No Stride, framei->img.strides[0]=%d---------------\n", framei->frame_data.stride[0]);
- }
- for (int p = 0; p < PLANE[cid]; p++){
- /* loop for each planar */
- //printf("-------------framei->img.usr_addr[%d]=0x%llx---------------\n", p, framei->img.usr_addr[p]);
- lindex = 0;
- //int size = 0;
- if(smode == 0){
- /* no stride, write plane by plane*/
- printf("-------------No Stride, length is = %d---------------\n", PLNS[cid][p]);
- //while(size < PLNS[cid][p]){
- // size += fwrite(framei->img.usr_addr[p] + size, sizeof(char), PLNS[cid][p] - size, fp);
- // }
- fwrite(framei->frame_data.vir_addr[p], sizeof(char), PLNS[cid][p], fp);
- }
- else{
- /* stride mode, write line by line */
- for(int l = 0; l < LNN[cid][p]; l++){
- if(framei->frame_data.stride[p] == 0){
- printf("-------------Error: stride[%d] is 0---------------\n", p);
- lindex = LSZ[cid][p] * l;
- }
- else{
- /* for each plane, the strides[x] is the same */
- lindex = framei->frame_data.stride[0] * l;
- }
- fwrite(framei->frame_data.vir_addr[p] + lindex, sizeof(char), LSZ[cid][p], fp);
- }
- }
- }
- }
- else{
- if(framei->frame_data.stride[0] != LSZV[cid][0] && NOSTRD[cid] == 0){
- smode = 1;
- printf("-------------In Stride mode, framei->img.strides[0]=%d---------------\n", framei->frame_data.stride[0]);
- }
- else{
- printf("-------------No Stride, framei->img.strides[0]=%d---------------\n", framei->frame_data.stride[0]);
- }
- for (int p = 0; p < PLANE[cid]; p++){
- /* loop for each planar */
- //printf("-------------framei->img.usr_addr[%d]=0x%llx---------------\n", p, framei->img.usr_addr[p]);
- lindex = 0;
- int size = 0;
- if(smode == 0){
- /* no stride, write plane by plane*/
- printf("-------------No Stride, length is = %d---------------\n", PLNS[cid][p]);
- while(size < PLNS[cid][p]){
- size += fwrite(framei->frame_data.vir_addr[p] + size, sizeof(char), PLNS[cid][p] - size, fp);
- }
- }
- else{
- /* stride mode, write line by line */
- for(int l = 0; l < LNNV[cid][p]; l++){
- if(framei->frame_data.stride[p] == 0){
- printf("-------------Error: stride[%d] is 0---------------\n", p);
- lindex = LSZV[cid][p] * l;
- }
- else{
- /* for each plane, the strides[x] is the same */
- lindex = framei->frame_data.stride[0] * l;
- }
- fwrite(framei->frame_data.vir_addr[p] + lindex, sizeof(char), LSZV[cid][p], fp);
- }
- }
- }
- }
- }
- /*
- function: convert dma-buf file point to target address
- input1: framei
- input2: channel index
- */
- // static void handle_dma_buf(csi_frame_ex_s *framei, int cid)
- // {
- // if (frame->img.type == CSI_IMG_TYPE_DMA_BUF) {
- // void *p[3] = {0};
- // /*
- // The first plane which exists always.
- // All data for packed; Y data for planar or semi-planar
- // */
- // void *phyaddr = vi_mem_import(framei->img.dmabuf[0].fds);
- // p[0] = vi_mem_map(phyaddr) + framei->img.dmabuf[0].offset;
- // framei->img.usr_addr[0] = p[0];
- // /*
- // For other planes, in our solution, we only have plane[1] for
- // planar or sp; or no other plane for packed.
- // */
- // for (int i=1; i<PLANE[cid]; i++){
- // if (framei->img.dmabuf[i].offset != NULL){
- // p[i] = framei->img.dmabuf[i].offset + p[0];
- // framei->img.usr_addr[i] = p[i];
- // }
- // else{
- // printf("-------------DMA ERROR, no usr_addr for plane=%d---------------\n", i);
- // }
- // }
- // vi_mem_release(phyaddr);
- // }
- // }
- /*
- function: save data as image
- input1: channel index
- */
- static void* save_camera_img(void * idx)
- {
- int index = *(int*)(idx);
- free(idx);
- char fname[512];
- char fidname[256];
- FILE *fp;
- char fidc[128];
- int fcount;
- int fidi = fid[index];
- int cid = channelIdx[index];
- int hresi = hres[index];
- int vresi = vres[index];
- enum csi_pixel_fmt fmt = fenum[index];
- csi_frame_ex_s *framei = &frame[index];
- int vmode = 0;
- if(framei->frame_info.width == vresi && framei->frame_info.height == hresi && vresi != hresi){
- vmode = 1;
- vresi = framei->frame_info.height;
- hresi = framei->frame_info.width;
- }
- /* generate the image name */
- fcount = fidi%tframes;
- sprintf(fname, "%s%s%s%s%d%s%d%s%d%s%d%s%d%s%s", path, "/img_", dname, "_", PLANE[index], "P_", cid, "_", hresi, "x", vresi, "_", fcount, ".", fmtArray[fmt]);
- /* dma-buf to address */
- // handle_dma_buf(framei, index);
- if((fp = fopen(fname, "wb")) == NULL){
- printf("Error: Can't open file\n");
- return NULL;
- }
- /* data saving */
- i_save(framei, index, fp, vmode);
- fclose(fp);
- /* frame ID saving */
- sprintf(fidc, "%d\n", fidi);
- sprintf(fidname, "%s%s%s%s%d%s", path, "/fid_", dname, "_chn_", cid, ".txt");
- if((fp = fopen(fidname, "a+")) == NULL){
- printf("Error: Can't open file\n");
- return NULL;
- }
- fwrite(fidc, sizeof(char), strlen(fidc), fp);
- fclose(fp);
- if(meta_mode >= 0){
- dump_camera_meta(framei, index);
- }
- //csi_camera_frame_unlock(cam_handle, framei);
- csi_camera_put_frame(framei);
- // csi_frame_release(framei);
- if (onoffMode == 1 && fNumInc[index] % onoffFrame == 0){
- afterOnOff[index] = onoffDrop;
- // stop stream, sleep, start stream
- csi_camera_channel_stop(cam_handle, CAMERA_CHANNEL_ID[index]);
- //sleep(1);
- csi_camera_channel_start(cam_handle, CAMERA_CHANNEL_ID[index]);
- }
- return NULL;
- }
- /*
- function: save data as stream
- input1: channel index
- */
- static void* save_camera_stream(void *idx)
- {
- int index = *(int*)(idx);
- free(idx);
- FILE *fp;
- char fname[256];
- int cid = channelIdx[index];
- int hresi = hres[index];
- int vresi = vres[index];
- enum csi_pixel_fmt fmt = fenum[index];
- csi_frame_ex_s *framei = &frame[index];
- int vmode = 0;
- if(framei->frame_info.width == vresi && framei->frame_info.height == hresi && vresi != hresi){
- vmode = 1;
- vresi = framei->frame_info.height;
- hresi = framei->frame_info.width;
- }
- /* generate stream name - for each time it is the same name */
- sprintf(fname, "%s%s%s%s%d%s%d%s%d%s%d%s%s", path, "/str_", dname, "_", PLANE[index], "P_", cid, "_", hresi, "x", vresi, ".", fmtArray[fmt]);
- // handle_dma_buf(framei, index);
- if((fp = fopen(fname, "ab+")) == NULL){
- printf("Error: Can't open file\n");
- return NULL;
- }
- i_save(framei, index, fp, vmode);
- fclose(fp);
- if(meta_mode >= 0){
- dump_camera_meta(framei, index);
- }
- //csi_camera_frame_unlock(cam_handle, framei);
- csi_camera_put_frame(framei);
- // csi_frame_release(framei);
- if (onoffMode == 1 && fNumInc[index] % onoffFrame == 0){
- afterOnOff[index] = onoffDrop;
- // stop stream, sleep, start stream
- csi_camera_channel_stop(cam_handle, CAMERA_CHANNEL_ID[index]);
- //sleep(1);
- csi_camera_channel_start(cam_handle, CAMERA_CHANNEL_ID[index]);
- }
- return NULL;
- }
- // 同时配置多个参数
- static int set_properties(csi_cam_handle_t cam_handle, char *pArgs)
- {
- csi_camera_properties_s properties;
- csi_camera_property_s property[30];
- char *pDelim=":/";
- int pid;
- int ptype;
- int pvalueInt;
- char *pvalueStr;
- char *pFirst;
- /*
- parse multi-properties which delimited by : or /
- 1. / is used to seprate multi properties
- 2. : is used to sperate pid:type:value
- for example: 1:2:1/2:2:1/3:1:90
- */
- pFirst = strtok(pArgs, pDelim);
- int i = 0;
- while(pFirst != NULL){
- pid = atoi(pFirst);
- property[i].id = pid + CSI_CAMERA_PID_BASE;
- /*
- property type difinition:
- CSI_CAMERA_PROPERTY_TYPE_INTEGER = 1,
- CSI_CAMERA_PROPERTY_TYPE_BOOLEAN = 2,
- CSI_CAMERA_PROPERTY_TYPE_ENUM = 3,
- CSI_CAMERA_PROPERTY_TYPE_STRING = 7,
- CSI_CAMERA_PROPERTY_TYPE_BITMASK = 8,
- */
- ptype = atoi(strtok(NULL, pDelim));
- property[i].type = ptype;
- if (ptype == CSI_CAMERA_PROPERTY_TYPE_STRING) {
- pvalueStr = strtok(NULL, pDelim);
- strcpy(property[i].value.str_value, pvalueStr);
- }
- else {
- pvalueInt = atoi(strtok(NULL, pDelim));
- property[i].value.int_value = pvalueInt;
- }
- i++;
- pFirst = strtok(NULL, pDelim);
- }
- /* set multi-properties(here the property number is i) by calling API just one time */
- properties.count = i;
- properties.property = property;
- if (csi_camera_set_property(cam_handle, &properties) < 0) {
- printf("set_property fail!\n");
- return -1;
- }
- printf("set_property ok!\n");
- return 0;
- }
- static enum csi_pixel_fmt parse_format(char *fmt)
- {
- for(int i=0; i<fmtMAX; i++){
- if(strstr(fmtArray[i], fmt)){
- return CSI_PIX_FMT_I420 + i;
- }
- }
- return CSI_PIX_FMT_NV12;
- }
|