if PACKAGE_mjpg-streamer
config MJPG_STREAMER_V4L2
- bool "Compile input_uvc with libv4l2 (camera controls)"
+ bool "Build input_uvc with libv4l2 (camera controls)"
default n
select PACKAGE_libv4l
bool "Install input uvc plugin"
default y
-config MJPG_STREAMER_INPUT_TESTPICTURE
- bool "Install input testpicture plugin"
+config MJPG_STREAMER_INPUT_HTTP
+ bool "Install input HTTP plugin"
+ default n
+
+config MJPG_STREAMER_OUTPUT_RTSP
+ bool "Install output RTSP plugin"
+ default n
+
+config MJPG_STREAMER_OUTPUT_UDP
+ bool "Install output UDP plugin"
default n
config MJPG_STREAMER_OUTPUT_FILE
default n
config MJPG_STREAMER_OUTPUT_HTTP
- bool "Install output http plugin"
+ bool "Install output HTTP plugin"
default y
config MJPG_STREAMER_WWW
include $(TOPDIR)/rules.mk
PKG_NAME:=mjpg-streamer
-PKG_REV:=182
-PKG_VERSION:=r$(PKG_REV)
-PKG_RELEASE:=10
+PKG_VERSION:=2018-04-14
+PKG_RELEASE:=1
PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>, \
Ted Hess <thess@kitschensync.net>
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).1.tar.xz
-PKG_SOURCE_URL:=https://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer-experimental
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/jacksonliam/mjpg-streamer.git
+PKG_SOURCE_VERSION:=821c330ea6bbb5fbed98d48e00aac156e923161b
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_SOURCE_VERSION:=$(PKG_REV)
-PKG_SOURCE_PROTO:=svn
-PKG_MIRROR_HASH:=ccff417d0a34f7cee12c7984f77788267b1da0f2a7d849bc1b2e3614e670078b
+PKG_MIRROR_HASH:=f95e54bc95c808b9867bbca364e58b6c7e08cb26613205f8d87450ab9c899942
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
PKG_BUILD_DEPENDS:=MJPG_STREAMER_V4L2:libv4l
CATEGORY:=Multimedia
TITLE:=MJPG-streamer
DEPENDS:=+libpthread +libjpeg +MJPG_STREAMER_V4L2:libv4l
- URL:=http://mjpg-streamer.wiki.sourceforge.net/
+ URL:=https://github.com/jacksonliam/mjpg-streamer
MENU:=1
endef
source "$(SOURCE)/Config.in"
endef
-EXTRA_CFLAGS += $(TARGET_CPPFLAGS) $(TARGET_LDFLAGS)
-
define Package/mjpg-streamer/conffiles
/etc/config/mjpg-streamer
endef
MD5SUM:=35c45188aa9635aef2b745c35c311396
endef
-# Fetch latest cambozola that works with latest Java(s)
-# Yes, I know this is ugly
+# redefine prepare to extract to our build dir
+# apply patches
define Build/Prepare
- $(call Build/Prepare/Default)
+ rm -rf $(PKG_BUILD_DIR)/
+ mkdir -p $(PKG_BUILD_DIR)/
+ $(TAR) -xJf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip=2
+ $(Build/Patch)
+ # Fetch latest cambozola that works with latest Java(s)
+ # Yes, I know this is ugly
ifeq ($(CONFIG_MJPG_STREAMER_WWW),y)
$(eval $(call Download,cambozola))
- $(TAR) -xvf $(DL_DIR)/$(CAMBOZOLA) --strip=2 --wildcards \
+ $(TAR) -xf $(DL_DIR)/$(CAMBOZOLA) --strip=2 --wildcards \
-C $(PKG_BUILD_DIR)/www */dist/cambozola.jar
endif
endef
$(RM) $(PKG_BUILD_DIR)/plugins/input_uvc/uvcvideo.h
endef
+ TARGET_LDFLAGS+= -ljpeg
+
ifeq ($(CONFIG_MJPG_STREAMER_V4L2),y)
TARGET_CFLAGS+= -DUSE_LIBV4L2
TARGET_LDFLAGS+= -lv4l2
ifeq ($(CONFIG_MJPG_STREAMER_INPUT_UVC),y)
$(CP) $(PKG_BUILD_DIR)/input_uvc.so $(1)/usr/lib
endif
-ifeq ($(CONFIG_MJPG_STREAMER_INPUT_TESTPICTURE),y)
- $(CP) $(PKG_BUILD_DIR)/input_testpicture.so $(1)/usr/lib
+ifeq ($(CONFIG_MJPG_STREAMER_INPUT_HTTP),y)
+ $(CP) $(PKG_BUILD_DIR)/input_http.so $(1)/usr/lib
+endif
+ifeq ($(CONFIG_MJPG_STREAMER_OUTPUT_RTSP),y)
+ $(CP) $(PKG_BUILD_DIR)/output_rtsp.so $(1)/usr/lib
+endif
+ifeq ($(CONFIG_MJPG_STREAMER_OUTPUT_UDP),y)
+ $(CP) $(PKG_BUILD_DIR)/output_udp.so $(1)/usr/lib
endif
ifeq ($(CONFIG_MJPG_STREAMER_OUTPUT_FILE),y)
$(CP) $(PKG_BUILD_DIR)/output_file.so $(1)/usr/lib
+
#include <linux/types.h> /* for videodev2.h */
#include <linux/videodev2.h>
-
+ #include <pthread.h>
+++ /dev/null
---- a/Makefile
-+++ b/Makefile
-@@ -33,12 +33,12 @@ APP_BINARY = mjpg_streamer
-
- # define the names and targets of the plugins
- PLUGINS = input_uvc.so
--#PLUGINS += output_file.so
-+PLUGINS += output_file.so
- #PLUGINS += output_udp.so
- PLUGINS += output_http.so
- PLUGINS += input_testpicture.so
- #PLUGINS += output_autofocus.so
--#PLUGINS += input_file.so
-+PLUGINS += input_file.so
- # PLUGINS += input_pylon.so
- # PLUGINS += input_megatec.so
- # PLUGINS += output_mars2020.so
--- /dev/null
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -58,9 +58,9 @@ find_library(JPEG_LIB jpeg)
+
+ add_subdirectory(plugins/input_file)
+ add_subdirectory(plugins/input_http)
+-add_subdirectory(plugins/input_opencv)
+-add_subdirectory(plugins/input_raspicam)
+-add_subdirectory(plugins/input_ptp2)
++#add_subdirectory(plugins/input_opencv)
++#add_subdirectory(plugins/input_raspicam)
++#add_subdirectory(plugins/input_ptp2)
+ add_subdirectory(plugins/input_uvc)
+
+ #
+@@ -71,7 +71,7 @@ add_subdirectory(plugins/output_file)
+ add_subdirectory(plugins/output_http)
+ add_subdirectory(plugins/output_rtsp)
+ add_subdirectory(plugins/output_udp)
+-add_subdirectory(plugins/output_viewer)
++#add_subdirectory(plugins/output_viewer)
+
+ #
+ # mjpg_streamer executable
--- /dev/null
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -49,8 +49,7 @@ set (MJPG_STREAMER_PLUGIN_INSTALL_PATH "
+ # Global dependencies
+ #
+
+-find_library(JPEG_LIB jpeg)
+-
++#find_library(JPEG_LIB jpeg)
+
+ #
+ # Input plugins
+--- a/plugins/input_uvc/CMakeLists.txt
++++ b/plugins/input_uvc/CMakeLists.txt
+@@ -8,27 +8,27 @@ if (PLUGIN_INPUT_UVC)
+
+ add_definitions(-DLINUX -D_GNU_SOURCE)
+
+- find_library(V4L2_LIB v4l2)
++# find_library(V4L2_LIB v4l2)
+
+- if (V4L2_LIB)
+- add_definitions(-DUSE_LIBV4L2)
+- endif (V4L2_LIB)
++# if (V4L2_LIB)
++# add_definitions(-DUSE_LIBV4L2)
++# endif (V4L2_LIB)
+
+- if (NOT JPEG_LIB)
+- add_definitions(-DNO_LIBJPEG)
+- endif (NOT JPEG_LIB)
++# if (NOT JPEG_LIB)
++# add_definitions(-DNO_LIBJPEG)
++# endif (NOT JPEG_LIB)
+
+ MJPG_STREAMER_PLUGIN_COMPILE(input_uvc dynctrl.c
+ input_uvc.c
+ jpeg_utils.c
+ v4l2uvc.c)
+
+- if (V4L2_LIB)
+- target_link_libraries(input_uvc ${V4L2_LIB})
+- endif (V4L2_LIB)
++# if (V4L2_LIB)
++# target_link_libraries(input_uvc ${V4L2_LIB})
++# endif (V4L2_LIB)
+
+- if (JPEG_LIB)
+- target_link_libraries(input_uvc ${JPEG_LIB})
+- endif (JPEG_LIB)
++# if (JPEG_LIB)
++# target_link_libraries(input_uvc ${JPEG_LIB})
++# endif (JPEG_LIB)
+
+ endif()
+++ /dev/null
---- a/plugins/input_uvc/Makefile
-+++ b/plugins/input_uvc/Makefile
-@@ -13,7 +13,7 @@ OTHER_HEADERS = ../../mjpg_streamer.h ..
-
- CFLAGS += -O1 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC
-
--CFLAGS += -g -DDEBUG
-+#CFLAGS += -g -DDEBUG
-
- ifeq ($(USE_LIBV4L2),true)
- LFLAGS += -lv4l2
---- a/plugins/output_file/Makefile
-+++ b/plugins/output_file/Makefile
-@@ -12,7 +12,7 @@ CC = gcc
- OTHER_HEADERS = ../../mjpg_streamer.h ../../utils.h ../output.h ../input.h
-
- CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC
--CFLAGS += -DDEBUG -g
-+#CFLAGS += -DDEBUG -g
- LFLAGS += -lpthread -ldl
-
- all: output_file.so
---- a/plugins/output_udp/Makefile
-+++ b/plugins/output_udp/Makefile
-@@ -14,7 +14,7 @@ CC = gcc
- OTHER_HEADERS = ../../mjpg_streamer.h ../../utils.h ../output.h ../input.h
-
- CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC
--CFLAGS += -DDEBUG
-+#CFLAGS += -DDEBUG
- LFLAGS += -lpthread -ldl
-
- all: output_udp.so
+++ /dev/null
---- a/plugins/input_uvc/v4l2uvc.c
-+++ b/plugins/input_uvc/v4l2uvc.c
-@@ -69,7 +69,7 @@ int init_videoIn(struct vdIn *vd, char *
- vd->videodevice = (char *) calloc(1, 16 * sizeof(char));
- vd->status = (char *) calloc(1, 100 * sizeof(char));
- vd->pictName = (char *) calloc(1, 80 * sizeof(char));
-- snprintf(vd->videodevice, 12, "%s", device);
-+ snprintf(vd->videodevice, 16, "%s", device);
- vd->toggleAvi = 0;
- vd->getPict = 0;
- vd->signalquit = 1;
--- /dev/null
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -18,21 +18,6 @@ include(FeatureSummary)
+ include(mjpg_streamer_utils)
+
+ #
+-# Get the current git hash
+-#
+-execute_process(
+- COMMAND git rev-parse HEAD
+- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+- RESULT_VARIABLE GIT_RESULT
+- OUTPUT_VARIABLE GIT_HASH
+- OUTPUT_STRIP_TRAILING_WHITESPACE
+-)
+-
+-if(GIT_RESULT EQUAL 0)
+- add_definitions("-DGIT_HASH=\"${GIT_HASH}\"")
+-endif()
+-
+-#
+ # Options
+ #
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG")
+++ /dev/null
---- a/Makefile
-+++ b/Makefile
-@@ -15,8 +15,8 @@ DESTDIR = /usr/local
- # set the compiler to use
- CC = gcc
-
--SVNDEV := -D'SVN_REV="$(shell svnversion -c .)"'
--CFLAGS += $(SVNDEV)
-+#SVNDEV := -D'SVN_REV="$(shell svnversion -c .)"'
-+#CFLAGS += $(SVNDEV)
-
- # general compile flags, enable all warnings to make compile more verbose
- CFLAGS += -DLINUX -D_GNU_SOURCE -Wall
---- a/mjpg_streamer.c
-+++ b/mjpg_streamer.c
-@@ -253,15 +253,12 @@ int main(int argc, char *argv[])
- /* v, version */
- case 6:
- case 7:
-- printf("MJPG Streamer Version: %s\n" \
-- "Compilation Date.....: %s\n" \
-- "Compilation Time.....: %s\n",
-+ printf("MJPG Streamer Version: %s\n",
- #ifdef SVN_REV
-- SVN_REV,
-+ SVN_REV);
- #else
-- SOURCE_VERSION,
-+ SOURCE_VERSION);
- #endif
-- __DATE__, __TIME__);
- return 0;
- break;
-
+++ /dev/null
-From 19202b54698b343a0207d7e213448e32b8e58fc3 Mon Sep 17 00:00:00 2001
-From: Olliver Schinagl <o.schinagl@ultimaker.com>
-Date: Wed, 29 Oct 2014 09:34:41 +0100
-Subject: [PATCH 1/7] Buffer the bytesused variable from struct v4l2_buffer
-
-Starting with kernel versions 3.16, (DE)Queing of buffers has been fixed
-after it was leaking data for ages. in the struct v4l2_buffer is the
-bytesused element which indicates the size of the buffer. This however
-gets cleared whenever the buffer gets requeued and is thus no longer
-valid.
-
-This patch copies the bytesused variable so it is available until the
-next frame captured again.
-
-Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com>
----
- plugins/input_uvc/input_uvc.c | 6 +++---
- plugins/input_uvc/v4l2uvc.c | 2 ++
- plugins/input_uvc/v4l2uvc.h | 1 +
- 3 files changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/plugins/input_uvc/input_uvc.c b/plugins/input_uvc/input_uvc.c
-index e6c74fd..64f66cb 100644
---- a/plugins/input_uvc/input_uvc.c
-+++ b/plugins/input_uvc/input_uvc.c
-@@ -482,7 +482,7 @@ void *cam_thread(void *arg)
- exit(EXIT_FAILURE);
- }
-
-- //DBG("received frame of size: %d from plugin: %d\n", pcontext->videoIn->buf.bytesused, pcontext->id);
-+ //DBG("received frame of size: %d from plugin: %d\n", pcontext->videoIn->tmpbytesused, pcontext->id);
-
- /*
- * Workaround for broken, corrupted frames:
-@@ -491,7 +491,7 @@ void *cam_thread(void *arg)
- * For example a VGA (640x480) webcam picture is normally >= 8kByte large,
- * corrupted frames are smaller.
- */
-- if(pcontext->videoIn->buf.bytesused < minimum_size) {
-+ if(pcontext->videoIn->tmpbytesused < minimum_size) {
- DBG("dropping too small frame, assuming it as broken\n");
- continue;
- }
-@@ -529,7 +529,7 @@ void *cam_thread(void *arg)
- } else {
- #endif
- //DBG("copying frame from input: %d\n", (int)pcontext->id);
-- pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->buf.bytesused);
-+ pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->tmpbytesused);
- #ifndef NO_LIBJPEG
- }
- #endif
-diff --git a/plugins/input_uvc/v4l2uvc.c b/plugins/input_uvc/v4l2uvc.c
-index c5a5aa4..d11510c 100644
---- a/plugins/input_uvc/v4l2uvc.c
-+++ b/plugins/input_uvc/v4l2uvc.c
-@@ -532,6 +532,7 @@ int uvcGrab(struct vdIn *vd)
- */
-
- memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused);
-+ vd->tmpbytesused = vd->buf.bytesused;
-
- if(debug)
- fprintf(stderr, "bytes in used %d \n", vd->buf.bytesused);
-@@ -570,6 +571,7 @@ int close_v4l2(struct vdIn *vd)
- if(vd->tmpbuffer)
- free(vd->tmpbuffer);
- vd->tmpbuffer = NULL;
-+ vd->tmpbytesused = 0;
- free(vd->framebuffer);
- vd->framebuffer = NULL;
- free(vd->videodevice);
-diff --git a/plugins/input_uvc/v4l2uvc.h b/plugins/input_uvc/v4l2uvc.h
-index 022c57e..2c7c8ba 100644
---- a/plugins/input_uvc/v4l2uvc.h
-+++ b/plugins/input_uvc/v4l2uvc.h
-@@ -83,6 +83,7 @@ struct vdIn {
- struct v4l2_requestbuffers rb;
- void *mem[NB_BUFFER];
- unsigned char *tmpbuffer;
-+ int tmpbytesused;
- unsigned char *framebuffer;
- streaming_state streamingState;
- int grabmethod;
---
-1.9.1
-
+++ /dev/null
-From 11b28b36a8711b53658e8bbc50435595522f91ba Mon Sep 17 00:00:00 2001
-From: Olliver Schinagl <o.schinagl@ultimaker.com>
-Date: Wed, 29 Oct 2014 11:21:16 +0100
-Subject: [PATCH 2/7] Stop leaking data via struct v4l2_buffer
-
-Before the 3.16 kernel, the v4l2_buffer was leaking data and violating
-its own spec. Since 3.16 this has been corrected and after calling the
-QBUF ioctl, the struct gets cleaned up.
-
-Right now, input_uvc assumes the buffer is valid at all times. This no
-longer being true, this patch removes the v4l2_buffer from the vdIn
-struct. Certain values are still needed outside of this buffer however,
-the length buffer in the buffer array 'mem' and the timestamp. These are
-now stored in the vdIn struct.
-
-All of this is still somewhat hackish, as a) the processing of the image
-should really be done inside the uvcGrab function between the queuing
-and dequeing of the buffers (or separate that into 3 functions, deq, q
-and process and call them from input_uvc). b) we are still copying the
-image using memcpy, which is something we don't really want and defeats
-the purpose of using a mmap in the first place. Changing this however
-requires some heavier re-architecting and in the end, may still not be avoided.
-
-More information about this bug and change can be found on the
-linux-media mailing list[0] with the title uvcvideo fails on 3.16 and
-3.17 kernels.
-
-[0] http://www.spinics.net/lists/linux-media/msg81515.html
-
-Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com>
----
- plugins/input_uvc/input_uvc.c | 6 ++--
- plugins/input_uvc/v4l2uvc.c | 64 +++++++++++++++++++++++--------------------
- plugins/input_uvc/v4l2uvc.h | 4 ++-
- 3 files changed, 41 insertions(+), 33 deletions(-)
-
-diff --git a/plugins/input_uvc/input_uvc.c b/plugins/input_uvc/input_uvc.c
-index 64f66cb..64ef56c 100644
---- a/plugins/input_uvc/input_uvc.c
-+++ b/plugins/input_uvc/input_uvc.c
-@@ -500,8 +500,8 @@ void *cam_thread(void *arg)
- if (pcontext->videoIn->soft_framedrop == 1) {
- unsigned long last = pglobal->in[pcontext->id].timestamp.tv_sec * 1000 +
- (pglobal->in[pcontext->id].timestamp.tv_usec/1000); // convert to ms
-- unsigned long current = pcontext->videoIn->buf.timestamp.tv_sec * 1000 +
-- pcontext->videoIn->buf.timestamp.tv_usec/1000; // convert to ms
-+ unsigned long current = pcontext->videoIn->tmptimestamp.tv_sec * 1000 +
-+ pcontext->videoIn->tmptimestamp.tv_usec/1000; // convert to ms
-
- // if the requested time did not esplashed skip the frame
- if ((current - last) < pcontext->videoIn->frame_period_time) {
-@@ -543,7 +543,7 @@ void *cam_thread(void *arg)
- #endif
-
- /* copy this frame's timestamp to user space */
-- pglobal->in[pcontext->id].timestamp = pcontext->videoIn->buf.timestamp;
-+ pglobal->in[pcontext->id].timestamp = pcontext->videoIn->tmptimestamp;
-
- /* signal fresh_frame */
- pthread_cond_broadcast(&pglobal->in[pcontext->id].db_update);
-diff --git a/plugins/input_uvc/v4l2uvc.c b/plugins/input_uvc/v4l2uvc.c
-index d11510c..7ec5eec 100644
---- a/plugins/input_uvc/v4l2uvc.c
-+++ b/plugins/input_uvc/v4l2uvc.c
-@@ -217,6 +217,9 @@ static int init_v4l2(struct vdIn *vd)
- {
- int i;
- int ret = 0;
-+ struct v4l2_buffer buf;
-+
-+
- if((vd->fd = OPEN_VIDEO(vd->videodevice, O_RDWR)) == -1) {
- perror("ERROR opening V4L interface");
- DBG("errno: %d", errno);
-@@ -375,26 +378,27 @@ static int init_v4l2(struct vdIn *vd)
- * map the buffers
- */
- for(i = 0; i < NB_BUFFER; i++) {
-- memset(&vd->buf, 0, sizeof(struct v4l2_buffer));
-- vd->buf.index = i;
-- vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-- vd->buf.memory = V4L2_MEMORY_MMAP;
-- ret = xioctl(vd->fd, VIDIOC_QUERYBUF, &vd->buf);
-+ memset(&buf, 0, sizeof(struct v4l2_buffer));
-+ buf.index = i;
-+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ buf.memory = V4L2_MEMORY_MMAP;
-+ ret = xioctl(vd->fd, VIDIOC_QUERYBUF, &buf);
- if(ret < 0) {
- perror("Unable to query buffer");
- goto fatal;
- }
-
- if(debug)
-- fprintf(stderr, "length: %u offset: %u\n", vd->buf.length, vd->buf.m.offset);
-+ fprintf(stderr, "length: %u offset: %u\n", buf.length, buf.m.offset);
-
- vd->mem[i] = mmap(0 /* start anywhere */ ,
-- vd->buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, vd->fd,
-- vd->buf.m.offset);
-+ buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, vd->fd,
-+ buf.m.offset);
- if(vd->mem[i] == MAP_FAILED) {
- perror("Unable to map buffer");
- goto fatal;
- }
-+ vd->memlength[i] = buf.length;
- if(debug)
- fprintf(stderr, "Buffer mapped at address %p.\n", vd->mem[i]);
- }
-@@ -403,11 +407,11 @@ static int init_v4l2(struct vdIn *vd)
- * Queue the buffers.
- */
- for(i = 0; i < NB_BUFFER; ++i) {
-- memset(&vd->buf, 0, sizeof(struct v4l2_buffer));
-- vd->buf.index = i;
-- vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-- vd->buf.memory = V4L2_MEMORY_MMAP;
-- ret = xioctl(vd->fd, VIDIOC_QBUF, &vd->buf);
-+ memset(&buf, 0, sizeof(struct v4l2_buffer));
-+ buf.index = i;
-+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ buf.memory = V4L2_MEMORY_MMAP;
-+ ret = xioctl(vd->fd, VIDIOC_QBUF, &buf);
- if(ret < 0) {
- perror("Unable to queue buffer");
- goto fatal;;
-@@ -499,17 +503,18 @@ int memcpy_picture(unsigned char *out, unsigned char *buf, int size)
- int uvcGrab(struct vdIn *vd)
- {
- #define HEADERFRAME1 0xaf
-+ struct v4l2_buffer buf;
- int ret;
-
- if(vd->streamingState == STREAMING_OFF) {
- if(video_enable(vd))
- goto err;
- }
-- memset(&vd->buf, 0, sizeof(struct v4l2_buffer));
-- vd->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-- vd->buf.memory = V4L2_MEMORY_MMAP;
-+ memset(&buf, 0, sizeof(struct v4l2_buffer));
-+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-+ buf.memory = V4L2_MEMORY_MMAP;
-
-- ret = xioctl(vd->fd, VIDIOC_DQBUF, &vd->buf);
-+ ret = xioctl(vd->fd, VIDIOC_DQBUF, &buf);
- if(ret < 0) {
- perror("Unable to dequeue buffer");
- goto err;
-@@ -517,33 +522,34 @@ int uvcGrab(struct vdIn *vd)
-
- switch(vd->formatIn) {
- case V4L2_PIX_FMT_MJPEG:
-- if(vd->buf.bytesused <= HEADERFRAME1) {
-+ if(buf.bytesused <= HEADERFRAME1) {
- /* Prevent crash
- * on empty image */
- fprintf(stderr, "Ignoring empty buffer ...\n");
- return 0;
- }
-
-- /* memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused);
-+ /* memcpy(vd->tmpbuffer, vd->mem[buf.index], buf.bytesused);
-
-- memcpy (vd->tmpbuffer, vd->mem[vd->buf.index], HEADERFRAME1);
-+ memcpy (vd->tmpbuffer, vd->mem[buf.index], HEADERFRAME1);
- memcpy (vd->tmpbuffer + HEADERFRAME1, dht_data, sizeof(dht_data));
-- memcpy (vd->tmpbuffer + HEADERFRAME1 + sizeof(dht_data), vd->mem[vd->buf.index] + HEADERFRAME1, (vd->buf.bytesused - HEADERFRAME1));
-+ memcpy (vd->tmpbuffer + HEADERFRAME1 + sizeof(dht_data), vd->mem[buf.index] + HEADERFRAME1, (buf.bytesused - HEADERFRAME1));
- */
-
-- memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused);
-- vd->tmpbytesused = vd->buf.bytesused;
-+ memcpy(vd->tmpbuffer, vd->mem[buf.index], buf.bytesused);
-+ vd->tmpbytesused = buf.bytesused;
-+ vd->tmptimestamp = buf.timestamp;
-
- if(debug)
-- fprintf(stderr, "bytes in used %d \n", vd->buf.bytesused);
-+ fprintf(stderr, "bytes in used %d \n", buf.bytesused);
- break;
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_RGB24:
-- if(vd->buf.bytesused > vd->framesizeIn)
-- memcpy(vd->framebuffer, vd->mem[vd->buf.index], (size_t) vd->framesizeIn);
-+ if(buf.bytesused > vd->framesizeIn)
-+ memcpy(vd->framebuffer, vd->mem[buf.index], (size_t) vd->framesizeIn);
- else
-- memcpy(vd->framebuffer, vd->mem[vd->buf.index], (size_t) vd->buf.bytesused);
-+ memcpy(vd->framebuffer, vd->mem[buf.index], (size_t) buf.bytesused);
- break;
-
- default:
-@@ -551,7 +557,7 @@ int uvcGrab(struct vdIn *vd)
- break;
- }
-
-- ret = xioctl(vd->fd, VIDIOC_QBUF, &vd->buf);
-+ ret = xioctl(vd->fd, VIDIOC_QBUF, &buf);
- if(ret < 0) {
- perror("Unable to requeue buffer");
- goto err;
-@@ -947,7 +953,7 @@ int setResolution(struct vdIn *vd, int width, int height)
- DBG("Unmap buffers\n");
- int i;
- for(i = 0; i < NB_BUFFER; i++)
-- munmap(vd->mem[i], vd->buf.length);
-+ munmap(vd->mem[i], vd->memlength[i]);
-
- if(CLOSE_VIDEO(vd->fd) == 0) {
- DBG("Device closed successfully\n");
-diff --git a/plugins/input_uvc/v4l2uvc.h b/plugins/input_uvc/v4l2uvc.h
-index 2c7c8ba..e625957 100644
---- a/plugins/input_uvc/v4l2uvc.h
-+++ b/plugins/input_uvc/v4l2uvc.h
-@@ -35,6 +35,7 @@
- #include <sys/ioctl.h>
- #include <sys/mman.h>
- #include <sys/select.h>
-+#include <sys/time.h>
-
- #include <linux/types.h> /* for videodev2.h */
- #include <linux/videodev2.h>
-@@ -79,11 +80,12 @@ struct vdIn {
- char *pictName;
- struct v4l2_capability cap;
- struct v4l2_format fmt;
-- struct v4l2_buffer buf;
- struct v4l2_requestbuffers rb;
- void *mem[NB_BUFFER];
-+ int memlength[NB_BUFFER];
- unsigned char *tmpbuffer;
- int tmpbytesused;
-+ struct timeval tmptimestamp;
- unsigned char *framebuffer;
- streaming_state streamingState;
- int grabmethod;
---
-1.9.1
-
+++ /dev/null
-Binary files a/ipkg-ar71xx/mjpg-streamer/usr/lib/input_uvc.so and b/ipkg-ar71xx/mjpg-streamer/usr/lib/input_uvc.so differ
-diff -ur a/plugins/input_uvc/input_uvc.c b/plugins/input_uvc/input_uvc.c
---- a/plugins/input_uvc/input_uvc.c 2015-03-02 09:14:05.000000000 +0200
-+++ b/plugins/input_uvc/input_uvc.c 2015-03-02 09:18:22.000000000 +0200
-@@ -311,6 +311,10 @@
- }
- memset(cams[id].videoIn, 0, sizeof(struct vdIn));
-
-+ /* Non-MJPEG formats seem to fail with unlimited FPS */
-+ if (format != V4L2_PIX_FMT_MJPEG && fps == -1)
-+ fps = 15;
-+
- /* display the parsed values */
- IPRINT("Using V4L2 device.: %s\n", dev);
- IPRINT("Desired Resolution: %i x %i\n", width, height);
-diff -ur a/plugins/input_uvc/jpeg_utils.c b/plugins/input_uvc/jpeg_utils.c
---- a/plugins/input_uvc/jpeg_utils.c 2015-03-02 09:17:02.000000000 +0300
-+++ b/plugins/input_uvc/jpeg_utils.c 2015-03-02 09:25:18.000000000 +0200
-@@ -198,7 +198,7 @@
- }
-
- row_pointer = (JSAMPROW*)line_buffer;
-- jpeg_write_scanlines(&cinfo, row_pointer, 1);
-+ jpeg_write_scanlines(&cinfo, &row_pointer, 1);
- }
- } else if (vd->formatIn == V4L2_PIX_FMT_RGB565) {
- while(cinfo.next_scanline < vd->height) {
-@@ -220,7 +220,7 @@
- }
-
- row_pointer = (JSAMPROW*)line_buffer;
-- jpeg_write_scanlines(&cinfo, row_pointer, 1);
-+ jpeg_write_scanlines(&cinfo, &row_pointer, 1);
- }
- } else if (vd->formatIn == V4L2_PIX_FMT_RGB24) {
- jpeg_write_scanlines(&cinfo, (JSAMPROW*)vd->framebuffer, vd->height);
-diff -ur a/plugins/input_uvc/v4l2uvc.c b/plugins/input_uvc/v4l2uvc.c
---- a/plugins/input_uvc/v4l2uvc.c 2015-03-02 09:14:05.000000000 +0200
-+++ b/plugins/input_uvc/v4l2uvc.c 2015-03-02 09:22:09.000000000 +0200
-@@ -338,11 +338,15 @@
- vd->frame_period_time = 1000/vd->fps; // calcualate frame period time in ms
- IPRINT("Frame period time ......: %ld ms\n", vd->frame_period_time);
-
-- // set FPS to maximum in order to minimize the lagging
- memset(setfps, 0, sizeof(struct v4l2_streamparm));
- setfps->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- setfps->parm.capture.timeperframe.numerator = 1;
-- setfps->parm.capture.timeperframe.denominator = 255;
-+ if (vd->formatIn == V4L2_PIX_FMT_MJPEG)
-+ // set FPS to maximum in order to minimize the lagging
-+ setfps->parm.capture.timeperframe.denominator = 255;
-+ else
-+ setfps->parm.capture.timeperframe.denominator = vd->fps;
-+
- ret = xioctl(vd->fd, VIDIOC_S_PARM, setfps);
- if (ret) {
- perror("Unable to set the FPS\n");
-
+++ /dev/null
---- a/plugins/input_uvc/v4l2uvc.c
-+++ b/plugins/input_uvc/v4l2uvc.c
-@@ -130,7 +130,7 @@ int init_videoIn(struct vdIn *vd, char *
- return -1;
- }
-
-- memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(input_format));
-+ memcpy(&pglobal->in[id].in_formats[pglobal->in[id].formatCount], &fmtdesc, sizeof(struct v4l2_fmtdesc));
-
- if(fmtdesc.pixelformat == format)
- pglobal->in[id].currentFormat = pglobal->in[id].formatCount;