camera_test.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "camera.h"
  2. #include "device.h"
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. double get_time()
  9. {
  10. struct timeval t;
  11. struct timezone tzp;
  12. gettimeofday(&t, &tzp);
  13. return t.tv_sec + t.tv_usec*1e-6;
  14. }
  15. void on_capture(MPImage image, void *user_data)
  16. {
  17. size_t num_bytes = mp_pixel_format_width_to_bytes(image.pixel_format, image.width) * image.height;
  18. uint8_t *data = malloc(num_bytes);
  19. memcpy(data, image.data, num_bytes);
  20. printf(" first byte: %d.", data[0]);
  21. free(data);
  22. }
  23. int main(int argc, char *argv[])
  24. {
  25. if (argc != 2 && argc != 3) {
  26. printf("Usage: %s <media_device_name> [<sub_device_name>]\n", argv[0]);
  27. return 1;
  28. }
  29. char *video_name = argv[1];
  30. char *subdev_name = NULL;
  31. if (argc == 3) {
  32. subdev_name = argv[2];
  33. }
  34. double find_start = get_time();
  35. // First find the device
  36. MPDevice *device = mp_device_find(video_name);
  37. if (!device) {
  38. printf("Device not found\n");
  39. return 1;
  40. }
  41. double find_end = get_time();
  42. printf("Finding the device took %fms\n", (find_end - find_start) * 1000);
  43. int video_fd;
  44. uint32_t video_entity_id;
  45. {
  46. const struct media_v2_entity *entity = mp_device_find_entity(device, video_name);
  47. if (!entity) {
  48. printf("Unable to find video device interface\n");
  49. return 1;
  50. }
  51. video_entity_id = entity->id;
  52. const struct media_v2_interface *iface = mp_device_find_entity_interface(device, video_entity_id);
  53. char buf[256];
  54. if (!mp_find_device_path(iface->devnode, buf, 256)) {
  55. printf("Unable to find video device path\n");
  56. return 1;
  57. }
  58. video_fd = open(buf, O_RDWR);
  59. if (video_fd == -1) {
  60. printf("Unable to open video device\n");
  61. return 1;
  62. }
  63. }
  64. int subdev_fd = -1;
  65. if (subdev_name)
  66. {
  67. const struct media_v2_entity *entity = mp_device_find_entity(device, subdev_name);
  68. if (!entity) {
  69. printf("Unable to find sub-device\n");
  70. return 1;
  71. }
  72. const struct media_v2_pad *source_pad = mp_device_get_pad_from_entity(device, entity->id);
  73. const struct media_v2_pad *sink_pad = mp_device_get_pad_from_entity(device, video_entity_id);
  74. // Disable other links
  75. const struct media_v2_entity *entities = mp_device_get_entities(device);
  76. for (int i = 0; i < mp_device_get_num_entities(device); ++i) {
  77. if (entities[i].id != video_entity_id && entities[i].id != entity->id) {
  78. const struct media_v2_pad *pad = mp_device_get_pad_from_entity(device, entities[i].id);
  79. mp_device_setup_link(device, pad->id, sink_pad->id, false);
  80. }
  81. }
  82. // Then enable ours
  83. mp_device_setup_link(device, source_pad->id, sink_pad->id, true);
  84. const struct media_v2_interface *iface = mp_device_find_entity_interface(device, entity->id);
  85. char buf[256];
  86. if (!mp_find_device_path(iface->devnode, buf, 256)) {
  87. printf("Unable to find sub-device path\n");
  88. return 1;
  89. }
  90. subdev_fd = open(buf, O_RDWR);
  91. if (subdev_fd == -1) {
  92. printf("Unable to open sub-device\n");
  93. return 1;
  94. }
  95. }
  96. double open_end = get_time();
  97. printf("Opening the device took %fms\n", (open_end - find_end) * 1000);
  98. MPCamera *camera = mp_camera_new(video_fd, subdev_fd);
  99. MPControlList *controls = mp_camera_list_controls(camera);
  100. double control_list_end = get_time();
  101. printf("Available controls: (took %fms)\n", (control_list_end - open_end) * 1000);
  102. for (MPControlList *list = controls; list; list = mp_control_list_next(list)) {
  103. MPControl *c = mp_control_list_get(list);
  104. printf(" %32s id:%s type:%s default:%d\n", c->name, mp_control_id_to_str(c->id), mp_control_type_to_str(c->type), c->default_value);
  105. }
  106. double mode_list_begin = get_time();
  107. MPCameraModeList *modes = mp_camera_list_available_modes(camera);
  108. double mode_list_end = get_time();
  109. printf("Available modes: (took %fms)\n", (mode_list_end - mode_list_begin) * 1000);
  110. for (MPCameraModeList *list = modes; list; list = mp_camera_mode_list_next(list)) {
  111. MPCameraMode *m = mp_camera_mode_list_get(list);
  112. printf(" %dx%d interval:%d/%d fmt:%s\n", m->width, m->height, m->frame_interval.numerator, m->frame_interval.denominator, mp_pixel_format_to_str(m->pixel_format));
  113. // Skip really slow framerates
  114. if (m->frame_interval.denominator < 15) {
  115. printf(" Skipping…\n");
  116. continue;
  117. }
  118. double start_capture = get_time();
  119. mp_camera_set_mode(camera, m);
  120. mp_camera_start_capture(camera);
  121. double last = get_time();
  122. printf(" Testing 10 captures, starting took %fms\n", (last - start_capture) * 1000);
  123. for (int i = 0; i < 10; ++i) {
  124. mp_camera_capture_image(camera, on_capture, NULL);
  125. double now = get_time();
  126. printf(" capture took %fms\n", (now - last) * 1000);
  127. last = now;
  128. }
  129. mp_camera_stop_capture(camera);
  130. }
  131. double cleanup_start = get_time();
  132. mp_camera_free(camera);
  133. close(video_fd);
  134. if (subdev_fd != -1)
  135. close(subdev_fd);
  136. mp_device_close(device);
  137. double cleanup_end = get_time();
  138. printf("Cleanup took %fms\n", (cleanup_end - cleanup_start) * 1000);
  139. }