cam_demo_multi.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. /*
  2. * Copyright (C) 2021 Alibaba Group Holding Limited
  3. * Author: ShenWuYi <shenwuyi.swy@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 <fcntl.h>
  13. #include <unistd.h>
  14. #include <sys/mman.h>
  15. #define LOG_LEVEL 2
  16. #define LOG_PREFIX "cam_demo_multi"
  17. #include <syslog.h>
  18. #include <csi_frame.h>
  19. #include <csi_camera.h>
  20. #include <csi_camera_dev_api.h>
  21. #ifdef PLATFORM_SIMULATOR
  22. #include "apputilities.h"
  23. #endif
  24. #define MAX_CAM_NUM 3
  25. #define MAX_CHANNEL_NUM 3
  26. static void dump_camera_meta(csi_frame_ex_s *frame);
  27. static void dump_camera_frame(csi_frame_ex_s *frame, int ch_id);
  28. // extern int csi_camera_frame_unlock(csi_cam_handle_t cam_handle, csi_frame_s *frame);
  29. #define TEST_DEVICE_NAME "/dev/video0"
  30. #define CSI_CAMERA_TRUE 1
  31. #define CSI_CAMERA_FALSE 0
  32. typedef struct frame_fps {
  33. uint64_t frameNumber;
  34. struct timeval initTick;
  35. float fps;
  36. } frame_fps_t;
  37. typedef enum _frame_mode{
  38. FRAME_NONE =0,
  39. FRAME_SAVE_IMG =1,
  40. FRAME_SAVE_STREAM =2,
  41. FRAME_SAVE_DISPLAY,
  42. FRAME_INVALID,
  43. }frame_mode_t;
  44. typedef enum _cam_type{
  45. CAM_TYEP_RGB =0,
  46. CAM_TYEP_IR,
  47. CAM_TYEP_INVALID,
  48. }cam_type_e;
  49. typedef struct _camera_param{
  50. int video_id;
  51. int channel_num;
  52. struct {
  53. int width;
  54. int height;
  55. csi_pixel_fmt_e fmt;
  56. }out_pic[MAX_CHANNEL_NUM];
  57. cam_type_e type;
  58. frame_mode_t mode;
  59. int frames_to_stop;
  60. }camera_param_t;
  61. typedef struct event_queue_item{
  62. struct csi_camera_event evet;
  63. struct event_queue_item *next;
  64. }event_queue_item_t;
  65. typedef struct _camera_ctx{
  66. int cam_id;
  67. pthread_t cam_thread;
  68. int exit;
  69. csi_cam_handle_t cam_handle;
  70. int channel_num;
  71. csi_cam_event_handle_t event_handle;
  72. csi_camera_event_subscription_s event_subscribe;
  73. csi_camera_channel_cfg_s chn_cfg[MAX_CHANNEL_NUM];
  74. void * disaply_plink[MAX_CHANNEL_NUM];
  75. int frame_num;
  76. frame_mode_t frame_mode[MAX_CHANNEL_NUM];
  77. }camera_ctx_t;
  78. int file_id = 0;
  79. extern void *vi_plink_create(csi_camera_channel_cfg_s *chn_cfg);
  80. extern void vi_plink_release(void * plink);
  81. extern void display_camera_frame(void * plink, csi_frame_ex_s *frame);
  82. static void usage(void)
  83. {
  84. printf(" 1 : RGB Camera id \n");
  85. printf(" 2 : RGB Camera id channel num\n");
  86. printf(" 3 : RGB Camera frame mode :0 none ,1 dump enable,2 display \n");
  87. printf(" 4 : RGB Camera frame num :0 not stop ,else frame num to stop \n");
  88. printf(" 5 : IR Camera id \n");
  89. printf(" 6 : IR Camera id channel num\n");
  90. printf(" 7 : IR Camera frame mode :0 none ,1 dump enable,2 display \n");
  91. printf(" 8 : IR Camera frame num :0 not stop ,else frame num to stop \n");
  92. }
  93. void printUsage(char *name)
  94. {
  95. printf("usage: %s [options]\n"
  96. "\n"
  97. " Available options:\n"
  98. " -f fisrt camera device 5 param \n"
  99. " 1:video id 2: channel num 3: camrea type (0->rgb ;1->IR) (mandatory)\n"
  100. " 3: mode【0->none ,1->save image,2->display 】(default 1) \n"
  101. " 4: frame num to stop 【0 not stop】(default 0) \n"
  102. " -s second camera device 5 param)\n"
  103. " same param setting as above)\n"
  104. " -t third camera device 5 param)\n"
  105. " same param setting above)\n"
  106. "\n", name);
  107. }
  108. static int parseParams(int argc, char **argv, camera_param_t *params)
  109. {
  110. int index =0;
  111. params[index].video_id = 2;
  112. params[index].type = CAM_TYEP_RGB;
  113. params[index].channel_num =1;
  114. params[index].out_pic[0].width = 1920;
  115. params[index].out_pic[0].height = 1080;
  116. params[index].out_pic[0].fmt = CSI_PIX_FMT_NV12;
  117. params[index].mode = FRAME_SAVE_IMG;
  118. params[index].frames_to_stop = 0;
  119. index++;
  120. params[index].video_id = 6;
  121. params[index].type = CAM_TYEP_IR;
  122. params[index].channel_num = 2;
  123. params[index].out_pic[0].width = 1080;
  124. params[index].out_pic[0].height = 1280;
  125. params[index].out_pic[0].fmt =CSI_PIX_FMT_RAW_12BIT;
  126. params[index].out_pic[1].width = 1080;
  127. params[index].out_pic[1].height = 1280;
  128. params[index].out_pic[1].fmt =CSI_PIX_FMT_RAW_12BIT;
  129. params[index].mode = FRAME_SAVE_IMG;
  130. params[index].frames_to_stop = 0;
  131. index++;
  132. return index;
  133. }
  134. static void get_system_time(const char *func, int line_num)
  135. {
  136. struct timeval cur_time;
  137. memset(&cur_time, 0, sizeof(cur_time));
  138. gettimeofday(&cur_time, 0);
  139. printf("%s %s line_num = %d, cur_time.tv_sec = %ld, cur_time.tv_usec = %ld\n",
  140. __func__, func, line_num, cur_time.tv_sec, cur_time.tv_usec);
  141. }
  142. static int camera_get_chl_id(int env_type, int *chl_id)
  143. {
  144. if (chl_id == NULL) {
  145. LOG_E("fail to check param chl_id = %p\n", chl_id);
  146. return -1;
  147. }
  148. switch (env_type) {
  149. case CSI_CAMERA_EVENT_TYPE_CHANNEL0:
  150. *chl_id = CSI_CAMERA_CHANNEL_0;
  151. break;
  152. case CSI_CAMERA_EVENT_TYPE_CHANNEL1:
  153. *chl_id = CSI_CAMERA_CHANNEL_1;
  154. break;
  155. case CSI_CAMERA_EVENT_TYPE_CHANNEL2:
  156. *chl_id = CSI_CAMERA_CHANNEL_2;
  157. break;
  158. default:
  159. LOG_D("%s fail to check env_type = %d unsupport\n", env_type);
  160. break;
  161. }
  162. return 0;
  163. }
  164. /***********************DSP ALGO *******************************/
  165. typedef struct cb_context{
  166. int id;
  167. csi_cam_handle_t cam_handle;
  168. int dsp_id;
  169. int dsp_path;
  170. void *ref_buf;
  171. int buf_size;
  172. }cb_context_t;
  173. typedef struct cb_args{
  174. char lib_name[8];
  175. char setting[16];
  176. uint32_t frame_id;
  177. uint64_t timestap;
  178. uint32_t temp_projector; //投射器温度
  179. uint32_t temp_sensor; //sensor 温度
  180. }cb_args_t;
  181. cb_context_t cb_context[2];
  182. void dsp_algo_result_cb(void*context,void*arg)
  183. {
  184. cb_context_t *ctx = (cb_context_t *)context;
  185. cb_args_t *cb_args= (cb_args_t*)arg;
  186. char update_setting[16];
  187. struct timeval times_value;
  188. uint32_t frame_id = cb_args->frame_id;
  189. uint64_t frame_timestap = cb_args->timestap;
  190. times_value.tv_sec = cb_args->timestap/1000000;
  191. times_value.tv_usec = cb_args->timestap%1000000;
  192. LOG_O("cb:%d,%s,setting:%s,frame :%d,timestad:(%ld s,%ld us)\n",ctx->id,cb_args->lib_name,cb_args->setting,
  193. frame_id,times_value.tv_sec,times_value.tv_usec);
  194. LOG_O("temperate projector:%d,sensor:%d\n",cb_args->temp_projector,cb_args->temp_sensor);
  195. // if(test_flag!=0)
  196. {
  197. sprintf(update_setting, "update_%d", frame_id);
  198. csi_camera_update_dsp_algo_setting(ctx->cam_handle,ctx->dsp_id,ctx->dsp_path,update_setting);
  199. if(frame_id%20==0)
  200. {
  201. void *replace_buf;
  202. *((uint32_t*)ctx->ref_buf) = frame_id;
  203. csi_camera_update_dsp_algo_buf(ctx->cam_handle, ctx->dsp_id,ctx->dsp_path,ctx->ref_buf,&replace_buf);
  204. LOG_D("cb:%d,old buffer:0x%llx,new buffer:0x%llx\n",ctx->id,ctx->ref_buf,replace_buf);
  205. ctx->ref_buf = replace_buf;
  206. }
  207. }
  208. }
  209. static void *camera_event_thread(void *arg)
  210. {
  211. int ret = 0;
  212. if (arg == NULL) {
  213. LOG_E("NULL Ptr\n");
  214. pthread_exit(0);
  215. }
  216. camera_ctx_t* ctx = (camera_ctx_t*)arg;
  217. csi_cam_event_handle_t ev_handle = ctx->event_handle;
  218. csi_camera_channel_cfg_s *ch_cfg=NULL;
  219. struct timeval init_time, cur_time;
  220. memset(&init_time, 0, sizeof(init_time));
  221. memset(&cur_time, 0, sizeof(cur_time));
  222. frame_fps_t demo_fps;
  223. memset(&demo_fps, 0, sizeof(demo_fps));
  224. csi_frame_ex_s frame;
  225. if (ev_handle == NULL) {
  226. LOG_E("fail to get ev_handle ev_handle\n");
  227. pthread_exit(0);
  228. }
  229. int timeout = -1; // unit: ms, -1 means wait forever, or until error occurs
  230. int loop_count = 0;
  231. struct csi_camera_event event;
  232. LOG_O("Theard is runing............\n");
  233. while (ctx->exit==0) {
  234. int timeout = -1; // unit: ms, -1 means wait forever, or until error occurs
  235. csi_camera_get_event(ev_handle, &event, timeout);
  236. LOG_D("Camera_%d event.type = %d, event.id = %d\n",ctx->cam_id ,event.type, event.id);
  237. switch (event.type) {
  238. case CSI_CAMERA_EVENT_TYPE_CAMERA:
  239. switch (event.id) {
  240. case CSI_CAMERA_EVENT_ERROR:
  241. // do sth.
  242. LOG_E("get CAMERA EVENT CSI_CAMERA_EVENT_ERROR!\n");
  243. break;
  244. case CSI_CAMERA_EVENT_WARNING:
  245. LOG_W("get CAMERA EVENT CSI_CAMERA_EVENT_WRN,RC: %s\n",event.bin);
  246. break;
  247. default:
  248. break;
  249. }
  250. break;
  251. case CSI_CAMERA_EVENT_TYPE_CHANNEL0:
  252. case CSI_CAMERA_EVENT_TYPE_CHANNEL1:
  253. case CSI_CAMERA_EVENT_TYPE_CHANNEL2:
  254. case CSI_CAMERA_EVENT_TYPE_CHANNEL3:
  255. switch (event.id) {
  256. case CSI_CAMERA_CHANNEL_EVENT_FRAME_READY: {
  257. int chn_id = 0;
  258. ret = camera_get_chl_id(event.type, &chn_id);
  259. if (ret) {
  260. LOG_E("fail to get chl_id = %d\n", chn_id);
  261. continue;
  262. }
  263. ch_cfg = &ctx->chn_cfg[chn_id];
  264. get_system_time(__func__, __LINE__);
  265. int read_frame_count = csi_camera_get_frame_count(ctx->cam_handle,
  266. chn_id);
  267. unsigned long diff;
  268. if (init_time.tv_usec == 0)
  269. gettimeofday(&init_time,0);//osGetTick();
  270. gettimeofday(&cur_time, 0);
  271. diff = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
  272. demo_fps.frameNumber++;
  273. if (diff != 0)
  274. demo_fps.fps = (float)demo_fps.frameNumber / diff * 1000000.0f;
  275. LOG_O("cam:%d,channle:%d ,read_frame_count = %d, frame_count = %ld, fps = %.2f diff = %ld\n", ctx->cam_id, chn_id, read_frame_count, demo_fps.frameNumber, demo_fps.fps, diff);
  276. for (int i = 0; i < read_frame_count; i++) {
  277. csi_camera_get_frame(ctx->cam_handle, chn_id, &frame, timeout);
  278. dump_camera_meta(&frame);
  279. if (ctx->frame_mode[chn_id] == FRAME_SAVE_IMG) {
  280. dump_camera_frame(&frame, chn_id);
  281. }
  282. if (ctx->disaply_plink && ctx->frame_mode[chn_id]==FRAME_SAVE_DISPLAY) {
  283. display_camera_frame(ctx->disaply_plink, &frame);
  284. }
  285. csi_camera_put_frame(&frame);
  286. ctx->frame_num++;
  287. }
  288. break;
  289. }
  290. default:
  291. break;
  292. }
  293. break;
  294. default:
  295. break;
  296. }
  297. }
  298. LOG_O("exit!\n");
  299. pthread_exit(0);
  300. }
  301. static void camera_start_all(camera_ctx_t * ctx)
  302. {
  303. camera_ctx_t * cam_ctx = ctx;
  304. int loop_ch;
  305. for(loop_ch=0;loop_ch<cam_ctx->channel_num;loop_ch++)
  306. {
  307. csi_camera_channel_start(cam_ctx->cam_handle, cam_ctx->chn_cfg[loop_ch].chn_id);
  308. }
  309. }
  310. static void camera_stop_all(camera_ctx_t * ctx)
  311. {
  312. camera_ctx_t * cam_ctx = ctx;
  313. int loop_ch;
  314. for(loop_ch=0;loop_ch<cam_ctx->channel_num;loop_ch++)
  315. {
  316. csi_camera_channel_stop(cam_ctx->cam_handle, cam_ctx->chn_cfg[loop_ch].chn_id);
  317. }
  318. }
  319. static camera_ctx_t * camera_open(camera_param_t *params)
  320. {
  321. int ret = 0;
  322. char dev_name[128];
  323. camera_ctx_t * cam_ctx = NULL;
  324. int loop_ch;
  325. LOG_O("Open Camera %d\n",params->video_id);
  326. if(params==NULL || params->video_id <0)
  327. {
  328. LOG_E("param err\n");
  329. return NULL;
  330. }
  331. if(params->channel_num> MAX_CHANNEL_NUM)
  332. {
  333. LOG_E("unsupoort channle num:%d \n",params->channel_num);
  334. return NULL;
  335. }
  336. if(params->mode >=FRAME_INVALID)
  337. {
  338. LOG_E("unsupoort frame process mode:%d \n",params->mode);
  339. return NULL;
  340. }
  341. cam_ctx = malloc(sizeof(camera_ctx_t));
  342. if(!cam_ctx)
  343. {
  344. return NULL;
  345. }
  346. memset(cam_ctx,0x0,sizeof(camera_ctx_t));
  347. // 打开Camera设备获取句柄,作为后续操对象
  348. sprintf(dev_name, "/dev/video%d", params->video_id);
  349. if(csi_camera_open(&cam_ctx->cam_handle, dev_name))
  350. {
  351. LOG_E("Fail to open cam :%s\n",dev_name);
  352. goto ONE_ERR;
  353. }
  354. for(loop_ch= CSI_CAMERA_CHANNEL_0;loop_ch<params->channel_num;loop_ch++)
  355. {
  356. cam_ctx->chn_cfg[loop_ch].chn_id = loop_ch;
  357. cam_ctx->chn_cfg[loop_ch].img_fmt.pix_fmt = params->out_pic[loop_ch].fmt;
  358. cam_ctx->chn_cfg[loop_ch].img_fmt.width= params->out_pic[loop_ch].width;
  359. cam_ctx->chn_cfg[loop_ch].img_fmt.height = params->out_pic[loop_ch].height;
  360. cam_ctx->chn_cfg[loop_ch].img_type = CSI_IMG_TYPE_DMA_BUF;
  361. cam_ctx->chn_cfg[loop_ch].meta_fields = CSI_CAMERA_META_DEFAULT_FIELDS;
  362. if(csi_camera_channel_open(cam_ctx->cam_handle,&cam_ctx->chn_cfg[loop_ch]))
  363. {
  364. LOG_E("Fail to open cam %s,channel :%d\n",dev_name,loop_ch);
  365. goto TWO_ERR;
  366. }
  367. if(params->mode == FRAME_SAVE_DISPLAY)
  368. {
  369. cam_ctx->disaply_plink[loop_ch] = vi_plink_create(&cam_ctx->chn_cfg[loop_ch]);
  370. if(!cam_ctx->disaply_plink[loop_ch]&& loop_ch== CSI_CAMERA_CHANNEL_0) //temp only channel to display
  371. {
  372. LOG_E("Fail to create plink for cam %s,channel :%d\n",dev_name,loop_ch);
  373. goto TWO_ERR;
  374. }
  375. }
  376. cam_ctx->frame_mode[loop_ch]=params->mode;
  377. cam_ctx->channel_num++;
  378. }
  379. if(csi_camera_create_event(&cam_ctx->event_handle,cam_ctx->cam_handle))
  380. {
  381. LOG_E("Fail to create event handler for cam %s\n",dev_name);
  382. goto TWO_ERR;
  383. }
  384. cam_ctx->event_subscribe.type = CSI_CAMERA_EVENT_TYPE_CAMERA;
  385. cam_ctx->event_subscribe.id = CSI_CAMERA_EVENT_WARNING | CSI_CAMERA_EVENT_ERROR;
  386. if(csi_camera_subscribe_event(cam_ctx->event_handle,&cam_ctx->event_subscribe))
  387. {
  388. LOG_E("Fail to subscribe eventfor cam %s\n",dev_name);
  389. goto TWO_ERR;
  390. }
  391. for(loop_ch=0;loop_ch<cam_ctx->channel_num;loop_ch++)
  392. {
  393. cam_ctx->event_subscribe.type = CSI_CAMERA_EVENT_TYPE_CHANNEL0+loop_ch;
  394. cam_ctx->event_subscribe.id = CSI_CAMERA_CHANNEL_EVENT_FRAME_READY;
  395. if(csi_camera_subscribe_event(cam_ctx->event_handle,&cam_ctx->event_subscribe))
  396. {
  397. LOG_E("Fail to subscribe eventfor cam %s\n",dev_name);
  398. goto TWO_ERR;
  399. }
  400. }
  401. LOG_O("%s open successfully\n",dev_name);
  402. ret = pthread_create(&cam_ctx->cam_thread, NULL,
  403. (void *)camera_event_thread, cam_ctx);
  404. if (ret != 0) {
  405. LOG_E("pthread_create() failed, ret=%d", ret);
  406. goto TWO_ERR;
  407. }
  408. if(params->type == CAM_TYEP_IR)
  409. {
  410. cb_context[0].id=0;
  411. cb_context[0].cam_handle = cam_ctx->cam_handle;
  412. cb_context[0].dsp_id = 1;
  413. cb_context[0].dsp_path = 3;
  414. char test_set[16]="init";
  415. cb_context[0].buf_size = 1920*1080;
  416. cb_context[0].ref_buf=NULL;
  417. csi_camera_dsp_algo_param_t algo_param_1={
  418. .algo_name = "dsp1_dummy_algo_flo_1",
  419. .algo_cb.cb = dsp_algo_result_cb,
  420. .algo_cb.context = &cb_context[0],
  421. .algo_cb.arg_size = sizeof(cb_args_t),
  422. .sett_ptr = test_set,
  423. .sett_size =sizeof(test_set),
  424. .extra_buf_num =1,
  425. .extra_buf_sizes = &cb_context[0].buf_size,
  426. .extra_bufs = &cb_context[0].ref_buf,
  427. };
  428. if(csi_camera_set_dsp_algo_param(cam_ctx->cam_handle, cb_context[0].dsp_id,cb_context[0].dsp_path, &algo_param_1))
  429. {
  430. LOG_E("set DSP algo fail\n");
  431. goto TWO_ERR;
  432. }
  433. cb_context[1].id=1;
  434. cb_context[1].cam_handle = cam_ctx->cam_handle;
  435. cb_context[1].dsp_id = 1;
  436. cb_context[1].dsp_path = 4;
  437. cb_context[1].buf_size = 1920*1080;
  438. cb_context[1].ref_buf=NULL;
  439. csi_camera_dsp_algo_param_t algo_param_2={
  440. .algo_name = "dsp1_dummy_algo_flo",
  441. .algo_cb.cb = dsp_algo_result_cb,
  442. .algo_cb.context = &cb_context[1],
  443. .algo_cb.arg_size = sizeof(cb_args_t),
  444. .sett_ptr = test_set,
  445. .sett_size =sizeof(test_set),
  446. .extra_buf_num =1,
  447. .extra_buf_sizes = &cb_context[1].buf_size,
  448. .extra_bufs = &cb_context[1].ref_buf,
  449. };
  450. if(csi_camera_set_dsp_algo_param(cam_ctx->cam_handle, cb_context[1].dsp_id,cb_context[1].dsp_path, &algo_param_2))
  451. {
  452. LOG_E("set DSP algo fail\n");
  453. goto TWO_ERR;
  454. }
  455. csi_camera_floodlight_led_set_flash_bright(cam_ctx->cam_handle, 500); //500ma
  456. csi_camera_projection_led_set_flash_bright(cam_ctx->cam_handle, 500); //500ma
  457. csi_camera_projection_led_set_mode(cam_ctx->cam_handle, LED_IR_ENABLE);
  458. csi_camera_floodlight_led_set_mode(cam_ctx->cam_handle, LED_IR_ENABLE);
  459. csi_camera_led_enable(cam_ctx->cam_handle, LED_FLOODLIGHT_PROJECTION);
  460. }
  461. // for(loop_ch=0;loop_ch<cam_ctx->channel_num;loop_ch++)
  462. // {
  463. // csi_camera_channel_start(cam_ctx->cam_handle, cam_ctx->chn_cfg[loop_ch].chn_id);
  464. // }
  465. get_system_time(__func__, __LINE__);
  466. return cam_ctx;
  467. TWO_ERR:
  468. for(loop_ch=0;loop_ch<cam_ctx->channel_num;loop_ch++)
  469. {
  470. csi_camera_channel_close(cam_ctx->cam_handle, cam_ctx->chn_cfg[loop_ch].chn_id);
  471. }
  472. csi_camera_close(cam_ctx->cam_handle);
  473. ONE_ERR:
  474. free(cam_ctx);
  475. return NULL;
  476. }
  477. static void camera_close(camera_ctx_t *ctx)
  478. {
  479. int loop_ch;
  480. if(ctx->cam_handle==NULL)
  481. {
  482. return;
  483. }
  484. if (pthread_join(ctx->cam_thread, NULL)) {
  485. LOG_E("pthread_join() failed\n");
  486. }
  487. csi_camera_unsubscribe_event(ctx->event_handle, &ctx->event_subscribe);
  488. csi_camera_destory_event(ctx->event_handle);
  489. // int loop_ch;
  490. // for(loop_ch=0;loop_ch<ctx->channel_num;loop_ch++)
  491. // {
  492. // csi_camera_channel_stop(cam_ctx->cam_handle, cam_ctx->chn_cfg[loop_ch].chn_id);
  493. // }
  494. for(loop_ch=0;loop_ch<ctx->channel_num;loop_ch++)
  495. {
  496. csi_camera_channel_close(ctx->cam_handle, ctx->chn_cfg[loop_ch].chn_id);
  497. }
  498. csi_camera_close(ctx->cam_handle);
  499. free(ctx);
  500. }
  501. int main(int argc, char *argv[])
  502. {
  503. char dev_name[128];
  504. int camera_id = 0;
  505. // 打印HAL接口版本号
  506. csi_api_version_u version;
  507. csi_camera_get_version(&version);
  508. camera_param_t params[MAX_CAM_NUM];
  509. camera_ctx_t * ctx[MAX_CAM_NUM]={NULL,NULL,NULL};
  510. int cam_num=0;
  511. bool running = false;
  512. cam_num =parseParams(argc,argv,params);
  513. if(cam_num <=0 || cam_num>MAX_CAM_NUM)
  514. {
  515. LOG_E("not camera is active\n");
  516. exit(0);
  517. }
  518. for(int i =0;i<cam_num;i++)
  519. {
  520. switch(params[i].type)
  521. {
  522. case CAM_TYEP_RGB:
  523. ctx[i]=camera_open(&params[i]);
  524. break;
  525. case CAM_TYEP_IR:
  526. ctx[i]=camera_open(&params[i]);
  527. break;
  528. default:
  529. LOG_E("unspuoort camera :%d\n",i);
  530. continue;
  531. }
  532. if(ctx[i]==NULL)
  533. {
  534. LOG_E("camera_%d open %d fail\n",i,params[i].type);
  535. goto ONR_ERR;
  536. }
  537. ctx[i]->cam_id = i;
  538. ctx[i]->frame_num =0;
  539. ctx[i]->exit = 0;
  540. camera_start_all(ctx[i]);
  541. running = true;
  542. }
  543. int all_exit;
  544. do{
  545. sleep(1);
  546. all_exit = 1;
  547. for(int i =0;i<cam_num;i++)
  548. {
  549. if(ctx[i]&&
  550. ctx[i]->exit==0 &&
  551. params[i].frames_to_stop>0 &&
  552. ctx[i]->frame_num >=params[i].frames_to_stop)
  553. {
  554. camera_stop_all(ctx[i]);
  555. ctx[i]->exit=1;
  556. }
  557. if(ctx[i])
  558. all_exit &= ctx[i]->exit;
  559. }
  560. if(all_exit ==1)
  561. {
  562. LOG_O("all_exit\n");
  563. running = false;
  564. }
  565. }while(running);
  566. ONR_ERR:
  567. for(int i =0;i<cam_num;i++)
  568. {
  569. if(ctx[i])
  570. camera_close(ctx[i]);
  571. }
  572. exit(0);
  573. }
  574. static void dump_camera_meta(csi_frame_ex_s *frame)
  575. {
  576. int i;
  577. //printf("%s\n", __func__);
  578. if (frame->frame_meta.type != CSI_META_TYPE_CAMERA)
  579. return;
  580. csi_camera_meta_s *meta_data = (csi_camera_meta_s *)frame->frame_meta.data;
  581. int meta_count = meta_data->count;
  582. csi_camera_meta_unit_s meta_unit;
  583. csi_camera_frame_get_meta_unit(
  584. &meta_unit, meta_data, CSI_CAMERA_META_ID_FRAME_ID);
  585. LOG_I("meta_id=%d, meta_type=%d, meta_value=%d\n",
  586. meta_unit.id, meta_unit.type, meta_unit.int_value);
  587. }
  588. static void dump_camera_frame(csi_frame_ex_s *frame, int ch_id)
  589. {
  590. char file[128];
  591. static int file_indx=0;
  592. int size;
  593. uint32_t indexd, j;
  594. void *buf[3]={NULL,NULL,NULL};
  595. int buf_size;
  596. csi_camera_meta_s *meta_data = (csi_camera_meta_s *)frame->frame_meta.data;
  597. csi_camera_meta_unit_s meta_unit;
  598. csi_camera_frame_get_meta_unit(&meta_unit, meta_data, CSI_CAMERA_META_ID_CAMERA_NAME);
  599. sprintf(file, "demo_save_img_%s_ch%d_%d_%d", meta_unit.str_value, ch_id,file_id, file_indx++%10);
  600. int fd = open(file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH);
  601. if(fd == -1) {
  602. LOG_E("%s, %d, open file error!!!!!!!!!!!!!!!\n", __func__, __LINE__);
  603. return;
  604. }
  605. for(j =0;j<frame->frame_data.num_plane;j++)
  606. {
  607. buf[j] = frame->frame_data.vir_addr[j];
  608. }
  609. LOG_I("save img from: addr:%p,to %s, fd:%d,fmt:%d width:%d stride:%d height:%d\n", buf[0], file, frame->frame_data.fd[0],
  610. frame->frame_info.pixel_format, frame->frame_info.width, frame->frame_data.stride[0], frame->frame_info.height);
  611. switch(frame->frame_info.pixel_format) {
  612. case CSI_PIX_FMT_NV12:
  613. case CSI_PIX_FMT_YUV_SEMIPLANAR_420:
  614. for (j = 0; j < frame->frame_info.height; j++) { //Y
  615. indexd = j*frame->frame_data.stride[0];
  616. write(fd, buf[0] + indexd, frame->frame_info.width);
  617. }
  618. for (j = 0; j < frame->frame_info.height / 2; j++) { //UV
  619. indexd = j*frame->frame_data.stride[0];
  620. write(fd, buf[1] + indexd, frame->frame_info.width);
  621. }
  622. break;
  623. case CSI_PIX_FMT_RGB_INTEVLEAVED_888:
  624. case CSI_PIX_FMT_YUV_TEVLEAVED_444:
  625. size = frame->frame_info.width*3;
  626. for (j = 0; j < frame->frame_info.height; j++) {
  627. indexd = j*frame->frame_data.stride[0];
  628. write(fd, buf[0] + indexd, size);
  629. }
  630. break;
  631. case CSI_PIX_FMT_BGR:
  632. case CSI_PIX_FMT_RGB_PLANAR_888:
  633. case CSI_PIX_FMT_YUV_PLANAR_444:
  634. size = frame->frame_info.width * frame->frame_info.height * 3;
  635. write(fd, buf[0], size);
  636. break;
  637. case CSI_PIX_FMT_RAW_8BIT:
  638. size = frame->frame_info.width;
  639. for (j = 0; j < frame->frame_info.height; j++) {
  640. indexd = j*frame->frame_data.stride[0];
  641. write(fd, buf[0] + indexd, size);
  642. }
  643. break;
  644. case CSI_PIX_FMT_YUV_TEVLEAVED_422:
  645. case CSI_PIX_FMT_RAW_10BIT:
  646. case CSI_PIX_FMT_RAW_12BIT:
  647. case CSI_PIX_FMT_RAW_14BIT:
  648. case CSI_PIX_FMT_RAW_16BIT:
  649. size = frame->frame_info.width*2;
  650. for (j = 0; j < frame->frame_info.height; j++) {
  651. indexd = j*frame->frame_data.stride[0];
  652. write(fd, buf[0] + indexd, size);
  653. }
  654. break;
  655. case CSI_PIX_FMT_YUV_SEMIPLANAR_422:
  656. if (frame->frame_data.stride[0] == 0) {
  657. frame->frame_data.stride[0] = frame->frame_info.width;
  658. }
  659. for (j = 0; j < frame->frame_info.height; j++) { //Y
  660. indexd = j*frame->frame_data.stride[0];
  661. write(fd,buf[0] + indexd, frame->frame_info.width);
  662. }
  663. for (j = 0; j < frame->frame_info.height; j++) { //UV
  664. indexd = j*frame->frame_data.stride[0];
  665. write(fd, buf[1]+ indexd, frame->frame_info.width);
  666. }
  667. break;
  668. default:
  669. LOG_E("%s unsupported format to save\n", __func__);
  670. break;
  671. }
  672. close(fd);
  673. }