mjpg-streamer: Update to latest from github/jacksonliam repository. Add additional plugins for RTSP, UDP, etc.

Signed-off-by: Ted Hess <thess@kitschensync.net>
This commit is contained in:
Ted Hess 2018-05-21 18:01:20 -04:00
parent 0356afbc12
commit 82742a6b4e
14 changed files with 144 additions and 515 deletions

View File

@ -5,7 +5,7 @@
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
@ -17,8 +17,16 @@ config MJPG_STREAMER_INPUT_UVC
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
@ -26,7 +34,7 @@ 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

View File

@ -6,23 +6,23 @@
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
@ -31,7 +31,7 @@ define Package/mjpg-streamer
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
@ -43,8 +43,6 @@ define Package/mjpg-streamer/config
source "$(SOURCE)/Config.in"
endef
EXTRA_CFLAGS += $(TARGET_CPPFLAGS) $(TARGET_LDFLAGS)
define Package/mjpg-streamer/conffiles
/etc/config/mjpg-streamer
endef
@ -60,13 +58,18 @@ define Download/cambozola
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
@ -75,6 +78,8 @@ define Build/Configure
$(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
@ -96,8 +101,14 @@ endif
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

View File

@ -10,4 +10,4 @@
+
#include <linux/types.h> /* for videodev2.h */
#include <linux/videodev2.h>
#include <pthread.h>

View File

@ -1,17 +0,0 @@
--- 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

View File

@ -0,0 +1,24 @@
--- 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

View File

@ -0,0 +1,55 @@
--- 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()

View File

@ -1,33 +0,0 @@
--- 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

View File

@ -1,11 +0,0 @@
--- 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;

View File

@ -0,0 +1,24 @@
--- 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")

View File

@ -1,34 +0,0 @@
--- 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;

View File

@ -1,87 +0,0 @@
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

View File

@ -1,242 +0,0 @@
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

View File

@ -1,58 +0,0 @@
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");

View File

@ -1,11 +0,0 @@
--- 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;