Advertisement
Guest User

opencvstream

a guest
Oct 1st, 2012
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.07 KB | None | 0 0
  1. /**
  2. * stream_server.c:
  3. * OpenCV video streaming server
  4. *
  5. * Author Nash <me_at_nashruddin.com>
  6. *
  7. * See the tutorial at
  8. * http://nashruddin.com/StrEAMinG_oPENcv_vIdEos_ovER_tHe_nEtWoRk
  9. */
  10.  
  11. #include <netinet/in.h>
  12. #include <sys/socket.h>
  13. #include <arpa/inet.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <unistd.h>
  17. #include <pthread.h>
  18. #include "cv.h"
  19. #include "highgui.h"
  20.  
  21. #define PORT 8888
  22.  
  23. CvCapture* capture;
  24. IplImage* img0;
  25. IplImage* img1;
  26. int is_data_ready = 0;
  27. int serversock, clientsock;
  28.  
  29. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  30.  
  31. void* streamServer(void* arg);
  32. void quit(char* msg, int retval);
  33.  
  34. int main(int argc, char** argv)
  35. {
  36. pthread_t thread_s;
  37. int key;
  38.  
  39. if (argc == 2) {
  40. capture = cvCaptureFromFile(argv[1]);
  41. } else {
  42. capture = cvCaptureFromCAM(0);
  43. }
  44.  
  45. if (!capture) {
  46. quit("cvCapture failed", 1);
  47. }
  48.  
  49. img0 = cvQueryFrame(capture);
  50. img1 = cvCreateImage(cvGetSize(img0), IPL_DEPTH_8U, 1);
  51.  
  52. cvZero(img1);
  53. cvNamedWindow("stream_server", CV_WINDOW_AUTOSIZE);
  54.  
  55. /* print the width and height of the frame, needed by the client */
  56. fprintf(stdout, "width: %d\nheight: %d\n\n", img0->width, img0->height);
  57. fprintf(stdout, "Press 'q' to quit.\n\n");
  58.  
  59. /* run the streaming server as a separate thread */
  60. if (pthread_create(&thread_s, NULL, streamServer, NULL)) {
  61. quit("pthread_create failed.", 1);
  62. }
  63.  
  64. while(key != 'q') {
  65. /* get a frame from camera */
  66. img0 = cvQueryFrame(capture);
  67. if (!img0) break;
  68.  
  69. img0->origin = 0;
  70. cvFlip(img0, img0, 1); //-1);
  71.  
  72. /**
  73. * convert to grayscale
  74. * note that the grayscaled image is the image to be sent to the client
  75. * so we enclose it with pthread_mutex_lock to make it thread safe
  76. */
  77. pthread_mutex_lock(&mutex);
  78. cvCvtColor(img0, img1, CV_BGR2GRAY);
  79. is_data_ready = 1;
  80. pthread_mutex_unlock(&mutex);
  81.  
  82. /* also display the video here on server */
  83. cvShowImage("stream_server", img0);
  84. key = cvWaitKey(30);
  85. }
  86.  
  87. /* user has pressed 'q', terminate the streaming server */
  88. if (pthread_cancel(thread_s)) {
  89. quit("pthread_cancel failed.", 1);
  90. }
  91.  
  92. /* free memory */
  93. cvDestroyWindow("stream_server");
  94. quit(NULL, 0);
  95. }
  96.  
  97. /**
  98. * This is the streaming server, run as a separate thread
  99. * This function waits for a client to connect, and send the grayscaled images
  100. */
  101. void* streamServer(void* arg)
  102. {
  103. struct sockaddr_in server;
  104.  
  105. /* make this thread cancellable using pthread_cancel() */
  106. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  107. pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  108.  
  109. /* open socket */
  110. if ((serversock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
  111. quit("socket() failed", 1);
  112. }
  113.  
  114. /* setup server's IP and port */
  115. memset(&server, 0, sizeof(server));
  116. server.sin_family = AF_INET;
  117. server.sin_port = htons(PORT);
  118. server.sin_addr.s_addr = INADDR_ANY;
  119.  
  120. /* bind the socket */
  121. if (bind(serversock, (const void*)&server, sizeof(server)) == -1) {
  122. quit("bind() failed", 1);
  123. }
  124.  
  125. /* wait for connection */
  126. if (listen(serversock, 10) == -1) {
  127. quit("listen() failed.", 1);
  128. }
  129.  
  130. /* accept a client */
  131. if ((clientsock = accept(serversock, NULL, NULL)) == -1) {
  132. quit("accept() failed", 1);
  133. }
  134.  
  135. /* the size of the data to be sent */
  136. int imgsize = img1->imageSize;
  137. int bytes, i;
  138.  
  139. /* start sending images */
  140. while(1)
  141. {
  142. /* send the grayscaled frame, thread safe */
  143. pthread_mutex_lock(&mutex);
  144. if (is_data_ready) {
  145. bytes = send(clientsock, img1->imageData, imgsize, 0);
  146. is_data_ready = 0;
  147. }
  148. pthread_mutex_unlock(&mutex);
  149.  
  150. /* if something went wrong, restart the connection */
  151. if (bytes != imgsize) {
  152. fprintf(stderr, "Connection closed.\n");
  153. close(clientsock);
  154.  
  155. if ((clientsock = accept(serversock, NULL, NULL)) == -1) {
  156. quit("accept() failed", 1);
  157. }
  158. }
  159.  
  160. /* have we terminated yet? */
  161. pthread_testcancel();
  162.  
  163. /* no, take a rest for a while */
  164. usleep(1000);
  165. }
  166. }
  167.  
  168. /**
  169. * this function provides a way to exit nicely from the system
  170. */
  171. void quit(char* msg, int retval)
  172. {
  173. if (retval == 0) {
  174. fprintf(stdout, (msg == NULL ? "" : msg));
  175. fprintf(stdout, "\n");
  176. } else {
  177. fprintf(stderr, (msg == NULL ? "" : msg));
  178. fprintf(stderr, "\n");
  179. }
  180.  
  181. if (clientsock) close(clientsock);
  182. if (serversock) close(serversock);
  183. if (capture) cvReleaseCapture(&capture);
  184. if (img1) cvReleaseImage(&img1);
  185.  
  186. pthread_mutex_destroy(&mutex);
  187.  
  188. exit(retval);
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement