v4l update

This update removes the components for v4l and implements only
the v4l2 and BSD option.  This commit also consolidates some
of the pre-processor directives and only uses the WITHOUT_V4L2
instead of the multiple.  The checks for the HAVE_LINUX_VIDEODEV2_H
were removed from the code because the WITHOUT_V4L2 is actually
set based upon the existance of the HAVE_LINUX_VIDEODEV2_H.
Finally, this renames some files to be more consistent.
This commit is contained in:
MrDave
2016-12-15 21:44:41 -07:00
parent f01b81a8f8
commit 74b4223f6e
19 changed files with 142 additions and 924 deletions

View File

@@ -24,7 +24,7 @@ option(WITH_MMAL "enable MMAL (Multi-Media Abstraction Layer API) support for Ra
option(WITH_MYSQL "enable MySQL database support" ${MYSQL_FOUND})
option(WITH_PGSQL "enable PostgreSQL database support" ${PostgreSQL_FOUND})
option(WITH_SQLITE3 "enable SQLite database support" ${SQLITE3_FOUND})
option(WITH_V4L "enable Video 4 Linux (2) webcam support" ON)
option(WITH_V4L2 "enable Video 4 Linux (2) webcam support" ON)
option(WITH_PWCBSD "enable PWC webcam support (BSD only)" OFF)
set(HAVE_FFMPEG ${WITH_FFMPEG})
@@ -32,15 +32,12 @@ set(HAVE_MMAL ${WITH_MMAL})
set(HAVE_MYSQL ${WITH_MYSQL})
set(HAVE_PGSQL ${WITH_PGSQL})
set(HAVE_SQLITE3 ${WITH_SQLITE3})
check_include_files("linux/videodev.h" HAVE_LINUX_VIDEODEV_H)
check_include_files("linux/videodev2.h" HAVE_LINUX_VIDEODEV2_H)
check_include_files("sys/videoio.h" HAVE_SYS_VIDEOIO_H)
if(${WITH_V4L})
set(WITHOUT_V4L OFF)
else(${WITH_V4L})
set(WITHOUT_V4L ON)
endif(${WITH_V4L})
set(MOTION_V4L2 ${HAVE_LINUX_VIDEODEV2_H})
if(${WITH_V4L2})
set(WITHOUT_V4L2 HAVE_LINUX_VIDEODEV2_H)
else(${WITH_V4L2})
set(WITHOUT_V4L2 OFF)
endif(${WITH_V4L2})
set(PWCBSD WITH_PWCBSD)
configure_file(config.h.in "${CMAKE_CURRENT_SOURCE_DIR}/config.h")
@@ -58,11 +55,11 @@ configure_file(motion.init-FreeBSD.sh.in motion.init-FreeBSD.sh)
list(APPEND SRC_FILES
conf.c motion.c alg.c draw.c event.c ffmpeg.c jpegutils.c logger.c md5.c
netcam.c netcam_ftp.c netcam_jpeg.c netcam_rtsp.c netcam_wget.c
picture.c rotate.c stream.c track.c vloopback_motion.c webhttpd.c)
picture.c rotate.c stream.c track.c vloopback_motion2.c webhttpd.c)
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" AND NOT(WITH_PWCBSD))
list(APPEND SRC_FILES video_freebsd.c)
else()
list(APPEND SRC_FILES video2.c video.c video_common.c)
list(APPEND SRC_FILES video2.c video_common.c)
endif()
include_directories(${JPEG_INCLUDE_DIR})

View File

@@ -36,7 +36,7 @@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@ @MMAL_LIBS@ @FFMPEG_LIBS@
VIDEO_OBJ = @VIDEO@
OBJ = motion.o logger.o conf.o draw.o jpegutils.o \
vloopback_motion.o vloopback_motion2.o $(VIDEO_OBJ) \
vloopback_motion2.o $(VIDEO_OBJ) \
netcam.o netcam_ftp.o netcam_jpeg.o netcam_wget.o track.o \
alg.o event.o picture.o rotate.o webhttpd.o \
stream.o md5.o netcam_rtsp.o ffmpeg.o \

2
conf.c
View File

@@ -32,7 +32,7 @@
#if (defined(__FreeBSD__) && !defined(PWCBSD))
#include "video_freebsd.h"
#else
#include "video.h"
#include "video2.h"
#endif
#define EXTENSION ".conf"

View File

@@ -40,7 +40,7 @@ if test "${Darwin}" = ""; then
FreeBSD=`uname -a | grep "FreeBSD"`
if test "${FreeBSD}" = ""; then
AC_MSG_RESULT(no)
VIDEO="video.o video2.o video_common.o"
VIDEO="video2.o video_common.o"
else
AC_MSG_RESULT(yes)
if test "${LINUXTHREADS}" = "no"; then
@@ -52,7 +52,7 @@ if test "${Darwin}" = ""; then
fi
if test "${PWCBSD}" != "no"; then
VIDEO="video.o video2.o video_common.o"
VIDEO="video2.o video_common.o"
TEMP_CFLAGS="${CFLAGS} -I/usr/local/include -DPWCBSD"
else
VIDEO="video_freebsd.o"
@@ -71,7 +71,7 @@ else
VIDEO="video_freebsd.o"
FINK_LIB="-L/sw/lib"
Darwin="yes"
V4L="no"
V4L2="no"
AC_MSG_RESULT($Darwin)
fi
@@ -94,43 +94,43 @@ if test "${FreeBSD}" != "" && test "${PWCBSD}" = "no"; then
else
AC_MSG_RESULT(no)
fi
#
# Check to Exclude BKTR
#
BKTR="yes"
AC_ARG_WITH(bktr,
[ --without-bktr Exclude to use bktr subsystem , that usually useful
for devices as network cameras ( ONLY used in *BSD).
]
,
BKTR="$withval"
)
if test "${BKTR}" = "no"; then
TEMP_CFLAGS="${TEMP_CFLAGS} -DWITHOUT_V4L"
fi
#
# Check to Exclude BKTR
#
BKTR="yes"
AC_ARG_WITH(bktr,
[ --without-bktr Exclude to use bktr subsystem , that usually useful
for devices as network cameras ( ONLY used in *BSD).
] ,
BKTR="$withval")
if test "${BKTR}" = "no"; then
TEMP_CFLAGS="${TEMP_CFLAGS} -DWITHOUT_V4L2"
fi
else
#
# Check to Exclude V4L2
#
V4L2="yes"
AC_ARG_WITH(v4l2,
[ --without-v4l2 Exclude using v4l2 (video4linux2) subsystem.
Makes Motion so it only supports network cameras.
],
V4L2="$withval" )
#
# Check to Exclude V4L
#
V4L="yes"
AC_ARG_WITH(v4l,
[ --without-v4l Exclude using v4l (video4linux) subsystem.
Makes Motion so it only supports network cameras.
],
V4L="$withval"
)
if test "${V4L2}" = "no"; then
TEMP_CFLAGS="${TEMP_CFLAGS} -DWITHOUT_V4L2"
else
AC_CHECK_HEADERS(linux/videodev2.h,[V4L2="yes"],[V4L2="no"])
AC_MSG_CHECKING(for V4L2 support)
if test "${V4L2}" = "no"; then
AC_MSG_RESULT(no)
TEMP_CFLAGS="${TEMP_CFLAGS} -DWITHOUT_V4L2"
else
AC_MSG_RESULT(yes)
fi
fi
fi
if test "${V4L}" = "no"; then
TEMP_CFLAGS="${TEMP_CFLAGS} -DWITHOUT_V4L"
fi
if test "${FreeBSD}" != "" && test "${LINUXTHREADS}" != "no" ; then
AC_MSG_CHECKING(for linuxthreads)
@@ -740,34 +740,7 @@ fi
#Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(stdio.h unistd.h stdint.h fcntl.h time.h signal.h sys/ioctl.h sys/mman.h linux/videodev.h linux/videodev2.h sys/param.h sys/types.h sys/videoio.h)
# Check if v4l2 is available
SUPPORTED_V4L2=false
if test "${V4L}" = "no"; then
AC_MSG_CHECKING(for V42L support)
AC_MSG_RESULT(skipping)
else
AC_CHECK_TYPE([struct v4l2_buffer],
[SUPPORTED_V4L2=true],
[SUPPORTED_V4L2=false],
[#include <sys/time.h>
#ifdef HAVE_LINUX_VIDEODEV2_H
#include <linux/videodev2.h>
#elif HAVE_LINUX_VIDEODEV_H
#include <linux/videodev.h>
#elif HAVE_SYS_VIDEOIO_H
#include <sys/videoio.h>
#endif])
AC_MSG_CHECKING(for V42L support)
if test x$SUPPORTED_V4L2 = xtrue; then
AC_MSG_RESULT(yes)
TEMP_CFLAGS="${TEMP_CFLAGS} -DMOTION_V4L2"
else
AC_MSG_RESULT(no)
fi
fi
AC_CHECK_HEADERS(stdio.h unistd.h stdint.h fcntl.h time.h signal.h sys/ioctl.h sys/mman.h linux/videodev2.h sys/param.h sys/types.h)
OPTIMIZECPU="yes"
@@ -1121,13 +1094,7 @@ if test "${FreeBSD}" != ""; then
fi
else
if test "${V4L}" = "yes"; then
echo "V4L support: Yes"
else
echo "V4L support: No"
fi
if test x$SUPPORTED_V4L2 = xtrue; then
if test "$V4L2" = "yes"; then
echo "V4L2 support: Yes"
else
echo "V4L2 support: No"

10
event.c
View File

@@ -12,7 +12,7 @@
#include "picture.h" /* already includes motion.h */
#include "event.h"
#if (!defined(__FreeBSD__))
#include "video.h"
#include "video2.h"
#endif
/* Various functions (most doing the actual action) */
@@ -306,7 +306,7 @@ static void event_stream_put(struct context *cnt,
}
#if defined(HAVE_LINUX_VIDEODEV_H) && !defined(WITHOUT_V4L) && !defined(__FreeBSD__)
#if !defined(WITHOUT_V4L2) && !defined(__FreeBSD__)
static void event_vid_putpipe(struct context *cnt,
motion_event type ATTRIBUTE_UNUSED,
unsigned char *img, char *dummy ATTRIBUTE_UNUSED, void *devpipe,
@@ -317,7 +317,7 @@ static void event_vid_putpipe(struct context *cnt,
MOTION_LOG(ERR, TYPE_EVENTS, SHOW_ERRNO, "%s: Failed to put image into video pipe");
}
}
#endif /* !WITHOUT_V4L && !__FreeBSD__ */
#endif /* !WITHOUT_V4L2 && !__FreeBSD__ */
const char *imageext(struct context *cnt)
{
@@ -953,7 +953,7 @@ struct event_handlers event_handlers[] = {
EVENT_IMAGE_SNAPSHOT,
event_image_snapshot
},
#if defined(HAVE_LINUX_VIDEODEV_H) && !defined(WITHOUT_V4L) && !defined(__FreeBSD__)
#if !defined(WITHOUT_V4L2) && !defined(__FreeBSD__)
{
EVENT_IMAGE,
event_vid_putpipe
@@ -962,7 +962,7 @@ struct event_handlers event_handlers[] = {
EVENT_IMAGEM,
event_vid_putpipe
},
#endif /* !WITHOUT_V4L && !__FreeBSD__ */
#endif /* !WITHOUT_V4L2 && !__FreeBSD__ */
{
EVENT_STREAM,
event_stream_put

View File

@@ -12,7 +12,7 @@
#if (defined(__FreeBSD__) && !defined(PWCBSD))
#include "video_freebsd.h"
#else
#include "video.h"
#include "video2.h"
#endif
#include "conf.h"
@@ -894,13 +894,13 @@ static int motion_init(struct context *cnt)
/* create a reference frame */
alg_update_reference_frame(cnt, RESET_REF_FRAME);
#if defined(HAVE_LINUX_VIDEODEV_H) && !defined(WITHOUT_V4L) && !defined(__FreeBSD__)
#if !defined(WITHOUT_V4L2) && !defined(__FreeBSD__)
/* open video loopback devices if enabled */
if (cnt->conf.vidpipe) {
MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, "%s: Opening video loopback device for normal pictures");
/* vid_startpipe should get the output dimensions */
cnt->pipe = vid_startpipe(cnt->conf.vidpipe, cnt->imgs.width, cnt->imgs.height, cnt->imgs.type);
cnt->pipe = vid_startpipe(cnt->conf.vidpipe, cnt->imgs.width, cnt->imgs.height, V4L2_PIX_FMT_YUV420);
if (cnt->pipe < 0) {
MOTION_LOG(ERR, TYPE_ALL, NO_ERRNO, "%s: Failed to open video loopback for normal pictures");
@@ -912,14 +912,14 @@ static int motion_init(struct context *cnt)
MOTION_LOG(NTC, TYPE_ALL, NO_ERRNO, "%s: Opening video loopback device for motion pictures");
/* vid_startpipe should get the output dimensions */
cnt->mpipe = vid_startpipe(cnt->conf.motionvidpipe, cnt->imgs.width, cnt->imgs.height, cnt->imgs.type);
cnt->mpipe = vid_startpipe(cnt->conf.motionvidpipe, cnt->imgs.width, cnt->imgs.height, V4L2_PIX_FMT_YUV420);
if (cnt->mpipe < 0) {
MOTION_LOG(ERR, TYPE_ALL, NO_ERRNO, "%s: Failed to open video loopback for motion pictures");
return -1;
}
}
#endif /* !WITHOUT_V4L && !__FreeBSD__ */
#endif /* !WITHOUT_V4L2 && !__FreeBSD__ */
#if defined(HAVE_MYSQL) || defined(HAVE_PGSQL) || defined(HAVE_SQLITE3)
if (cnt->conf.database_type) {
@@ -2579,7 +2579,7 @@ static void motion_shutdown(void)
free(cnt_list);
cnt_list = NULL;
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
vid_cleanup();
#endif
}
@@ -2670,7 +2670,7 @@ static void motion_startup(int daemonize, int argc, char *argv[])
}
}
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
vid_init();
#endif
}
@@ -2857,7 +2857,7 @@ int main (int argc, char **argv)
MOTION_LOG(WRN, TYPE_ALL, NO_ERRNO, "%s: Restarting motion.");
motion_shutdown();
restart = 0; /* only one reset for now */
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
SLEEP(5, 0); // maybe some cameras needs less time
#endif
motion_startup(0, argc, argv); /* 0 = skip daemon init */

View File

@@ -608,7 +608,7 @@ how Motion is built.
<tr>
<td bgcolor="#edf4f9" word-wrap:break-word > --with-pwcbsd </td>
<td bgcolor="#edf4f9" word-wrap:break-word > Use pwcbsd based webcams ( only BSD ) </td>
<td bgcolor="#edf4f9" word-wrap:break-word > This option allow to build motion to support V4L/V4L2 in BSD. </td>
<td bgcolor="#edf4f9" word-wrap:break-word > This option allow to build motion to support V4L2 in BSD. </td>
</tr>
<tr>
<td bgcolor="#edf4f9" word-wrap:break-word > --without-bktr </td>
@@ -616,8 +616,8 @@ how Motion is built.
<td bgcolor="#edf4f9" word-wrap:break-word > ONLY used in *BSD </td>
</tr>
<tr>
<td bgcolor="#edf4f9" word-wrap:break-word > --without-v4l </td>
<td bgcolor="#edf4f9" word-wrap:break-word > Exclude using v4l (video4linux) subsystem. Makes Motion so it only supports network cameras. </td>
<td bgcolor="#edf4f9" word-wrap:break-word > --without-v4l2 </td>
<td bgcolor="#edf4f9" word-wrap:break-word > Exclude using v4l2 (video4linux2) subsystem. Makes Motion so it only supports network cameras. </td>
<td bgcolor="#edf4f9" word-wrap:break-word > Can be used if you do not need support and maybe lack some of the libraries for it. </td>
</tr>
<tr>
@@ -3026,7 +3026,7 @@ Motion automatically swaps width and height if you rotate 90 or 270 degrees, so
</ul>
<p></p>
The width in pixels of each frame. Valid range is camera dependent.
Motion does not scale so should be set to the actual size of the v4l device.
Motion does not scale so should be set to the actual size of the v4l2 device.
In case of a net camera motion sets the height to the height of the first image read
except for rtsp streams which does rescale the network camera image to the
requested dimensions. Note that this rescaling comes at a very high CPU cost so it

View File

@@ -103,7 +103,7 @@ struct pwc_serial
{
char serial[30]; /* String with serial number. Contains terminating 0 */
};
/* pwc_whitebalance.mode values */
#define PWC_WB_INDOOR 0
#define PWC_WB_OUTDOOR 1
@@ -111,14 +111,14 @@ struct pwc_serial
#define PWC_WB_MANUAL 3
#define PWC_WB_AUTO 4
/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
/* Used with VIDIOCPWC[SG]AWB (Auto White Balance).
Set mode to one of the PWC_WB_* values above.
*red and *blue are the respective gains of these colour components inside
*red and *blue are the respective gains of these colour components inside
the camera; range 0..65535
When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read;
otherwise undefined.
'read_red' and 'read_blue' are read-only.
*/
*/
struct pwc_whitebalance
{
int mode;
@@ -126,9 +126,9 @@ struct pwc_whitebalance
int read_red, read_blue; /* R/O */
};
/*
/*
'control_speed' and 'control_delay' are used in automatic whitebalance mode,
and tell the camera how fast it should react to changes in lighting, and
and tell the camera how fast it should react to changes in lighting, and
with how much delay. Valid values are 0..65535.
*/
struct pwc_wb_speed
@@ -157,11 +157,11 @@ struct pwc_imagesize
#define PWC_MPT_TILT 0x02
#define PWC_MPT_TIMEOUT 0x04 /* for status */
/* Set angles; when absolute != 0, the angle is absolute and the
/* Set angles; when absolute != 0, the angle is absolute and the
driver calculates the relative offset for you. This can only
be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns
absolute angles.
*/
*/
struct pwc_mpt_angles
{
int absolute; /* write-only */
@@ -188,7 +188,7 @@ struct pwc_mpt_status
/* This is used for out-of-kernel decompression. With it, you can get
all the necessary information to initialize and use the decompressor
routines in standalone applications.
*/
*/
struct pwc_video_command
{
int type; /* camera type (645, 675, 730, etc.) */
@@ -273,7 +273,7 @@ struct pwc_video_command
/* Flickerless mode; = 0 off, otherwise on */
#define VIDIOCPWCSFLICKER _IOW('v', 208, int)
#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
#define VIDIOCPWCGFLICKER _IOR('v', 208, int)
/* Dynamic noise reduction; 0 off, 3 = high noise reduction */
#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int)
@@ -282,7 +282,7 @@ struct pwc_video_command
/* Real image size as used by the camera; tells you whether or not there's a gray border around the image */
#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize)
/* Motorized pan & tilt functions */
/* Motorized pan & tilt functions */
#define VIDIOCPWCMPTRESET _IOW('v', 211, int)
#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range)
#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles)
@@ -299,11 +299,11 @@ struct pwc_table_init_buffer {
/*
* This is private command used when communicating with v4l2.
* In the future all private ioctl will be remove/replace to
* In the future all private ioctl will be remove/replace to
* use interface offer by v4l2.
*/
#if (defined(MOTION_V4L2)) && defined(__linux__)
#if (!defined(WITHOUT_V4L2)) && defined(__linux__)
#define V4L2_CID_PRIVATE_SAVE_USER (V4L2_CID_PRIVATE_BASE + 0)
#define V4L2_CID_PRIVATE_RESTORE_USER (V4L2_CID_PRIVATE_BASE + 1)
@@ -323,6 +323,6 @@ struct pwc_raw_frame {
__u8 rawframe[0]; /* frame_size = H/4*vbandlength */
} __attribute__ ((packed));
#endif /* MOTION_V4L2 && __linux__ */
#endif /* !WITHOUT_V4L2 && __linux__ */
#endif

14
track.c
View File

@@ -8,7 +8,7 @@
#include <math.h>
#include "motion.h"
#ifdef MOTION_V4L2
#ifndef WITHOUT_V4L2
#include <linux/videodev2.h>
#include "pwc-ioctl.h"
#endif
@@ -52,14 +52,14 @@ static unsigned int servo_move(struct context *cnt, struct coord *cent,
struct images *imgs, unsigned int manual);
static unsigned int iomojo_move(struct context *cnt, int dev, struct coord *cent, struct images *imgs);
#ifdef MOTION_V4L2
#ifndef WITHOUT_V4L2
static unsigned int lqos_center(struct context *cnt, int dev, int xoff, int yoff);
static unsigned int lqos_move(struct context *cnt, int dev, struct coord *cent,
struct images *imgs, unsigned int manual);
static unsigned int uvc_center(struct context *cnt, int dev, int xoff, int yoff);
static unsigned int uvc_move(struct context *cnt, int dev, struct coord *cent,
struct images *imgs, unsigned int manual);
#endif /* MOTION_V4L2 */
#endif /* WITHOUT_V4L2 */
/* Add a call to your functions here: */
unsigned int track_center(struct context *cnt, int dev ATTRIBUTE_UNUSED,
@@ -79,7 +79,7 @@ unsigned int track_center(struct context *cnt, int dev ATTRIBUTE_UNUSED,
} else if (cnt->track.type == TRACK_TYPE_SERVO) {
return servo_center(cnt, xoff, yoff);
}
#ifdef MOTION_V4L2
#ifndef WITHOUT_V4L2
else if (cnt->track.type == TRACK_TYPE_PWC)
return lqos_center(cnt, dev, xoff, yoff);
else if (cnt->track.type == TRACK_TYPE_UVC)
@@ -108,7 +108,7 @@ unsigned int track_move(struct context *cnt, int dev, struct coord *cent, struct
return stepper_move(cnt, cent, imgs);
else if (cnt->track.type == TRACK_TYPE_SERVO)
return servo_move(cnt, cent, imgs, manual);
#ifdef MOTION_V4L2
#ifndef WITHOUT_V4L2
else if (cnt->track.type == TRACK_TYPE_PWC)
return lqos_move(cnt, dev, cent, imgs, manual);
else if (cnt->track.type == TRACK_TYPE_UVC)
@@ -780,7 +780,7 @@ static unsigned int iomojo_move(struct context *cnt, int dev, struct coord *cent
Logitech QuickCam Orbit camera tracking code by folkert@vanheusden.com
******************************************************************************/
#ifdef MOTION_V4L2
#ifndef WITHOUT_V4L2
static unsigned int lqos_center(struct context *cnt, int dev, int x_angle, int y_angle)
{
int reset = 3;
@@ -1219,4 +1219,4 @@ static unsigned int uvc_move(struct context *cnt, int dev, struct coord *cent,
return cnt->track.move_wait;
}
#endif /* MOTION_V4L2 */
#endif /* WITHOUT_V4L2 */

11
track.h
View File

@@ -117,7 +117,7 @@ unsigned int track_move(struct context *, int, struct coord *, struct images *,
#define SERVO_BAUDRATE B9600
#define SERVO_COMMAND_STATUS 0
#define SERVO_COMMAND_STATUS 0
#define SERVO_COMMAND_LEFT_N 1
#define SERVO_COMMAND_RIGHT_N 2
#define SERVO_COMMAND_LEFT 3
@@ -155,7 +155,7 @@ unsigned int track_move(struct context *, int, struct coord *, struct images *,
#define IOMOJO_DIRECTION_DOWN 0x04
#define IOMOJO_DIRECTION_UP 0x08
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
/*
* Defines for the Logitech QuickCam Orbit/Sphere USB webcam
@@ -165,11 +165,9 @@ unsigned int track_move(struct context *, int, struct coord *, struct images *,
#define LQOS_HORIZONAL_DEGREES 120
/*
* UVC
* UVC
*/
#ifdef MOTION_V4L2
#ifndef V4L2_CID_PAN_RELATIVE
#define V4L2_CID_PAN_RELATIVE (V4L2_CID_PRIVATE_BASE+7)
#endif
@@ -183,9 +181,8 @@ unsigned int track_move(struct context *, int, struct coord *, struct images *,
#endif
#define INCPANTILT 64 // 1 degree
#endif /* MOTION_V4L2 */
#endif /* WITHOUT_V4L */
#endif /* WITHOUT_V4L2 */
#endif /* _INCLUDE_TRACK_H */

453
video.c
View File

@@ -1,453 +0,0 @@
/*
* video.c
*
* Video stream functions for motion.
* Copyright 2000 by Jeroen Vreeken (pe1rxq@amsat.org)
* This software is distributed under the GNU public license version 2
* See also the file 'COPYING'.
*
*/
#include "motion.h"
#include "video.h"
#include "rotate.h"
#if defined(HAVE_LINUX_VIDEODEV_H) && !defined(WITHOUT_V4L)
/**
* v4l_picture_controls
*/
static void v4l_picture_controls(struct context *cnt, struct video_dev *viddev)
{
int dev = viddev->fd;
struct video_picture vid_pic;
int make_change = 0;
if (cnt->conf.contrast && cnt->conf.contrast != viddev->contrast) {
if (ioctl(dev, VIDIOCGPICT, &vid_pic) == -1)
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGPICT)");
make_change = 1;
vid_pic.contrast = cnt->conf.contrast * 256;
viddev->contrast = cnt->conf.contrast;
}
if (cnt->conf.saturation && cnt->conf.saturation != viddev->saturation) {
if (!make_change) {
if (ioctl(dev, VIDIOCGPICT, &vid_pic)==-1)
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGPICT)");
}
make_change = 1;
vid_pic.colour = cnt->conf.saturation * 256;
viddev->saturation = cnt->conf.saturation;
}
if (cnt->conf.hue && cnt->conf.hue != viddev->hue) {
if (!make_change) {
if (ioctl(dev, VIDIOCGPICT, &vid_pic) == -1)
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGPICT)");
}
make_change = 1;
vid_pic.hue = cnt->conf.hue * 256;
viddev->hue = cnt->conf.hue;
}
/* Only tested with PWCBSD in FreeBSD */
#if defined(PWCBSD)
if (cnt->conf.frame_limit != viddev->fps) {
struct video_window vw;
int fps;
if (ioctl(dev, VIDIOCGWIN, &vw) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl VIDIOCGWIN");
} else {
fps = vw.flags >> PWC_FPS_SHIFT;
MOTION_LOG(INF, TYPE_VIDEO, NO_ERRNO, "%s: Get Current framerate %d .. trying %d",
fps, cnt->conf.frame_limit);
}
fps = cnt->conf.frame_limit;
vw.flags = fps << PWC_FPS_SHIFT;
if (ioctl(dev, VIDIOCSWIN, &vw) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl VIDIOCSWIN");
} else if (ioctl(dev, VIDIOCGWIN, &vw) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl VIDIOCGWIN");
} else {
fps = vw.flags >> PWC_FPS_SHIFT;
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Set new framerate %d", fps);
}
viddev->fps = fps;
}
#endif
if (cnt->conf.autobright) {
if (vid_do_autobright(cnt, viddev)) {
/* If we already read the VIDIOGPICT - we should not do it again. */
if (!make_change) {
if (ioctl(dev, VIDIOCGPICT, &vid_pic) == -1)
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGPICT)");
}
vid_pic.brightness = viddev->brightness * 256;
make_change = 1;
}
} else if (cnt->conf.brightness && cnt->conf.brightness != viddev->brightness) {
if ((!make_change) && (ioctl(dev, VIDIOCGPICT, &vid_pic) == -1))
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGPICT)");
make_change = 1;
vid_pic.brightness = cnt->conf.brightness * 256;
viddev->brightness = cnt->conf.brightness;
}
if (make_change) {
if (ioctl(dev, VIDIOCSPICT, &vid_pic) == -1)
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCSPICT)");
}
}
/*******************************************************************************
Video4linux capture routines
********************************************************************************/
/**
* v4l_start
* Initialize video device to start capturing and allocates memory map
* for video device.
*
* Returns mmapped buffer for video device or NULL if any error happens.
*
*/
unsigned char *v4l_start(struct video_dev *viddev, int width, int height,int input,
int norm, unsigned long freq, int tuner_number)
{
int dev = viddev->fd;
struct video_capability vid_caps;
struct video_channel vid_chnl;
struct video_tuner vid_tuner;
struct video_mbuf vid_buf;
struct video_mmap vid_mmap;
void *map;
if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGCAP)");
return NULL;
}
if (vid_caps.type & VID_TYPE_MONOCHROME)
viddev->v4l_fmt = VIDEO_PALETTE_GREY;
if (input != IN_DEFAULT) {
memset(&vid_chnl, 0, sizeof(struct video_channel));
vid_chnl.channel = input;
if (ioctl (dev, VIDIOCGCHAN, &vid_chnl) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGCHAN) Input %d",
input);
} else {
vid_chnl.channel = input;
vid_chnl.norm = norm;
if (ioctl (dev, VIDIOCSCHAN, &vid_chnl) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCSCHAN) Input %d"
" Standard method %d", input, norm);
return NULL;
}
}
}
if (freq) {
memset(&vid_tuner, 0, sizeof(struct video_tuner));
vid_tuner.tuner = tuner_number;
if (ioctl (dev, VIDIOCGTUNER, &vid_tuner) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGTUNER) tuner %d",
tuner_number);
} else {
if (vid_tuner.flags & VIDEO_TUNER_LOW)
freq = freq * 16; /* steps of 1/16 KHz */
else
freq = freq * 10 / 625;
if (ioctl(dev, VIDIOCSFREQ, &freq) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCSFREQ)"
" Frequency %ul", freq);
return NULL;
}
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Set Tuner to %d Frequency set to %ul",
tuner_number, freq);
}
}
if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, NO_ERRNO, "%s: ioctl(VIDIOCGMBUF) - Error device"
" does not support memory map\n V4L capturing using read is deprecated!\n"
"Motion only supports mmap.");
return NULL;
} else {
map = mmap(0, vid_buf.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
viddev->size_map = vid_buf.size;
if (vid_buf.frames > 1) {
viddev->v4l_maxbuffer = 2;
viddev->v4l_buffers[0] = map;
viddev->v4l_buffers[1] = (unsigned char *)map + vid_buf.offsets[1];
} else {
viddev->v4l_buffers[0] = map;
viddev->v4l_maxbuffer = 1;
}
if (MAP_FAILED == map) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: MAP_FAILED");
return NULL;
}
viddev->v4l_curbuffer = 0;
vid_mmap.format = viddev->v4l_fmt;
vid_mmap.frame = viddev->v4l_curbuffer;
vid_mmap.width = width;
vid_mmap.height = height;
if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
MOTION_LOG(WRN, TYPE_VIDEO, SHOW_ERRNO, "%s: Failed with YUV420P, "
"trying YUV422 palette");
viddev->v4l_fmt = VIDEO_PALETTE_YUV422;
vid_mmap.format = viddev->v4l_fmt;
/* Try again... */
if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
MOTION_LOG(WRN, TYPE_VIDEO, SHOW_ERRNO, "%s: Failed with YUV422,"
" trying YUYV palette");
viddev->v4l_fmt = VIDEO_PALETTE_YUYV;
vid_mmap.format = viddev->v4l_fmt;
if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
MOTION_LOG(WRN, TYPE_VIDEO, SHOW_ERRNO, "%s: Failed with YUYV, trying RGB24 palette");
viddev->v4l_fmt = VIDEO_PALETTE_RGB24;
vid_mmap.format = viddev->v4l_fmt;
/* Try again... */
if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
MOTION_LOG(WRN, TYPE_VIDEO, SHOW_ERRNO, "%s: Failed with RGB24, trying"
"GREYSCALE palette");
viddev->v4l_fmt = VIDEO_PALETTE_GREY;
vid_mmap.format = viddev->v4l_fmt;
/* Try one last time... */
if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
MOTION_LOG(CRT, TYPE_VIDEO, SHOW_ERRNO, "%s: Failed with all supported palettes "
"- giving up");
return NULL;
}
}
}
}
}
}
switch (viddev->v4l_fmt) {
case VIDEO_PALETTE_YUV420P:
viddev->v4l_bufsize = (width * height * 3) / 2;
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Using VIDEO_PALETTE_YUV420P palette");
break;
case VIDEO_PALETTE_YUV422:
viddev->v4l_bufsize = (width * height * 2);
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Using VIDEO_PALETTE_YUV422 palette");
break;
case VIDEO_PALETTE_YUYV:
viddev->v4l_bufsize = (width * height * 2);
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Using VIDEO_PALETTE_YUYV palette");
break;
case VIDEO_PALETTE_RGB24:
viddev->v4l_bufsize = (width * height * 3);
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Using VIDEO_PALETTE_RGB24 palette");
break;
case VIDEO_PALETTE_GREY:
viddev->v4l_bufsize = width * height;
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Using VIDEO_PALETTE_GREY palette");
break;
}
return map;
}
/**
* v4l_next
* Fetches a video frame from a v4l device
*
* Parameters:
* viddev Pointer to struct containing video device handle amd device parameters
* map Pointer to the buffer in which the function puts the new image
* width Width of image in pixels
* height Height of image in pixels
*
* Returns
* 0 Success
* V4L_FATAL_ERROR Fatal error
* Positive with bit 0 set and bit 1 unset
* Non fatal error (not implemented)
*/
int v4l_next(struct video_dev *viddev, unsigned char *map, int width, int height)
{
int dev = viddev->fd;
int frame = viddev->v4l_curbuffer;
struct video_mmap vid_mmap;
unsigned char *cap_map;
sigset_t set, old;
/* MMAP method is used */
vid_mmap.format = viddev->v4l_fmt;
vid_mmap.width = width;
vid_mmap.height = height;
/* Block signals during IOCTL */
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGHUP);
pthread_sigmask (SIG_BLOCK, &set, &old);
cap_map = viddev->v4l_buffers[viddev->v4l_curbuffer];
viddev->v4l_curbuffer++;
if (viddev->v4l_curbuffer >= viddev->v4l_maxbuffer)
viddev->v4l_curbuffer = 0;
vid_mmap.frame = viddev->v4l_curbuffer;
if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
MOTION_LOG(ALR, TYPE_VIDEO, SHOW_ERRNO, "%s: mcapture error in proc %d",
getpid());
sigprocmask (SIG_UNBLOCK, &old, NULL);
return V4L_FATAL_ERROR;
}
vid_mmap.frame = frame;
if (ioctl(dev, VIDIOCSYNC, &vid_mmap.frame) == -1) {
MOTION_LOG(ALR, TYPE_VIDEO, SHOW_ERRNO, "%s: sync error in proc %d",
getpid());
sigprocmask (SIG_UNBLOCK, &old, NULL);
}
pthread_sigmask (SIG_UNBLOCK, &old, NULL); /*undo the signal blocking*/
switch (viddev->v4l_fmt) {
case VIDEO_PALETTE_RGB24:
conv_rgb24toyuv420p(map, cap_map, width, height);
break;
case VIDEO_PALETTE_YUYV:
case VIDEO_PALETTE_YUV422:
conv_yuv422to420p(map, cap_map, width, height);
break;
default:
memcpy(map, cap_map, viddev->v4l_bufsize);
}
return 0;
}
/**
* v4l_set_input
* Sets input for video device, adjust picture controls.
* If needed skip frames for round robin.
*
* Parameters:
* cnt Pointer to context struct
* viddev Pointer to struct containing video device handle amd device parameters
* map Pointer to the buffer in which the function puts the new image
* width Width of image in pixels
* height Height of image in pixels
* conf Pointer to config struct
*
* Returns nothing
*/
void v4l_set_input(struct context *cnt, struct video_dev *viddev, unsigned char *map,
int width, int height, struct config *conf)
{
int dev = viddev->fd;
struct video_channel vid_chnl;
struct video_tuner vid_tuner;
unsigned long frequnits , freq;
int input = conf->input;
int norm = conf->norm;
int tuner_number = conf->tuner_number;
frequnits = freq = conf->frequency;
if (input != viddev->input || width != viddev->width || height != viddev->height ||
freq != viddev->freq || tuner_number != viddev->tuner_number || norm != viddev->norm) {
unsigned int skip = conf->roundrobin_skip, i;
if (freq) {
memset(&vid_tuner, 0, sizeof(struct video_tuner));
vid_tuner.tuner = tuner_number;
if (ioctl (dev, VIDIOCGTUNER, &vid_tuner) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGTUNER) tuner number %d",
tuner_number);
} else {
if (vid_tuner.flags & VIDEO_TUNER_LOW)
frequnits = freq * 16; /* steps of 1/16 KHz */
else
frequnits = (freq * 10) / 625;
if (ioctl(dev, VIDIOCSFREQ, &frequnits) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCSFREQ) Frequency %ul",
frequnits);
return;
}
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Set Tuner to %d Frequency to %ul",
tuner_number, frequnits);
}
}
memset(&vid_chnl, 0, sizeof(struct video_channel));
vid_chnl.channel = input;
if (ioctl (dev, VIDIOCGCHAN, &vid_chnl) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGCHAN) Input %d",
input);
} else {
vid_chnl.channel = input;
vid_chnl.norm = norm;
if (ioctl (dev, VIDIOCSCHAN, &vid_chnl) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCSCHAN) Input %d"
" Standard method %d", input, norm);
return;
}
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Set Input to %d Standard method to %d",
input, norm);
}
v4l_picture_controls(cnt, viddev);
conf->input = viddev->input = input;
conf->width = viddev->width = width;
conf->height = viddev->height = height;
conf->frequency = viddev->freq = freq;
conf->tuner_number = viddev->tuner_number = tuner_number;
conf->norm = viddev->norm = norm;
/* skip a few frames if needed */
for (i = 0; i < skip; i++)
v4l_next(viddev, map, width, height);
} else {
/* No round robin - we only adjust picture controls */
v4l_picture_controls(cnt, viddev);
}
}
#endif /* !WITHOUT_V4L */

View File

@@ -69,9 +69,9 @@
*/
#include "motion.h"
#include "video.h"
#include "video2.h"
#if !defined(WITHOUT_V4L) && defined(MOTION_V4L2)
#ifndef WITHOUT_V4L2
#define u8 unsigned char
#define u16 unsigned short
@@ -1153,4 +1153,4 @@ void v4l2_cleanup(struct video_dev *viddev)
free(vid_source);
viddev->v4l2_private = NULL;
}
#endif /* !WITHOUT_V4L && MOTION_V4L2 */
#endif /* !WITHOUT_V4L2 */

View File

@@ -1,4 +1,4 @@
/* video.h
/* video2.h
*
* Include file for video.c
* Copyright 2000 by Jeroen Vreeken (pe1rxq@amsat.org)
@@ -12,16 +12,12 @@
#include <sys/mman.h>
#if !defined(WITHOUT_V4L)
#if defined(HAVE_LINUX_VIDEODEV2_H)
#ifndef WITHOUT_V4L2
#include <linux/videodev2.h>
#elif defined(HAVE_LINUX_VIDEODEV_H)
#include <linux/videodev.h>
#elif defined(HAVE_SYS_VIDEOIO_H)
#include <sys/videoio.h>
#endif
#include "vloopback_motion.h"
#include "vloopback_motion2.h"
#include "pwc-ioctl.h"
#endif
/* video4linux stuff */
@@ -76,7 +72,7 @@ struct video_dev {
int frames;
/* Device type specific stuff: */
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
/* v4l */
int v4l2;
void *v4l2_private;
@@ -106,13 +102,7 @@ int mjpegtoyuv420p(unsigned char *map, unsigned char *cap_map, int width, int he
void y10torgb24(unsigned char *map, unsigned char *cap_map, int width, int height, int shift);
void conv_greytoyuv420p(unsigned char *map, unsigned char *cap_map, int width, int height);
#ifndef WITHOUT_V4L
/* video functions, video.c */
unsigned char *v4l_start(struct video_dev *viddev, int width, int height,
int input, int norm, unsigned long freq, int tuner_number);
void v4l_set_input(struct context *cnt, struct video_dev *viddev, unsigned char *map, int width, int height,
struct config *conf);
int v4l_next(struct video_dev *viddev, unsigned char *map, int width, int height);
#ifndef WITHOUT_V4L2
/* video2.c */
unsigned char *v4l2_start(struct context *cnt, struct video_dev *viddev, int width, int height,
@@ -122,6 +112,6 @@ void v4l2_set_input(struct context *cnt, struct video_dev *viddev, unsigned char
int v4l2_next(struct context *cnt, struct video_dev *viddev, unsigned char *map, int width, int height);
void v4l2_close(struct video_dev *viddev);
void v4l2_cleanup(struct video_dev *viddev);
#endif /* WITHOUT_V4L */
#endif /* WITHOUT_V4L2 */
#endif /* _INCLUDE_VIDEO_H */

View File

@@ -11,7 +11,7 @@
/* For rotation */
#include "rotate.h" /* Already includes motion.h */
#include "video.h"
#include "video2.h"
#include "jpegutils.h"
typedef unsigned char uint8_t;
@@ -584,7 +584,7 @@ int vid_do_autobright(struct context *cnt, struct video_dev *viddev)
Wrappers calling the actual capture routines
*****************************************************************************/
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
/*
* Big lock for vid_start to ensure exclusive access to viddevs while adding
* devices during initialization of each thread.
@@ -618,7 +618,7 @@ void vid_cleanup(void)
pthread_mutex_destroy(&vid_mutex);
}
#endif /* WITHOUT_V4L */
#endif /* WITHOUT_V4L2 */
/**
* vid_close
@@ -627,10 +627,10 @@ void vid_cleanup(void)
*/
void vid_close(struct context *cnt)
{
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
struct video_dev *dev = viddevs;
struct video_dev *prev = NULL;
#endif /* WITHOUT_V4L */
#endif /* WITHOUT_V4L2 */
/* Cleanup the netcam part */
#ifdef HAVE_MMAL
@@ -649,9 +649,9 @@ void vid_close(struct context *cnt)
return;
}
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
/* Cleanup the v4l part */
/* Cleanup the v4l2 part */
pthread_mutex_lock(&vid_mutex);
while (dev) {
if (dev->fd == cnt->video_dev)
@@ -672,17 +672,14 @@ void vid_close(struct context *cnt)
if (--dev->usage_count == 0) {
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Closing video device %s",
dev->video_device);
#ifdef MOTION_V4L2
if (dev->v4l2) {
v4l2_close(dev);
v4l2_cleanup(dev);
} else {
#endif
close(dev->fd);
munmap(viddevs->v4l_buffers[0], dev->size_map);
#ifdef MOTION_V4L2
}
#endif
dev->fd = -1;
pthread_mutex_lock(&vid_mutex);
/* Remove from list */
@@ -708,10 +705,10 @@ void vid_close(struct context *cnt)
pthread_mutex_unlock(&dev->mutex);
}
}
#endif /* !WITHOUT_V4L */
#endif /* !WITHOUT_V4L2 */
}
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
/**
* vid_v4lx_start
@@ -855,11 +852,8 @@ static int vid_v4lx_start(struct context *cnt)
dev->owner = -1;
dev->v4l_fmt = VIDEO_PALETTE_YUV420P;
dev->fps = 0;
#ifdef MOTION_V4L2
/* First lets try V4L2 and if it's not supported V4L1. */
dev->v4l2 = 1;
if (!v4l2_start(cnt, dev, width, height, input, norm, frequency, tuner_number)) {
/*
* Restore width & height before test with v4l
@@ -867,24 +861,9 @@ static int vid_v4lx_start(struct context *cnt)
*/
dev->width = width;
dev->height = height;
#endif
#if defined(HAVE_LINUX_VIDEODEV_H) && (!defined(WITHOUT_V4L))
if (!v4l_start(dev, width, height, input, norm, frequency, tuner_number)) {
close(dev->fd);
pthread_mutexattr_destroy(&dev->attr);
pthread_mutex_destroy(&dev->mutex);
free(dev);
pthread_mutex_unlock(&vid_mutex);
return -1;
}
#endif
#ifdef MOTION_V4L2
dev->v4l2 = 0;
}
#endif
if (dev->v4l2 == 0) {
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Using V4L1");
} else {
@@ -921,7 +900,7 @@ static int vid_v4lx_start(struct context *cnt)
return fd;
}
#endif /* !WITHOUT_V4L */
#endif /* !WITHOUT_V4L2 */
/**
* vid_start
@@ -967,13 +946,13 @@ int vid_start(struct context *cnt)
cnt->netcam = NULL;
}
}
#ifdef WITHOUT_V4L
#ifdef WITHOUT_V4L2
else
MOTION_LOG(CRT, TYPE_VIDEO, NO_ERRNO, "%s: You must setup netcam_url");
#else
else
dev = vid_v4lx_start(cnt);
#endif /*WITHOUT_V4L */
#endif /*WITHOUT_V4L2 */
return dev;
}
@@ -1018,7 +997,7 @@ int vid_next(struct context *cnt, unsigned char *map)
return netcam_next(cnt, map);
}
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
/*
* We start a new block so we can make declarations without breaking
* gcc 2.95 or older.
@@ -1048,19 +1027,12 @@ int vid_next(struct context *cnt, unsigned char *map)
dev->owner = cnt->threadnr;
dev->frames = conf->roundrobin_frames;
}
#ifdef MOTION_V4L2
if (dev->v4l2) {
v4l2_set_input(cnt, dev, map, width, height, conf);
ret = v4l2_next(cnt, dev, map, width, height);
} else {
#endif
#if defined(HAVE_LINUX_VIDEODEV_H) && (!defined(WITHOUT_V4L))
v4l_set_input(cnt, dev, map, width, height, conf);
ret = v4l_next(dev, map, width, height);
#endif
#ifdef MOTION_V4L2
}
#endif
if (--dev->frames <= 0) {
dev->owner = -1;
dev->frames = 0;
@@ -1072,6 +1044,6 @@ int vid_next(struct context *cnt, unsigned char *map)
rotate_map(cnt, map);
}
#endif /*WITHOUT_V4L */
#endif /*WITHOUT_V4L2 */
return ret;
}

View File

@@ -11,7 +11,7 @@
#include "rotate.h" /* Already includes motion.h */
#include "video_freebsd.h"
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
/* For the v4l stuff: */
#include <sys/mman.h>
@@ -950,7 +950,7 @@ void vid_cleanup(void)
pthread_mutex_destroy(&vid_mutex);
}
#endif /*WITHOUT_V4L*/
#endif /*WITHOUT_V4L2*/
/**
* vid_close
@@ -959,7 +959,7 @@ void vid_cleanup(void)
*/
void vid_close(struct context *cnt)
{
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
struct video_dev *dev = viddevs;
struct video_dev *prev = NULL;
#endif
@@ -971,7 +971,7 @@ void vid_close(struct context *cnt)
return;
}
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
/* Cleanup the v4l part */
pthread_mutex_lock(&vid_mutex);
@@ -1041,7 +1041,7 @@ void vid_close(struct context *cnt)
pthread_mutex_unlock(&dev->mutex);
}
}
#endif /* !WITHOUT_V4L */
#endif /* !WITHOUT_V4L2 */
}
@@ -1061,7 +1061,7 @@ int vid_start(struct context *cnt)
cnt->netcam = NULL;
}
}
#ifdef WITHOUT_V4L
#ifdef WITHOUT_V4L2
else
MOTION_LOG(CRT, TYPE_VIDEO, NO_ERRNO, "%s: You must setup netcam_url");
#else
@@ -1249,7 +1249,7 @@ int vid_start(struct context *cnt)
pthread_mutex_unlock(&vid_mutex);
}
#endif /* !WITHOUT_V4L */
#endif /* !WITHOUT_V4L2 */
/* FIXME needed tuner device ?! */
return fd_bktr;
@@ -1282,7 +1282,7 @@ int vid_next(struct context *cnt, unsigned char *map)
return ret;
}
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
struct video_dev *dev;
int width, height;
@@ -1329,6 +1329,6 @@ int vid_next(struct context *cnt, unsigned char *map)
rotate_map(cnt, map);
#endif /* !WITHOUT_V4L */
#endif /* !WITHOUT_V4L2 */
return ret;
}

View File

@@ -11,7 +11,7 @@
#ifndef _INCLUDE_VIDEO_FREEBSD_H
#define _INCLUDE_VIDEO_FREEBSD_H
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <dev/ic/bt8xx.h>
@@ -20,7 +20,7 @@
#include <dev/bktr/ioctl_bt848.h>
#endif
#endif /* !WITHOUT_V4L */
#endif /* !WITHOUT_V4L2 */
/* bktr (video4linux) stuff FIXME more modes not only these */
@@ -109,7 +109,7 @@ struct video_dev {
int frames;
/* Device type specific stuff: */
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
int capture_method;
int v4l_fmt;
unsigned char *v4l_buffers[2];
@@ -124,7 +124,7 @@ int vid_start(struct context *);
int vid_next(struct context *, unsigned char *);
void vid_close(struct context *);
#ifndef WITHOUT_V4L
#ifndef WITHOUT_V4L2
void vid_init(void);
void vid_cleanup(void);
#endif

View File

@@ -1,252 +0,0 @@
/*
* vloopback_motion.c
*
* Video loopback functions for motion.
* Copyright 2000 by Jeroen Vreeken (pe1rxq@amsat.org)
* Copyright 2008 by Angel Carpintero (motiondevelop@gmail.com)
* This software is distributed under the GNU public license version 2
* See also the file 'COPYING'.
*
*/
#include "vloopback_motion.h"
#if defined(HAVE_LINUX_VIDEODEV_H) && (!defined(WITHOUT_V4L)) && (!defined(BSD))
#include <sys/utsname.h>
#include <dirent.h>
/**
* v4l_open_vidpipe
*
*/
static int v4l_open_vidpipe(void)
{
int pipe_fd = -1;
char pipepath[255];
char buffer[255];
char *major;
char *minor;
struct utsname uts;
if (uname(&uts) < 0) {
MOTION_LOG(CRT, TYPE_VIDEO, SHOW_ERRNO, "%s: Unable to execute uname");
return -1;
}
major = strtok(uts.release, ".");
minor = strtok(NULL, ".");
if ((major == NULL) || (minor == NULL) || (strcmp(major, "2"))) {
MOTION_LOG(CRT, TYPE_VIDEO, SHOW_ERRNO, "%s: Unable to decipher OS version");
return -1;
}
if (strcmp(minor, "5") < 0) {
FILE *vloopbacks;
char *input;
char *istatus;
char *output;
vloopbacks = fopen("/proc/video/vloopback/vloopbacks", "r");
if (!vloopbacks) {
MOTION_LOG(CRT, TYPE_VIDEO, SHOW_ERRNO, "%s: Failed to open "
"'/proc/video/vloopback/vloopbacks'");
return -1;
}
/* Read vloopback version*/
if (!fgets(buffer, sizeof(buffer), vloopbacks)) {
MOTION_LOG(CRT, TYPE_VIDEO, SHOW_ERRNO, "%s: Unable to read vloopback version");
myfclose(vloopbacks);
return -1;
}
fprintf(stderr, "\t%s", buffer);
/* Read explanation line */
if (!fgets(buffer, sizeof(buffer), vloopbacks)) {
MOTION_LOG(CRT, TYPE_VIDEO, SHOW_ERRNO, "%s: Unable to read vloopback"
" explanation line");
myfclose(vloopbacks);
return -1;
}
while (fgets(buffer, sizeof(buffer), vloopbacks)) {
if (strlen(buffer) > 1) {
buffer[strlen(buffer)-1] = 0;
input = strtok(NULL, "\t");
istatus = strtok(NULL, "\t");
output = strtok(NULL, "\t");
if (istatus[0] == '-') {
snprintf(pipepath, sizeof(pipepath), "/dev/%s", input);
pipe_fd = open(pipepath, O_RDWR);
if (pipe_fd >= 0) {
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: \tInput: /dev/%s "
"\tOutput: /dev/%s", input, output);
break;
}
}
}
}
myfclose(vloopbacks);
} else {
DIR *dir;
struct dirent *dirp;
const char prefix[] = "/sys/class/video4linux/";
char *ptr, *io;
int fd;
int low = 9999;
int tfd;
int tnum;
if ((dir = opendir(prefix)) == NULL) {
MOTION_LOG(CRT, TYPE_VIDEO, SHOW_ERRNO, "%s: Failed to open '%s'",
prefix);
return -1;
}
while ((dirp = readdir(dir)) != NULL) {
if (!strncmp(dirp->d_name, "video", 5)) {
strncpy(buffer, prefix, sizeof(buffer));
strncat(buffer, dirp->d_name, sizeof(buffer) - strlen(buffer));
strncat(buffer, "/name", sizeof(buffer) - strlen(buffer));
if ((fd = open(buffer, O_RDONLY)) >= 0) {
if ((read(fd, buffer, sizeof(buffer)-1)) < 0) {
close(fd);
continue;
}
ptr = strtok(buffer, " ");
if (strcmp(ptr, "Video")) {
close(fd);
continue;
}
major = strtok(NULL, " ");
minor = strtok(NULL, " ");
io = strtok(NULL, " \n");
if (strcmp(major, "loopback") || strcmp(io, "input")) {
close(fd);
continue;
}
if ((ptr = strtok(buffer, " ")) == NULL) {
close(fd);
continue;
}
tnum = atoi(minor);
if (tnum < low) {
mystrcpy(buffer, "/dev/");
strncat(buffer, dirp->d_name, sizeof(buffer) - strlen(buffer));
if ((tfd = open(buffer, O_RDWR)) >= 0) {
strncpy(pipepath, buffer, sizeof(pipepath));
if (pipe_fd >= 0)
close(pipe_fd);
pipe_fd = tfd;
low = tnum;
}
}
close(fd);
}
}
}
closedir(dir);
if (pipe_fd >= 0)
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Opened %s as input",
pipepath);
}
return pipe_fd;
}
/**
* v4l_startpipe
*
*/
static int v4l_startpipe(const char *dev_name, int width, int height, int type)
{
int dev;
struct video_picture vid_pic;
struct video_window vid_win;
if (!strcmp(dev_name, "-")) {
dev = v4l_open_vidpipe();
} else {
dev = open(dev_name, O_RDWR);
MOTION_LOG(NTC, TYPE_VIDEO, NO_ERRNO, "%s: Opened %s as input",
dev_name);
}
if (dev < 0) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: Opening %s as input failed",
dev_name);
return -1;
}
if (ioctl(dev, VIDIOCGPICT, &vid_pic) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGPICT)");
return -1;
}
vid_pic.palette = type;
if (ioctl(dev, VIDIOCSPICT, &vid_pic) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCSPICT)");
return -1;
}
if (ioctl(dev, VIDIOCGWIN, &vid_win) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCGWIN)");
return -1;
}
vid_win.height = height;
vid_win.width = width;
if (ioctl(dev, VIDIOCSWIN, &vid_win) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOCSWIN)");
return -1;
}
return dev;
}
/**
* v4l_putpipe
*
*/
static int v4l_putpipe(int dev, unsigned char *image, int size)
{
return write(dev, image, size);
}
/**
* vid_startpipe
*
*/
int vid_startpipe(const char *dev_name, int width, int height, int type)
{
return v4l_startpipe(dev_name, width, height, type);
}
/**
* vid_putpipe
*
*/
int vid_putpipe (int dev, unsigned char *image, int size)
{
return v4l_putpipe(dev, image, size);
}
#endif /* !WITHOUT_V4L && !BSD */

View File

@@ -8,8 +8,8 @@
* See also the file 'COPYING'.
*
*/
#include "vloopback_motion.h"
#if defined(HAVE_LINUX_VIDEODEV2_H) && (!defined(WITHOUT_V4L)) && (!defined(BSD))
#include "vloopback_motion2.h"
#if (!defined(WITHOUT_V4L2)) && (!defined(BSD))
#include <dirent.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
@@ -67,10 +67,10 @@ static int v4l2_open_vidpipe(void)
if ((tfd = open(buffer, O_RDWR)) >= 0) {
strncpy(pipepath, buffer, sizeof(pipepath));
if (pipe_fd >= 0)
close(pipe_fd);
pipe_fd = tfd;
break;
}
@@ -176,7 +176,7 @@ static int v4l2_startpipe(const char *dev_name, int width, int height, int type)
show_vcap(&vc);
memset(&v, 0, sizeof(v));
v.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (ioctl(dev, VIDIOC_G_FMT, &v) == -1) {
@@ -184,7 +184,7 @@ static int v4l2_startpipe(const char *dev_name, int width, int height, int type)
return -1;
}
printf("Original Format******************\n");
show_vfmt(&v);
show_vfmt(&v);
v.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
v.fmt.pix.width = width;
v.fmt.pix.height = height;
@@ -195,14 +195,14 @@ static int v4l2_startpipe(const char *dev_name, int width, int height, int type)
v.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
printf("Proposed new Format**************\n");
show_vfmt(&v);
show_vfmt(&v);
if (ioctl(dev,VIDIOC_S_FMT, &v) == -1) {
MOTION_LOG(ERR, TYPE_VIDEO, SHOW_ERRNO, "%s: ioctl (VIDIOC_S_FMT)");
return -1;
}
printf("Final Format*********************\n");
show_vfmt(&v);
show_vfmt(&v);
return dev;
}
@@ -232,4 +232,4 @@ int vid_putpipe (int dev, unsigned char *image, int size)
{
return v4l2_putpipe(dev, image, size);
}
#endif /* !WITHOUT_V4L && !BSD */
#endif /* !WITHOUT_V4L2 && !BSD */

View File