camera_test1.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276
  1. /*
  2. * Copyright (C) 2021-2022 Alibaba Group Holding Limited
  3. * Author: LuChongzhi <chongzhi.lcz@alibaba-inc.com>; Minxiong Tian <minxiong.tmx@alibaba-inc.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <pthread.h>
  13. #include <unistd.h>
  14. #include <error.h>
  15. #include <errno.h>
  16. #include <sys/mman.h>
  17. #include <sys/ipc.h>
  18. #include <sys/shm.h>
  19. #include <sys/sem.h>
  20. #include "csi_camera_dev_api.h"
  21. /* macros for share memory and semaphore */
  22. #define SHMKEY (key_t)0x39126
  23. #define SEMKEY (key_t)0x49126
  24. #define IFLAGS (IPC_CREAT|IPC_EXCL)
  25. #define LOG_LEVEL 2
  26. #define LOG_PREFIX "camera_demo1"
  27. #include <syslog.h>
  28. #include <csi_frame_ex.h>
  29. #include <csi_camera.h>
  30. #ifdef PLATFORM_SIMULATOR
  31. #include "apputilities.h"
  32. #endif
  33. #define PAGE_SIZE 1024
  34. #define PAGE_ALIGN(addr) (void *)(((int)(addr)+PAGE_SIZE-1)&~( PAGE_SIZE-1))
  35. /* data store in share-memory */
  36. struct databuf {
  37. int d_buf[2];
  38. };
  39. static void dump_camera_meta(csi_frame_ex_s *frame, int idx);
  40. static void* save_camera_img(void *);
  41. static void* save_camera_stream(void *);
  42. static int set_properties(csi_cam_handle_t cam_handle, char *pArgs);
  43. static enum csi_pixel_fmt parse_format(char *fmt);
  44. // static void handle_dma_buf(csi_frame_s *framei, int cid);
  45. //extern int csi_camera_frame_unlock(csi_cam_handle_t cam_handle, csi_frame_s *frame);
  46. extern int csi_camera_put_frame(csi_frame_ex_s *frame);
  47. static void i_save(csi_frame_ex_s *framei, int cid, FILE *fp, int vmode);
  48. static void parse_fmt_res(int cindx);
  49. static void getseg(struct databuf* *pdata);
  50. static int getsem();
  51. static void remove_s();
  52. static void writer(struct databuf *buf, int index, int value);
  53. static void reader(struct databuf *buf, int index, int * rv);
  54. static int pr_error(char *mess);
  55. extern int csi_camera_set_pp_path_param(csi_cam_handle_t cam_handle, uint16_t line_num,uint16_t buf_mode);
  56. extern void *vi_plink_create(csi_camera_channel_cfg_s *chn_cfg);
  57. extern void vi_plink_release(void * plink);
  58. extern void display_camera_frame(void * plink, csi_frame_ex_s *frame);
  59. #define TEST_DEVICE_NAME "/dev/video0"
  60. #define CSI_CAMERA_TRUE 1
  61. #define CSI_CAMERA_FALSE 0
  62. #define chnMAX 8
  63. #define fmtMAX 19
  64. csi_cam_handle_t cam_handle;
  65. char *prog_name;
  66. int Soff = 0;
  67. static char device[CSI_CAMERA_NAME_MAX_LEN]; /* target video device like /dev/video0 */
  68. static char path[128] = "./"; /* output path */
  69. static int channelIdx[chnMAX]; /* channel information like 8 */
  70. enum csi_pixel_fmt fenum[chnMAX];
  71. int fid[chnMAX] = {0};
  72. int tframes = 4;
  73. csi_camera_channel_id_e CAMERA_CHANNEL_ID[chnMAX];
  74. /* File local Global array to store information which will be used when storig images */
  75. static int PLANE[chnMAX] = {0};
  76. static int PBIT[chnMAX] = {0};
  77. static int PLNS[chnMAX][3] = {0};
  78. static int LNN[chnMAX][3] = {0};
  79. static int LSZ[chnMAX][3] = {0};
  80. static int LNNV[chnMAX][3] = {0}; /* for rotation 90/270 */
  81. static int LSZV[chnMAX][3] = {0}; /* for rotation 90/270 */
  82. static int NOSTRD[chnMAX] = {0};
  83. /* local global array for meta data verify */
  84. static int cur_metaint[chnMAX] = {-1, -1, -1, -1};
  85. static int pre_metaint[chnMAX] = {-1, -1, -1, -1};
  86. static int cur_metasec[chnMAX] = {-1, -1, -1, -1};
  87. static int pre_metasec[chnMAX] = {-1, -1, -1, -1};
  88. static int cur_metausec[chnMAX] = {-1, -1, -1, -1};
  89. static int pre_metausec[chnMAX] = {-1, -1, -1, -1};
  90. static int shmid, semid;
  91. struct sembuf p1 = {0, -1, 0}, v1 = {0, 1, 0};
  92. int meta_mode = -1;
  93. int flashMode = 0;
  94. int fNumInc[chnMAX] = {0};
  95. int fCount = 1;
  96. int onoffMode = 0;
  97. int afterOnOff[chnMAX];
  98. int onoffDrop = 4;
  99. int onoffFrame = 0;
  100. int ooNum[chnMAX] = {0};
  101. int ofTop = 30;
  102. csi_frame_ex_s frame[chnMAX];
  103. pthread_t tid[chnMAX]={0};
  104. int hres[chnMAX], vres[chnMAX]; /* resolution information like 640x480 */
  105. int idxArray[chnMAX][10]={0};
  106. static char *dname;
  107. static int chNum = 0;
  108. char fmtArray[fmtMAX][50] = {
  109. "CSI_PIX_FMT_I420",
  110. "CSI_PIX_FMT_NV12",
  111. "CSI_PIX_FMT_BGR",
  112. "CSI_PIX_FMT_RAW_8BIT",
  113. "CSI_PIX_FMT_RAW_10BIT",
  114. "CSI_PIX_FMT_RAW_12BIT",
  115. "CSI_PIX_FMT_RAW_14BIT",
  116. "CSI_PIX_FMT_RAW_16BIT",
  117. "CSI_PIX_FMT_RGB_PLANAR_888",
  118. "CSI_PIX_FMT_RGB_INTEVLEAVED_888",
  119. "CSI_PIX_FMT_YUV_PLANAR_422",
  120. "CSI_PIX_FMT_YUV_PLANAR_420",
  121. "CSI_PIX_FMT_YUV_PLANAR_444",
  122. "CSI_PIX_FMT_YUV_SEMIPLANAR_422",
  123. "CSI_PIX_FMT_YUV_SEMIPLANAR_420",
  124. "CSI_PIX_FMT_YUV_SEMIPLANAR_444",
  125. "CSI_PIX_FMT_YUV_TEVLEAVED_422",
  126. "CSI_PIX_FMT_YUV_TEVLEAVED_420",
  127. "CSI_PIX_FMT_YUV_TEVLEAVED_444"
  128. };
  129. void usage()
  130. {
  131. fprintf (stderr,
  132. "usage: %s [options]\n"
  133. "Options:\n"
  134. "\t-D dev target video device like /dev/video0\n"
  135. "\t-R resolution format is like 640x480, use 640x480/1092x1080 for multi channel output\n"
  136. "\t-F format like NV12, use NV12/NV12 to support multi channel output\n"
  137. "\t-C channel_index channel index defined in dts, index from 0, use 0/2 for multi channel output\n"
  138. "\t-M test mode 0: save as image; 1: save as stream file; 2: output to plink; 3. performace test\n"
  139. "\t-N number for frames 0: record forever; others: the recorded frame numbers, use 30/30 from multi channel output\n"
  140. "\t-n number of frames to save if not given, 4 is used\n"
  141. "\t-P Property id:type:value, use id:type:value/id:type:value for multi property setting\n"
  142. "\t-p output path store output file in the give path\n"
  143. "\t-S turn off stride mode if given, turn off stride mode\n"
  144. "\t-t stream turn on/off test if will turn off stream after several streams then turn on\n"
  145. "\t-s turn off sram mode if given, turn off sram mode between ISP/DSP and DSP/ISP-RY\n"
  146. "\t-m disable DW DMA-BUF if given, turn off dma-buf mode\n"
  147. "\t-f enable LED flash mode if given, enable LED flash mode for odd and even frame feature in lightA production board\n"
  148. "\t-i nubmer of process which needs to do IPC, use for multi-video and mutli-process test scenarios\n"
  149. "\t-y meta-data test 0 - meta dump all all elements; 1 - meta verify for CAMERA_NAME;\n"
  150. " 2 - meta verify for CHANNEL_ID; 3 - meta verify for FRAME_ID;\n"
  151. " 4 - meta verify for TIMESTAMP.\n"
  152. " 200 - meta verify for all elements\n"
  153. , prog_name
  154. );
  155. }
  156. int main(int argc, char *argv[])
  157. {
  158. bool running = 0;
  159. csi_camera_info_s camera_info;
  160. int opt;
  161. char *resDelim = "xX/";
  162. int outMode = 0;
  163. int fNum[chnMAX] = {0};
  164. char pArgs[500] = {'\0'}; /* store property args */
  165. char *devDelim = "/";
  166. char *sCur;
  167. int idx = 0;
  168. int ret = 0;
  169. csi_camera_event_type_e CAMERA_CHANNEL_EVENT_TYPE[chnMAX];
  170. struct timeval init_time, cur_time;
  171. memset(&init_time, 0, sizeof(init_time));
  172. memset(&cur_time, 0, sizeof(cur_time));
  173. unsigned long video_open = 0;
  174. unsigned long channel_open = 0;
  175. unsigned long channel_start = 0;
  176. unsigned long first_frame = 0;
  177. unsigned long total_frame = 0;
  178. float fps = 0.0;
  179. int sramMode = 1;
  180. /* data for share-memory */
  181. struct databuf *buf;
  182. int mi = 0;
  183. int srv1 = 0, srv2 = 0;
  184. prog_name = argv[0];
  185. while ((opt = getopt(argc, argv, "t:D:R:F:C:M:hN:P:p:Smi:y:fsn:")) != EOF) {
  186. switch(opt) {
  187. case 'D':
  188. strcpy(device, optarg);
  189. strtok(optarg, devDelim);
  190. dname=strtok(NULL, devDelim);
  191. continue;
  192. case 'p':
  193. strcpy(path, optarg);
  194. continue;
  195. case 'S':
  196. Soff = 1;
  197. continue;
  198. case 't':
  199. onoffMode = 1;
  200. onoffFrame = atoi(optarg);
  201. continue;
  202. case 's':
  203. sramMode = 0;
  204. case 'f':
  205. flashMode = 1;
  206. continue;
  207. case 'P':
  208. strcpy(pArgs, optarg);
  209. continue;
  210. case 'R':
  211. idx = 0;
  212. sCur=strtok(optarg, resDelim);
  213. while (sCur != NULL){
  214. if (idx % 2 == 0)
  215. hres[idx/2] = atoi(sCur);
  216. if (idx % 2 == 1)
  217. vres[idx/2] = atoi(sCur);
  218. sCur=strtok(NULL, resDelim);
  219. idx++;
  220. }
  221. continue;
  222. case 'M':
  223. outMode = atoi(optarg);
  224. continue;
  225. case 'i':
  226. mi = atoi(optarg);
  227. continue;
  228. case 'y':
  229. meta_mode = atoi(optarg);
  230. continue;
  231. case 'N':
  232. for(int j=0; j<chnMAX; j++)
  233. fNum[j] = atoi(optarg);
  234. continue;
  235. case 'n':
  236. tframes = atoi(optarg);
  237. continue;
  238. case 'F':
  239. idx = 0;
  240. sCur=strtok(optarg, devDelim);
  241. while (sCur != NULL){
  242. fenum[idx] = parse_format(sCur);
  243. sCur=strtok(NULL, devDelim);
  244. idx++;
  245. }
  246. continue;
  247. case 'C':
  248. idx = 0;
  249. sCur=strtok(optarg, devDelim);
  250. while (sCur != NULL){
  251. channelIdx[idx] = atoi(sCur);
  252. sCur=strtok(NULL, devDelim);
  253. idx++;
  254. }
  255. chNum = idx;
  256. continue;
  257. case '?':
  258. case 'h':
  259. default:
  260. usage();
  261. return 1;
  262. }
  263. }
  264. /* get semaphore ID and share-memory ID if mi >=2 */
  265. if(mi >= 2){
  266. semid = getsem();
  267. getseg(&buf);
  268. printf("------IPC mode enable - finish-------\n");
  269. }
  270. /* init the target channel ID and channel event type array */
  271. for (int j=0; j<chNum; j++){
  272. CAMERA_CHANNEL_ID[j] = CSI_CAMERA_CHANNEL_0 + channelIdx[j];
  273. CAMERA_CHANNEL_EVENT_TYPE[j] = CSI_CAMERA_EVENT_TYPE_CHANNEL0 + channelIdx[j];
  274. }
  275. if (fNum[0] == 0){
  276. running = 1;
  277. printf("------running = 1-------\n");
  278. }
  279. // 打印HAL接口版本号
  280. csi_api_version_u version;
  281. csi_camera_get_version(&version);
  282. printf("Camera HAL version: %d.%d\n", version.major, version.minor);
  283. // 获取设备中,所有的Camera
  284. struct csi_camera_infos camera_infos;
  285. memset(&camera_infos, 0, sizeof(camera_infos));
  286. csi_camera_query_list(&camera_infos);
  287. // 打印所有设备所支持的Camera
  288. for (int i = 0; i < camera_infos.count; i++) {
  289. camera_info = camera_infos.info[i];
  290. printf("Camera[%d]: camera_name='%s', device_name='%s', bus_info='%s', capabilities=0x%08x\n",
  291. i,
  292. camera_info.camera_name, camera_info.device_name, camera_info.bus_info,
  293. camera_info.capabilities);
  294. printf("Camera[%d] caps are:\n",
  295. i); /* The caps are: Video capture, metadata capture */
  296. for (int j = 1; j <= 0x08000000; j = j << 1) {
  297. switch (camera_info.capabilities & j) {
  298. case CSI_CAMERA_CAP_VIDEO_CAPTURE:
  299. printf("\t camera_infos.info[%d]:Video capture,\n", i);
  300. break;
  301. case CSI_CAMERA_CAP_META_CAPTURE:
  302. printf("\t camera_infos.info[%d] metadata capture,\n", i);
  303. break;
  304. default:
  305. if (camera_info.capabilities & j) {
  306. printf("\t camera_infos.info[%d] unknown capabilities(0x%08x)\n", i,
  307. camera_info.capabilities & j);
  308. }
  309. break;
  310. }
  311. }
  312. }
  313. // 打开Camera设备获取句柄,作为后续操对象
  314. strcpy(camera_info.device_name, device);
  315. gettimeofday(&init_time, 0);
  316. csi_camera_open(&cam_handle, camera_info.device_name);
  317. gettimeofday(&cur_time, 0);
  318. video_open = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
  319. // 获取Camera支持的工作模式
  320. struct csi_camera_modes camera_modes;
  321. csi_camera_get_modes(cam_handle, &camera_modes);
  322. // 打印camera所支持的所有工作模式
  323. printf("Camera:'%s' modes are:\n", device);
  324. printf("{\n");
  325. for (int i = 0; i < camera_modes.count; i++) {
  326. printf("\t mode_id=%d: description:'%s'\n",
  327. camera_modes.modes[i].mode_id, camera_modes.modes[i].description);
  328. }
  329. printf("}\n");
  330. // 设置camera的工作模式及其配置
  331. csi_camera_mode_cfg_s camera_cfg;
  332. camera_cfg.mode_id = 1;
  333. camera_cfg.calibriation = NULL; // 采用系统默认配置
  334. camera_cfg.lib3a = NULL; // 采用系统默认配置
  335. csi_camera_set_mode(cam_handle, &camera_cfg);
  336. // 获取单个可控单元的属性
  337. csi_camera_property_description_s description;
  338. // 轮询获取所有可控制的单元
  339. printf("all properties are:\n");
  340. description.id = CSI_CAMERA_PID_HFLIP;
  341. while (!csi_camera_query_property(cam_handle, &description)) {
  342. switch (description.type) {
  343. case (CSI_CAMERA_PROPERTY_TYPE_INTEGER):
  344. printf("id=0x%08x type=%d default=%d value=%d\n",
  345. description.id, description.type,
  346. description.default_value.int_value, description.value.int_value);
  347. break;
  348. case (CSI_CAMERA_PROPERTY_TYPE_BOOLEAN):
  349. printf("id=0x%08x type=%d default=%d value=%d\n",
  350. description.id, description.type,
  351. description.default_value.bool_value, description.value.bool_value);
  352. break;
  353. case (CSI_CAMERA_PROPERTY_TYPE_ENUM):
  354. printf("id=0x%08x type=%d default=%d value=%d\n",
  355. description.id, description.type,
  356. description.default_value.enum_value, description.value.enum_value);
  357. break;
  358. case (CSI_CAMERA_PROPERTY_TYPE_STRING):
  359. printf("id=0x%08x type=%d default=%s value=%s\n",
  360. description.id, description.type,
  361. description.default_value.str_value, description.value.str_value);
  362. break;
  363. case (CSI_CAMERA_PROPERTY_TYPE_BITMASK):
  364. printf("id=0x%08x type=%d default=%x value=%x\n",
  365. description.id, description.type,
  366. description.default_value.bitmask_value, description.value.bitmask_value);
  367. break;
  368. default:
  369. LOG_E("error type!\n");
  370. break;
  371. }
  372. description.id |= CSI_CAMERA_FLAG_NEXT_CTRL;
  373. }
  374. if (pArgs[0] != '\0'){
  375. set_properties(cam_handle, pArgs);
  376. }
  377. // 查询输出channel
  378. csi_camera_channel_cfg_s chn_cfg[chnMAX];
  379. for (int j=0; j<chNum; j++){
  380. chn_cfg[j].chn_id = CAMERA_CHANNEL_ID[j];
  381. csi_camera_channel_query(cam_handle, &chn_cfg[j]);
  382. if (chn_cfg[j].status != CSI_CAMERA_CHANNEL_CLOSED) {
  383. printf("Can't open channel: %d\n", CAMERA_CHANNEL_ID[j]);
  384. exit(-1);
  385. }
  386. }
  387. // 打开输出channel
  388. if (sramMode == 1){
  389. csi_camera_set_pp_path_param(cam_handle,0,1);
  390. }
  391. csi_cam_event_handle_t event_handle;
  392. csi_camera_event_subscription_s subscribe;
  393. for (int j=0; j<chNum; j++){
  394. chn_cfg[j].chn_id = CAMERA_CHANNEL_ID[j];
  395. chn_cfg[j].frm_cnt = fCount;
  396. chn_cfg[j].img_fmt.width = hres[j];
  397. chn_cfg[j].img_fmt.height = vres[j];
  398. chn_cfg[j].img_fmt.pix_fmt = fenum[j];
  399. chn_cfg[j].img_type = CSI_IMG_TYPE_DMA_BUF;
  400. chn_cfg[j].meta_fields = CSI_CAMERA_META_DEFAULT_FIELDS;
  401. chn_cfg[j].capture_type = CSI_CAMERA_CHANNEL_CAPTURE_VIDEO |
  402. CSI_CAMERA_CHANNEL_CAPTURE_META;
  403. parse_fmt_res(j);
  404. gettimeofday(&init_time, 0);
  405. ret = csi_camera_channel_open(cam_handle, &chn_cfg[j]);
  406. if (ret) {
  407. exit(-1);
  408. }
  409. gettimeofday(&cur_time, 0);
  410. channel_open = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
  411. }
  412. // 订阅Event
  413. csi_camera_create_event(&event_handle, cam_handle);
  414. for (int j=0; j<chNum; j++){
  415. subscribe.type =
  416. CSI_CAMERA_EVENT_TYPE_CAMERA; // 订阅Camera的ERROR事件
  417. subscribe.id = CSI_CAMERA_EVENT_WARNING | CSI_CAMERA_EVENT_ERROR;
  418. csi_camera_subscribe_event(event_handle, &subscribe);
  419. subscribe.type =
  420. CAMERA_CHANNEL_EVENT_TYPE[j]; // 订阅Channel0的FRAME_READY事件
  421. subscribe.id = CSI_CAMERA_CHANNEL_EVENT_FRAME_READY |
  422. CSI_CAMERA_CHANNEL_EVENT_OVERFLOW;
  423. csi_camera_subscribe_event(event_handle, &subscribe);
  424. }
  425. if ( flashMode == 1){
  426. csi_camera_floodlight_led_set_flash_bright(cam_handle, 500); //500ma
  427. csi_camera_projection_led_set_flash_bright(cam_handle, 500); //500ma
  428. csi_camera_projection_led_set_mode(cam_handle, LED_IR_ENABLE);
  429. csi_camera_floodlight_led_set_mode(cam_handle, LED_IR_ENABLE);
  430. csi_camera_led_enable(cam_handle, LED_FLOODLIGHT_PROJECTION);
  431. }
  432. // start all channels
  433. for (int j=0; j<chNum; j++){
  434. gettimeofday(&init_time, 0);
  435. csi_camera_channel_start(cam_handle, CAMERA_CHANNEL_ID[j]);
  436. gettimeofday(&cur_time, 0);
  437. channel_start = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
  438. }
  439. gettimeofday(&init_time, 0);
  440. // 处理订阅的Event
  441. struct csi_camera_event event;
  442. int fnumTotal = fNum[0] * chNum;
  443. int frameTotal = fnumTotal;
  444. while (running || fnumTotal > 0 ) {
  445. int timeout = -1; // unit: ms, -1 means wait forever, or until error occurs
  446. csi_camera_get_event(event_handle, &event, timeout);
  447. printf("%s event.type = %d, event.id = %d\n", __func__, event.type, event.id);
  448. if(event.type == CSI_CAMERA_EVENT_TYPE_CAMERA){
  449. switch (event.id) {
  450. case CSI_CAMERA_EVENT_ERROR:
  451. // do sth.
  452. printf("-------get CAMERA EVENT CSI_CAMERA_EVENT_ERROR!----------\n");
  453. break;
  454. case CSI_CAMERA_EVENT_WARNING:
  455. printf("-------get CAMERA EVENT CSI_CAMERA_EVENT_WRN,RC: %s-------\n",event.bin);
  456. break;
  457. default:
  458. break;
  459. }
  460. }
  461. for (int j=0; j<chNum; j++){
  462. if(event.type == CAMERA_CHANNEL_EVENT_TYPE[j]){
  463. switch (event.id) {
  464. case CSI_CAMERA_CHANNEL_EVENT_OVERFLOW:
  465. printf("-------get channel EVENT CSI_CAMERA_CHANNEL_EVENT_OVERFLOW-------\n");
  466. break;
  467. case CSI_CAMERA_CHANNEL_EVENT_FRAME_READY: {
  468. int read_frame_count = csi_camera_get_frame_count(cam_handle,
  469. CAMERA_CHANNEL_ID[j]);
  470. printf("-------read_frame_count=%d-------\n", read_frame_count);
  471. for (int i = 0; i < fCount; i++) {
  472. if (tid[j] != 0){
  473. /* wait for previous image save thread end */
  474. pthread_join(tid[j], NULL);
  475. }
  476. csi_camera_get_frame(cam_handle, CAMERA_CHANNEL_ID[j], &frame[j], timeout);
  477. if (afterOnOff[j] != 0 ){
  478. /* drop the first event after on/off operation */
  479. afterOnOff[j]--;
  480. csi_camera_put_frame(&frame[j]);
  481. // csi_frame_release(&frame[j]);
  482. continue;
  483. }
  484. fNum[j]--;
  485. fNumInc[j]++;
  486. if (fNum[j] < 0 && running == 0 ){
  487. //csi_camera_frame_unlock(cam_handle, &frame[j]);
  488. csi_camera_put_frame(&frame[j]);
  489. // csi_frame_release(&frame[j]);
  490. continue;
  491. }
  492. #ifdef PLATFORM_SIMULATOR
  493. show_frame_image(frame[j].img.usr_addr[0], frame[j].img.height, frame.img.width);
  494. #endif
  495. fid[j]++;
  496. fnumTotal--;
  497. if (outMode == 0){
  498. int * tIdx = malloc(sizeof(int));
  499. *tIdx = j;
  500. /* submit thread to save image for current channel then we can go to handle other channel */
  501. pthread_create(&tid[j], NULL, save_camera_img, (void *)tIdx);
  502. }
  503. else if (outMode == 1){
  504. int * tIdx = malloc(sizeof(int));
  505. *tIdx = j;
  506. pthread_create(&tid[j], NULL, save_camera_stream, (void *)tIdx);
  507. }
  508. else if(outMode == 3){
  509. /* mode 3 only do performance test, no actual image saving */
  510. gettimeofday(&cur_time, 0);
  511. if (fid[j] == 1){
  512. /* first frame */
  513. 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;
  514. }
  515. if (fnumTotal == 0){
  516. /* last frame */
  517. total_frame = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
  518. fps = (float)frameTotal / total_frame * 1000000.0f;
  519. printf("\n");
  520. printf("\n");
  521. printf("Performance data:\n");
  522. printf("video_open:%lu ms\n", video_open/1000);
  523. printf("channel_open:%lu ms\n", channel_open/1000);
  524. printf("channel_start:%lu ms\n", channel_start/1000);
  525. printf("first_frame:%lu ms\n", first_frame/1000);
  526. printf("fps:%f fps\n", fps);
  527. printf("\n");
  528. printf("\n");
  529. }
  530. /* for mode 3, unlock in this branch, for mode 0,1 unlock in thread */
  531. //csi_camera_frame_unlock(cam_handle, &frame[j]);
  532. csi_camera_put_frame(&frame[j]);
  533. }
  534. else{
  535. chn_cfg[j].chn_id = j;
  536. csi_camera_channel_query(cam_handle, &chn_cfg[j]);
  537. // display_camera_frame(cam_handle, &chn_cfg[j], &frame[j]);
  538. //csi_camera_frame_unlock(cam_handle, &frame[j]);
  539. csi_camera_put_frame(&frame[j]);
  540. }
  541. }
  542. break;
  543. }
  544. default:
  545. break;
  546. }
  547. }
  548. }
  549. }
  550. /* for IPC, update finish status to share-memory */
  551. if(mi >= 2){
  552. writer(buf, 0, 1);
  553. }
  554. for (int j=0; j<chNum; j++){
  555. /* for IPC only do stop when share memory value equals mi */
  556. if(mi >= 2){
  557. while (1){
  558. reader(buf, 0, &srv1);
  559. if (srv1 != mi){
  560. sleep(2);
  561. }
  562. else{
  563. /* update the second value in share-memory which is used to decide whether to remove share-memory */
  564. writer(buf, 1, 1);
  565. reader(buf, 1, &srv2);
  566. if (srv2 == mi){
  567. /* I am the last process to update the buf[1], remove the share-memory */
  568. remove_s();
  569. printf("------IPC mode: remove-------\n");
  570. }
  571. break;
  572. }
  573. }
  574. }
  575. csi_camera_channel_stop(cam_handle, CAMERA_CHANNEL_ID[j]);
  576. }
  577. if ( flashMode == 1){
  578. csi_camera_led_disable(cam_handle, LED_FLOODLIGHT_PROJECTION);
  579. }
  580. usleep (1000000);
  581. // 取消订阅某一个event, 也可以直接调用csi_camera_destory_event,结束所有的订阅
  582. for (int j=0; j<chNum; j++){
  583. subscribe.type = CAMERA_CHANNEL_EVENT_TYPE[j];
  584. subscribe.id = CSI_CAMERA_CHANNEL_EVENT_FRAME_READY;
  585. csi_camera_unsubscribe_event(event_handle, &subscribe);
  586. }
  587. csi_camera_destory_event(event_handle);
  588. for (int j=0; j<chNum; j++){
  589. csi_camera_channel_close(cam_handle, CAMERA_CHANNEL_ID[j]);
  590. }
  591. csi_camera_close(cam_handle);
  592. }
  593. int pr_error(char *mess){
  594. perror(mess);
  595. exit(1);
  596. }
  597. /* function: get or create share-memory*/
  598. void getseg(struct databuf* *pdata){
  599. /* try to get share-memory */
  600. if((shmid = shmget(SHMKEY, sizeof(struct databuf), 0600 | IFLAGS)) < 0){
  601. if(errno == EEXIST){
  602. /* exist, return its ID */
  603. shmid = shmget(SHMKEY, sizeof(struct databuf), 0600 | IPC_CREAT);
  604. if(shmid < 0){
  605. pr_error("--------share-memory getting: error!!!!!---------");
  606. }
  607. }
  608. else {
  609. pr_error("--------share-memory getting: other error!!!!!---------");
  610. }
  611. }
  612. if((*pdata = (struct databuf *)(shmat(shmid, 0, 0))) < 0 ){
  613. /* mapping share-memory */
  614. pr_error("--------share-memory mapping error!!!!!---------");
  615. }
  616. }
  617. /* function: get semaphore */
  618. int getsem(){
  619. /* try to get or create semaphore */
  620. if((semid = semget(SEMKEY, 1, 0600|IFLAGS)) < 0){
  621. if(errno == EEXIST){
  622. /* exist, reurn its ID */
  623. semid = semget(SEMKEY, 1, 0600 | IPC_CREAT);
  624. if(semid < 0){
  625. pr_error("--------semaphore getting ID: error!!!!!---------");
  626. }
  627. else{
  628. /* semaphore already exsit and return ID directly */
  629. return semid;
  630. }
  631. }
  632. else{
  633. pr_error("--------semaphore getting: error!!!!!---------");
  634. }
  635. }
  636. /* do semaphore init to 1 once just after semaphore creating */
  637. if(semctl(semid, 0, SETVAL, 1) < 0){
  638. pr_error("-----------semctl-----------");
  639. }
  640. return semid;
  641. }
  642. /* function remove share-memory and semaphore */
  643. void remove_s(){
  644. if(shmctl(shmid, IPC_RMID, NULL) < 0)
  645. pr_error("-----------shmctl when removing-----------");
  646. if(semctl(semid, 0, IPC_RMID) < 0)
  647. pr_error("-----------semctl when removing-----------");
  648. }
  649. /* function writer to share-memory */
  650. void writer(struct databuf *buf, int index, int value){
  651. /* get semaphore before update share-memory */
  652. semop(semid, &p1, 1);
  653. /* update share-memory */
  654. buf->d_buf[index] += value;
  655. /* release semaphore */
  656. semop(semid, &v1, 1);
  657. }
  658. /* function read to share-memory */
  659. void reader(struct databuf *buf, int index, int *rv){
  660. /* get semaphore before update share-memory */
  661. semop(semid, &p1, 1);
  662. /* get share-memory value */
  663. *rv = buf->d_buf[index];
  664. /* release semaphore */
  665. semop(semid, &v1, 1);
  666. }
  667. static void dump_camera_meta(csi_frame_ex_s *frame, int idx)
  668. {
  669. int i;
  670. //printf("%s\n", __func__);
  671. if (frame->frame_meta.type != CSI_META_TYPE_CAMERA)
  672. return;
  673. csi_camera_meta_s *meta_data = (csi_camera_meta_s *)frame->frame_meta.data;
  674. int meta_count = meta_data->count;
  675. csi_camera_meta_unit_s meta_unit;
  676. csi_camera_meta_id_e meta_id;
  677. if(meta_mode > 0){
  678. meta_id = (1<<(meta_mode - 1));
  679. csi_camera_frame_get_meta_unit(
  680. &meta_unit, meta_data, meta_id);
  681. }
  682. if(meta_mode == 1 || meta_mode == 2){
  683. /* camera_name and channel_id - which should keep same during testing */
  684. cur_metaint[idx] = meta_unit.int_value;
  685. if(pre_metaint[idx] == -1){
  686. pre_metaint[idx] = cur_metaint[idx];
  687. }
  688. else{
  689. if(cur_metaint[idx] != pre_metaint[idx]){
  690. pr_error("-----meta test fail: camera_id or channel_id changes during test--------");
  691. }
  692. pre_metaint[idx] = cur_metaint[idx];
  693. printf("-----meta test camera_name or channel_id:%d--------\n", cur_metaint[idx]);
  694. }
  695. }
  696. else if(meta_mode == 3){
  697. /* frame id - which should increase from 0 */
  698. if(cur_metaint[idx] == -1 && meta_unit.int_value != 1){
  699. pr_error("-----meta test fail: first frame ID is not 1--------\n");
  700. }
  701. cur_metaint[idx] = meta_unit.int_value;
  702. if(pre_metaint[idx] == -1){
  703. pre_metaint[idx] = cur_metaint[idx];
  704. }
  705. else{
  706. if(cur_metaint[idx] != (pre_metaint[idx]+1)){
  707. pr_error("-----meta test fail: frame_id is not continuous--------\n");
  708. }
  709. printf("-----meta test: meta_id: %d, frame_id:%d, previous_id: %d--------\n", meta_unit.id, cur_metaint[idx], pre_metaint[idx]);
  710. pre_metaint[idx] = cur_metaint[idx];
  711. }
  712. }
  713. else if(meta_mode == 4){
  714. /* timestamps - which should be larger or equal to previous */
  715. cur_metasec[idx] = meta_unit.time_value.tv_sec;
  716. cur_metausec[idx] = meta_unit.time_value.tv_usec;
  717. if(pre_metasec[idx] == -1){
  718. pre_metasec[idx] = cur_metasec[idx];
  719. pre_metausec[idx] = cur_metausec[idx];
  720. }
  721. else{
  722. if(cur_metasec[idx] <= pre_metasec[idx] && cur_metausec[idx] <= pre_metausec[idx]){
  723. pr_error("-----meta test fail: timestamp decrease--------");
  724. }
  725. printf("-----meta test time - second:%d--------\n", cur_metasec[idx]);
  726. printf("-----meta test time - usecond:%d--------\n", cur_metausec[idx]);
  727. pre_metasec[idx] = cur_metasec[idx];
  728. pre_metausec[idx] = cur_metausec[idx];
  729. }
  730. }
  731. else{
  732. /* means meta_mode = 0 */
  733. for (i = 0; i < meta_count; i++) {
  734. meta_id = (1<<i);
  735. csi_camera_frame_get_meta_unit(
  736. &meta_unit, meta_data, meta_id);
  737. printf("meta_id=%d, meta_type=%d, meta_value=%d\n",
  738. meta_unit.id, meta_unit.type, meta_unit.int_value);
  739. }
  740. }
  741. }
  742. /*
  743. function: parse the format and resolution to generate the output information used to save img
  744. Input args: index of channel will be tested whose order is decided when running
  745. Below information should be included:
  746. 1. how may planars which will be store in global int PLANE[] array
  747. 2. the pix bit which will be store in global int PBIT[] array
  748. 3. the bytes of each plane for the give channel to store in global int PLNS[][3] array
  749. 4. the line numbers of each plane for the give channel to store in global int LNN[][3] array
  750. 5. the bytes to store for each line size in each plane to store in global int LSZ[][3] array
  751. */
  752. static void parse_fmt_res(int cindx){
  753. /* fetch the format the resolution information */
  754. enum csi_pixel_fmt fmt = fenum[cindx];
  755. int iw = hres[cindx];
  756. int ih = vres[cindx];
  757. /* decide the pixel bit number */
  758. switch(fmt) {
  759. case CSI_PIX_FMT_RAW_10BIT:
  760. PBIT[cindx] = 10;
  761. break;
  762. case CSI_PIX_FMT_RAW_12BIT:
  763. PBIT[cindx] = 12;
  764. break;
  765. case CSI_PIX_FMT_RAW_14BIT:
  766. PBIT[cindx] = 14;
  767. break;
  768. case CSI_PIX_FMT_RAW_16BIT:
  769. PBIT[cindx] = 16;
  770. break;
  771. default:
  772. PBIT[cindx] = 8;
  773. break;
  774. }
  775. /* decide plane numbers, each plane size(byte) and line and line size*/
  776. switch(fmt) {
  777. case CSI_PIX_FMT_RAW_8BIT:
  778. PLNS[cindx][0] = iw * ih;
  779. LNN[cindx][0] = ih;
  780. LSZ[cindx][0] = iw * 2 ;
  781. LNNV[cindx][0] = iw;
  782. LSZV[cindx][0] = ih * 2 ;
  783. PLANE[cindx] = 1;
  784. NOSTRD[cindx] = 0;
  785. break;
  786. case CSI_PIX_FMT_RAW_10BIT:
  787. case CSI_PIX_FMT_RAW_12BIT:
  788. case CSI_PIX_FMT_RAW_14BIT:
  789. case CSI_PIX_FMT_RAW_16BIT:
  790. PLNS[cindx][0] = iw * ih * 2;
  791. LNN[cindx][0] = ih;
  792. LSZ[cindx][0] = iw * 2 ;
  793. LNNV[cindx][0] = iw;
  794. LSZV[cindx][0] = ih * 2 ;
  795. PLANE[cindx] = 1;
  796. NOSTRD[cindx] = 0;
  797. break;
  798. case CSI_PIX_FMT_RGB_INTEVLEAVED_888:
  799. case CSI_PIX_FMT_YUV_TEVLEAVED_444:
  800. PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8) * 3;
  801. LNN[cindx][0] = ih;
  802. LSZ[cindx][0] = (iw * PBIT[cindx] / 8) * 3;
  803. LNNV[cindx][0] = iw;
  804. LSZV[cindx][0] = (ih * PBIT[cindx] / 8) * 3;
  805. PLANE[cindx] = 1;
  806. break;
  807. case CSI_PIX_FMT_YUV_TEVLEAVED_422:
  808. PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8) * 2;
  809. LNN[cindx][0] = ih;
  810. LSZ[cindx][0] = (iw * PBIT[cindx] / 8) * 2;
  811. LNNV[cindx][0] = iw;
  812. LSZV[cindx][0] = (ih * PBIT[cindx] / 8) * 2;
  813. PLANE[cindx] = 1;
  814. break;
  815. case CSI_PIX_FMT_YUV_TEVLEAVED_420:
  816. PLNS[cindx][0] = ((iw * ih * PBIT[cindx] / 8) * 3) / 2;
  817. LNN[cindx][0] = ih;
  818. LSZ[cindx][0] = ((iw * PBIT[cindx] / 8) * 3) / 2;
  819. LNNV[cindx][0] = iw;
  820. LSZV[cindx][0] = ((ih * PBIT[cindx] / 8) * 3) / 2;
  821. PLANE[cindx] = 1;
  822. break;
  823. case CSI_PIX_FMT_BGR:
  824. case CSI_PIX_FMT_RGB_PLANAR_888:
  825. case CSI_PIX_FMT_YUV_PLANAR_444:
  826. PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
  827. PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8);
  828. PLNS[cindx][2] = (iw * ih * PBIT[cindx] / 8);
  829. LNN[cindx][0] = ih;
  830. LNN[cindx][1] = ih;
  831. LNN[cindx][2] = ih;
  832. LSZ[cindx][0] = LSZ[cindx][1] = LSZ[cindx][2] = (iw * PBIT[cindx] / 8);
  833. LNNV[cindx][0] = iw;
  834. LNNV[cindx][1] = iw;
  835. LNNV[cindx][2] = iw;
  836. LSZV[cindx][0] = LSZV[cindx][1] = LSZV[cindx][2] = (ih * PBIT[cindx] / 8);
  837. PLANE[cindx] = 3;
  838. break;
  839. case CSI_PIX_FMT_YUV_PLANAR_422:
  840. PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
  841. PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8) / 2;
  842. PLNS[cindx][2] = (iw * ih * PBIT[cindx] / 8) / 2;
  843. LNN[cindx][0] = ih;
  844. LNN[cindx][1] = ih / 2;
  845. LNN[cindx][2] = ih / 2;
  846. LSZ[cindx][0] = (iw * PBIT[cindx] / 8);
  847. LSZ[cindx][1] = LSZ[cindx][2] = (iw * PBIT[cindx] / 8) / 2;
  848. LNNV[cindx][0] = iw;
  849. LNNV[cindx][1] = iw /2;
  850. LNNV[cindx][2] = iw /2;
  851. LSZV[cindx][0] = (ih * PBIT[cindx] / 8);
  852. LSZV[cindx][1] = LSZV[cindx][2] = (ih * PBIT[cindx] / 8) / 2;
  853. PLANE[cindx] = 3;
  854. break;
  855. case CSI_PIX_FMT_YUV_PLANAR_420:
  856. PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
  857. PLNS[cindx][1] = PLNS[cindx][2] = (iw * ih * PBIT[cindx] / 8) / 4;
  858. LNN[cindx][0] = ih;
  859. LNN[cindx][1] = LNN[cindx][2] = ih / 4;
  860. LSZ[cindx][0] = (iw * PBIT[cindx] / 8);
  861. LSZ[cindx][1] = LSZ[cindx][2] = (iw * PBIT[cindx] / 8) / 4;
  862. LNNV[cindx][0] = iw;
  863. LNNV[cindx][1] = LNNV[cindx][2] = iw / 4;
  864. LSZV[cindx][0] = (ih * PBIT[cindx] / 8);
  865. LSZV[cindx][1] = LSZV[cindx][2] = (ih * PBIT[cindx] / 8) / 4;
  866. PLANE[cindx] = 3;
  867. break;
  868. case CSI_PIX_FMT_I420:
  869. case CSI_PIX_FMT_NV12:
  870. case CSI_PIX_FMT_YUV_SEMIPLANAR_420:
  871. PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
  872. PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8) / 2;
  873. LNN[cindx][0] = ih;
  874. LNN[cindx][1] = ih / 2;
  875. LSZ[cindx][0] = LSZ[cindx][1] = (iw * PBIT[cindx] / 8);
  876. LNNV[cindx][0] = iw;
  877. LNNV[cindx][1] = iw / 2;
  878. LSZV[cindx][0] = LSZV[cindx][1] = (ih * PBIT[cindx] / 8);
  879. PLANE[cindx] = 2;
  880. break;
  881. case CSI_PIX_FMT_YUV_SEMIPLANAR_422:
  882. PLNS[cindx][0] = PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8);
  883. LNN[cindx][0] = ih;
  884. LNN[cindx][1] = ih;
  885. LSZ[cindx][0] = LSZ[cindx][0] = (iw * PBIT[cindx] / 8);
  886. LNNV[cindx][0] = iw;
  887. LNNV[cindx][1] = iw;
  888. LSZV[cindx][0] = LSZV[cindx][0] = (ih * PBIT[cindx] / 8);
  889. PLANE[cindx] = 2;
  890. break;
  891. case CSI_PIX_FMT_YUV_SEMIPLANAR_444:
  892. PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
  893. PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8) * 2;
  894. LNN[cindx][0] = ih;
  895. LNN[cindx][1] = ih * 2;
  896. LSZ[cindx][0] = (iw * PBIT[cindx] / 8);
  897. LSZ[cindx][1] = (iw * PBIT[cindx] / 8);
  898. LNNV[cindx][0] = iw;
  899. LNNV[cindx][1] = iw * 2;
  900. LSZV[cindx][0] = (ih * PBIT[cindx] / 8);
  901. LSZV[cindx][1] = (ih * PBIT[cindx] / 8);
  902. PLANE[cindx] = 2;
  903. break;
  904. default:
  905. PLNS[cindx][0] = (iw * ih * PBIT[cindx] / 8);
  906. PLNS[cindx][1] = (iw * ih * PBIT[cindx] / 8) / 2;
  907. LNN[cindx][0] = ih;
  908. LNN[cindx][1] = ih / 2;
  909. LSZ[cindx][0] = LSZ[cindx][1] = (iw * PBIT[cindx] / 8);
  910. LNNV[cindx][0] = iw;
  911. LNNV[cindx][1] = iw / 2;
  912. LSZV[cindx][0] = LSZV[cindx][1] = (ih * PBIT[cindx] / 8);
  913. PLANE[cindx] = 2;
  914. break;
  915. }
  916. }
  917. /*
  918. function: store image of each frame
  919. input1: frame
  920. input2: channel index
  921. input3: target file point
  922. input4: reverse mdoe for rotating 90 and 270 degree
  923. */
  924. static void i_save(csi_frame_ex_s *framei, int cid, FILE *fp, int vmode)
  925. {
  926. int lindex = 0;
  927. int smode = 0;
  928. if( vmode == 0){
  929. if(framei->frame_data.stride[0] != LSZ[cid][0] && NOSTRD[cid] == 0){
  930. //if(NOSTRD[cid] == 0){
  931. smode = 1;
  932. printf("-------------In Stride mode, framei->img.strides[0]=%d---------------\n", framei->frame_data.stride[0]);
  933. }
  934. else{
  935. printf("-------------No Stride, framei->img.strides[0]=%d---------------\n", framei->frame_data.stride[0]);
  936. }
  937. for (int p = 0; p < PLANE[cid]; p++){
  938. /* loop for each planar */
  939. //printf("-------------framei->img.usr_addr[%d]=0x%llx---------------\n", p, framei->img.usr_addr[p]);
  940. lindex = 0;
  941. //int size = 0;
  942. if(smode == 0){
  943. /* no stride, write plane by plane*/
  944. printf("-------------No Stride, length is = %d---------------\n", PLNS[cid][p]);
  945. //while(size < PLNS[cid][p]){
  946. // size += fwrite(framei->img.usr_addr[p] + size, sizeof(char), PLNS[cid][p] - size, fp);
  947. // }
  948. fwrite(framei->frame_data.vir_addr[p], sizeof(char), PLNS[cid][p], fp);
  949. }
  950. else{
  951. /* stride mode, write line by line */
  952. for(int l = 0; l < LNN[cid][p]; l++){
  953. if(framei->frame_data.stride[p] == 0){
  954. printf("-------------Error: stride[%d] is 0---------------\n", p);
  955. lindex = LSZ[cid][p] * l;
  956. }
  957. else{
  958. /* for each plane, the strides[x] is the same */
  959. lindex = framei->frame_data.stride[0] * l;
  960. }
  961. fwrite(framei->frame_data.vir_addr[p] + lindex, sizeof(char), LSZ[cid][p], fp);
  962. }
  963. }
  964. }
  965. }
  966. else{
  967. if(framei->frame_data.stride[0] != LSZV[cid][0] && NOSTRD[cid] == 0){
  968. smode = 1;
  969. printf("-------------In Stride mode, framei->img.strides[0]=%d---------------\n", framei->frame_data.stride[0]);
  970. }
  971. else{
  972. printf("-------------No Stride, framei->img.strides[0]=%d---------------\n", framei->frame_data.stride[0]);
  973. }
  974. for (int p = 0; p < PLANE[cid]; p++){
  975. /* loop for each planar */
  976. //printf("-------------framei->img.usr_addr[%d]=0x%llx---------------\n", p, framei->img.usr_addr[p]);
  977. lindex = 0;
  978. int size = 0;
  979. if(smode == 0){
  980. /* no stride, write plane by plane*/
  981. printf("-------------No Stride, length is = %d---------------\n", PLNS[cid][p]);
  982. while(size < PLNS[cid][p]){
  983. size += fwrite(framei->frame_data.vir_addr[p] + size, sizeof(char), PLNS[cid][p] - size, fp);
  984. }
  985. }
  986. else{
  987. /* stride mode, write line by line */
  988. for(int l = 0; l < LNNV[cid][p]; l++){
  989. if(framei->frame_data.stride[p] == 0){
  990. printf("-------------Error: stride[%d] is 0---------------\n", p);
  991. lindex = LSZV[cid][p] * l;
  992. }
  993. else{
  994. /* for each plane, the strides[x] is the same */
  995. lindex = framei->frame_data.stride[0] * l;
  996. }
  997. fwrite(framei->frame_data.vir_addr[p] + lindex, sizeof(char), LSZV[cid][p], fp);
  998. }
  999. }
  1000. }
  1001. }
  1002. }
  1003. /*
  1004. function: convert dma-buf file point to target address
  1005. input1: framei
  1006. input2: channel index
  1007. */
  1008. // static void handle_dma_buf(csi_frame_ex_s *framei, int cid)
  1009. // {
  1010. // if (frame->img.type == CSI_IMG_TYPE_DMA_BUF) {
  1011. // void *p[3] = {0};
  1012. // /*
  1013. // The first plane which exists always.
  1014. // All data for packed; Y data for planar or semi-planar
  1015. // */
  1016. // void *phyaddr = vi_mem_import(framei->img.dmabuf[0].fds);
  1017. // p[0] = vi_mem_map(phyaddr) + framei->img.dmabuf[0].offset;
  1018. // framei->img.usr_addr[0] = p[0];
  1019. // /*
  1020. // For other planes, in our solution, we only have plane[1] for
  1021. // planar or sp; or no other plane for packed.
  1022. // */
  1023. // for (int i=1; i<PLANE[cid]; i++){
  1024. // if (framei->img.dmabuf[i].offset != NULL){
  1025. // p[i] = framei->img.dmabuf[i].offset + p[0];
  1026. // framei->img.usr_addr[i] = p[i];
  1027. // }
  1028. // else{
  1029. // printf("-------------DMA ERROR, no usr_addr for plane=%d---------------\n", i);
  1030. // }
  1031. // }
  1032. // vi_mem_release(phyaddr);
  1033. // }
  1034. // }
  1035. /*
  1036. function: save data as image
  1037. input1: channel index
  1038. */
  1039. static void* save_camera_img(void * idx)
  1040. {
  1041. int index = *(int*)(idx);
  1042. free(idx);
  1043. char fname[512];
  1044. char fidname[256];
  1045. FILE *fp;
  1046. char fidc[128];
  1047. int fcount;
  1048. int fidi = fid[index];
  1049. int cid = channelIdx[index];
  1050. int hresi = hres[index];
  1051. int vresi = vres[index];
  1052. enum csi_pixel_fmt fmt = fenum[index];
  1053. csi_frame_ex_s *framei = &frame[index];
  1054. int vmode = 0;
  1055. if(framei->frame_info.width == vresi && framei->frame_info.height == hresi && vresi != hresi){
  1056. vmode = 1;
  1057. vresi = framei->frame_info.height;
  1058. hresi = framei->frame_info.width;
  1059. }
  1060. /* generate the image name */
  1061. fcount = fidi%tframes;
  1062. 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]);
  1063. /* dma-buf to address */
  1064. // handle_dma_buf(framei, index);
  1065. if((fp = fopen(fname, "wb")) == NULL){
  1066. printf("Error: Can't open file\n");
  1067. return NULL;
  1068. }
  1069. /* data saving */
  1070. i_save(framei, index, fp, vmode);
  1071. fclose(fp);
  1072. /* frame ID saving */
  1073. sprintf(fidc, "%d\n", fidi);
  1074. sprintf(fidname, "%s%s%s%s%d%s", path, "/fid_", dname, "_chn_", cid, ".txt");
  1075. if((fp = fopen(fidname, "a+")) == NULL){
  1076. printf("Error: Can't open file\n");
  1077. return NULL;
  1078. }
  1079. fwrite(fidc, sizeof(char), strlen(fidc), fp);
  1080. fclose(fp);
  1081. if(meta_mode >= 0){
  1082. dump_camera_meta(framei, index);
  1083. }
  1084. //csi_camera_frame_unlock(cam_handle, framei);
  1085. csi_camera_put_frame(framei);
  1086. // csi_frame_release(framei);
  1087. if (onoffMode == 1 && fNumInc[index] % onoffFrame == 0){
  1088. afterOnOff[index] = onoffDrop;
  1089. // stop stream, sleep, start stream
  1090. csi_camera_channel_stop(cam_handle, CAMERA_CHANNEL_ID[index]);
  1091. //sleep(1);
  1092. csi_camera_channel_start(cam_handle, CAMERA_CHANNEL_ID[index]);
  1093. }
  1094. return NULL;
  1095. }
  1096. /*
  1097. function: save data as stream
  1098. input1: channel index
  1099. */
  1100. static void* save_camera_stream(void *idx)
  1101. {
  1102. int index = *(int*)(idx);
  1103. free(idx);
  1104. FILE *fp;
  1105. char fname[256];
  1106. int cid = channelIdx[index];
  1107. int hresi = hres[index];
  1108. int vresi = vres[index];
  1109. enum csi_pixel_fmt fmt = fenum[index];
  1110. csi_frame_ex_s *framei = &frame[index];
  1111. int vmode = 0;
  1112. if(framei->frame_info.width == vresi && framei->frame_info.height == hresi && vresi != hresi){
  1113. vmode = 1;
  1114. vresi = framei->frame_info.height;
  1115. hresi = framei->frame_info.width;
  1116. }
  1117. /* generate stream name - for each time it is the same name */
  1118. 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]);
  1119. // handle_dma_buf(framei, index);
  1120. if((fp = fopen(fname, "ab+")) == NULL){
  1121. printf("Error: Can't open file\n");
  1122. return NULL;
  1123. }
  1124. i_save(framei, index, fp, vmode);
  1125. fclose(fp);
  1126. if(meta_mode >= 0){
  1127. dump_camera_meta(framei, index);
  1128. }
  1129. //csi_camera_frame_unlock(cam_handle, framei);
  1130. csi_camera_put_frame(framei);
  1131. // csi_frame_release(framei);
  1132. if (onoffMode == 1 && fNumInc[index] % onoffFrame == 0){
  1133. afterOnOff[index] = onoffDrop;
  1134. // stop stream, sleep, start stream
  1135. csi_camera_channel_stop(cam_handle, CAMERA_CHANNEL_ID[index]);
  1136. //sleep(1);
  1137. csi_camera_channel_start(cam_handle, CAMERA_CHANNEL_ID[index]);
  1138. }
  1139. return NULL;
  1140. }
  1141. // 同时配置多个参数
  1142. static int set_properties(csi_cam_handle_t cam_handle, char *pArgs)
  1143. {
  1144. csi_camera_properties_s properties;
  1145. csi_camera_property_s property[30];
  1146. char *pDelim=":/";
  1147. int pid;
  1148. int ptype;
  1149. int pvalueInt;
  1150. char *pvalueStr;
  1151. char *pFirst;
  1152. /*
  1153. parse multi-properties which delimited by : or /
  1154. 1. / is used to seprate multi properties
  1155. 2. : is used to sperate pid:type:value
  1156. for example: 1:2:1/2:2:1/3:1:90
  1157. */
  1158. pFirst = strtok(pArgs, pDelim);
  1159. int i = 0;
  1160. while(pFirst != NULL){
  1161. pid = atoi(pFirst);
  1162. property[i].id = pid + CSI_CAMERA_PID_BASE;
  1163. /*
  1164. property type difinition:
  1165. CSI_CAMERA_PROPERTY_TYPE_INTEGER = 1,
  1166. CSI_CAMERA_PROPERTY_TYPE_BOOLEAN = 2,
  1167. CSI_CAMERA_PROPERTY_TYPE_ENUM = 3,
  1168. CSI_CAMERA_PROPERTY_TYPE_STRING = 7,
  1169. CSI_CAMERA_PROPERTY_TYPE_BITMASK = 8,
  1170. */
  1171. ptype = atoi(strtok(NULL, pDelim));
  1172. property[i].type = ptype;
  1173. if (ptype == CSI_CAMERA_PROPERTY_TYPE_STRING) {
  1174. pvalueStr = strtok(NULL, pDelim);
  1175. strcpy(property[i].value.str_value, pvalueStr);
  1176. }
  1177. else {
  1178. pvalueInt = atoi(strtok(NULL, pDelim));
  1179. property[i].value.int_value = pvalueInt;
  1180. }
  1181. i++;
  1182. pFirst = strtok(NULL, pDelim);
  1183. }
  1184. /* set multi-properties(here the property number is i) by calling API just one time */
  1185. properties.count = i;
  1186. properties.property = property;
  1187. if (csi_camera_set_property(cam_handle, &properties) < 0) {
  1188. printf("set_property fail!\n");
  1189. return -1;
  1190. }
  1191. printf("set_property ok!\n");
  1192. return 0;
  1193. }
  1194. static enum csi_pixel_fmt parse_format(char *fmt)
  1195. {
  1196. for(int i=0; i<fmtMAX; i++){
  1197. if(strstr(fmtArray[i], fmt)){
  1198. return CSI_PIX_FMT_I420 + i;
  1199. }
  1200. }
  1201. return CSI_PIX_FMT_NV12;
  1202. }