io_pipeline.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. #include "io_pipeline.h"
  2. #include "camera.h"
  3. #include "flash.h"
  4. #include "pipeline.h"
  5. #include "process_pipeline.h"
  6. #include "state.h"
  7. #include <assert.h>
  8. #include <errno.h>
  9. #include <fcntl.h>
  10. #include <glib.h>
  11. #include <math.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <sys/ioctl.h>
  15. mp_state_io state_io;
  16. MPCamera *mpcamera = NULL;
  17. static MPPipeline *pipeline;
  18. static GSource *capture_source;
  19. static void
  20. setup(MPPipeline *pipeline, const void *data)
  21. {
  22. return;
  23. }
  24. void
  25. mp_io_pipeline_start()
  26. {
  27. mp_process_pipeline_start();
  28. pipeline = mp_pipeline_new();
  29. mp_pipeline_invoke(pipeline, setup, NULL, 0);
  30. }
  31. void
  32. mp_io_pipeline_stop()
  33. {
  34. if (capture_source) {
  35. g_source_destroy(capture_source);
  36. }
  37. mp_pipeline_free(pipeline);
  38. mp_process_pipeline_stop();
  39. }
  40. /*
  41. * Update state from IO -> Process
  42. */
  43. static void
  44. update_process_pipeline()
  45. {
  46. // Grab the latest control values
  47. if (!state_io.gain.manual && state_io.gain.control) {
  48. state_io.gain.value = mp_camera_control_get_int32(
  49. state_io.camera, state_io.gain.control);
  50. }
  51. if (!state_io.exposure.manual && state_io.exposure.control) {
  52. state_io.exposure.value = mp_camera_control_get_int32(
  53. state_io.camera, state_io.exposure.control);
  54. }
  55. float balance_red = 1.0f;
  56. float balance_blue = 1.0f;
  57. if (state_io.red.control && state_io.blue.control) {
  58. int red = mp_camera_control_get_int32(state_io.camera,
  59. state_io.red.control);
  60. int blue = mp_camera_control_get_int32(state_io.camera,
  61. state_io.blue.control);
  62. balance_red = (float)red / (float)state_io.red.max;
  63. balance_blue = (float)blue / (float)state_io.blue.max;
  64. }
  65. struct mp_process_pipeline_state pipeline_state = {
  66. .camera = state_io.camera,
  67. .burst_length = state_io.burst_length,
  68. .preview_width = state_io.preview_width,
  69. .preview_height = state_io.preview_height,
  70. .device_rotation = state_io.device_rotation,
  71. .gain_is_manual = state_io.gain.manual,
  72. .gain = state_io.gain.value,
  73. .gain_max = state_io.gain.max,
  74. .balance_red = balance_red,
  75. .balance_blue = balance_blue,
  76. .exposure_is_manual = state_io.exposure.manual,
  77. .exposure = state_io.exposure.value,
  78. .has_auto_focus_continuous = state_io.focus.control != 0,
  79. .has_auto_focus_start = state_io.can_af_trigger,
  80. .flash_enabled = state_io.flash_enabled,
  81. .control_gain = state_io.gain.control != 0,
  82. .control_exposure = state_io.exposure.control != 0,
  83. .control_focus = state_io.focus.control != 0,
  84. .control_flash = true,
  85. };
  86. mp_process_pipeline_update_state(&pipeline_state);
  87. }
  88. static void
  89. focus(MPPipeline *pipeline, const void *data)
  90. {
  91. state_io.trigger_af = true;
  92. }
  93. void
  94. mp_io_pipeline_focus()
  95. {
  96. mp_pipeline_invoke(pipeline, focus, NULL, 0);
  97. }
  98. static void
  99. capture(MPPipeline *pipeline, const void *data)
  100. {
  101. float gain_norm;
  102. // Disable the autogain/exposure while taking the burst
  103. mp_camera_control_set_int32(state_io.camera, V4L2_CID_AUTOGAIN, 0);
  104. mp_camera_control_set_int32(
  105. state_io.camera, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL);
  106. // Get current gain to calculate a burst length;
  107. // with low gain there's 3, with the max automatic gain of the ov5640
  108. // the value seems to be 248 which creates a 5 frame burst
  109. // for manual gain you can go up to 11 frames
  110. state_io.gain.value =
  111. mp_camera_control_get_int32(state_io.camera, V4L2_CID_GAIN);
  112. gain_norm = (float)state_io.gain.value / (float)state_io.gain.max;
  113. state_io.burst_length = (int)fmax(sqrtf(gain_norm) * 10, 2) + 1;
  114. state_io.burst_length = MAX(1, state_io.burst_length);
  115. state_io.captures_remaining = state_io.burst_length;
  116. // Change camera mode for capturing
  117. mp_process_pipeline_sync();
  118. mp_camera_stop_capture(mpcamera);
  119. struct v4l2_format format = { 0 };
  120. libmegapixels_select_mode(state_io.camera, state_io.mode_capture, &format);
  121. state_io.flush_pipeline = true;
  122. mp_camera_start_capture(mpcamera);
  123. // Enable flash
  124. /* TODO: implement
  125. if (info->flash && flash_enabled) {
  126. mp_flash_enable(info->flash);
  127. }
  128. */
  129. update_process_pipeline();
  130. mp_process_pipeline_capture();
  131. }
  132. void
  133. mp_io_pipeline_capture()
  134. {
  135. mp_pipeline_invoke(pipeline, capture, NULL, 0);
  136. }
  137. static void
  138. release_buffer(MPPipeline *pipeline, const uint32_t *buffer_index)
  139. {
  140. mp_camera_release_buffer(mpcamera, *buffer_index);
  141. }
  142. void
  143. mp_io_pipeline_release_buffer(uint32_t buffer_index)
  144. {
  145. mp_pipeline_invoke(pipeline,
  146. (MPPipelineCallback)release_buffer,
  147. &buffer_index,
  148. sizeof(uint32_t));
  149. }
  150. static pid_t focus_continuous_task = 0;
  151. static pid_t start_focus_task = 0;
  152. static void
  153. start_focus()
  154. {
  155. // only run 1 manual focus at once
  156. if (!mp_camera_check_task_complete(mpcamera, start_focus_task) ||
  157. !mp_camera_check_task_complete(mpcamera, focus_continuous_task))
  158. return;
  159. if (state_io.focus.control) {
  160. focus_continuous_task = mp_camera_control_set_bool_bg(
  161. state_io.camera, state_io.focus.control, 1);
  162. } else if (state_io.can_af_trigger) {
  163. start_focus_task = mp_camera_control_set_bool_bg(
  164. state_io.camera, V4L2_CID_AUTO_FOCUS_START, 1);
  165. }
  166. }
  167. static void
  168. update_controls()
  169. {
  170. // Don't update controls while capturing
  171. if (state_io.captures_remaining > 0) {
  172. return;
  173. }
  174. if (state_io.trigger_af) {
  175. state_io.trigger_af = false;
  176. start_focus();
  177. }
  178. if (state_io.gain.manual != state_io.gain.manual_req) {
  179. mp_camera_control_set_bool_bg(state_io.camera,
  180. V4L2_CID_AUTOGAIN,
  181. !state_io.gain.manual_req);
  182. state_io.gain.manual = state_io.gain.manual_req;
  183. }
  184. if (state_io.gain.manual && state_io.gain.value != state_io.gain.value_req) {
  185. mp_camera_control_set_int32_bg(state_io.camera,
  186. state_io.gain.control,
  187. state_io.gain.value_req);
  188. state_io.gain.value = state_io.gain.value_req;
  189. }
  190. if (state_io.exposure.manual != state_io.exposure.manual_req) {
  191. mp_camera_control_set_bool_bg(state_io.camera,
  192. V4L2_CID_EXPOSURE_AUTO,
  193. state_io.exposure.manual_req ?
  194. V4L2_EXPOSURE_MANUAL :
  195. V4L2_EXPOSURE_AUTO);
  196. state_io.exposure.manual = state_io.exposure.manual_req;
  197. }
  198. if (state_io.exposure.manual &&
  199. state_io.exposure.value != state_io.exposure.value_req) {
  200. mp_camera_control_set_int32_bg(state_io.camera,
  201. state_io.exposure.control,
  202. state_io.exposure.value_req);
  203. state_io.exposure.value = state_io.exposure.value_req;
  204. }
  205. }
  206. static void
  207. on_frame(MPBuffer buffer, void *_data)
  208. {
  209. // Only update controls right after a frame was captured
  210. update_controls();
  211. // When the mode is switched while capturing we get a couple blank frames,
  212. // presumably from buffers made ready during the switch. Ignore these.
  213. if (state_io.flush_pipeline) {
  214. if (state_io.blank_frame_count < 20) {
  215. // Only check a 10x10 area
  216. size_t test_size =
  217. MIN(10, state_io.camera->current_mode->width) *
  218. MIN(10, state_io.camera->current_mode->height);
  219. bool image_is_blank = true;
  220. for (size_t i = 0; i < test_size; ++i) {
  221. if (buffer.data[i] != 0) {
  222. image_is_blank = false;
  223. }
  224. }
  225. if (image_is_blank) {
  226. ++state_io.blank_frame_count;
  227. return;
  228. }
  229. } else {
  230. printf("Blank image limit reached, resulting capture may be blank\n");
  231. }
  232. state_io.flush_pipeline = false;
  233. state_io.blank_frame_count = 0;
  234. }
  235. // Send the image off for processing
  236. mp_process_pipeline_process_image(buffer);
  237. if (state_io.captures_remaining > 0) {
  238. --state_io.captures_remaining;
  239. if (state_io.captures_remaining == 0) {
  240. // Restore the auto exposure and gain if needed
  241. if (!state_io.exposure.manual) {
  242. mp_camera_control_set_int32_bg(
  243. state_io.camera,
  244. V4L2_CID_EXPOSURE_AUTO,
  245. V4L2_EXPOSURE_AUTO);
  246. }
  247. if (!state_io.gain.manual) {
  248. mp_camera_control_set_bool_bg(
  249. state_io.camera, V4L2_CID_AUTOGAIN, true);
  250. }
  251. // Go back to preview mode
  252. mp_process_pipeline_sync();
  253. mp_camera_stop_capture(mpcamera);
  254. struct v4l2_format format = { 0 };
  255. libmegapixels_select_mode(
  256. state_io.camera, state_io.mode_preview, &format);
  257. state_io.flush_pipeline = true;
  258. mp_camera_start_capture(mpcamera);
  259. // Disable flash
  260. /* TODO: implement
  261. if (info->flash && flash_enabled) {
  262. mp_flash_disable(info->flash);
  263. }
  264. */
  265. update_process_pipeline();
  266. }
  267. }
  268. }
  269. static void
  270. init_controls()
  271. {
  272. if (mp_camera_query_control(
  273. state_io.camera, V4L2_CID_FOCUS_ABSOLUTE, NULL)) {
  274. // TODO: Set focus state
  275. state_io.focus.control = V4L2_CID_FOCUS_ABSOLUTE;
  276. } else {
  277. state_io.focus.control = 0;
  278. }
  279. if (mp_camera_query_control(state_io.camera, V4L2_CID_FOCUS_AUTO, NULL)) {
  280. mp_camera_control_set_bool_bg(
  281. state_io.camera, V4L2_CID_FOCUS_AUTO, true);
  282. }
  283. state_io.can_af_trigger = mp_camera_query_control(
  284. state_io.camera, V4L2_CID_AUTO_FOCUS_START, NULL);
  285. MPControl control;
  286. if (mp_camera_query_control(state_io.camera, V4L2_CID_GAIN, &control)) {
  287. state_io.gain.control = V4L2_CID_GAIN;
  288. state_io.gain.max = control.max;
  289. } else if (mp_camera_query_control(
  290. state_io.camera, V4L2_CID_ANALOGUE_GAIN, &control)) {
  291. state_io.gain.control = V4L2_CID_ANALOGUE_GAIN;
  292. state_io.gain.max = control.max;
  293. } else {
  294. state_io.gain.max = 0;
  295. state_io.gain.control = 0;
  296. }
  297. if (state_io.gain.control) {
  298. state_io.gain.value = mp_camera_control_get_int32(
  299. state_io.camera, state_io.gain.control);
  300. } else {
  301. state_io.gain.value = 0;
  302. }
  303. state_io.gain.manual =
  304. mp_camera_control_get_bool(state_io.camera, V4L2_CID_AUTOGAIN) == 0;
  305. state_io.exposure.value =
  306. mp_camera_control_get_int32(state_io.camera, V4L2_CID_EXPOSURE);
  307. state_io.exposure.manual =
  308. mp_camera_control_get_int32(state_io.camera,
  309. V4L2_CID_EXPOSURE_AUTO) ==
  310. V4L2_EXPOSURE_MANUAL;
  311. if (mp_camera_query_control(
  312. state_io.camera, V4L2_CID_RED_BALANCE, &control)) {
  313. state_io.red.control = V4L2_CID_RED_BALANCE;
  314. state_io.red.max = control.max;
  315. } else {
  316. state_io.red.control = 0;
  317. }
  318. if (mp_camera_query_control(
  319. state_io.camera, V4L2_CID_BLUE_BALANCE, &control)) {
  320. state_io.blue.control = V4L2_CID_BLUE_BALANCE;
  321. state_io.blue.max = control.max;
  322. } else {
  323. state_io.blue.control = 0;
  324. }
  325. }
  326. /*
  327. * State transfer from Main -> IO
  328. */
  329. static void
  330. update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
  331. {
  332. if (state_io.camera != state->camera) {
  333. if (state_io.camera != NULL) {
  334. mp_process_pipeline_sync();
  335. mp_camera_stop_capture(mpcamera);
  336. libmegapixels_close(state_io.camera);
  337. }
  338. if (capture_source) {
  339. g_source_destroy(capture_source);
  340. capture_source = NULL;
  341. }
  342. state_io.camera = state->camera;
  343. if (state_io.camera) {
  344. libmegapixels_open(state_io.camera);
  345. mpcamera = mp_camera_new(state_io.camera);
  346. state_io.mode_preview = NULL;
  347. state_io.mode_capture = NULL;
  348. float score = 0;
  349. int area_preview =
  350. state_io.preview_width * state_io.preview_height;
  351. for (int m = 0; m < state_io.camera->num_modes; m++) {
  352. float mscore = 0;
  353. if (state_io.camera->modes[m]->rate > 29) {
  354. mscore += 1;
  355. }
  356. int mode_area = state_io.camera->modes[m]->width *
  357. state_io.camera->modes[m]->height;
  358. mscore += 1.0f -
  359. (float)(ABS(mode_area - area_preview) /
  360. area_preview);
  361. if (mscore > score) {
  362. state_io.mode_preview =
  363. state_io.camera->modes[m];
  364. score = mscore;
  365. }
  366. }
  367. long area = 0;
  368. for (int m = 0; m < state_io.camera->num_modes; m++) {
  369. long this_pixels = state_io.camera->modes[m]->width *
  370. state_io.camera->modes[m]->height;
  371. if (this_pixels > area) {
  372. area = this_pixels;
  373. state_io.mode_capture =
  374. state_io.camera->modes[m];
  375. }
  376. }
  377. if (state_io.mode_preview == NULL &&
  378. state_io.mode_capture != NULL) {
  379. // If no fast preview mode is available, make due
  380. // with slow modes.
  381. state_io.mode_preview = state_io.mode_capture;
  382. }
  383. if (state_io.mode_preview != NULL) {
  384. if (state_io.camera->video_fd == 0) {
  385. libmegapixels_open(state_io.camera);
  386. }
  387. struct v4l2_format format = { 0 };
  388. libmegapixels_select_mode(state_io.camera,
  389. state_io.mode_preview,
  390. &format);
  391. }
  392. mp_camera_start_capture(mpcamera);
  393. capture_source = mp_pipeline_add_capture_source(
  394. pipeline, mpcamera, on_frame, NULL);
  395. init_controls();
  396. }
  397. }
  398. state_io.burst_length = state->burst_length;
  399. state_io.preview_width = state->preview_width;
  400. state_io.preview_height = state->preview_height;
  401. state_io.device_rotation = state->device_rotation;
  402. if (state_io.camera) {
  403. state_io.gain.manual_req = state->gain_is_manual;
  404. state_io.gain.value_req = state->gain;
  405. state_io.exposure.manual_req = state->exposure_is_manual;
  406. state_io.exposure.value_req = state->exposure;
  407. state_io.flash_enabled = state->flash_enabled;
  408. }
  409. update_process_pipeline();
  410. }
  411. void
  412. mp_io_pipeline_update_state(const struct mp_io_pipeline_state *state)
  413. {
  414. mp_pipeline_invoke(pipeline,
  415. (MPPipelineCallback)update_state,
  416. state,
  417. sizeof(struct mp_io_pipeline_state));
  418. }