From 937306f0c9961da810103dab5a2cf53bad5026e8 Mon Sep 17 00:00:00 2001 From: AlexeyAB Date: Fri, 11 Jan 2019 22:39:29 +0300 Subject: [PATCH] Fixed JSON-stream and MJPEG-stream on Windows and Linux. --- json_mjpeg_streams.sh | 6 ++++ mjpeg_stream.sh | 8 ----- src/demo.c | 1 - src/http_stream.cpp | 77 +++++++++++++++++++++++++++++-------------- 4 files changed, 59 insertions(+), 33 deletions(-) create mode 100644 json_mjpeg_streams.sh delete mode 100644 mjpeg_stream.sh diff --git a/json_mjpeg_streams.sh b/json_mjpeg_streams.sh new file mode 100644 index 00000000..23ce450c --- /dev/null +++ b/json_mjpeg_streams.sh @@ -0,0 +1,6 @@ +# Run this file and then open URL in Chrome/Firefox in 2 tabs: http://localhost:8070 and http://localhost:8090 +# Or open: http://ip-address:8070 and http://ip-address:8090 +# to get run: sudo ifconfig + +./darknet detector demo ./cfg/coco.data ./cfg/yolov3.cfg ./yolov3.weights test50.mp4 -json_port 8070 -http_port 8090 -ext_output + diff --git a/mjpeg_stream.sh b/mjpeg_stream.sh deleted file mode 100644 index ff21ddf4..00000000 --- a/mjpeg_stream.sh +++ /dev/null @@ -1,8 +0,0 @@ -rem Run this file and then open URL in Chrome/Firefox: rem http://localhost:8090 -rem Or open: http://ip-address:8090 - -./darknet detector demo ./cfg/coco.data ./cfg/yolov3.cfg ./yolov3.weights test50.mp4 -i 0 -thresh 0.25 -http_port 8090 - - - -pause \ No newline at end of file diff --git a/src/demo.c b/src/demo.c index 53e8bd10..10b90861 100644 --- a/src/demo.c +++ b/src/demo.c @@ -302,7 +302,6 @@ void demo(char *cfgfile, char *weightfile, float thresh, float hier_thresh, int if (flag_exit == 1) break; if(delay == 0){ - printf("\n show_img = det_img; \n"); show_img = det_img; } det_img = in_img; diff --git a/src/http_stream.cpp b/src/http_stream.cpp index b4c88a32..29d8aa7c 100644 --- a/src/http_stream.cpp +++ b/src/http_stream.cpp @@ -21,7 +21,22 @@ struct _INIT_W32DATA WSADATA w; _INIT_W32DATA() { WSAStartup(MAKEWORD(2, 1), &w); } } _init_once; -#else /* ! win32 */ + +// Graceful closes will first close their output channels and then wait for the peer +// on the other side of the connection to close its output channels. When both sides are done telling +// each other they won’t be sending any more data (i.e., closing output channels), +// the connection can be closed fully, with no risk of reset. +static int close_socket(SOCKET s) { + int close_output = ::shutdown(s, 1); // 0 close input, 1 close output, 2 close both + char *buf = (char *)calloc(1024, sizeof(char)); + ::recv(s, buf, 1024, 0); + free(buf); + int close_input = ::shutdown(s, 0); + int result = ::closesocket(s); + printf("Close socket: out = %d, in = %d \n", close_output, close_input); + return result; +} +#else // nix #include #include #include @@ -29,6 +44,7 @@ struct _INIT_W32DATA #include #include #include +#include #define PORT unsigned short #define SOCKET int #define HOSTENT struct hostent @@ -37,7 +53,29 @@ struct _INIT_W32DATA #define ADDRPOINTER unsigned int* #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 -#endif /* _WIN32 */ +struct _IGNORE_PIPE_SIGNAL +{ + struct sigaction new_actn, old_actn; + _IGNORE_PIPE_SIGNAL() { + new_actn.sa_handler = SIG_IGN; // ignore the broken pipe signal + sigemptyset(&new_actn.sa_mask); + new_actn.sa_flags = 0; + sigaction(SIGPIPE, &new_actn, &old_actn); + // sigaction (SIGPIPE, &old_actn, NULL); // - to restore the previous signal handling + } +} _init_once; + +static int close_socket(SOCKET s) { + int close_output = ::shutdown(s, 1); // 0 close input, 1 close output, 2 close both + char *buf = (char *)calloc(1024, sizeof(char)); + ::recv(s, buf, 1024, 0); + free(buf); + int close_input = ::shutdown(s, 0); + int result = close(s); + printf("Close socket: out = %d, in = %d \n", close_output, close_input); + return result; +} +#endif // _WIN32 #include #include @@ -139,8 +177,9 @@ public: bool write(const Mat & frame) { fd_set rread = master; - struct timeval to = { 0,timeout }; - if (::select(maxfd+1, &rread, NULL, NULL, &to) <= 0) + struct timeval select_timeout = { 0, 0 }; + struct timeval socket_timeout = { 0, timeout }; + if (::select(maxfd+1, &rread, NULL, NULL, &select_timeout) <= 0) return true; // nothing broken, there's just noone listening std::vector outbuf; @@ -171,10 +210,10 @@ public: cerr << "error MJPG_sender: couldn't accept connection on sock " << sock << " !" << endl; return false; } - if (setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&to, sizeof(to)) < 0) { + if (setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&socket_timeout, sizeof(socket_timeout)) < 0) { cerr << "error MJPG_sender: SO_RCVTIMEO setsockopt failed\n"; } - if (setsockopt(client, SOL_SOCKET, SO_SNDTIMEO, (char *)&to, sizeof(to)) < 0) { + if (setsockopt(client, SOL_SOCKET, SO_SNDTIMEO, (char *)&socket_timeout, sizeof(socket_timeout)) < 0) { cerr << "error MJPG_sender: SO_SNDTIMEO setsockopt failed\n"; } maxfd = (maxfd>client ? maxfd : client); @@ -195,11 +234,7 @@ public: else // existing client, just stream pix { if (close_all_sockets) { - int result = ::shutdown(s, 1); // 0 close input, 1 close output, 2 close both - char *buf = (char *)calloc(1024, sizeof(char)); - ::recv(s, buf, 1024, 0); - free(buf); - //::closesocket(s); + int result = close_socket(s); printf("MJPG_sender: close clinet: %d \n", result); continue; } @@ -309,8 +344,9 @@ public: bool write(char *outputbuf) { fd_set rread = master; - struct timeval to = { 0,timeout }; - if (::select(maxfd + 1, &rread, NULL, NULL, &to) <= 0) + struct timeval select_timeout = { 0, 0 }; + struct timeval socket_timeout = { 0, timeout }; + if (::select(maxfd + 1, &rread, NULL, NULL, &select_timeout) <= 0) return true; // nothing broken, there's just noone listening size_t outlen = strlen(outputbuf); @@ -336,10 +372,10 @@ public: cerr << "error JSON_sender: couldn't accept connection on sock " << sock << " !" << endl; return false; } - if (setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&to, sizeof(to)) < 0) { + if (setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (char *)&socket_timeout, sizeof(socket_timeout)) < 0) { cerr << "error JSON_sender: SO_RCVTIMEO setsockopt failed\n"; } - if (setsockopt(client, SOL_SOCKET, SO_SNDTIMEO, (char *)&to, sizeof(to)) < 0) { + if (setsockopt(client, SOL_SOCKET, SO_SNDTIMEO, (char *)&socket_timeout, sizeof(socket_timeout)) < 0) { cerr << "error JSON_sender: SO_SNDTIMEO setsockopt failed\n"; } maxfd = (maxfd>client ? maxfd : client); @@ -376,17 +412,10 @@ public: FD_CLR(s, &master); } - // Graceful closes will first close their output channels and then wait for the peer - // on the other side of the connection to close its output channels. When both sides are done telling - // each other they won’t be sending any more data (i.e., closing output channels), - // the connection can be closed fully, with no risk of reset. if (close_all_sockets) { - int result = ::shutdown(s, 1); // 0 close input, 1 close output, 2 close both - char *buf = (char *)calloc(1024, sizeof(char)); - ::recv(s, buf, 1024, 0); - free(buf); - //::closesocket(s); + int result = close_socket(s); printf("JSON_sender: close clinet: %d \n", result); + continue; } } }