dialog_channel_open.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  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 <ctype.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <curses.h>
  15. #define LOG_LEVEL 3
  16. #define LOG_PREFIX "dlg_prop_list"
  17. #include <syslog.h>
  18. #include <csi_camera_property.h>
  19. #include <csi_camera_platform_spec.h>
  20. #include <camera_manager.h>
  21. #include <camera_string.h>
  22. #include "param.h"
  23. #include "app_dialogs.h"
  24. extern cams_t *cam_session;
  25. static int fill_channel_config_items(csi_camera_channel_cfg_s *channel)
  26. {
  27. char str_buf[128];
  28. const char item_format[] = "%-14s";
  29. item_make(item_format, "capture_type");
  30. item_add_str(": (%s) --->", camera_string_chn_capture_types(channel->capture_type, str_buf));
  31. item_set_data(channel);
  32. item_make(item_format, "Capture fields");
  33. item_add_str(": (%s) --->", camera_string_chn_meta_fields(channel->meta_fields, str_buf));
  34. item_set_data(channel);
  35. item_make(item_format, "Buffer count");
  36. item_add_str(": (%d) --->", channel->frm_cnt);
  37. item_set_data(channel);
  38. item_make(item_format, "Image width");
  39. item_add_str(": (%d) --->", channel->img_fmt.width);
  40. item_set_data(channel);
  41. item_make(item_format, "Image height");
  42. item_add_str(": (%d) --->", channel->img_fmt.height);
  43. item_set_data(channel);
  44. item_make(item_format, "Pixel format");
  45. item_add_str(": (%s) --->", camera_string_pixel_format(channel->img_fmt.pix_fmt));
  46. item_set_data(channel);
  47. item_make(item_format, "Buffer type");
  48. item_add_str(": (%s) --->", camera_string_img_type(channel->img_type));
  49. item_set_data(channel);
  50. return 0;
  51. }
  52. typedef enum channel_param {
  53. CHANNEL_PARAM_CAPTURE_TYPE = 0,
  54. CHANNEL_PARAM_META_FIELDS,
  55. CHANNEL_PARAM_FRM_CNT,
  56. CHANNEL_PARAM_IMG_WIDTH,
  57. CHANNEL_PARAM_IMG_HEIGIT,
  58. CHANNEL_PARAM_IMG_PIX_FMT,
  59. CHANNEL_PARAM_IMG_TYPE,
  60. } channel_param_e;
  61. extern char dialog_input_result[MAX_LEN + 1];
  62. static int channel_config_integer(csi_camera_channel_cfg_s *channel, channel_param_e param)
  63. {
  64. int ret_key = KEY_ESC;
  65. char title[64];
  66. char prompt[64] = "Please enter the appropriate number";
  67. char str_value[32];
  68. if (channel == NULL) {
  69. LOG_W("channel is NULL\n");
  70. return KEY_ESC;
  71. }
  72. again:
  73. switch (param) {
  74. case CHANNEL_PARAM_FRM_CNT:
  75. snprintf(title, sizeof(title), "Config Channel[%d] %s",
  76. channel->chn_id, "Buffer Count");
  77. snprintf(str_value, sizeof(str_value), "%d", channel->frm_cnt);
  78. break;
  79. case CHANNEL_PARAM_IMG_WIDTH:
  80. snprintf(title, sizeof(title), "Config Channel[%d] %s",
  81. channel->chn_id, "Image Width");
  82. snprintf(str_value, sizeof(str_value), "%d", channel->img_fmt.width);
  83. break;
  84. case CHANNEL_PARAM_IMG_HEIGIT:
  85. snprintf(title, sizeof(title), "Config Channel[%d] %s",
  86. channel->chn_id, "Image Height");
  87. snprintf(str_value, sizeof(str_value), "%d", channel->img_fmt.height);
  88. break;
  89. default:
  90. break;
  91. }
  92. curs_set(1);
  93. ret_key = dialog_inputbox(title, prompt, 9, 40, str_value);
  94. curs_set(0);
  95. if (ret_key == KEY_ESC || ret_key == 1)
  96. return KEY_ESC;
  97. /* can't be empty */
  98. if (strlen(dialog_input_result) == 0) {
  99. goto again;
  100. }
  101. /* value check, reset if invalid */
  102. int value = atoi(dialog_input_result);
  103. if (value <= 0){
  104. goto again;
  105. }
  106. /* accept value, set into property */
  107. switch (param) {
  108. case CHANNEL_PARAM_FRM_CNT:
  109. if (value > 100){ // filt unreasonable out
  110. goto again;
  111. }
  112. channel->frm_cnt = value;
  113. break;
  114. case CHANNEL_PARAM_IMG_WIDTH:
  115. if (value > (7680*2)){ // filt unreasonable out
  116. goto again;
  117. }
  118. channel->img_fmt.width = value;
  119. break;
  120. case CHANNEL_PARAM_IMG_HEIGIT:
  121. if (value > (4320*2)){ // filt unreasonable out
  122. goto again;
  123. }
  124. channel->img_fmt.height = value;
  125. break;
  126. default:
  127. break;
  128. }
  129. return 0;
  130. }
  131. static int channel_config_enum(csi_camera_channel_cfg_s *channel, channel_param_e param)
  132. {
  133. int ret_key = KEY_ESC;
  134. char title[64];
  135. char prompt[64] = "Please select the appropriate enum item";
  136. char str_value[32];
  137. const camera_spec_enums_s *enums_array;
  138. if (channel == NULL) {
  139. LOG_W("channel is NULL\n");
  140. return KEY_ESC;
  141. }
  142. item_reset();
  143. switch (param) {
  144. case CHANNEL_PARAM_IMG_PIX_FMT:
  145. snprintf(title, sizeof(title), "Config Channel[%d] %s",
  146. channel->chn_id, "Image Pixel Format");
  147. enums_array = camera_spec_get_enum_array(CAMERA_SPEC_ENUM_CHANNEL_PIX_FMT);
  148. if (enums_array == NULL) {
  149. LOG_E("No enum array for CAMERA_SPEC_ENUM_CHN_PIX_FMT(%d)\n",
  150. CAMERA_SPEC_ENUM_CHANNEL_PIX_FMT);
  151. return KEY_ESC;
  152. }
  153. for (int i = 0; i < enums_array->count; i++) {
  154. item_make("%d-%s", enums_array->enums[i],
  155. camera_string_pixel_format(enums_array->enums[i]));
  156. //item_add_str("");
  157. if (channel->img_fmt.pix_fmt == enums_array->enums[i]) {
  158. item_set_selected(1);
  159. item_set_tag('X');
  160. } else {
  161. item_set_selected(0);
  162. item_set_tag(' ');
  163. }
  164. }
  165. break;
  166. case CHANNEL_PARAM_IMG_TYPE:
  167. snprintf(title, sizeof(title), "Config Channel[%d] %s",
  168. channel->chn_id, "Image Buffer Type");
  169. enums_array = camera_spec_get_enum_array(CAMERA_SPEC_ENUM_CHANNEL_IMG_TYPE);
  170. if (enums_array == NULL) {
  171. LOG_E("No enum array for CAMERA_SPEC_ENUM_CHN_IMG_TYPE(%08x)\n",
  172. CAMERA_SPEC_ENUM_CHANNEL_IMG_TYPE);
  173. return KEY_ESC;
  174. }
  175. for (int i = 0; i < enums_array->count; i++) {
  176. item_make("%d-%s", i, camera_string_img_type(i));
  177. //item_add_str("");
  178. if (channel->img_type == enums_array->enums[i]) {
  179. item_set_selected(1);
  180. item_set_tag('X');
  181. } else {
  182. item_set_selected(0);
  183. item_set_tag(' ');
  184. }
  185. }
  186. break;
  187. default:
  188. return KEY_ESC;
  189. }
  190. int list_height = MIN(enums_array->count + 1, 8);
  191. ret_key = dialog_checklist(
  192. title, prompt,
  193. CHECKLIST_HEIGTH_MIN + list_height + 2,
  194. WIN_COLS - CHECKLIST_WIDTH_MIN - 32,
  195. list_height,
  196. NULL, 0);
  197. LOG_D("dialog_checklist() ret_key=%d\n", ret_key);
  198. if (ret_key == KEY_ESC) {
  199. return KEY_ESC;
  200. } else if (ret_key == 0) { /* select */
  201. if (!item_is_selected())
  202. return KEY_ESC;
  203. int enum_id = enums_array->enums[item_n()];
  204. switch(param) {
  205. case CHANNEL_PARAM_IMG_PIX_FMT:
  206. LOG_D("select item: pos=%d, enum=%d:%s\n",
  207. item_n(), enum_id, camera_string_pixel_format(enum_id));
  208. channel->img_fmt.pix_fmt = enum_id;
  209. break;
  210. case CHANNEL_PARAM_IMG_TYPE:
  211. LOG_D("select item: pos=%d, enum=%d:%s\n",
  212. item_n(), enum_id, camera_string_img_type(enum_id));
  213. channel->img_type = enum_id;
  214. break;
  215. default:
  216. return KEY_ESC;
  217. }
  218. return ret_key;
  219. } else if (ret_key == 1) { /* help */
  220. LOG_W("Help does not support yet\n");
  221. return ret_key;
  222. } else {
  223. LOG_E("Unknown return value: %d\n", ret_key);
  224. return KEY_ESC;
  225. }
  226. return 0;
  227. }
  228. static int channel_config_bitmsk_capture_type(csi_camera_channel_cfg_s *channel)
  229. {
  230. int ret_key = KEY_ESC;
  231. if (channel == NULL) {
  232. LOG_W("channel is NULL\n");
  233. return KEY_ESC;
  234. }
  235. char title[64];
  236. char prompt[64] = "Please select the appropriate enum item";
  237. int item_pos = 0;
  238. snprintf(title, sizeof(title), "Config Channel[%d] Capture Types", channel->chn_id);
  239. const camera_spec_bitmasks_t *bitmasks_array =
  240. camera_spec_get_bitmask_array(CAMERA_SPEC_BITMAKS_CHANNEL_CAPTURE_TYPE);
  241. if (bitmasks_array == NULL)
  242. return KEY_ESC;
  243. again:
  244. item_reset();
  245. for (int i = 0; i < bitmasks_array->count; i++) {
  246. item_make("bit-%02d: %s", bitmasks_array->bitmask[i],
  247. camera_string_capture_type(bitmasks_array->bitmask[i], true));
  248. //item_add_str("");
  249. if (bitmasks_array->bitmask[i] & channel->capture_type) {
  250. item_set_selected(1);
  251. item_set_tag('*');
  252. }
  253. else {
  254. item_set_selected(0);
  255. item_set_tag(' ');
  256. }
  257. }
  258. int list_height = MIN(bitmasks_array->count + 1, 8);
  259. ret_key = dialog_checkbox(
  260. title, prompt,
  261. CHECKLIST_HEIGTH_MIN + list_height + 2,
  262. WIN_COLS - CHECKLIST_WIDTH_MIN - 32,
  263. list_height, item_pos);
  264. LOG_D("dialog_checkbox() ret_key=%d\n", ret_key);
  265. if (ret_key == KEY_ESC) {
  266. return KEY_ESC;
  267. } else if (ret_key == 0) {/* select */
  268. item_pos = item_n();
  269. int bitmask_value = bitmasks_array->bitmask[item_n()];
  270. if (item_is_selected()) {
  271. channel->capture_type |= bitmask_value;
  272. } else {
  273. channel->capture_type &= ~bitmask_value;
  274. }
  275. int enum_id = bitmasks_array->bitmask[item_n()];
  276. LOG_D("%s item: pos=%d, enum=%d-%s, bitmask_value=%08x\n",
  277. item_is_selected() ? "Select" : "Unselect",
  278. item_n(), enum_id,
  279. camera_string_capture_type(enum_id, true),
  280. channel->capture_type);
  281. goto again;
  282. return ret_key;
  283. } else if (ret_key == 1) {/* help */
  284. LOG_W("Help does not support yet\n");
  285. return ret_key;
  286. } else {
  287. LOG_E("Unknown return value: %d\n", ret_key);
  288. return KEY_ESC;
  289. }
  290. }
  291. static int channel_config_bitmsk_meta_type(csi_camera_channel_cfg_s *channel)
  292. {
  293. int ret_key = KEY_ESC;
  294. if (channel == NULL) {
  295. LOG_W("channel is NULL\n");
  296. return KEY_ESC;
  297. }
  298. char title[64];
  299. char prompt[64] = "Please select the appropriate enum item";
  300. int item_pos = 0;
  301. snprintf(title, sizeof(title), "Config Channel[%d] Meta Types", channel->chn_id);
  302. const camera_spec_bitmasks_t *bitmasks_array =
  303. camera_spec_get_bitmask_array(CAMERA_SPEC_BITMAKS_CHANNEL_META_TYPE);
  304. if (bitmasks_array == NULL)
  305. return KEY_ESC;
  306. again:
  307. item_reset();
  308. for (int i = 0; i < bitmasks_array->count; i++) {
  309. item_make("bit-%02d: %s", bitmasks_array->bitmask[i],
  310. camera_string_meta_field(bitmasks_array->bitmask[i], true));
  311. //item_add_str("");
  312. if (bitmasks_array->bitmask[i] & channel->meta_fields) {
  313. item_set_selected(1);
  314. item_set_tag('*');
  315. }
  316. else {
  317. item_set_selected(0);
  318. item_set_tag(' ');
  319. }
  320. }
  321. int list_height = MIN(bitmasks_array->count + 1, 8);
  322. ret_key = dialog_checkbox(
  323. title, prompt,
  324. CHECKLIST_HEIGTH_MIN + list_height + 2,
  325. WIN_COLS - CHECKLIST_WIDTH_MIN - 32,
  326. list_height, item_pos);
  327. LOG_D("dialog_checkbox() ret_key=%d\n", ret_key);
  328. if (ret_key == KEY_ESC) {
  329. return KEY_ESC;
  330. } else if (ret_key == 0) {/* select */
  331. item_pos = item_n();
  332. int bitmask_value = bitmasks_array->bitmask[item_n()];
  333. if (item_is_selected()) {
  334. channel->meta_fields |= bitmask_value;
  335. } else {
  336. channel->meta_fields &= ~bitmask_value;
  337. }
  338. int enum_id = bitmasks_array->bitmask[item_n()];
  339. LOG_D("%s item: pos=%d, enum=%d-%s, bitmask_value=%08x\n",
  340. item_is_selected() ? "Select" : "Unselect",
  341. item_n(), enum_id,
  342. camera_string_meta_field(enum_id, true),
  343. channel->meta_fields);
  344. goto again;
  345. return ret_key;
  346. } else if (ret_key == 1) {/* help */
  347. LOG_W("Help does not support yet\n");
  348. return ret_key;
  349. } else {
  350. LOG_E("Unknown return value: %d\n", ret_key);
  351. return KEY_ESC;
  352. }
  353. }
  354. /* return int: property rows */
  355. static int get_diff_string(char *text, csi_camera_channel_cfg_s *channel)
  356. {
  357. int count = 0;
  358. int total_len = 0;
  359. int add_len;
  360. text[0] = '\0';
  361. strcat(text,"-------------------------------------------\n");
  362. char item_name[64];
  363. char item_value[256];
  364. char str_buf1[128];
  365. char str_buf2[128];
  366. if(cam_session->chn_cfg_tmp.capture_type != channel->capture_type) {
  367. snprintf(item_name, sizeof(item_name), "%-14s", "capture type");
  368. snprintf(item_value, sizeof(item_value), ": (%s) => (%s)\n",
  369. camera_string_chn_capture_types(channel->capture_type, str_buf1),
  370. camera_string_chn_capture_types(cam_session->chn_cfg_tmp.capture_type, str_buf2));
  371. strcat(text, item_name);
  372. strcat(text, item_value);
  373. count++;
  374. }
  375. if(cam_session->chn_cfg_tmp.meta_fields != channel->meta_fields) {
  376. snprintf(item_name, sizeof(item_name), "%-14s", "Meta fields");
  377. snprintf(item_value, sizeof(item_value), ": (%s) =>\n\t\t (%s)\n",
  378. camera_string_chn_meta_fields(channel->meta_fields, str_buf1),
  379. camera_string_chn_meta_fields(cam_session->chn_cfg_tmp.meta_fields, str_buf2));
  380. strcat(text, item_name);
  381. strcat(text, item_value);
  382. count+=2;
  383. }
  384. if(cam_session->chn_cfg_tmp.frm_cnt != channel->frm_cnt) {
  385. snprintf(item_name, sizeof(item_name), "%-14s", "buffer count");
  386. snprintf(item_value, sizeof(item_value), ": (%d) => (%d)\n",
  387. channel->frm_cnt, cam_session->chn_cfg_tmp.frm_cnt);
  388. strcat(text, item_name);
  389. strcat(text, item_value);
  390. count++;
  391. }
  392. if(cam_session->chn_cfg_tmp.img_fmt.width != channel->img_fmt.width) {
  393. snprintf(item_name, sizeof(item_name), "%-14s", "Image width");
  394. snprintf(item_value, sizeof(item_value), ": (%d) => (%d)\n",
  395. channel->img_fmt.width, cam_session->chn_cfg_tmp.img_fmt.width);
  396. strcat(text, item_name);
  397. strcat(text, item_value);
  398. count++;
  399. }
  400. if(cam_session->chn_cfg_tmp.img_fmt.height != channel->img_fmt.height) {
  401. snprintf(item_name, sizeof(item_name), "%-14s", "Image height");
  402. snprintf(item_value, sizeof(item_value), ": (%d) => (%d)\n",
  403. channel->img_fmt.height, cam_session->chn_cfg_tmp.img_fmt.height);
  404. strcat(text, item_name);
  405. strcat(text, item_value);
  406. count++;
  407. }
  408. if(cam_session->chn_cfg_tmp.img_fmt.pix_fmt != channel->img_fmt.pix_fmt) {
  409. snprintf(item_name, sizeof(item_name), "%-14s", "Pixel format");
  410. snprintf(item_value, sizeof(item_value), ": (%s) => (%s)\n",
  411. camera_string_pixel_format(channel->img_fmt.pix_fmt),
  412. camera_string_pixel_format(cam_session->chn_cfg_tmp.img_fmt.pix_fmt));
  413. strcat(text, item_name);
  414. strcat(text, item_value);
  415. count++;
  416. }
  417. if(cam_session->chn_cfg_tmp.img_type != channel->img_type) {
  418. snprintf(item_name, sizeof(item_name), "%-14s", "Buffer type");
  419. snprintf(item_value, sizeof(item_value), ": (%s) => (%s)\n",
  420. camera_string_img_type(channel->img_type),
  421. camera_string_img_type(cam_session->chn_cfg_tmp.img_type));
  422. strcat(text, item_name);
  423. strcat(text, item_value);
  424. count++;
  425. }
  426. return count;
  427. }
  428. static int channel_open_internal(char *feedback)
  429. {
  430. int ret = camera_channel_open(cam_session, &cam_session->chn_cfg_tmp);
  431. if (ret != 0) {
  432. LOG_E("camera_channel_open() failed, ret=%d\n", ret);
  433. }
  434. if (feedback) {
  435. if (ret)
  436. sprintf(feedback, "camera_channel_open() failed, ret=%d\n", ret);
  437. else
  438. sprintf(feedback, "camera_channel_open() OK\n");
  439. }
  440. return ret;
  441. }
  442. int dialog_channel_open(csi_camera_channel_cfg_s *channel)
  443. {
  444. int ret_key = KEY_ESC;
  445. int ret = 0;
  446. char str_buf[1024];
  447. int item_pos = 0;
  448. csi_camera_channel_cfg_s *chn_tmp = &(cam_session->chn_cfg_tmp);
  449. memcpy(chn_tmp, channel, sizeof(*chn_tmp));
  450. again:
  451. item_reset();
  452. if (fill_channel_config_items(chn_tmp) != 0) {
  453. LOG_E("fill_channel_config_items() failed\n");
  454. ret = KEY_ESC;
  455. goto exit;
  456. }
  457. char *button_names[] = {"Config", " Open ", "Cancel"};
  458. int s_scroll = 0;
  459. snprintf(str_buf, sizeof(str_buf), "Config Camera[%d] - Channel[%d]",
  460. cam_session->camera_id, chn_tmp->chn_id);
  461. ret_key = dialog_menu(str_buf, "Select item, press Enter to config",
  462. WIN_ROWS-2, WIN_COLS, NULL, item_pos, &s_scroll, button_names, 3);
  463. item_pos = item_activate_selected_pos();
  464. LOG_D("dialog_menu() ret_key=%d, item_pos=%d\n", ret_key, item_pos);
  465. if (ret_key == 0) { /* Select button */
  466. if (item_pos == CHANNEL_PARAM_FRM_CNT ||
  467. item_pos == CHANNEL_PARAM_IMG_WIDTH ||
  468. item_pos == CHANNEL_PARAM_IMG_HEIGIT) {
  469. channel_config_integer(chn_tmp, item_pos);
  470. } else if (item_pos == CHANNEL_PARAM_IMG_PIX_FMT ||
  471. item_pos == CHANNEL_PARAM_IMG_TYPE) {
  472. channel_config_enum(chn_tmp, item_pos);
  473. } else if (item_pos == CHANNEL_PARAM_CAPTURE_TYPE) {
  474. channel_config_bitmsk_capture_type(chn_tmp);
  475. } else if (item_pos == CHANNEL_PARAM_META_FIELDS){
  476. channel_config_bitmsk_meta_type(chn_tmp);
  477. }
  478. goto again;
  479. } else if (ret_key == 1) { /* Open button */
  480. ret = channel_open_internal(str_buf);
  481. LOG_I("%s\n", str_buf);
  482. dialog_textbox_simple("Infomation", str_buf, 10, 40);
  483. if (ret != 0) {
  484. goto again;
  485. }
  486. goto exit;
  487. } else if (ret_key == 2) { /* Cancel button */
  488. // do nothing
  489. ret = KEY_ESC;
  490. goto exit;
  491. } else {
  492. ret = KEY_ESC;
  493. goto exit;
  494. }
  495. /* else, Select button */
  496. goto again;
  497. exit:
  498. return ret;
  499. }