cam_demo_simple.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. /*
  2. * Copyright (C) 2021 Alibaba Group Holding Limited
  3. * Author: LuChongzhi <chongzhi.lcz@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 <sys/mman.h>
  13. #include <fcntl.h>
  14. #include <unistd.h>
  15. #define LOG_LEVEL 2
  16. #define LOG_PREFIX "cam_demo_simple"
  17. #include <syslog.h>
  18. #include <csi_frame.h>
  19. #include <csi_camera.h>
  20. #include "csi_camera_dev_api.h"
  21. // #include "vi_mem.h"
  22. #ifdef PLATFORM_SIMULATOR
  23. #include "apputilities.h"
  24. #endif
  25. static void dump_camera_meta(csi_frame_s *frame);
  26. static void dump_camera_frame(csi_frame_s *frame, csi_pixel_fmt_e fmt);
  27. #define TEST_DEVICE_NAME "/dev/video0"
  28. #define CSI_CAMERA_TRUE 1
  29. #define CSI_CAMERA_FALSE 0
  30. typedef struct frame_fps {
  31. uint64_t frameNumber;
  32. struct timeval initTick;
  33. float fps;
  34. } frame_fps_t;
  35. typedef struct cb_context{
  36. int id;
  37. csi_cam_handle_t cam_handle;
  38. int dsp_id;
  39. int dsp_path;
  40. void *ref_buf;
  41. int buf_size;
  42. }cb_context_t;
  43. typedef struct cb_args{
  44. char setting[16];
  45. uint32_t frame_id;
  46. uint32_t timestap;
  47. }cb_args_t;
  48. cb_context_t cb_context[2];
  49. void dsp_algo_result_cb(void*context,void*arg)
  50. {
  51. cb_context_t *ctx = (cb_context_t *)context;
  52. cb_args_t *cb_args= (cb_args_t*)arg;
  53. char update_setting[16];
  54. uint32_t frame_id = cb_args->frame_id;
  55. uint32_t frame_timestap = cb_args->timestap;
  56. LOG_O("cb:%d,setting:%s,frame :%d,timestad:0x%x\n",ctx->id,cb_args->setting,frame_id,frame_timestap);
  57. sprintf(update_setting, "update_%d", frame_id);
  58. csi_camera_update_dsp_algo_setting(ctx->cam_handle,ctx->dsp_id,ctx->dsp_path,update_setting);
  59. if(frame_id%20)
  60. {
  61. void *replace_buf;
  62. csi_camera_update_dsp_algo_buf(ctx->cam_handle, ctx->dsp_id,ctx->dsp_path,ctx->ref_buf,&replace_buf);
  63. LOG_O("cb:%d,old buffer:0x%lx,new buffer:0x%lx\n",ctx->id,(uint64_t)ctx->ref_buf,(uint64_t)replace_buf);
  64. ctx->ref_buf = replace_buf;
  65. }
  66. }
  67. static void usage(void)
  68. {
  69. printf(" 1 : video id cases\n");
  70. printf(" 2 : channel cases\n");
  71. printf(" 3 : dump enable\n");
  72. printf(" 4 : display enable\n");
  73. printf(" 5 : width\n");
  74. printf(" 6 : heithg\n");
  75. printf(" 7 : fmt\n");
  76. printf(" 8 : frame_num\n");
  77. printf(" 9 : file_id\n");
  78. }
  79. static void get_system_time(const char *func, int line_num)
  80. {
  81. struct timeval cur_time;
  82. memset(&cur_time, 0, sizeof(cur_time));
  83. gettimeofday(&cur_time, 0);
  84. LOG_O("%s %s line_num = %d, cur_time.tv_sec = %ld, cur_time.tv_usec = %ld\n",
  85. __func__, func, line_num, cur_time.tv_sec, cur_time.tv_usec);
  86. }
  87. int file_id = 0;
  88. extern void *vi_plink_create(csi_camera_channel_cfg_s *chn_cfg);
  89. extern void vi_plink_release(void * plink);
  90. extern void display_camera_frame(void * plink, csi_frame_s *frame);
  91. int main(int argc, char *argv[])
  92. {
  93. bool running = true;
  94. int channel_id = -1;
  95. int video_id = -1;
  96. int dump_enable = -1;
  97. int display_enable = -1;
  98. int width = 0, height = 0, fmt = -1;
  99. int ret = 0;
  100. uint64_t frame_num = 0;
  101. csi_camera_info_s camera_info;
  102. memset(&camera_info, 0, sizeof(camera_info));
  103. int chn_id = CSI_CAMERA_CHANNEL_0;
  104. int env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL0;
  105. frame_fps_t demo_fps;
  106. memset(&demo_fps, 0, sizeof(demo_fps));
  107. struct timeval init_time, cur_time;
  108. memset(&init_time, 0, sizeof(init_time));
  109. memset(&cur_time, 0, sizeof(cur_time));
  110. get_system_time(__func__, __LINE__);
  111. char dev_name[128];
  112. // 打印HAL接口版本号
  113. csi_api_version_u version;
  114. csi_camera_get_version(&version);
  115. if (argc == 5)
  116. {
  117. video_id = atoi(argv[1]);
  118. channel_id = atoi(argv[2]);
  119. dump_enable = atoi(argv[3]);
  120. display_enable = atoi(argv[4]);
  121. width = 640;
  122. height = 480;
  123. fmt = 1;
  124. printf("%s, %s, %s, %s \n", argv[1],argv[2],argv[3],argv[4]);
  125. printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$, %d, display_enable is %d\n", __LINE__, display_enable );
  126. } else if (argc == 8) {
  127. video_id = atoi(argv[1]);
  128. channel_id = atoi(argv[2]);
  129. dump_enable = atoi(argv[3]);
  130. display_enable = atoi(argv[4]);
  131. width = atoi(argv[5]);
  132. height = atoi(argv[6]);
  133. fmt = atoi(argv[7]);
  134. }else if (argc == 9) {
  135. video_id = atoi(argv[1]);
  136. channel_id = atoi(argv[2]);
  137. dump_enable = atoi(argv[3]);
  138. display_enable = atoi(argv[4]);
  139. width = atoi(argv[5]);
  140. height = atoi(argv[6]);
  141. fmt = atoi(argv[7]);
  142. frame_num = atoi(argv[8]);
  143. }else if (argc == 10) {
  144. video_id = atoi(argv[1]);
  145. channel_id = atoi(argv[2]);
  146. dump_enable = atoi(argv[3]);
  147. display_enable = atoi(argv[4]);
  148. width = atoi(argv[5]);
  149. height = atoi(argv[6]);
  150. fmt = atoi(argv[7]);
  151. frame_num = atoi(argv[8]);
  152. file_id = atoi(argv[9]);
  153. } else {
  154. usage();
  155. video_id = 0;
  156. channel_id = 0;
  157. dump_enable = 0;
  158. display_enable = 0;
  159. width = 640;
  160. height = 480;
  161. fmt = 1;
  162. printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$, %d, display_enable is %d\n", __LINE__, display_enable );
  163. }
  164. sprintf(dev_name, "/dev/video%d", video_id);
  165. LOG_O("Camera HAL version: %d.%d video_id = %d channel_id = %d size{%d, %d} fmt = %d\n", version.major, version.minor, video_id, channel_id, width, height, fmt);
  166. // 获取设备中,所有的Camera
  167. struct csi_camera_infos camera_infos;
  168. memset(&camera_infos, 0, sizeof(camera_infos));
  169. csi_camera_query_list(&camera_infos);
  170. // 打印所有设备所支持的Camera
  171. for (int i = 0; i < camera_infos.count; i++) {
  172. camera_info = camera_infos.info[i];
  173. printf("Camera[%d]: camera_name='%s', device_name='%s', bus_info='%s', capabilities=0x%08x\n",
  174. i,
  175. camera_info.camera_name, camera_info.device_name, camera_info.bus_info,
  176. camera_info.capabilities);
  177. printf("Camera[%d] caps are:\n", i); /* The caps are: Video capture, metadata capture */
  178. for (int j = 1; j <= 0x08000000; j = j << 1) {
  179. switch (camera_info.capabilities & j) {
  180. case CSI_CAMERA_CAP_VIDEO_CAPTURE:
  181. printf("\t camera_infos.info[%d]:Video capture,\n", i);
  182. break;
  183. case CSI_CAMERA_CAP_META_CAPTURE:
  184. printf("\t camera_infos.info[%d] metadata capture,\n", i);
  185. break;
  186. default:
  187. if (camera_info.capabilities & j) {
  188. printf("\t camera_infos.info[%d] unknown capabilities(0x%08x)\n", i,
  189. camera_info.capabilities & j);
  190. }
  191. break;
  192. }
  193. }
  194. }
  195. /* Camera[0]: camera_name='RGB_Camera', device_name='/dev/video0', bus_info='CSI-MIPI', capabilities=0x00800001
  196. * Camera[1]: camera_name:'Mono_Camera', device_name:'/dev/video8', bus_info='USB', capabilities=0x00000001
  197. */
  198. bool found_camera = false;
  199. for (int i = 0; i < camera_infos.count; i++) {
  200. if (strcmp(camera_infos.info[i].device_name, dev_name) == 0) {
  201. camera_info = camera_infos.info[i];
  202. printf("found device_name:'%s'\n", camera_info.device_name);
  203. found_camera = true;
  204. break;
  205. }
  206. }
  207. if (!found_camera) {
  208. LOG_E("Can't find camera_name:'%s'\n", dev_name);
  209. exit(-1);
  210. }
  211. get_system_time(__func__, __LINE__);
  212. // 打开Camera设备获取句柄,作为后续操对象
  213. csi_cam_handle_t cam_handle;
  214. ret = csi_camera_open(&cam_handle, camera_info.device_name);
  215. if (ret) {
  216. LOG_E("Failed to csi_camera_open %s\n", camera_info.device_name);
  217. exit(-1);
  218. }
  219. get_system_time(__func__, __LINE__);
  220. // 获取Camera支持的工作模式
  221. struct csi_camera_modes camera_modes;
  222. csi_camera_get_modes(cam_handle, &camera_modes);
  223. // 打印camera所支持的所有工作模式
  224. printf("Camera:'%s' modes are:\n", dev_name);
  225. printf("{\n");
  226. for (int i = 0; i < camera_modes.count; i++) {
  227. printf("\t mode_id=%d: description:'%s'\n",
  228. camera_modes.modes[i].mode_id, camera_modes.modes[i].description);
  229. }
  230. printf("}\n");
  231. // 设置camera的工作模式及其配置
  232. csi_camera_mode_cfg_s camera_cfg;
  233. camera_cfg.mode_id = 1;
  234. camera_cfg.calibriation = NULL; // 采用系统默认配置
  235. camera_cfg.lib3a = NULL; // 采用系统默认配置
  236. csi_camera_set_mode(cam_handle, &camera_cfg);
  237. // 获取单个可控单元的属性
  238. csi_camera_property_description_s description;
  239. /* id=0x0098090x, type=2 default=0 value=1 */
  240. /* Other example:
  241. * id=0x0098090y, type=3 min=0 max=255 step=1 default=127 value=116
  242. * id=0x0098090z, type=4 min=0 max=3 default=0 value=2
  243. * 0: IDLE
  244. * 1: BUSY
  245. * 2: REACHED
  246. * 3: FAILED
  247. */
  248. // 轮询获取所有可控制的单元
  249. printf("all properties are:\n");
  250. description.id = CSI_CAMERA_PID_HFLIP;
  251. while (!csi_camera_query_property(cam_handle, &description)) {
  252. switch (description.type) {
  253. case (CSI_CAMERA_PROPERTY_TYPE_INTEGER):
  254. printf("id=0x%08x type=%d default=%d value=%d\n",
  255. description.id, description.type,
  256. description.default_value.int_value, description.value.int_value);
  257. break;
  258. case (CSI_CAMERA_PROPERTY_TYPE_BOOLEAN):
  259. printf("id=0x%08x type=%d default=%d value=%d\n",
  260. description.id, description.type,
  261. description.default_value.bool_value, description.value.bool_value);
  262. break;
  263. case (CSI_CAMERA_PROPERTY_TYPE_ENUM):
  264. printf("id=0x%08x type=%d default=%d value=%d\n",
  265. description.id, description.type,
  266. description.default_value.enum_value, description.value.enum_value);
  267. break;
  268. case (CSI_CAMERA_PROPERTY_TYPE_STRING):
  269. printf("id=0x%08x type=%d default=%s value=%s\n",
  270. description.id, description.type,
  271. description.default_value.str_value, description.value.str_value);
  272. break;
  273. case (CSI_CAMERA_PROPERTY_TYPE_BITMASK):
  274. printf("id=0x%08x type=%d default=%x value=%x\n",
  275. description.id, description.type,
  276. description.default_value.bitmask_value, description.value.bitmask_value);
  277. break;
  278. default:
  279. LOG_E("error type!\n");
  280. break;
  281. }
  282. description.id |= CSI_CAMERA_FLAG_NEXT_CTRL;
  283. }
  284. // 同时配置多个参数
  285. csi_camera_properties_s properties;
  286. csi_camera_property_s property[3];
  287. property[0].id = CSI_CAMERA_PID_HFLIP;
  288. property[0].type = CSI_CAMERA_PROPERTY_TYPE_BOOLEAN;
  289. property[0].value.bool_value = false;
  290. property[1].id = CSI_CAMERA_PID_VFLIP;
  291. property[1].type = CSI_CAMERA_PROPERTY_TYPE_BOOLEAN;
  292. property[1].value.bool_value = false;
  293. property[2].id = CSI_CAMERA_PID_ROTATE;
  294. property[2].type = CSI_CAMERA_PROPERTY_TYPE_INTEGER;
  295. property[2].value.int_value = 0;
  296. properties.count = 3;
  297. properties.property = property;
  298. if (csi_camera_set_property(cam_handle, &properties) < 0) {
  299. LOG_O("set_property fail!\n");
  300. }
  301. else
  302. {
  303. LOG_O("set_property ok!\n");
  304. }
  305. // extern int csi_camera_set_pp_path_param(csi_cam_handle_t cam_handle, uint16_t line_num,uint16_t buf_mode);
  306. // csi_camera_set_pp_path_param(cam_handle,80,0);
  307. // 查询输出channel
  308. switch (channel_id) {
  309. case 0:
  310. chn_id = CSI_CAMERA_CHANNEL_0;
  311. env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL0;
  312. break;
  313. case 1:
  314. chn_id = CSI_CAMERA_CHANNEL_1;
  315. env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL1;
  316. break;
  317. case 2:
  318. chn_id = CSI_CAMERA_CHANNEL_2;
  319. env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL2;
  320. break;
  321. case 3:
  322. chn_id = CSI_CAMERA_CHANNEL_3;
  323. env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL3;
  324. break;
  325. case 4:
  326. chn_id = CSI_CAMERA_CHANNEL_4;
  327. env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL4;
  328. break;
  329. case 5:
  330. chn_id = CSI_CAMERA_CHANNEL_5;
  331. env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL5;
  332. break;
  333. case 6:
  334. chn_id = CSI_CAMERA_CHANNEL_6;
  335. env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL6;
  336. break;
  337. case 7:
  338. chn_id = CSI_CAMERA_CHANNEL_7;
  339. env_type = CSI_CAMERA_EVENT_TYPE_CHANNEL7;
  340. break;
  341. default:
  342. LOG_E("fail to check chn_id = %d unsupport\n", chn_id);
  343. exit(-1);
  344. }
  345. csi_camera_channel_cfg_s chn_cfg;
  346. chn_cfg.chn_id = chn_id;
  347. csi_camera_channel_query(cam_handle, &chn_cfg);
  348. if (chn_cfg.status != CSI_CAMERA_CHANNEL_CLOSED) {
  349. LOG_E("Can't open chn_id = %d\n", chn_id);
  350. exit(-1);
  351. }
  352. extern int csi_camera_set_pp_path_param(csi_cam_handle_t cam_handle, uint16_t line_num,uint16_t buf_mode);
  353. /*set PP line num to default and enable sram*/
  354. csi_camera_set_pp_path_param(cam_handle,0,1);
  355. // 打开输出channel
  356. chn_cfg.chn_id = chn_id;
  357. chn_cfg.frm_cnt = 1;
  358. chn_cfg.img_fmt.width = width;
  359. chn_cfg.img_fmt.height = height;
  360. chn_cfg.img_fmt.pix_fmt = fmt;
  361. chn_cfg.img_type = CSI_IMG_TYPE_DMA_BUF;
  362. chn_cfg.meta_fields = CSI_CAMERA_META_DEFAULT_FIELDS;
  363. chn_cfg.capture_type = CSI_CAMERA_CHANNEL_CAPTURE_VIDEO |
  364. CSI_CAMERA_CHANNEL_CAPTURE_META;
  365. ret = csi_camera_channel_open(cam_handle, &chn_cfg);
  366. if (ret) {
  367. exit(-1);
  368. }
  369. get_system_time(__func__, __LINE__);
  370. /*init for vi->vo plink*/
  371. void * display_plink = NULL;
  372. if (display_enable == 1) {
  373. chn_cfg.chn_id = chn_id;
  374. display_plink = vi_plink_create(&chn_cfg);
  375. if(display_plink==NULL)
  376. {
  377. LOG_E("plink create fail\n");
  378. exit(-1);
  379. }
  380. }
  381. // 订阅Event
  382. csi_cam_event_handle_t event_handle;
  383. csi_camera_create_event(&event_handle, cam_handle);
  384. csi_camera_event_subscription_s subscribe;
  385. subscribe.type =
  386. CSI_CAMERA_EVENT_TYPE_CAMERA; // 订阅Camera的ERROR事件
  387. subscribe.id = CSI_CAMERA_EVENT_WARNING | CSI_CAMERA_EVENT_ERROR;
  388. csi_camera_subscribe_event(event_handle, &subscribe);
  389. subscribe.type =
  390. env_type; // 订阅Channel0的FRAME_READY事件
  391. subscribe.id = CSI_CAMERA_CHANNEL_EVENT_FRAME_READY |
  392. CSI_CAMERA_CHANNEL_EVENT_OVERFLOW;
  393. csi_camera_subscribe_event(event_handle, &subscribe);
  394. /* for dsp algo setting
  395. cb_context[0].id=0;
  396. cb_context[0].cam_handle = cam_handle;
  397. cb_context[0].dsp_id = 1;
  398. cb_context[0].dsp_path = 2;
  399. char test_set[16]="init";
  400. cb_context[0].buf_size = 1920*1080;
  401. cb_context[0].ref_buf=NULL;
  402. csi_camera_dsp_algo_param_t algo_param_1={
  403. .algo_name = "dsp1_dummy_algo_flo",
  404. .algo_cb.cb = dsp_algo_result_cb,
  405. .algo_cb.context = &cb_context[0],
  406. .algo_cb.arg_size = sizeof(cb_args_t),
  407. .sett_ptr = test_set,
  408. .sett_size =16,
  409. .extra_buf_num =1,
  410. .extra_buf_sizes = &cb_context[0].buf_size,
  411. .extra_bufs = &cb_context[0].ref_buf,
  412. };
  413. if(csi_camera_set_dsp_algo_param(cam_handle,cb_context[0].dsp_id,cb_context[0].dsp_path, &algo_param_1))
  414. {
  415. LOG_E("set DSP algo fail\n");
  416. }
  417. */
  418. // 开始从channel中取出准备好的frame
  419. ret = csi_camera_channel_start(cam_handle, chn_id);
  420. if (ret) {
  421. LOG_E("Failed to csi_camera_channel_start ch%d\n", chn_id);
  422. exit(-1);
  423. }
  424. get_system_time(__func__, __LINE__);
  425. // 处理订阅的Event
  426. csi_frame_s frame;
  427. struct csi_camera_event event;
  428. while (running) {
  429. if (frame_num != 0) {
  430. if (demo_fps.frameNumber > frame_num) {
  431. running = false;
  432. }
  433. }
  434. int timeout = -1; // unit: ms, -1 means wait forever, or until error occurs
  435. if(csi_camera_get_event(event_handle, &event, timeout))
  436. {
  437. LOG_E("Failed to get event \n");
  438. continue;
  439. }
  440. // printf("%s event.type = %d, event.id = %d\n", __func__, event.type, event.id);
  441. switch (event.type) {
  442. case CSI_CAMERA_EVENT_TYPE_CAMERA:
  443. switch (event.id) {
  444. case CSI_CAMERA_EVENT_ERROR:
  445. // do sth.
  446. LOG_O("get CAMERA EVENT CSI_CAMERA_EVENT_ERROR!\n");
  447. break;
  448. case CSI_CAMERA_EVENT_WARNING:
  449. LOG_O("get CAMERA EVENT CSI_CAMERA_EVENT_WRN,RC: %s\n",event.bin);
  450. break;
  451. default:
  452. break;
  453. }
  454. break;
  455. case CSI_CAMERA_EVENT_TYPE_CHANNEL0:
  456. case CSI_CAMERA_EVENT_TYPE_CHANNEL1:
  457. case CSI_CAMERA_EVENT_TYPE_CHANNEL2:
  458. case CSI_CAMERA_EVENT_TYPE_CHANNEL3:
  459. case CSI_CAMERA_EVENT_TYPE_CHANNEL4:
  460. case CSI_CAMERA_EVENT_TYPE_CHANNEL5:
  461. case CSI_CAMERA_EVENT_TYPE_CHANNEL6:
  462. case CSI_CAMERA_EVENT_TYPE_CHANNEL7:
  463. switch (event.id) {
  464. case CSI_CAMERA_CHANNEL_EVENT_FRAME_READY: {
  465. get_system_time(__func__, __LINE__);
  466. int read_frame_count = csi_camera_get_frame_count(cam_handle,
  467. chn_id);
  468. unsigned long diff;
  469. if (init_time.tv_usec == 0)
  470. gettimeofday(&init_time,0);//osGetTick();
  471. gettimeofday(&cur_time, 0);
  472. diff = 1000000 * (cur_time.tv_sec-init_time.tv_sec)+ cur_time.tv_usec-init_time.tv_usec;
  473. demo_fps.frameNumber++;
  474. if (diff != 0)
  475. demo_fps.fps = (float)demo_fps.frameNumber / diff * 1000000.0f;
  476. LOG_O("%s %d read_frame_count = %d, frame_count = %ld, fps = %.2f diff = %ld\n", __func__, __LINE__, read_frame_count, demo_fps.frameNumber, demo_fps.fps, diff);
  477. for (int i = 0; i < read_frame_count; i++) {
  478. if(csi_camera_get_frame(cam_handle, chn_id, &frame, timeout))
  479. {
  480. LOG_W("get frame fail\n");
  481. continue;
  482. }
  483. #ifdef PLATFORM_SIMULATOR
  484. if (frame.img.type == CSI_IMG_TYPE_DMA_BUF) {
  485. void *phyaddr = vi_mem_import(frame.img.dmabuf[0].fds);
  486. void *p = vi_mem_map(phyaddr) + frame.img.dmabuf[0].offset;
  487. show_frame_image(p, frame.img.height, frame.img.width);
  488. vi_mem_release(phyaddr);
  489. } else {
  490. show_frame_image(frame.img.usr_addr[0], frame.img.height, frame.img.width);
  491. }
  492. #endif
  493. dump_camera_meta(&frame);
  494. chn_cfg.chn_id = chn_id;
  495. csi_camera_channel_query(cam_handle, &chn_cfg);
  496. frame.img.pix_format = chn_cfg.img_fmt.pix_fmt;
  497. if (dump_enable) {
  498. dump_camera_frame(&frame, chn_cfg.img_fmt.pix_fmt);
  499. }
  500. if (display_enable == 1) {
  501. display_camera_frame(display_plink, &frame);
  502. continue;
  503. }
  504. csi_camera_put_frame(&frame);
  505. csi_frame_release(&frame);
  506. }
  507. break;
  508. }
  509. default:
  510. break;
  511. }
  512. break;
  513. default:
  514. break;
  515. }
  516. }
  517. csi_camera_channel_stop(cam_handle, chn_id);
  518. usleep (1000000);
  519. // 取消订阅某一个event, 也可以直接调用csi_camera_destory_event,结束所有的订阅
  520. subscribe.type = env_type;
  521. subscribe.id = CSI_CAMERA_CHANNEL_EVENT_FRAME_READY;
  522. csi_camera_unsubscribe_event(event_handle, &subscribe);
  523. csi_camera_destory_event(event_handle);
  524. csi_camera_channel_close(cam_handle, chn_id);
  525. csi_camera_close(cam_handle);
  526. if(display_plink)
  527. {
  528. vi_plink_release(display_plink);
  529. }
  530. }
  531. static void dump_camera_meta(csi_frame_s *frame)
  532. {
  533. int i;
  534. if (frame->meta.type != CSI_META_TYPE_CAMERA)
  535. return;
  536. csi_camera_meta_s *meta_data = (csi_camera_meta_s *)frame->meta.data;
  537. int meta_count = meta_data->count;
  538. csi_camrea_meta_unit_s meta_unit;
  539. csi_camera_frame_get_meta_unit(
  540. &meta_unit, meta_data, CSI_CAMERA_META_ID_FRAME_ID);
  541. LOG_O("meta_id=%d, meta_type=%d, meta_value=%d\n",
  542. meta_unit.id, meta_unit.type, meta_unit.int_value);
  543. }
  544. static void dump_camera_frame(csi_frame_s *frame, csi_pixel_fmt_e fmt)
  545. {
  546. char file[128];
  547. static int file_indx=0;
  548. int size;
  549. uint32_t indexd, j;
  550. void *buf[3];
  551. int buf_size;
  552. csi_camera_meta_s *meta_data = (csi_camera_meta_s *)frame->meta.data;
  553. csi_camrea_meta_unit_s meta_unit;
  554. csi_camera_frame_get_meta_unit(
  555. &meta_unit, meta_data, CSI_CAMERA_META_ID_CAMERA_NAME);
  556. sprintf(file,"demo_save_img%s_%d_%d",meta_unit.str_value,file_id, file_indx++%10);
  557. int fd = open(file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH);
  558. if(fd == -1) {
  559. LOG_E("%s, %d, open file error!!!!!!!!!!!!!!!\n", __func__, __LINE__);
  560. return ;
  561. }
  562. if (frame->img.type == CSI_IMG_TYPE_DMA_BUF) {
  563. buf_size = frame->img.strides[0]*frame->img.height;
  564. switch(fmt) {
  565. case CSI_PIX_FMT_NV12:
  566. case CSI_PIX_FMT_YUV_SEMIPLANAR_420:
  567. if(frame->img.num_planes ==2)
  568. {
  569. buf_size+=frame->img.strides[1]*frame->img.height/2;
  570. }
  571. else{
  572. LOG_E("img fomrat is not match with frame planes:%d\n",frame->img.num_planes);
  573. return;
  574. }
  575. break;
  576. case CSI_PIX_FMT_YUV_SEMIPLANAR_422:
  577. if(frame->img.num_planes ==2)
  578. {
  579. buf_size+=frame->img.strides[1]*frame->img.height;
  580. }
  581. else{
  582. LOG_E("img fomrat is not match with frame planes:%d\n",frame->img.num_planes);
  583. return;
  584. }
  585. break;
  586. default:
  587. break;
  588. }
  589. buf[0]= mmap(0, buf_size, PROT_READ | PROT_WRITE,
  590. MAP_SHARED, frame->img.dmabuf[0].fds, frame->img.dmabuf[0].offset);
  591. // plane_size[1] = frame->img.strides[1]*frame->img.height;
  592. // printf("frame plane 1 stride:%d,offset:%d\n", frame->img.strides[1],(uint32_t)frame->img.dmabuf[1].offset);
  593. if(frame->img.num_planes ==2)
  594. {
  595. // buf[1] = mmap(0, plane_size[1]/2, PROT_READ | PROT_WRITE,
  596. // MAP_SHARED, frame->img.dmabuf[1].fds, frame->img.dmabuf[1].offset);
  597. buf[1] = buf[0]+frame->img.dmabuf[1].offset;
  598. }
  599. }
  600. else{
  601. buf[0] = frame->img.usr_addr[0];
  602. buf[1] = frame->img.usr_addr[1];
  603. }
  604. LOG_O("%s,save img from : (%lx,%lx)size:%d to %s, fmt:%d width:%d stride:%d height:%d\n",__FUNCTION__, (uint64_t)buf[0],(uint64_t)buf[1],size, file, fmt, frame->img.width, frame->img.strides[0], frame->img.height);
  605. if (frame->img.strides[0] == 0) {
  606. frame->img.strides[0] = frame->img.width;
  607. }
  608. switch(fmt) {
  609. case CSI_PIX_FMT_NV12:
  610. case CSI_PIX_FMT_YUV_SEMIPLANAR_420:
  611. for (j = 0; j < frame->img.height; j++) { //Y
  612. indexd = j*frame->img.strides[0];
  613. write(fd, buf[0] + indexd, frame->img.width);
  614. }
  615. for (j = 0; j < frame->img.height / 2; j++) { //UV
  616. indexd = j*frame->img.strides[0];
  617. write(fd, buf[1] + indexd, frame->img.width);
  618. }
  619. break;
  620. case CSI_PIX_FMT_RGB_INTEVLEAVED_888:
  621. case CSI_PIX_FMT_YUV_TEVLEAVED_444:
  622. size = frame->img.width*3;
  623. for (j = 0; j < frame->img.height; j++) {
  624. indexd = j*frame->img.strides[0];
  625. write(fd, buf[0] + indexd, size);
  626. }
  627. break;
  628. case CSI_PIX_FMT_BGR:
  629. case CSI_PIX_FMT_RGB_PLANAR_888:
  630. case CSI_PIX_FMT_YUV_PLANAR_444:
  631. size = frame->img.width * frame->img.height * 3;
  632. write(fd, buf[0], size);
  633. break;
  634. case CSI_PIX_FMT_RAW_8BIT:
  635. size = frame->img.width;
  636. for (j = 0; j < frame->img.height; j++) {
  637. indexd = j*frame->img.strides[0];
  638. write(fd, buf[0] + indexd, size);
  639. }
  640. break;
  641. case CSI_PIX_FMT_YUV_TEVLEAVED_422:
  642. case CSI_PIX_FMT_RAW_10BIT:
  643. case CSI_PIX_FMT_RAW_12BIT:
  644. case CSI_PIX_FMT_RAW_14BIT:
  645. case CSI_PIX_FMT_RAW_16BIT:
  646. size = frame->img.width*2;
  647. for (j = 0; j < frame->img.height; j++) {
  648. indexd = j*frame->img.strides[0];
  649. write(fd, buf[0] + indexd, size);
  650. }
  651. break;
  652. case CSI_PIX_FMT_YUV_SEMIPLANAR_422:
  653. if (frame->img.strides[0] == 0) {
  654. frame->img.strides[0] = frame->img.width;
  655. }
  656. for (j = 0; j < frame->img.height; j++) { //Y
  657. indexd = j*frame->img.strides[0];
  658. write(fd,buf[0] + indexd, frame->img.width);
  659. }
  660. for (j = 0; j < frame->img.height; j++) { //UV
  661. indexd = j*frame->img.strides[0];
  662. write(fd, buf[1]+ indexd, frame->img.width);
  663. }
  664. break;
  665. default:
  666. LOG_E("%s unsupported format to save\n", __func__);
  667. exit(-1);
  668. break;
  669. }
  670. close(fd);
  671. munmap(buf[0],buf_size);
  672. // munmap(buf[1],plane_size[1]);
  673. LOG_O("%s exit\n", __func__);
  674. }