From 99699802511f3d945668d99c6b269f86045efdc6 Mon Sep 17 00:00:00 2001 From: leiju <3074194431@qq.com> Date: Tue, 28 Aug 2018 09:15:03 +0800 Subject: [PATCH] add camera_server --- camera_server/Makefile | 11 ++ camera_server/include/camera.h | 11 ++ camera_server/include/convert.h | 9 + camera_server/include/jpg.h | 11 ++ camera_server/include/tcp.h | 21 +++ camera_server/src/camera.c | 251 ++++++++++++++++++++++++++ camera_server/src/convert.c | 232 ++++++++++++++++++++++++ camera_server/src/main.c | 167 ++++++++++++++++++ camera_server/src/srv.c | 96 ++++++++++ camera_server/src/tcp.c | 301 ++++++++++++++++++++++++++++++++ 10 files changed, 1110 insertions(+) create mode 100755 camera_server/Makefile create mode 100755 camera_server/include/camera.h create mode 100755 camera_server/include/convert.h create mode 100755 camera_server/include/jpg.h create mode 100755 camera_server/include/tcp.h create mode 100755 camera_server/src/camera.c create mode 100755 camera_server/src/convert.c create mode 100755 camera_server/src/main.c create mode 100755 camera_server/src/srv.c create mode 100755 camera_server/src/tcp.c diff --git a/camera_server/Makefile b/camera_server/Makefile new file mode 100755 index 0000000..0c184cf --- /dev/null +++ b/camera_server/Makefile @@ -0,0 +1,11 @@ + +OBJS=main.c camera.c convert.c srv.c tcp.c +CC=arm-none-linux-gnueabi-gcc +TARGET=camera + +$(TARGET):$(OBJS) + $(CC) $^ -o $@ -lpthread -ljpeg -L/home/farsight/jpeg_8/lib + +clean: + rm -rf $(TARGET) + rm *~ diff --git a/camera_server/include/camera.h b/camera_server/include/camera.h new file mode 100755 index 0000000..ad271bb --- /dev/null +++ b/camera_server/include/camera.h @@ -0,0 +1,11 @@ +#ifndef __CAM_H__ +#define __CAM_H__ + +int camera_init(char *devpath, unsigned int *width, unsigned int *height, unsigned int *size, unsigned int *ismjpeg); +int camera_start(int fd); +int camera_dqbuf(int fd, void **buf, unsigned int *size, unsigned int *index); +int camera_eqbuf(int fd, unsigned int index); +int camera_stop(int fd); +int camera_exit(int fd); + +#endif diff --git a/camera_server/include/convert.h b/camera_server/include/convert.h new file mode 100755 index 0000000..5a4e3ac --- /dev/null +++ b/camera_server/include/convert.h @@ -0,0 +1,9 @@ +#ifndef __CONVERT_H__ +#define __CONVERT_H__ + +void convert_yuv_to_rgb(void *yuv, void *rgb, unsigned int width, unsigned int height, unsigned int bps); +void convert_rgb_to_jpg_init(void); +int convert_rgb_to_jpg_work(void *rgb, void *jpeg, unsigned int width, unsigned int height, unsigned int bpp, int quality); +void convert_rgb_to_jpg_exit(void); + +#endif diff --git a/camera_server/include/jpg.h b/camera_server/include/jpg.h new file mode 100755 index 0000000..a43f249 --- /dev/null +++ b/camera_server/include/jpg.h @@ -0,0 +1,11 @@ +#ifndef __JPG_H__ +#define __JPG_H__ + +#define MAX_JPG_SIZE (1024 * 1024 - sizeof (unsigned int)) + +struct jpg_buf_t { + unsigned char buf[MAX_JPG_SIZE]; + unsigned int len; +}; + +#endif diff --git a/camera_server/include/tcp.h b/camera_server/include/tcp.h new file mode 100755 index 0000000..e9c8b79 --- /dev/null +++ b/camera_server/include/tcp.h @@ -0,0 +1,21 @@ +#ifndef __TCP_H__ +#define __TCP_H__ + +int tcp_server_init(const char *ip, const char *port); +int tcp_server_wait_connect(int listenfd); +ssize_t tcp_server_recv(int connfd, void *buf, size_t count); +ssize_t tcp_server_send(int connfd, const void *buf, size_t count); +ssize_t tcp_server_recv_exact_nbytes(int connfd, void *buf, size_t count); +ssize_t tcp_server_send_exact_nbytes(int connfd, const void *buf, size_t count); +int tcp_server_disconnect(int connfd); +int tcp_server_exit(int listenfd); + +int tcp_client_init(void); +int tcp_client_connect(int sockfd, const char *ip, const char *port); +ssize_t tcp_client_recv(int sockfd, void *buf, size_t count); +ssize_t tcp_client_send(int sockfd, const void *buf, size_t count); +ssize_t tcp_client_recv_exact_nbytes(int sockfd, void *buf, size_t count); +ssize_t tcp_client_send_exact_nbytes(int sockfd, const void *buf, size_t count); +int tcp_client_exit(int sockfd); + +#endif diff --git a/camera_server/src/camera.c b/camera_server/src/camera.c new file mode 100755 index 0000000..6cfb86a --- /dev/null +++ b/camera_server/src/camera.c @@ -0,0 +1,251 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define REQBUFS_COUNT 4 + +struct cam_buf { + void *start; + size_t length; +}; + +struct v4l2_requestbuffers reqbufs; +struct cam_buf bufs[REQBUFS_COUNT]; + +int camera_init(char *devpath, unsigned int *width, unsigned int *height, unsigned int *size, unsigned int *ismjpeg) +{ + int i; + int fd; + int ret; + struct v4l2_buffer vbuf; + struct v4l2_format format; + struct v4l2_capability capability; + + fd = open(devpath, O_RDWR); + if (fd == -1) { + perror("camera->init"); + return -1; + } + + ret = ioctl(fd, VIDIOC_QUERYCAP, &capability); + if (ret == -1) { + perror("camera->init"); + return -1; + } + + if(!(capability.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { + fprintf(stderr, "camera->init: device can not support V4L2_CAP_VIDEO_CAPTURE\n"); + close(fd); + return -1; + } + + if(!(capability.capabilities & V4L2_CAP_STREAMING)) { + fprintf(stderr, "camera->init: device can not support V4L2_CAP_STREAMING\n"); + close(fd); + return -1; + } + + /*memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; + format.fmt.pix.width = *width; + format.fmt.pix.height = *height; + format.fmt.pix.field = V4L2_FIELD_ANY; + ret = ioctl(fd, VIDIOC_S_FMT, &format); + if(ret == -1) + perror("camera init"); + else { + fprintf(stdout, "camera->init: picture format is mjpeg\n"); + *ismjpeg = 1; + goto get_fmt; + } +*/ + memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + format.fmt.pix.width = *width; + format.fmt.pix.height = *height; + format.fmt.pix.field = V4L2_FIELD_ANY; + ret = ioctl(fd, VIDIOC_S_FMT, &format); + if(ret == -1) { + perror("camera init"); + return -1; + } else { + *ismjpeg = 0; + fprintf(stdout, "camera->init: picture format is yuyv\n"); + } + +//get_fmt: + ret = ioctl(fd, VIDIOC_G_FMT, &format); + if (ret == -1) { + perror("camera init"); + return -1; + } + + memset(&reqbufs, 0, sizeof(struct v4l2_requestbuffers)); + reqbufs.count = REQBUFS_COUNT; + reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + reqbufs.memory = V4L2_MEMORY_MMAP; + ret = ioctl(fd, VIDIOC_REQBUFS, &reqbufs); + if (ret == -1) { + perror("camera init"); + close(fd); + return -1; + } + + for (i = 0; i < reqbufs.count; i++) + { + memset(&vbuf, 0, sizeof(struct v4l2_buffer)); + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + vbuf.index = i; + ret = ioctl(fd, VIDIOC_QUERYBUF, &vbuf); + if (ret == -1) { + perror("camera init"); + close(fd); + return -1; + } + + bufs[i].length = vbuf.length; + bufs[i].start = mmap(NULL, vbuf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, vbuf.m.offset); + if (bufs[i].start == MAP_FAILED) + { + perror("camera init"); + close(fd); + return -1; + } + + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + ret = ioctl(fd, VIDIOC_QBUF, &vbuf); + if (ret == -1) { + perror("camera init"); + close(fd); + return -1; + } + } + + *width = format.fmt.pix.width; + *height = format.fmt.pix.height; + *size = bufs[0].length; + + return fd; +} + +int camera_start(int fd) +{ + int ret; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(fd, VIDIOC_STREAMON, &type); + if (ret == -1) { + perror("camera->start"); + return -1; + } + fprintf(stdout, "camera->start: start capture\n"); + + return 0; +} + +int camera_dqbuf(int fd, void **buf, unsigned int *size, unsigned int *index) +{ + int ret; + fd_set fds; + struct timeval timeout; + struct v4l2_buffer vbuf; + + while (1) { + FD_ZERO(&fds); + FD_SET(fd, &fds); + timeout.tv_sec = 2; + timeout.tv_usec = 0; + ret = select(fd + 1, &fds, NULL, NULL, &timeout); + if (ret == -1) { + perror("camera->dqbuf"); + if (errno == EINTR) + continue; + else + return -1; + } else if (ret == 0) { + fprintf(stderr, "camera->dqbuf: dequeue buffer timeout\n"); + continue; + } else { + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + ret = ioctl(fd, VIDIOC_DQBUF, &vbuf); + if (ret == -1) { + perror("camera->dqbuf"); + return -1; + } + *buf = bufs[vbuf.index].start; + *size = vbuf.bytesused; + *index = vbuf.index; + + return 0; + } + } +} + +int camera_eqbuf(int fd, unsigned int index) +{ + int ret; + struct v4l2_buffer vbuf; + + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + vbuf.index = index; + ret = ioctl(fd, VIDIOC_QBUF, &vbuf); + if (ret == -1) { + perror("camera->eqbuf"); + return -1; + } + + return 0; +} + +int camera_stop(int fd) +{ + int ret; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(fd, VIDIOC_STREAMOFF, &type); + if (ret == -1) { + perror("camera->stop"); + return -1; + } + fprintf(stdout, "camera->stop: stop capture\n"); + + return 0; +} + +int camera_exit(int fd) +{ + int i; + int ret; + struct v4l2_buffer vbuf; + + vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vbuf.memory = V4L2_MEMORY_MMAP; + + for (i = 0; i < reqbufs.count; i++) { + ret = ioctl(fd, VIDIOC_DQBUF, &vbuf); + if (ret == -1) + break; + } + + for (i = 0; i < reqbufs.count; i++) + munmap(bufs[i].start, bufs[i].length); + + fprintf(stdout, "camera->exit: camera exit\n"); + + return close(fd); +} + diff --git a/camera_server/src/convert.c b/camera_server/src/convert.c new file mode 100755 index 0000000..d4eca0d --- /dev/null +++ b/camera_server/src/convert.c @@ -0,0 +1,232 @@ +#include +#include +#include +#include +#include +#include +#include + +#define ROUND_0_255(v) ((v) < 0 ? 0 : ((v) > 255 ? 255 : (v))) + +typedef struct { + struct jpeg_destination_mgr pub; + JOCTET *buffer; + unsigned char *outbuffer; + int outbuffer_size; + unsigned char *outbuffer_cursor; + int *written; +} jpeg_dest_mgr, *jpeg_dest_mgr_ptr; + +struct jpeg_mgr_info { + unsigned long written; + JSAMPROW row_pointer[1]; + struct jpeg_error_mgr jerr; + struct jpeg_compress_struct cinfo; +}; + +static struct jpeg_mgr_info jinfo; + +static short radj[] = { + -175, -174, -172, -171, -169, -168, -167, -165, + -164, -163, -161, -160, -159, -157, -156, -154, + -153, -152, -150, -149, -148, -146, -145, -143, + -142, -141, -139, -138, -137, -135, -134, -132, + -131, -130, -128, -127, -126, -124, -123, -121, + -120, -119, -117, -116, -115, -113, -112, -111, + -109, -108, -106, -105, -104, -102, -101, -100, + -98, -97, -95, -94, -93, -91, -90, -89, + -87, -86, -84, -83, -82, -80, -79, -78, + -76, -75, -74, -72, -71, -69, -68, -67, + -65, -64, -63, -61, -60, -58, -57, -56, + -54, -53, -52, -50, -49, -47, -46, -45, + -43, -42, -41, -39, -38, -37, -35, -34, + -32, -31, -30, -28, -27, -26, -24, -23, + -21, -20, -19, -17, -16, -15, -13, -12, + -10, -9, -8, -6, -5, -4, -2, -1, + 0, 1, 2, 4, 5, 6, 8, 9, + 10, 12, 13, 15, 16, 17, 19, 20, + 21, 23, 24, 26, 27, 28, 30, 31, + 32, 34, 35, 37, 38, 39, 41, 42, + 43, 45, 46, 47, 49, 50, 52, 53, + 54, 56, 57, 58, 60, 61, 63, 64, + 65, 67, 68, 69, 71, 72, 74, 75, + 76, 78, 79, 80, 82, 83, 84, 86, + 87, 89, 90, 91, 93, 94, 95, 97, + 98, 100, 101, 102, 104, 105, 106, 108, + 109, 111, 112, 113, 115, 116, 117, 119, + 120, 121, 123, 124, 126, 127, 128, 130, + 131, 132, 134, 135, 137, 138, 139, 141, + 142, 143, 145, 146, 148, 149, 150, 152, + 153, 154, 156, 157, 159, 160, 161, 163, + 164, 165, 167, 168, 169, 171, 172, 174, +}; + +static short gadj1[] = { + -89, -88, -87, -87, -86, -85, -85, -84, + -83, -83, -82, -81, -80, -80, -79, -78, + -78, -77, -76, -76, -75, -74, -73, -73, + -72, -71, -71, -70, -69, -69, -68, -67, + -67, -66, -65, -64, -64, -63, -62, -62, + -61, -60, -60, -59, -58, -57, -57, -56, + -55, -55, -54, -53, -53, -52, -51, -50, + -50, -49, -48, -48, -47, -46, -46, -45, + -44, -43, -43, -42, -41, -41, -40, -39, + -39, -38, -37, -36, -36, -35, -34, -34, + -33, -32, -32, -31, -30, -30, -29, -28, + -27, -27, -26, -25, -25, -24, -23, -23, + -22, -21, -20, -20, -19, -18, -18, -17, + -16, -16, -15, -14, -13, -13, -12, -11, + -11, -10, -9, -9, -8, -7, -6, -6, + -5, -4, -4, -3, -2, -2, -1, 0, + 0, 0, 1, 2, 2, 3, 4, 4, + 5, 6, 6, 7, 8, 9, 9, 10, + 11, 11, 12, 13, 13, 14, 15, 16, + 16, 17, 18, 18, 19, 20, 20, 21, + 22, 23, 23, 24, 25, 25, 26, 27, + 27, 28, 29, 30, 30, 31, 32, 32, + 33, 34, 34, 35, 36, 36, 37, 38, + 39, 39, 40, 41, 41, 42, 43, 43, + 44, 45, 46, 46, 47, 48, 48, 49, + 50, 50, 51, 52, 53, 53, 54, 55, + 55, 56, 57, 57, 58, 59, 60, 60, + 61, 62, 62, 63, 64, 64, 65, 66, + 67, 67, 68, 69, 69, 70, 71, 71, + 72, 73, 73, 74, 75, 76, 76, 77, + 78, 78, 79, 80, 80, 81, 82, 83, + 83, 84, 85, 85, 86, 87, 87, 88, +}; + +static short gadj2[] = { + -43, -42, -42, -42, -41, -41, -41, -40, + -40, -40, -39, -39, -39, -38, -38, -38, + -37, -37, -37, -36, -36, -36, -35, -35, + -35, -34, -34, -34, -33, -33, -33, -32, + -32, -32, -31, -31, -31, -30, -30, -30, + -29, -29, -29, -28, -28, -28, -27, -27, + -27, -26, -26, -25, -25, -25, -24, -24, + -24, -23, -23, -23, -22, -22, -22, -21, + -21, -21, -20, -20, -20, -19, -19, -19, + -18, -18, -18, -17, -17, -17, -16, -16, + -16, -15, -15, -15, -14, -14, -14, -13, + -13, -13, -12, -12, -12, -11, -11, -11, + -10, -10, -10, -9, -9, -9, -8, -8, + -8, -7, -7, -7, -6, -6, -6, -5, + -5, -5, -4, -4, -4, -3, -3, -3, + -2, -2, -2, -1, -1, -1, 0, 0, + 0, 0, 0, 1, 1, 1, 2, 2, + 2, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 6, 6, 6, 7, 7, 7, + 8, 8, 8, 9, 9, 9, 10, 10, + 10, 11, 11, 11, 12, 12, 12, 13, + 13, 13, 14, 14, 14, 15, 15, 15, + 16, 16, 16, 17, 17, 17, 18, 18, + 18, 19, 19, 19, 20, 20, 20, 21, + 21, 21, 22, 22, 22, 23, 23, 23, + 24, 24, 24, 25, 25, 25, 26, 26, + 27, 27, 27, 28, 28, 28, 29, 29, + 29, 30, 30, 30, 31, 31, 31, 32, + 32, 32, 33, 33, 33, 34, 34, 34, + 35, 35, 35, 36, 36, 36, 37, 37, + 37, 38, 38, 38, 39, 39, 39, 40, + 40, 40, 41, 41, 41, 42, 42, 42, +}; + +static short badj[] = { + -221, -220, -218, -216, -214, -213, -211, -209, + -207, -206, -204, -202, -200, -199, -197, -195, + -194, -192, -190, -188, -187, -185, -183, -181, + -180, -178, -176, -174, -173, -171, -169, -168, + -166, -164, -162, -161, -159, -157, -155, -154, + -152, -150, -148, -147, -145, -143, -142, -140, + -138, -136, -135, -133, -131, -129, -128, -126, + -124, -123, -121, -119, -117, -116, -114, -112, + -110, -109, -107, -105, -103, -102, -100, -98, + -97, -95, -93, -91, -90, -88, -86, -84, + -83, -81, -79, -77, -76, -74, -72, -71, + -69, -67, -65, -64, -62, -60, -58, -57, + -55, -53, -51, -50, -48, -46, -45, -43, + -41, -39, -38, -36, -34, -32, -31, -29, + -27, -25, -24, -22, -20, -19, -17, -15, + -13, -12, -10, -8, -6, -5, -3, -1, + 0, 1, 3, 5, 6, 8, 10, 12, + 13, 15, 17, 19, 20, 22, 24, 25, + 27, 29, 31, 32, 34, 36, 38, 39, + 41, 43, 45, 46, 48, 50, 51, 53, + 55, 57, 58, 60, 62, 64, 65, 67, + 69, 71, 72, 74, 76, 77, 79, 81, + 83, 84, 86, 88, 90, 91, 93, 95, + 97, 98, 100, 102, 103, 105, 107, 109, + 110, 112, 114, 116, 117, 119, 121, 123, + 124, 126, 128, 129, 131, 133, 135, 136, + 138, 140, 142, 143, 145, 147, 148, 150, + 152, 154, 155, 157, 159, 161, 162, 164, + 166, 168, 169, 171, 173, 174, 176, 178, + 180, 181, 183, 185, 187, 188, 190, 192, + 194, 195, 197, 199, 200, 202, 204, 206, + 207, 209, 211, 213, 214, 216, 218, 220, +}; + +void convert_yuv_to_rgb(void *yuv, void *rgb, unsigned int width, unsigned int height, unsigned int bps) +{ + unsigned int i; + int y1, y2, u, v; + unsigned char *src = yuv; + unsigned char *dst = rgb; + unsigned int count = width * height / 2; + + switch (bps) { + case 24: + for (i = 0; i < count; i++) { + y1 = *src++; + u = *src++; + y2 = *src++; + v = *src++; + + *dst++ = ROUND_0_255(y1 + radj[v]); + *dst++ = ROUND_0_255(y1 - gadj1[u] - gadj2[v]); + *dst++ = ROUND_0_255(y1 + badj[u]); + + *dst++ = ROUND_0_255(y2 + radj[v]); + *dst++ = ROUND_0_255(y2 - gadj1[u] - gadj2[v]); + *dst++ = ROUND_0_255(y2 + badj[u]); + } + break; + } +} + +void convert_rgb_to_jpg_init(void) +{ + memset(&jinfo, 0, sizeof(struct jpeg_mgr_info)); + jinfo.cinfo.err = jpeg_std_error(&jinfo.jerr); + jpeg_create_compress(&jinfo.cinfo); +} + +int convert_rgb_to_jpg_work(void *rgb, void *jpeg, unsigned int width, unsigned int height, unsigned int bpp, int quality) +{ + jinfo.written = width * height * bpp / 3; + jpeg_mem_dest(&jinfo.cinfo, (unsigned char **)&jpeg, &jinfo.written); + + jinfo.cinfo.image_width = width; + jinfo.cinfo.image_height = height; + jinfo.cinfo.input_components = bpp / 8; + jinfo.cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&jinfo.cinfo); + jpeg_set_quality(&jinfo.cinfo, quality, TRUE); + + jpeg_start_compress(&jinfo.cinfo, TRUE); + + while(jinfo.cinfo.next_scanline < height) { + jinfo.row_pointer[0] = rgb + jinfo.cinfo.next_scanline * width * bpp / 8; + jpeg_write_scanlines(&jinfo.cinfo, jinfo.row_pointer, 1); + } + + jpeg_finish_compress(&jinfo.cinfo); + + return (jinfo.written); +} + +void convert_rgb_to_jpg_exit(void) +{ + jpeg_destroy_compress(&jinfo.cinfo); +} + diff --git a/camera_server/src/main.c b/camera_server/src/main.c new file mode 100755 index 0000000..3aabe40 --- /dev/null +++ b/camera_server/src/main.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "../include/tcp.h" +#include "../include/camera.h" +#include "../include/jpg.h" +#include "../include/convert.h" + +#define CAMERA_DEV_PATH "/dev/video0" + +struct jpg_buf_t *jpg; +pthread_t cam_tid; +pthread_mutex_t jpg_mutex; + +void *thread_cam(void *arg); +void *thread_srv(void *arg); +extern int client_process(int connfd, struct jpg_buf_t *jpg); + +int main(int argc, char *argv[]) +{ + int ret; + + pthread_mutex_init(&jpg_mutex, NULL); + + ret = pthread_create(&cam_tid, NULL, thread_cam, NULL); + if (ret) { + errno = ret; + perror("create camera thread"); + exit(EXIT_FAILURE); + } else + printf("create camera thread success\n"); + + ret = pthread_detach(cam_tid); + if (ret) { + errno = ret; + perror("detach camera thread"); + exit(EXIT_FAILURE); + } else + printf("detach camera thread success\n"); + + thread_srv(NULL); + + exit(EXIT_SUCCESS); +} + +void *thread_cam(void *arg) +{ + int i; + int fd; + int ret; + unsigned int width; + unsigned int height; + unsigned int size; + unsigned int index; + unsigned int ismjpeg; + char *yuv; + char *rgb; + + /* A8的屏幕比较小,所以设了较低的像素 */ + width = 1024; + height = 1024; + fd = camera_init(CAMERA_DEV_PATH, &width, &height, &size, &ismjpeg); + if (fd == -1) + exit(EXIT_FAILURE); + printf("width: %d\n", width); + printf("height: %d\n", height); + + ret = camera_start(fd); + if (ret == -1) + exit(EXIT_FAILURE); + + jpg = malloc(sizeof(struct jpg_buf_t)); + if (!jpg) { + perror("malloc"); + exit(EXIT_FAILURE); + } + + if (!ismjpeg) { + rgb = malloc(width * height * 3); + convert_rgb_to_jpg_init(); + } + + /* 采集几张图片丢弃 */ + for (i = 0; i < 8; i++) { + ret = camera_dqbuf(fd, (void **)&yuv, &size, &index); + if (ret == -1) + exit(EXIT_FAILURE); + + ret = camera_eqbuf(fd, index); + if (ret == -1) + exit(EXIT_FAILURE); + } + + fprintf(stdout, "init camera success\n"); + + + /* 循环采集图片 */ + while (1) { + ret = camera_dqbuf(fd, (void **)&yuv, &size, &index); + if (ret == -1) + exit(EXIT_FAILURE); + + /*if (ismjpeg) { + pthread_mutex_lock(&jpg_mutex); + memcpy(jpg->buf, yuv, size); + jpg->len = size; + pthread_mutex_unlock(&jpg_mutex); + } else { + convert_yuv_to_rgb(yuv, rgb, width, height, 24); + pthread_mutex_lock(&jpg_mutex); + jpg->len = convert_rgb_to_jpg_work(rgb, jpg->buf, width, height, 24, 80); + pthread_mutex_unlock(&jpg_mutex); + }*/ + + convert_yuv_to_rgb(yuv, rgb, width, height, 24); + pthread_mutex_lock(&jpg_mutex); + jpg->len = convert_rgb_to_jpg_work(rgb, jpg->buf, width, height, 24, 80); + pthread_mutex_unlock(&jpg_mutex); + + ret = camera_eqbuf(fd, index); + if (ret == -1) + exit(EXIT_FAILURE); + } + + /* 代码不应该运行到这里 */ + if (!ismjpeg) { + convert_rgb_to_jpg_exit(); + free(rgb); + } + free(jpg); + + ret = camera_stop(fd); + if (ret == -1) + exit(EXIT_FAILURE); + + ret = camera_exit(fd); + if (ret == -1) + exit(EXIT_FAILURE); +} + +void *thread_srv(void *arg) +{ + int listenfd; + int connfd; + + listenfd = tcp_server_init(NULL, "8888"); + if (listenfd == -1) + exit(EXIT_FAILURE); + else + fprintf(stdout, "init server success\n"); + + while (1) { + if ((connfd = tcp_server_wait_connect(listenfd)) != -1) { + while (1) { + if (client_process(connfd, jpg) == -1) { + tcp_server_disconnect(connfd); + break; + } + } + } + } +} diff --git a/camera_server/src/srv.c b/camera_server/src/srv.c new file mode 100755 index 0000000..78c9a4a --- /dev/null +++ b/camera_server/src/srv.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../include/tcp.h" +#include "../include/jpg.h" + +#define REQ_DATA_SIZE 32 +#define HDR_DATA_SIZE 128 + +//#define DEBUG + +extern pthread_mutex_t jpg_mutex; + +int client_process(int connfd, struct jpg_buf_t *jpg) +{ + /*int ret; + char request[REQ_DATA_SIZE] = {0}; + char response[HDR_DATA_SIZE] = {0}; + + memset(request, 0, sizeof(request)); + ret = tcp_server_recv(connfd, request, sizeof(request)); + if (ret <= 0) + return -1; + +#ifdef DEBUG + fprintf(stdout, "server->read: the request is\n%s\n", request); +#endif + + if (strstr(request, "pic") != NULL) { + int ret; + + pthread_mutex_lock(&jpg_mutex); + snprintf(response, sizeof(response), "%dlen", jpg->len); +#ifdef DEBUG + fprintf(stdout, "server->response: the response is: %s\n", response); +#endif + ret = tcp_server_send_exact_nbytes(connfd, response, sizeof(response)); + if (ret != sizeof(response)) { + fprintf(stderr, "server->write: send response failed\n"); + return -1; + } + + ret = tcp_server_send_exact_nbytes(connfd, jpg->buf, jpg->len); + if (ret != jpg->len) { + fprintf(stderr, "server->write: send response failed\n"); + return -1; + } + + pthread_mutex_unlock(&jpg_mutex); + } + + return 0;*/ + unsigned int piclen = 0; + unsigned char * buf ; + char response[20] = {0}; + char msg[3] = {0}; + int total = 0; + int ret1 = 0; + + ret1 = read(connfd,msg,3); + printf("msg : %s\n",msg); + + pthread_mutex_lock(&jpg_mutex); + piclen = jpg->len; + printf("piclen = %d\n",piclen); + snprintf(response, sizeof(response), "%dlen", piclen); + + buf = (unsigned char *)malloc(piclen); + memset(buf,0,piclen); + memcpy(buf,jpg->buf,piclen); + + pthread_mutex_unlock(&jpg_mutex); + + int ret = write(connfd,response,20); + printf("ret = %d\n",ret); + while(piclen>total) + { + ret1 = write(connfd,buf+total,piclen-total); + if(ret1 < 0) + { + break; + } + total += ret1; + printf("total = %d\n",total); + + } + + return 0; +} diff --git a/camera_server/src/tcp.c b/camera_server/src/tcp.c new file mode 100755 index 0000000..4c35a27 --- /dev/null +++ b/camera_server/src/tcp.c @@ -0,0 +1,301 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MAX_BACKLOG 1024 + +int tcp_server_init(const char *ip, const char *port) +{ + int ret; + int listenfd; + int opt = 1; + struct sockaddr_in srvaddr; + + memset(&srvaddr, 0, sizeof(struct sockaddr_in)); + srvaddr.sin_family = AF_INET; + + if (ip != NULL) { + ret = inet_pton(AF_INET, ip, &srvaddr.sin_addr); + if (ret != 1) { + fprintf(stderr, "server->ip: ip is error\n"); + return -1; + } + } else + srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (port != NULL) + srvaddr.sin_port = htons(atoi(port)); + else { + fprintf(stderr, "server->port: port must be assigned\n"); + return -1; + } + + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd == -1) { + perror("server->socket"); + return -1; + } + setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + ret = bind(listenfd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr_in)); + if (ret == -1) { + perror("server->bind"); + close(listenfd); + return -1; + } + + ret = listen(listenfd, MAX_BACKLOG); + if (ret == -1) { + perror("server->listen"); + close(listenfd); + return -1; + } + + return listenfd; +} + +int tcp_server_wait_connect(int listenfd) +{ + int connfd; + socklen_t addrlen; + struct sockaddr_in cliaddr; + + addrlen = sizeof(struct sockaddr_in); + memset(&cliaddr, 0, sizeof(struct sockaddr_in)); + connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen); + if (connfd == -1) { + perror("server->accept"); + return -1; + } + + return connfd; +} + +ssize_t tcp_server_recv(int connfd, void *buf, size_t count) +{ + ssize_t ret; + + assert(buf != NULL); + + ret = read(connfd, buf, count); + if (ret == -1) { + perror("server->read"); + return -1; + } else if (ret == 0) { + fprintf(stderr, "server->read: end-of-file\n"); + return 0; + } else + return ret; +} + +ssize_t tcp_server_send(int connfd, const void *buf, size_t count) +{ + ssize_t ret; + + assert(buf != NULL); + + ret = write(connfd, buf, count); + if (ret == -1) { + perror("server->read"); + return -1; + } else + return ret; +} + +ssize_t tcp_server_recv_exact_nbytes(int connfd, void *buf, size_t count) +{ + ssize_t ret; + ssize_t total = 0; + + assert(buf != NULL); + + while (total != count) { + ret = read(connfd, buf + total, count - total); + if (ret == -1) { + perror("server->read"); + return -1; + } else if (ret == 0) { + fprintf(stderr, "server->read: end-of-file\n"); + return total; + } else + total += ret; + } + + return total; +} + +ssize_t tcp_server_send_exact_nbytes(int connfd, const void *buf, size_t count) +{ + ssize_t ret; + ssize_t total = 0; + + assert(buf != NULL); + + while (total != count) { + ret = write(connfd, buf + total, count - total); + if (ret == -1) { + perror("server->write"); + return total; + } else + total += ret; + } + + return total; +} + +int tcp_server_disconnect(int connfd) +{ + if (close(connfd)) { + perror("server->close"); + return -1; + } + + return 0; +} + +int tcp_server_exit(int listenfd) +{ + if (close(listenfd)) { + perror("server->close"); + return -1; + } + + return 0; +} + +int tcp_client_init(void) +{ + int sockfd; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd == -1) { + perror("client->socket"); + return -1; + } + + return sockfd; +} + +int tcp_client_connect(int sockfd, const char *ip, const char *port) +{ + int ret; + struct sockaddr_in srvaddr; + + memset(&srvaddr, 0, sizeof(struct sockaddr_in)); + srvaddr.sin_family = AF_INET; + + if (ip != NULL) { + ret = inet_pton(AF_INET, ip, &srvaddr.sin_addr); + if (ret != 1) { + fprintf(stderr, "client->ip: server ip is error\n"); + return -1; + } + } else + fprintf(stderr, "client->ip: server ip must be assigned\n"); + + if (port != NULL) + srvaddr.sin_port = htons(atoi(port)); + else { + fprintf(stderr, "client->port: server port must be assigned\n"); + return -1; + } + + ret = connect(sockfd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr_in)); + if (ret == -1) { + perror("client->connect"); + return -1; + } + + return 0; +} + +ssize_t tcp_client_recv(int sockfd, void *buf, size_t count) +{ + ssize_t ret; + + assert(buf != NULL); + + ret = read(sockfd, buf, count); + if (ret == -1) { + perror("server->read"); + return -1; + } else if (ret == 0) { + fprintf(stderr, "server->read: end-of-file\n"); + return 0; + } else + return ret; +} + +ssize_t tcp_client_send(int sockfd, const void *buf, size_t count) +{ + ssize_t ret; + + assert(buf != NULL); + + ret = write(sockfd, buf, count); + if (ret == -1) { + perror("server->read"); + return -1; + } else + return ret; +} + +ssize_t tcp_client_recv_exact_nbytes(int sockfd, void *buf, size_t count) +{ + ssize_t ret; + ssize_t total = 0; + + assert(buf != NULL); + + while (total != count) { + ret = read(sockfd, buf + total, count - total); + if (ret == -1) { + perror("server->read"); + return -1; + } else if (ret == 0) { + fprintf(stderr, "server->read: end-of-file\n"); + return total; + } else + total += ret; + } + + return total; +} + +ssize_t tcp_client_send_exact_nbytes(int sockfd, const void *buf, size_t count) +{ + ssize_t ret; + ssize_t total = 0; + + assert(buf != NULL); + + while (total != count) { + ret = write(sockfd, buf + total, count - total); + if (ret == -1) { + perror("server->read"); + return total; + } else + total += ret; + } + + return total; +} + +int tcp_client_exit(int sockfd) +{ + if (close(sockfd)) { + perror("client->close"); + return -1; + } + + return 0; +} -- Gitee