From 75c882862135e38f00cfe531eb1d365c7b897680 Mon Sep 17 00:00:00 2001 From: lebarsfa Date: Mon, 17 Aug 2020 16:56:09 +0200 Subject: [PATCH] Corrected bugs related to MJPEG server boundary --- .travis.yml | 4 +- CHANGELOG.txt | 5 ++- CMakeLists.txt | 18 +++++++- Makefile | 15 ++++--- ReadMe.txt | 2 +- RemoteWebcamCli/Main.c | 8 ++-- RemoteWebcamCli/RemoteWebcamCli.vcxproj | 4 +- RemoteWebcamMultiSrv/Globals.h | 4 -- RemoteWebcamMultiSrv/Main.cpp | 41 +++++++++++-------- .../RemoteWebcamMultiSrv.vcxproj | 4 +- 10 files changed, 62 insertions(+), 43 deletions(-) diff --git a/.travis.yml b/.travis.yml index 560cf25..8f3102a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,9 +49,9 @@ jobs: - cmake -G "MSYS Makefiles" . && cmake --build . #- cmake -G "MSYS Makefiles" -D OpenCV_ARCH=x64 -D OpenCV_RUNTIME=mingw . && cmake --build . - - name: "Ubuntu 12.04" + - name: "Ubuntu 14.04" os: linux - dist: precise + dist: trusty compiler: gcc before_install: - sudo apt-get -q update || true diff --git a/CHANGELOG.txt b/CHANGELOG.txt index aa01178..5f157b2 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,8 +1,11 @@ +31 +Corrected bugs related to MJPEG server boundary. + 30 Added .travis.yml. 29 -Enabled USE_OPENCV_HIGHGUI_CPP_API as a workaround to get back working camera with OpenCV 3.2.0, however this is currently incompatible with Kinect v2. +Enabled USE_OPENCV_HIGHGUI_CPP_API as a workaround to get back working camera with OpenCV 3.2.0. Added CMakeLists.txt. 28 diff --git a/CMakeLists.txt b/CMakeLists.txt index 8418bef..913c14c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,11 +5,27 @@ project(RemoteWebcamMultiSrv) find_package(OpenCV) include_directories(${OpenCV_INCLUDE_DIRS}) -option(USE_OPENCV_HIGHGUI_CPP_API "USE_OPENCV_HIGHGUI_CPP_API" OFF) + +option(DISABLE_GUI_REMOTEWEBCAMMULTISRV "DISABLE_GUI_REMOTEWEBCAMMULTISRV" OFF) +option(DISABLE_TIMER_RECORDING "DISABLE_TIMER_RECORDING" OFF) +option(DISABLE_CUSTOM_BAUDRATE "DISABLE_CUSTOM_BAUDRATE" OFF) +option(USE_OPENCV_HIGHGUI_CPP_API "USE_OPENCV_HIGHGUI_CPP_API" ON) + +if(DISABLE_GUI_REMOTEWEBCAMMULTISRV) + add_definitions(-D DISABLE_GUI_REMOTEWEBCAMMULTISRV) +endif() +if(DISABLE_TIMER_RECORDING) + add_definitions(-D DISABLE_TIMER_RECORDING) +endif() +if(DISABLE_CUSTOM_BAUDRATE) + add_definitions(-D DISABLE_CUSTOM_BAUDRATE) +endif() if(USE_OPENCV_HIGHGUI_CPP_API) add_definitions(-D USE_OPENCV_HIGHGUI_CPP_API) endif() +mark_as_advanced(DISABLE_TIMER_RECORDING DISABLE_CUSTOM_BAUDRATE) + include_directories("${PROJECT_SOURCE_DIR}/../OSUtils") include_directories("${PROJECT_SOURCE_DIR}/../Extensions/Img") include_directories("${PROJECT_SOURCE_DIR}/../Extensions/Net") diff --git a/Makefile b/Makefile index e7e37ad..818d81a 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -# Designed for Ubuntu 18.04 (and Android 4.1.2). -# You might need to install C/C++ development tools and OpenCV 3.2.0 by typing : +# Designed for Ubuntu 16.04 (and Android 4.1.2). +# You might need to install C/C++ development tools and OpenCV 2.4 by typing : # sudo apt-get install build-essential libopencv-dev # in a terminal. # Use dos2unix *.txt to ensure line endings are correct for Linux in the configuration files. @@ -16,11 +16,10 @@ CFLAGS += -Wall -Wextra CFLAGS += -I. -I../OSUtils -I../Extensions/Img -I../Extensions/Net #CFLAGS += -D _DEBUG -D _DEBUG_DISPLAY #CFLAGS += -D _DEBUG_MESSAGES -#CFLAGS += -D DISABLE_GUI_REMOTEWEBCAMMULTISRV CFLAGS += -D USE_OPENCV_HIGHGUI_CPP_API -#CFLAGS += -D OPENCV2413 -CFLAGS += -D OPENCV320 -#CFLAGS += -D OPENCV412 + +# For Android +#CFLAGS += -D DISABLE_GUI_REMOTEWEBCAMMULTISRV -D DISABLE_TIMER_RECORDING -D DISABLE_CUSTOM_BAUDRATE # For MinGW #CFLAGS += -D ENABLE_GETTIMEOFDAY_WIN32 -D DISABLE_TIMEZONE_STRUCT_REDEFINITION @@ -37,8 +36,8 @@ CXXFLAGS += $(CFLAGS) -fpermissive #CXXFLAGS += -std=c++11 # Might be necessary to tweak depending on OpenCV version... -#LDFLAGS += -lopencv_core -lopencv_imgproc -lopencv_highgui -LDFLAGS += -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -lopencv_videoio +LDFLAGS += -lopencv_core -lopencv_imgproc -lopencv_highgui +#LDFLAGS += -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -lopencv_videoio # For MinGW #LDFLAGS += -lWinMM -lws2_32 -lm diff --git a/ReadMe.txt b/ReadMe.txt index 28d0923..776f225 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -14,7 +14,7 @@ _ Kinect v2 SDK (not compatible with Visual Studio 2008 and Windows XP) _ Visual Studio 2017 _ OpenCV 3.2.0 (see http://www.ensta-bretagne.fr/lebars/Share/setup_vs2017_opencv320.pdf ) -It is also supposed to be compatible with Linux with equivalent prerequisites, see Makefile. +It is also supposed to be compatible with Linux with equivalent prerequisites, see CMakeLists.txt or Makefile. Restart the computer after installation. diff --git a/RemoteWebcamCli/Main.c b/RemoteWebcamCli/Main.c index 220b17e..a73bbb9 100644 --- a/RemoteWebcamCli/Main.c +++ b/RemoteWebcamCli/Main.c @@ -385,11 +385,11 @@ int main(int argc, char* argv[]) sa.sin_port = htons((unsigned short)atoi(cli1port)); sprintf(databuf, "HELLO"); - sendtoall(s1, databuf, strlen("HELLO")+1, (struct sockaddr*)&sa, sizeof(sa)); - recvfromall(s1, databuf, strlen("OK")+1, (struct sockaddr*)&sa, (int*)&salen); + sendtoall(s1, databuf, (int)strlen("HELLO")+1, (struct sockaddr*)&sa, (int)sizeof(sa)); + recvfromall(s1, databuf, (int)strlen("OK")+1, (struct sockaddr*)&sa, (int*)&salen); sprintf(databuf, "HELLO"); - sendall(s1, databuf, strlen("HELLO")+1); - recvall(s1, databuf, strlen("OK")+1); + sendall(s1, databuf, (int)strlen("HELLO")+1); + recvall(s1, databuf, (int)strlen("OK")+1); //mSleep(15000); } diff --git a/RemoteWebcamCli/RemoteWebcamCli.vcxproj b/RemoteWebcamCli/RemoteWebcamCli.vcxproj index eb444f0..3e78460 100644 --- a/RemoteWebcamCli/RemoteWebcamCli.vcxproj +++ b/RemoteWebcamCli/RemoteWebcamCli.vcxproj @@ -55,7 +55,7 @@ Disabled ..\..\OSUtils;..\..\Extensions\Img;..\..\Extensions\Net;$(SystemDrive)\OpenCV3.2.0\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;_DEBUG_DISPLAY;_DEBUG_MESSAGES;OPENCV320;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;_DEBUG_DISPLAY;_DEBUG_MESSAGES;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -77,7 +77,7 @@ MaxSpeed true ..\..\OSUtils;..\..\Extensions\Img;..\..\Extensions\Net;$(SystemDrive)\OpenCV3.2.0\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;OPENCV320;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) MultiThreaded true diff --git a/RemoteWebcamMultiSrv/Globals.h b/RemoteWebcamMultiSrv/Globals.h index 58fccc5..5bab565 100644 --- a/RemoteWebcamMultiSrv/Globals.h +++ b/RemoteWebcamMultiSrv/Globals.h @@ -18,10 +18,6 @@ #include "OSNet.h" #include "CvInc.h" #ifdef ENABLE_CVKINECT2SDKHOOK -#ifndef INCLUDE_HEADERS_OUTSIDE_CVKINECT2SDKHOOK -#define INCLUDE_HEADERS_OUTSIDE_CVKINECT2SDKHOOK -#endif // !INCLUDE_HEADERS_OUTSIDE_CVKINECT2SDKHOOK -#include #include "CvKinect2SDKHook.h" #endif // ENABLE_CVKINECT2SDKHOOK diff --git a/RemoteWebcamMultiSrv/Main.cpp b/RemoteWebcamMultiSrv/Main.cpp index 3905075..0897715 100644 --- a/RemoteWebcamMultiSrv/Main.cpp +++ b/RemoteWebcamMultiSrv/Main.cpp @@ -236,17 +236,17 @@ inline int MovementDetection(IplImage* previmg, IplImage* img, IplImage* detecti val = UINT_MAX; // Special number to indicate a full image. memcpy(buf, (char*)&val, sizeof(unsigned int)); // Static compressed image dimensions. - i = bufmatvector.size(); + i = (unsigned int)bufmatvector.size(); memcpy(buf+sizeof(unsigned int), (char*)&i, sizeof(unsigned int)); i = 1; memcpy(buf+2*sizeof(unsigned int), (char*)&i, sizeof(unsigned int)); // Full image data (with static compression). - i = bufmatvector.size(); + i = (unsigned int)bufmatvector.size(); while (i--) { buf[3*sizeof(unsigned int)+i] = (char)bufmatvector[i]; } - count = 3*sizeof(unsigned int)+bufmatvector.size(); + count = (unsigned int)(3*sizeof(unsigned int)+bufmatvector.size()); } #endif // !USE_OPENCV_HIGHGUI_CPP_API else @@ -349,17 +349,17 @@ inline int MovementDetection2(IplImage* previmg, IplImage* img, IplImage* detect return EXIT_FAILURE; } // Static compressed image dimensions. - i = bufmatvector.size(); + i = (unsigned int)bufmatvector.size(); memcpy(buf+sizeof(unsigned int), (char*)&i, sizeof(unsigned int)); i = 1; memcpy(buf+2*sizeof(unsigned int), (char*)&i, sizeof(unsigned int)); // Full image data (with static compression). - i = bufmatvector.size(); + i = (unsigned int)bufmatvector.size(); while (i--) { buf[3*sizeof(unsigned int)+i] = (char)bufmatvector[i]; } - count = 3*sizeof(unsigned int)+bufmatvector.size(); + count = (unsigned int)(3*sizeof(unsigned int)+bufmatvector.size()); bufmatvector.clear(); #endif // !USE_OPENCV_HIGHGUI_CPP_API } @@ -446,6 +446,10 @@ int handlecli(SOCKET sockcli, void* pParam) free(sendbuf); return EXIT_FAILURE; } + + // See https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html, + // https://stackoverflow.com/questions/47729941/mjpeg-over-http-specification... + memset(httpbuf, 0, sizeof(httpbuf)); sprintf(httpbuf, "HTTP/1.1 200 OK\r\n" @@ -455,10 +459,11 @@ int handlecli(SOCKET sockcli, void* pParam) //"Expires: 0\r\n" //"Cache-Control: no-cache, private, no-store, must-revalidate, pre-check = 0, post-check = 0, max-age = 0\r\n" //"Pragma: no-cache\r\n" - "Content-Type: multipart/x-mixed-replace; boundary=--boundary\r\n" + "Content-Type: multipart/x-mixed-replace; boundary=boundary\r\n" //"Media-type: image/jpeg\r\n" - "\r\n"); - if (sendall(sockcli, httpbuf, strlen(httpbuf)) != EXIT_SUCCESS) + //"\r\n" // CRLF will be in the next encapsulation boundary "\r\n--boundary\r\n"... + ); + if (sendall(sockcli, httpbuf, (int)strlen(httpbuf)) != EXIT_SUCCESS) { free(sendbuf); return EXIT_FAILURE; @@ -485,7 +490,7 @@ int handlecli(SOCKET sockcli, void* pParam) free(sendbuf); return EXIT_FAILURE; } - mSleep(captureperiod); + uSleep(1000*captureperiod); break; } @@ -698,17 +703,17 @@ THREAD_PROC_RETURN_VALUE handlecam(void* pParam) return 0; } // Static compressed image dimensions. - i = bufmatvector.size(); + i = (unsigned int)bufmatvector.size(); memcpy(databuf+sizeof(unsigned int), (char*)&i, sizeof(unsigned int)); i = 1; memcpy(databuf+2*sizeof(unsigned int), (char*)&i, sizeof(unsigned int)); // Full image data (with static compression). - i = bufmatvector.size(); + i = (unsigned int)bufmatvector.size(); while (i--) { databuf[3*sizeof(unsigned int)+i] = (char)bufmatvector[i]; } - nbBytes = 3*sizeof(unsigned int)+bufmatvector.size(); + nbBytes = (int)(3*sizeof(unsigned int)+bufmatvector.size()); bufmatvector.clear(); #endif // !USE_OPENCV_HIGHGUI_CPP_API #ifndef DISABLE_GUI_REMOTEWEBCAMMULTISRV @@ -769,7 +774,7 @@ THREAD_PROC_RETURN_VALUE handlecam(void* pParam) } memset(httpbuf, 0, sizeof(httpbuf)); sprintf(httpbuf, - "--boundary\r\n" + "\r\n--boundary\r\n" "Content-Type: image/jpeg\r\n" "Content-Length: %d\r\n" "\r\n", mat->rows*mat->cols); @@ -788,14 +793,14 @@ THREAD_PROC_RETURN_VALUE handlecam(void* pParam) } memset(httpbuf, 0, sizeof(httpbuf)); sprintf(httpbuf, - "--boundary\r\n" + "\r\n--boundary\r\n" "Content-Type: image/jpeg\r\n" "Content-Length: %d\r\n" "\r\n", (int)bufmatvector.size()); memcpy(databuf+nbBytes, httpbuf, strlen(httpbuf)); - nbBytes += strlen(httpbuf); + nbBytes += (int)strlen(httpbuf); // Full image data (with static compression). - i = bufmatvector.size(); + i = (unsigned int)bufmatvector.size(); while (i--) { databuf[nbBytes+i] = (char)bufmatvector[i]; @@ -837,7 +842,7 @@ THREAD_PROC_RETURN_VALUE handlecam(void* pParam) #endif // !USE_OPENCV_HIGHGUI_CPP_API if ((char)c == 27) break; #else - mSleep(captureperiod); + uSleep(1000*captureperiod); #endif // !DISABLE_GUI_REMOTEWEBCAMMULTISRV if (bStop) break; } diff --git a/RemoteWebcamMultiSrv/RemoteWebcamMultiSrv.vcxproj b/RemoteWebcamMultiSrv/RemoteWebcamMultiSrv.vcxproj index 0542e71..49eb682 100644 --- a/RemoteWebcamMultiSrv/RemoteWebcamMultiSrv.vcxproj +++ b/RemoteWebcamMultiSrv/RemoteWebcamMultiSrv.vcxproj @@ -55,7 +55,7 @@ Disabled $(KINECTSDK20_DIR)\inc;..\..\OSUtils;..\..\Extensions\Img;..\..\Extensions\Net;$(SystemDrive)\OpenCV3.2.0\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;_DEBUG_DISPLAY;_DEBUG_MESSAGES;OPENCV320;USE_OPENCV_HIGHGUI_CPP_API;ENABLE_CVKINECT2SDKHOOK;ENABLE_GETTIMEOFDAY_WIN32;DISABLE_TIMEZONE_STRUCT_REDEFINITION;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;_DEBUG_DISPLAY;_DEBUG_MESSAGES;USE_OPENCV_HIGHGUI_CPP_API;ENABLE_CVKINECT2SDKHOOK;ENABLE_GETTIMEOFDAY_WIN32;DISABLE_TIMEZONE_STRUCT_REDEFINITION;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -77,7 +77,7 @@ MaxSpeed true $(KINECTSDK20_DIR)\inc;..\..\OSUtils;..\..\Extensions\Img;..\..\Extensions\Net;$(SystemDrive)\OpenCV3.2.0\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;OPENCV320;USE_OPENCV_HIGHGUI_CPP_API;ENABLE_CVKINECT2SDKHOOK;ENABLE_GETTIMEOFDAY_WIN32;DISABLE_TIMEZONE_STRUCT_REDEFINITION;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;USE_OPENCV_HIGHGUI_CPP_API;ENABLE_CVKINECT2SDKHOOK;ENABLE_GETTIMEOFDAY_WIN32;DISABLE_TIMEZONE_STRUCT_REDEFINITION;%(PreprocessorDefinitions) MultiThreaded true