frame_demo2_consumer.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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 <errno.h>
  13. #include <fcntl.h>
  14. #include <unistd.h>
  15. #include <sys/stat.h>
  16. #include <sys/ioctl.h>
  17. #include <sys/mman.h>
  18. #include <sys/time.h>
  19. #include <sys/wait.h>
  20. #include <sys/socket.h>
  21. #define LOG_LEVEL 3
  22. #define LOG_PREFIX "consumer"
  23. #include <syslog.h>
  24. #include <dump_utils.h>
  25. #include <ion.h>
  26. #include <csi_frame.h>
  27. #include <csi_camera_frame.h>
  28. #include "frame_demo_common.h"
  29. extern const char *img_name;
  30. extern csi_img_format_t img_format;
  31. int consumer_process(int socket_fd)
  32. {
  33. int ret = -1;
  34. LOG_D("Starting consumer\n");
  35. sleep(1); // waiting for producer exit to watch log easily
  36. if (socket_fd <= 0) {
  37. LOG_E("socket_fd(%d) is invalid\n", socket_fd);
  38. goto LAB_ERR;
  39. }
  40. LOG_D("The input socket_fd=%d\n", socket_fd);
  41. struct msghdr msghdr_recv = { // init data
  42. .msg_name = NULL, // the socket address
  43. .msg_namelen = 0, // len of socket name
  44. };
  45. char ctrls[CMSG_SPACE(sizeof(int)*3)] = {};
  46. memset(ctrls, 0, sizeof(ctrls));
  47. msghdr_recv.msg_control = ctrls;
  48. msghdr_recv.msg_controllen = sizeof(ctrls);
  49. csi_frame_s camera_frame;
  50. csi_camera_meta_s camera_meta;
  51. char meta_data[CSI_CAMERA_META_MAX_LEN]; //CSI_CAMERA_META_MAX_LEN
  52. struct iovec iov[3];
  53. iov[0].iov_base = &camera_frame.img; // iov[0] stores csi_frame.img info
  54. iov[0].iov_len = sizeof(camera_frame.img);
  55. iov[1].iov_base = &camera_frame.meta; // iov[1] stores csi_frame.meta info
  56. iov[1].iov_len = sizeof(camera_frame.meta);
  57. iov[2].iov_base = meta_data; // iov[2] stores csi_frame.meta data
  58. iov[2].iov_len = sizeof(meta_data);
  59. msghdr_recv.msg_iov = iov; // the io/vector info
  60. msghdr_recv.msg_iovlen = CSI_IMAGE_MAX_PLANES; // the num of iov
  61. ssize_t recv_len;
  62. if ((recv_len = recvmsg(socket_fd, &msghdr_recv, 0)) < 0) {
  63. // the msg is recv by msghdr_recv
  64. LOG_E("recv error:%d, %s\n", errno, strerror(errno));
  65. goto LAB_ERR;
  66. }
  67. LOG_D("recvmsg() length=%zd\n", recv_len);
  68. fdc_dump_msghdr(&msghdr_recv);
  69. int msghdr_count = 0;
  70. struct cmsghdr *pCmsghdr = NULL; // the pointer of control
  71. for (pCmsghdr = CMSG_FIRSTHDR(&msghdr_recv); pCmsghdr != NULL;
  72. pCmsghdr = CMSG_NXTHDR(&msghdr_recv,pCmsghdr)) {
  73. msghdr_count++;
  74. }
  75. LOG_D("msghdr_count=%d\n", msghdr_count);
  76. // now, only 1 plane even in I420 format (CSI_IMAGE_I420_PLANES)
  77. if ((pCmsghdr = CMSG_FIRSTHDR(&msghdr_recv)) != NULL &&
  78. pCmsghdr->cmsg_len == CMSG_LEN(sizeof(int) * 1)) {
  79. if (pCmsghdr->cmsg_level != SOL_SOCKET) {
  80. LOG_E("Ctl level should be SOL_SOCKET\n");
  81. goto LAB_ERR;
  82. }
  83. if (pCmsghdr->cmsg_type != SCM_RIGHTS) {
  84. LOG_E("Ctl type should be SCM_RIGHTS\n");
  85. goto LAB_ERR;
  86. }
  87. int fd_count = (pCmsghdr->cmsg_len - CMSG_SPACE(0)) / sizeof(int);
  88. LOG_D("pCmsghdr->cmsg_len=%zd, fd_count=%d\n", pCmsghdr->cmsg_len, fd_count);
  89. int *fdptr = (int *) CMSG_DATA(pCmsghdr);
  90. for (int i = 0; i < CSI_IMAGE_MAX_PLANES; i ++) {
  91. if (i < fd_count)
  92. camera_frame.img.fds[i] = fdptr[i];
  93. else
  94. camera_frame.img.fds[i] = -1;
  95. }
  96. } else {
  97. if (pCmsghdr == NULL)
  98. LOG_E("pCmsghdr=%p\n", pCmsghdr);
  99. else
  100. LOG_E("pCmsghdr->cmsg_len=%zu, should=%zu\n",
  101. pCmsghdr->cmsg_len,
  102. CMSG_LEN(sizeof(int) * CSI_IMAGE_MAX_PLANES));
  103. goto LAB_ERR;
  104. }
  105. int dma_buf_fd = camera_frame.img.fds[0];
  106. LOG_D("recvmsg() with dmabuf_fds={%d, %d, %d}\n",
  107. camera_frame.img.fds[0], camera_frame.img.fds[1], camera_frame.img.fds[2]);
  108. // fill camera frame img fds
  109. camera_frame.meta.data = meta_data;
  110. csi_dump_hex((char *)(&camera_frame.meta), sizeof(camera_frame.meta), "meta");
  111. csi_dump_hex(camera_frame.meta.data, camera_frame.meta.size, "consumer: meta.data");
  112. csi_dump_img_info(&camera_frame.img);
  113. csi_camera_meta_s *camera_meta_data = (csi_camera_meta_s *)camera_frame.meta.data;
  114. camera_meta_data->units = (csi_camrea_meta_unit_s *)((char *)camera_meta_data + sizeof(csi_camera_meta_s));
  115. fdc_dump_camera_meta(camera_meta_data);
  116. LOG_D("csi frame meta = {type=%d, size=%zd, data=%p}\n",
  117. camera_frame.meta.type, camera_frame.meta.size, camera_frame.meta.data);
  118. LOG_D("csi camera meta = {.count=%d, .size=%zd, .units=%p}\n",
  119. camera_meta_data->count, camera_meta_data->size, camera_meta_data->units);
  120. // save image file
  121. const char *save_file_name = "consumer_dump_file.yuv";
  122. remove(save_file_name);
  123. FILE *dump_file = fopen(save_file_name, "wb");
  124. if (dump_file) {
  125. void *addr = NULL;
  126. int length = 0;
  127. length = camera_frame.img.size; //(img_format.height * img_format.width);
  128. ret = fdc_mmap_dmabuf_addr(&addr, length, camera_frame.img.fds[0]);
  129. LOG_D("ret=%d, addr=%p, lenght=%d\n", ret, addr, length);
  130. if (ret == 0 || addr != NULL) {
  131. size_t write_len = fwrite(addr, length, 1, dump_file);
  132. LOG_O("dump dma-buf into '%s', write_len=%zd\n",
  133. save_file_name, write_len);
  134. }
  135. fclose(dump_file);
  136. } else {
  137. LOG_E("fopen failed, %s\n", strerror(errno));
  138. }
  139. //fclose(dump_file);
  140. for (int i = 0; i < CSI_IMAGE_MAX_PLANES; i++) {
  141. if (camera_frame.img.fds[i] > 0) {
  142. ret = close(camera_frame.img.fds[i]);
  143. LOG_D("close(camera_frame.img.fds[%d]) ret=%d, %s\n",
  144. i, errno, strerror(errno));
  145. }
  146. }
  147. ret = close(socket_fd);
  148. LOG_D("close(socket_fd) ret=%d, %s\n", errno, strerror(errno));
  149. ret = 0;
  150. LAB_ERR:
  151. if (ret)
  152. LOG_E("Exiting consumer\n");
  153. else
  154. LOG_D("Exiting consumer\n");
  155. return ret;
  156. }