frame_demo2_producer.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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 "producer"
  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 producer_process(int socket_fd)
  32. {
  33. int ret = -1;
  34. int img_fd;
  35. long img_size;
  36. int ion_fd;
  37. int dmabuf_fd;
  38. void *dmabuf_addr;
  39. csi_frame_s camera_frame;
  40. csi_camera_meta_s *camera_meta;
  41. LOG_D("Starting producer\n");
  42. if (socket_fd <= 0) {
  43. LOG_E("socket_fd(%d) is invalid\n", socket_fd);
  44. goto LAB_EXIT;
  45. }
  46. LOG_D("The input socket_fd=%d\n", socket_fd);
  47. // get image file size
  48. if (fdc_get_img_file_size(&img_size, img_name) != 0)
  49. goto LAB_EXIT;
  50. // open ion device
  51. if (fdc_get_ion_device_fd(&ion_fd) != 0)
  52. goto LAB_EXIT;
  53. // alloc dma-buf from ion device
  54. struct ion_allocation_data alloc_data;
  55. if (fdc_alloc_ion_buf(&alloc_data, ion_fd, img_size) != 0)
  56. goto LAB_ERR_ION_OPENED;
  57. dmabuf_fd = alloc_data.fd;
  58. // map dma-buf to user addr
  59. if (fdc_mmap_dmabuf_addr(&dmabuf_addr, img_size, dmabuf_fd) != 0) // should do unmap!!!!!!!!!!!!!!!!!
  60. goto LAB_ERR_BUF_ALLOCED;
  61. // open image file
  62. img_fd = open(img_name, O_RDONLY);
  63. if (img_fd < 0) {
  64. LOG_E("Open image file '%s' failed, %s\n",
  65. img_name, strerror(errno));
  66. goto LAB_ERR_MMAPPED;
  67. }
  68. // store image into dma-buf
  69. if (fdc_store_img_to_dmabuf(dmabuf_addr, img_fd, img_size) != 0)
  70. goto LAB_ERR_IMG_OPENED;
  71. // create csi_frame
  72. if (fdc_create_csi_frame(&camera_frame, &img_format, &camera_meta,
  73. img_size, dmabuf_fd, dmabuf_addr) != 0)
  74. goto LAB_ERR_IMG_OPENED;
  75. // dump camera meta from csi frame
  76. fdc_dump_camera_meta((csi_camera_meta_s *)camera_frame.meta.data);
  77. csi_dump_hex((char*)camera_meta, camera_frame.meta.size, "producer: meta.data");
  78. csi_dump_img_info(&camera_frame.img);
  79. ////////////////////////////////////////////////////////////////////////
  80. // store csi_frame into socket msg and send begin
  81. struct msghdr msghdr_send = { // init data
  82. .msg_name = NULL, // the socket address
  83. .msg_namelen = 0, // len of socket name
  84. };
  85. int transfer_fd_count = 1; // it's YUV420P, has only 2 planes
  86. char ctrls[CMSG_SPACE(sizeof(int)) * CSI_IMAGE_MAX_PLANES] = {}; // store dma-buf fd
  87. msghdr_send.msg_control = ctrls;
  88. msghdr_send.msg_controllen = CMSG_SPACE(sizeof(int)) * transfer_fd_count;
  89. LOG_D("msg_controllen = %zd\n", msghdr_send.msg_controllen);
  90. struct cmsghdr *pCmsghdr; // the pointer of control
  91. int *fdptr = (int *) CMSG_DATA(pCmsghdr);
  92. // the 1st info stores dma-buf fd[0]
  93. pCmsghdr = CMSG_FIRSTHDR(&msghdr_send); // the info of head
  94. pCmsghdr->cmsg_len = CMSG_LEN(sizeof(int)); // the msg len
  95. pCmsghdr->cmsg_level = SOL_SOCKET; // stream mode
  96. pCmsghdr->cmsg_type = SCM_RIGHTS; // file descriptor
  97. fdptr = (int *) CMSG_DATA(pCmsghdr);
  98. *fdptr = camera_frame.img.fds[0];
  99. struct iovec iov[3]; // io vector strores csi_frame
  100. iov[0].iov_base = &camera_frame.img; // iov[0] stores csi_frame.img
  101. iov[0].iov_len = sizeof(camera_frame.img);
  102. iov[1].iov_base = &camera_frame.meta; // iov[1] stores csi_frame.meta info
  103. iov[1].iov_len = sizeof(camera_frame.meta);
  104. iov[2].iov_base = camera_frame.meta.data; // iov[2] stores csi_frame.meta data
  105. iov[2].iov_len = sizeof(camera_frame.meta) + camera_frame.meta.size;
  106. msghdr_send.msg_iov = iov; // the io/vector info
  107. msghdr_send.msg_iovlen = 3; // the num of iov
  108. ssize_t size = sendmsg(socket_fd, &msghdr_send, 0);// send msg now
  109. if (size < 0) {
  110. LOG_E("sendmsg() failed, errno=%d, %s\n", errno, strerror(errno));
  111. } else if (size == 0) {
  112. LOG_W("sendmsg() failed, %zd bytes\n", size);
  113. } else {
  114. LOG_O("sendmsg() OK, %zd bytes\n", size);
  115. }
  116. // destory csi_frame
  117. fdc_destory_csi_frame(&camera_frame);
  118. ret = 0;
  119. LAB_ERR_IMG_OPENED:
  120. ret = close(img_fd);
  121. LOG_D("close(img_fd) ret=%d, %s\n", ret, strerror(errno));
  122. LAB_ERR_MMAPPED:
  123. ret = munmap(dmabuf_addr, img_size);
  124. LOG_D("munmap() ret=%d, %s\n", ret, strerror(errno));
  125. LAB_ERR_BUF_ALLOCED:
  126. ret = close(dmabuf_fd);
  127. LOG_D("close(dmabuf_fd) ret=%d, %s\n", ret, strerror(errno));
  128. LAB_ERR_ION_OPENED:
  129. close(ion_fd);
  130. LOG_D("close(ion_fd) ret=%d, %s\n", ret, strerror(errno));
  131. LAB_EXIT:
  132. ret = close(socket_fd);
  133. LOG_D("close(socket_fd) ret=%d, %s\n", ret, strerror(errno));
  134. if (ret)
  135. LOG_E("Exiting producer\n");
  136. else
  137. LOG_D("Exiting producer\n");
  138. return ret;
  139. }