V4L2 updates
git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@2723 e3e1d417-86f3-4887-817a-d78f3d33393f
This commit is contained in:
parent
69662d644a
commit
21d8d74a28
|
@ -269,8 +269,8 @@ CREATE TABLE `MonitorPresets` (
|
|||
`Name` varchar(64) NOT NULL default '',
|
||||
`Type` enum('Local','Remote','File','Ffmpeg') NOT NULL default 'Local',
|
||||
`Device` tinytext,
|
||||
`Channel` varchar(32) default NULL,
|
||||
`Format` varchar(32) default NULL,
|
||||
`Channel` tinyint(3) unsigned default NULL,
|
||||
`Format` int(10) unsigned default NULL,
|
||||
`Protocol` varchar(16) default NULL,
|
||||
`Method` varchar(16) default NULL,
|
||||
`Host` varchar(64) default NULL,
|
||||
|
@ -279,7 +279,7 @@ CREATE TABLE `MonitorPresets` (
|
|||
`SubPath` varchar(64) default NULL,
|
||||
`Width` smallint(5) unsigned default NULL,
|
||||
`Height` smallint(5) unsigned default NULL,
|
||||
`Palette` tinyint(3) unsigned default NULL,
|
||||
`Palette` int(10) unsigned default NULL,
|
||||
`MaxFPS` decimal(5,2) default NULL,
|
||||
`Controllable` tinyint(3) unsigned NOT NULL default '0',
|
||||
`ControlId` varchar(16) default NULL,
|
||||
|
@ -305,7 +305,7 @@ CREATE TABLE `Monitors` (
|
|||
`Triggers` set('X10') NOT NULL default '',
|
||||
`Device` varchar(64) NOT NULL default '',
|
||||
`Channel` tinyint(3) unsigned NOT NULL default '0',
|
||||
`Format` tinyint(3) unsigned NOT NULL default '0',
|
||||
`Format` int(10) unsigned NOT NULL default '0',
|
||||
`Protocol` varchar(16) NOT NULL default '',
|
||||
`Method` varchar(16) NOT NULL default '',
|
||||
`Host` varchar(64) NOT NULL default '',
|
||||
|
@ -314,7 +314,7 @@ CREATE TABLE `Monitors` (
|
|||
`Path` varchar(64) NOT NULL default '',
|
||||
`Width` smallint(5) unsigned NOT NULL default '0',
|
||||
`Height` smallint(5) unsigned NOT NULL default '0',
|
||||
`Palette` tinyint(3) unsigned NOT NULL default '1',
|
||||
`Palette` int(10) unsigned NOT NULL default '0',
|
||||
`Orientation` enum('0','90','180','270','hori','vert') NOT NULL default '0',
|
||||
`Brightness` mediumint(7) NOT NULL default '-1',
|
||||
`Contrast` mediumint(7) NOT NULL default '-1',
|
||||
|
|
|
@ -43,6 +43,15 @@ update Monitors set Method = "v4l1" where Type = 'Local';
|
|||
alter table Monitors modify column `Type` enum('Local','Remote','File','Ffmpeg') NOT NULL default 'Local';
|
||||
alter table MonitorPresets modify column `Type` enum('Local','Remote','File','Ffmpeg') NOT NULL default 'Local';
|
||||
|
||||
--
|
||||
-- Fix columns to fit V4L2 formats and palettes
|
||||
--
|
||||
alter table Monitors modify column `Format` int(10) unsigned NOT NULL default '0';
|
||||
alter table Monitors modify column `Palette` int(10) unsigned NOT NULL default '0';
|
||||
alter table MonitorPresets modify column `Channel` tinyint(3) unsigned default NULL;
|
||||
alter table MonitorPresets modify column `Format` int(10) unsigned default NULL;
|
||||
alter table MonitorPresets modify column `Palette` int(10) unsigned default NULL;
|
||||
|
||||
--
|
||||
-- Add in new MPEG presets
|
||||
--
|
||||
|
|
|
@ -17,22 +17,24 @@
|
|||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
//
|
||||
|
||||
#include "zm_local_camera.h"
|
||||
|
||||
#include "zm_ffmpeg.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "zm_local_camera.h"
|
||||
|
||||
static int vidioctl( int fd, int request, void *arg )
|
||||
{
|
||||
int result;
|
||||
do
|
||||
{
|
||||
result = ioctl( fd, request, arg );
|
||||
} while ( result == -1 && errno == EINTR );
|
||||
return( result );
|
||||
int result = -1;
|
||||
do
|
||||
{
|
||||
result = ioctl( fd, request, arg );
|
||||
} while ( result == -1 && errno == EINTR );
|
||||
return( result );
|
||||
}
|
||||
|
||||
int LocalCamera::camera_count = 0;
|
||||
|
@ -146,58 +148,17 @@ void LocalCamera::Initialise()
|
|||
|
||||
memset( &v4l2_data.fmt, 0, sizeof(v4l2_data.fmt) );
|
||||
v4l2_data.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
||||
if ( vidioctl( vid_fd, VIDIOC_G_FMT, &v4l2_data.fmt ) < 0 )
|
||||
Fatal( "Failed to get video format: %s", strerror(errno) );
|
||||
|
||||
v4l2_data.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
v4l2_data.fmt.fmt.pix.width = width;
|
||||
v4l2_data.fmt.fmt.pix.height = height;
|
||||
switch( palette )
|
||||
{
|
||||
case VIDEO_PALETTE_GREY :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
|
||||
break;
|
||||
case VIDEO_PALETTE_HI240 :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_HI240;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB565 :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB24 :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB32 :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR32;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB555 :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB555;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV422 :
|
||||
case VIDEO_PALETTE_YUYV :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
|
||||
break;
|
||||
case VIDEO_PALETTE_UYVY :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV420P :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV422P :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV411P :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV411P;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV411 :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_Y41P;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV410P :
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV410;
|
||||
break;
|
||||
// case VIDEO_PALETTE_YUV420 : // Defunct
|
||||
// case VIDEO_PALETTE_RAW : // Defunct
|
||||
default :
|
||||
Fatal( "Unrecognised palette/format entry %d", palette );
|
||||
}
|
||||
v4l2_data.fmt.fmt.pix.pixelformat = palette;
|
||||
v4l2_data.fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||
|
||||
if ( vidioctl( vid_fd, VIDIOC_S_FMT, &v4l2_data.fmt) )
|
||||
if ( vidioctl( vid_fd, VIDIOC_S_FMT, &v4l2_data.fmt ) < 0 )
|
||||
Fatal( "Failed to set video format: %s", strerror(errno) );
|
||||
|
||||
/* Note VIDIOC_S_FMT may change width and height. */
|
||||
|
@ -248,7 +209,7 @@ void LocalCamera::Initialise()
|
|||
vid_buf.memory = v4l2_data.reqbufs.memory;
|
||||
vid_buf.index = i;
|
||||
|
||||
if ( vidioctl( vid_fd, VIDIOC_QUERYBUF, &vid_buf ) )
|
||||
if ( vidioctl( vid_fd, VIDIOC_QUERYBUF, &vid_buf ) < 0 )
|
||||
Fatal( "Unable to query video buffer: %s", strerror(errno) );
|
||||
|
||||
v4l2_data.buffers[i].length = vid_buf.length;
|
||||
|
@ -257,6 +218,34 @@ void LocalCamera::Initialise()
|
|||
if ( v4l2_data.buffers[i].start == MAP_FAILED )
|
||||
Fatal( "Can't map video buffer %d (%d bytes) to memory: %s(%d)", i, vid_buf.length, strerror(errno), errno );
|
||||
}
|
||||
|
||||
Debug( 3, "Configuring video source" );
|
||||
|
||||
if ( vidioctl( vid_fd, VIDIOC_S_INPUT, &channel ) < 0 )
|
||||
{
|
||||
Fatal( "Failed to set camera source %d: %s", channel, strerror(errno) );
|
||||
}
|
||||
|
||||
struct v4l2_input input;
|
||||
v4l2_std_id stdId;
|
||||
|
||||
memset( &input, 0, sizeof(input) );
|
||||
|
||||
if ( vidioctl( vid_fd, VIDIOC_ENUMINPUT, &input ) < 0 )
|
||||
{
|
||||
Fatal( "Failed to enumerate input %d: %s", channel, strerror(errno) );
|
||||
}
|
||||
|
||||
if ( !(input.std & format) )
|
||||
{
|
||||
Fatal( "Device does not support video standard %d", format );
|
||||
}
|
||||
|
||||
stdId = format;
|
||||
if ( vidioctl( vid_fd, VIDIOC_S_STD, &stdId ) < 0 )
|
||||
{
|
||||
Fatal( "Failed to set video standard %d: %s", format, strerror(errno) );
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // ZM_V4L2
|
||||
|
@ -688,19 +677,22 @@ int LocalCamera::Brightness( int p_brightness )
|
|||
Error( "Unable to query brightness: %s", strerror(errno) )
|
||||
else
|
||||
Warning( "Brightness control is not suppported" )
|
||||
Info( "Brightness 1 %d", vid_control.value );
|
||||
}
|
||||
else
|
||||
else if ( p_brightness >= 0 )
|
||||
{
|
||||
vid_control.value = p_brightness;
|
||||
|
||||
Info( "Brightness 2 %d", vid_control.value );
|
||||
/* The driver may clamp the value or return ERANGE, ignored here */
|
||||
if ( vidioctl ( vid_fd, VIDIOC_S_CTRL, &vid_control ) < 0 )
|
||||
if ( vidioctl ( vid_fd, VIDIOC_S_CTRL, &vid_control ) )
|
||||
{
|
||||
if ( errno != ERANGE )
|
||||
Error( "Unable to set brightness: %s", strerror(errno) )
|
||||
else
|
||||
Warning( "Given brightness value (%d) may be out-of-range", p_brightness )
|
||||
}
|
||||
Info( "Brightness 3 %d", vid_control.value );
|
||||
}
|
||||
return( vid_control.value );
|
||||
}
|
||||
|
@ -744,7 +736,7 @@ int LocalCamera::Hue( int p_hue )
|
|||
else
|
||||
Warning( "Hue control is not suppported" )
|
||||
}
|
||||
else
|
||||
else if ( p_hue >= 0 )
|
||||
{
|
||||
vid_control.value = p_hue;
|
||||
|
||||
|
@ -799,7 +791,7 @@ int LocalCamera::Colour( int p_colour )
|
|||
else
|
||||
Warning( "Saturation control is not suppported" )
|
||||
}
|
||||
else
|
||||
else if ( p_colour >= 0 )
|
||||
{
|
||||
vid_control.value = p_colour;
|
||||
|
||||
|
@ -854,12 +846,12 @@ int LocalCamera::Contrast( int p_contrast )
|
|||
else
|
||||
Warning( "Contrast control is not suppported" )
|
||||
}
|
||||
else
|
||||
else if ( p_contrast >= 0 )
|
||||
{
|
||||
vid_control.value = p_contrast;
|
||||
|
||||
/* The driver may clamp the value or return ERANGE, ignored here */
|
||||
if ( vidioctl ( vid_fd, VIDIOC_S_CTRL, &vid_control ) < 0 )
|
||||
if ( vidioctl ( vid_fd, VIDIOC_S_CTRL, &vid_control ) )
|
||||
{
|
||||
if ( errno != ERANGE )
|
||||
Error( "Unable to set contrast: %s", strerror(errno) )
|
||||
|
@ -921,7 +913,7 @@ int LocalCamera::PrimeCapture()
|
|||
vid_buf.memory = v4l2_data.reqbufs.memory;
|
||||
vid_buf.index = i;
|
||||
|
||||
if ( vidioctl( vid_fd, VIDIOC_QBUF, &vid_buf ) )
|
||||
if ( vidioctl( vid_fd, VIDIOC_QBUF, &vid_buf ) < 0 )
|
||||
Fatal( "Failed to queue buffer %d: %s", i, strerror(errno) );
|
||||
}
|
||||
}
|
||||
|
@ -950,17 +942,27 @@ int LocalCamera::PreCapture()
|
|||
if ( channel_count > 1 )
|
||||
{
|
||||
Debug( 3, "Switching video source" );
|
||||
if ( vidioctl( vid_fd, VIDIOC_S_INPUT, &channel ) )
|
||||
if ( vidioctl( vid_fd, VIDIOC_S_INPUT, &channel ) < 0 )
|
||||
{
|
||||
Error( "Failed to set camera source %d: %s", channel, strerror(errno) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
v4l2_std_id stdId = format;
|
||||
if ( vidioctl( vid_fd, VIDIOC_S_STD, &stdId ) < 0 )
|
||||
{
|
||||
Error( "Failed to set video format %d: %s", format, strerror(errno) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
Debug( 3, "Requeing buffer" );
|
||||
if ( v4l2_data.buffer )
|
||||
{
|
||||
if ( vidioctl( vid_fd, VIDIOC_QBUF, v4l2_data.buffer ) < 0 )
|
||||
Fatal( "Unable to requeue buffer %d: %s", v4l2_data.buffer->index, strerror(errno) )
|
||||
{
|
||||
Error( "Unable to requeue buffer %d: %s", v4l2_data.buffer->index, strerror(errno) )
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1087,10 +1089,173 @@ int LocalCamera::PostCapture( Image &image )
|
|||
|
||||
Debug( 3, "Doing format conversion" );
|
||||
|
||||
#if HAVE_LIBSWSCALE
|
||||
static struct SwsContext *imgConversionContext = 0;
|
||||
static AVFrame *picture = NULL;
|
||||
static AVFrame *tmpPicture = NULL;
|
||||
|
||||
if ( !imgConversionContext )
|
||||
{
|
||||
int ffPixFormat = PIX_FMT_NONE;
|
||||
switch( palette )
|
||||
{
|
||||
case V4L2_PIX_FMT_RGB444 :
|
||||
ffPixFormat = PIX_FMT_RGB32;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB555 :
|
||||
case V4L2_PIX_FMT_RGB555 :
|
||||
ffPixFormat = PIX_FMT_RGB555;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB565 :
|
||||
case V4L2_PIX_FMT_RGB565 :
|
||||
ffPixFormat = PIX_FMT_RGB565;
|
||||
break;
|
||||
case V4L2_PIX_FMT_BGR24 :
|
||||
ffPixFormat = PIX_FMT_BGR24;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB24 :
|
||||
if ( config.local_bgr_invert )
|
||||
ffPixFormat = PIX_FMT_BGR24;
|
||||
else
|
||||
ffPixFormat = PIX_FMT_RGB24;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB24 :
|
||||
ffPixFormat = PIX_FMT_RGB24;
|
||||
break;
|
||||
case V4L2_PIX_FMT_BGR32 :
|
||||
ffPixFormat = PIX_FMT_BGR32;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB32 :
|
||||
ffPixFormat = PIX_FMT_RGB32;
|
||||
break;
|
||||
case VIDEO_PALETTE_GREY :
|
||||
case V4L2_PIX_FMT_GREY :
|
||||
ffPixFormat = PIX_FMT_GRAY8;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUYV :
|
||||
case VIDEO_PALETTE_YUV422 :
|
||||
case V4L2_PIX_FMT_YUYV :
|
||||
ffPixFormat = PIX_FMT_YUYV422;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV422P :
|
||||
case V4L2_PIX_FMT_YUV422P :
|
||||
ffPixFormat = PIX_FMT_YUV422P;
|
||||
break;
|
||||
case V4L2_PIX_FMT_YUV411P :
|
||||
ffPixFormat = PIX_FMT_YUV411P;
|
||||
break;
|
||||
case V4L2_PIX_FMT_YUV444 :
|
||||
ffPixFormat = PIX_FMT_YUV444P;
|
||||
break;
|
||||
case V4L2_PIX_FMT_YUV410 :
|
||||
ffPixFormat = PIX_FMT_YUV410P;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV420P :
|
||||
case V4L2_PIX_FMT_YUV420 :
|
||||
ffPixFormat = PIX_FMT_YUV420P;
|
||||
break;
|
||||
// These don't seem to have ffmpeg equivalents
|
||||
// See if you can match any of the ones in the default clause below!?
|
||||
case V4L2_PIX_FMT_UYVY :
|
||||
case V4L2_PIX_FMT_RGB332 :
|
||||
case V4L2_PIX_FMT_RGB555X :
|
||||
case V4L2_PIX_FMT_RGB565X :
|
||||
case V4L2_PIX_FMT_Y16 :
|
||||
case V4L2_PIX_FMT_PAL8 :
|
||||
case V4L2_PIX_FMT_YVU410 :
|
||||
case V4L2_PIX_FMT_YVU420 :
|
||||
case V4L2_PIX_FMT_Y41P :
|
||||
case V4L2_PIX_FMT_YUV555 :
|
||||
case V4L2_PIX_FMT_YUV565 :
|
||||
case V4L2_PIX_FMT_YUV32 :
|
||||
case V4L2_PIX_FMT_NV12 :
|
||||
case V4L2_PIX_FMT_NV21 :
|
||||
case V4L2_PIX_FMT_YYUV :
|
||||
case V4L2_PIX_FMT_HI240 :
|
||||
case V4L2_PIX_FMT_HM12 :
|
||||
case V4L2_PIX_FMT_SBGGR8 :
|
||||
case V4L2_PIX_FMT_SGBRG8 :
|
||||
case V4L2_PIX_FMT_SBGGR16 :
|
||||
case V4L2_PIX_FMT_MJPEG :
|
||||
case V4L2_PIX_FMT_JPEG :
|
||||
case V4L2_PIX_FMT_DV :
|
||||
case V4L2_PIX_FMT_MPEG :
|
||||
case V4L2_PIX_FMT_WNVA :
|
||||
case V4L2_PIX_FMT_SN9C10X :
|
||||
case V4L2_PIX_FMT_PWC1 :
|
||||
case V4L2_PIX_FMT_PWC2 :
|
||||
case V4L2_PIX_FMT_ET61X251 :
|
||||
case V4L2_PIX_FMT_SPCA501 :
|
||||
case V4L2_PIX_FMT_SPCA505 :
|
||||
case V4L2_PIX_FMT_SPCA508 :
|
||||
case V4L2_PIX_FMT_SPCA561 :
|
||||
case V4L2_PIX_FMT_PAC207 :
|
||||
case V4L2_PIX_FMT_PJPG :
|
||||
case V4L2_PIX_FMT_YVYU :
|
||||
default :
|
||||
{
|
||||
Fatal( "Can't find swscale format for palette %d", palette );
|
||||
break;
|
||||
// These are all spare and may match some of the above
|
||||
ffPixFormat = PIX_FMT_YUVJ420P;
|
||||
ffPixFormat = PIX_FMT_YUVJ422P;
|
||||
ffPixFormat = PIX_FMT_YUVJ444P;
|
||||
ffPixFormat = PIX_FMT_XVMC_MPEG2_MC;
|
||||
ffPixFormat = PIX_FMT_XVMC_MPEG2_IDCT;
|
||||
ffPixFormat = PIX_FMT_UYVY422;
|
||||
ffPixFormat = PIX_FMT_UYYVYY411;
|
||||
ffPixFormat = PIX_FMT_BGR565;
|
||||
ffPixFormat = PIX_FMT_BGR555;
|
||||
ffPixFormat = PIX_FMT_BGR8;
|
||||
ffPixFormat = PIX_FMT_BGR4;
|
||||
ffPixFormat = PIX_FMT_BGR4_BYTE;
|
||||
ffPixFormat = PIX_FMT_RGB8;
|
||||
ffPixFormat = PIX_FMT_RGB4;
|
||||
ffPixFormat = PIX_FMT_RGB4_BYTE;
|
||||
ffPixFormat = PIX_FMT_NV12;
|
||||
ffPixFormat = PIX_FMT_NV21;
|
||||
ffPixFormat = PIX_FMT_RGB32_1;
|
||||
ffPixFormat = PIX_FMT_BGR32_1;
|
||||
ffPixFormat = PIX_FMT_GRAY16BE;
|
||||
ffPixFormat = PIX_FMT_GRAY16LE;
|
||||
ffPixFormat = PIX_FMT_YUV440P;
|
||||
ffPixFormat = PIX_FMT_YUVJ440P;
|
||||
ffPixFormat = PIX_FMT_YUVA420P;
|
||||
ffPixFormat = PIX_FMT_VDPAU_H264;
|
||||
ffPixFormat = PIX_FMT_VDPAU_MPEG1;
|
||||
ffPixFormat = PIX_FMT_VDPAU_MPEG2;
|
||||
ffPixFormat = PIX_FMT_NB;
|
||||
}
|
||||
}
|
||||
imgConversionContext = sws_getContext( width, height, ffPixFormat, width, height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL );
|
||||
if ( !imgConversionContext )
|
||||
Fatal( "Unable to initialise image scaling context" );
|
||||
Info( "Using swscaler" );
|
||||
|
||||
picture = avcodec_alloc_frame();
|
||||
if ( !picture )
|
||||
Fatal( "Could not allocate picture" );
|
||||
int size = avpicture_get_size( ffPixFormat, width, height);
|
||||
avpicture_fill( (AVPicture *)picture, buffer, ffPixFormat, width, height );
|
||||
|
||||
tmpPicture = avcodec_alloc_frame();
|
||||
if ( !tmpPicture )
|
||||
Fatal( "Could not allocate temporary picture" );
|
||||
size = avpicture_get_size( PIX_FMT_RGB24, width, height);
|
||||
uint8_t *tmpPictureBuf = (uint8_t *)av_malloc(size);
|
||||
if (!tmpPictureBuf)
|
||||
Fatal( "Could not allocate temporary picture buffer" );
|
||||
avpicture_fill( (AVPicture *)tmpPicture, tmpPictureBuf, PIX_FMT_RGB24, width, height );
|
||||
}
|
||||
|
||||
sws_scale( imgConversionContext, picture->data, picture->linesize, 0, height, tmpPicture->data, tmpPicture->linesize );
|
||||
buffer = tmpPicture->data[0];
|
||||
#else // HAVE_LIBSWSCALE
|
||||
static unsigned char temp_buffer[ZM_MAX_IMAGE_SIZE];
|
||||
switch( palette )
|
||||
{
|
||||
case VIDEO_PALETTE_YUV420P :
|
||||
case V4L2_PIX_FMT_YUV420 :
|
||||
{
|
||||
static unsigned char y_plane[ZM_MAX_IMAGE_DIM];
|
||||
static char u_plane[ZM_MAX_IMAGE_DIM];
|
||||
|
@ -1163,6 +1328,7 @@ int LocalCamera::PostCapture( Image &image )
|
|||
break;
|
||||
}
|
||||
case VIDEO_PALETTE_YUV422P :
|
||||
case V4L2_PIX_FMT_YUV422P :
|
||||
{
|
||||
static unsigned char y_plane[ZM_MAX_IMAGE_DIM];
|
||||
static char u_plane[ZM_MAX_IMAGE_DIM];
|
||||
|
@ -1221,6 +1387,7 @@ int LocalCamera::PostCapture( Image &image )
|
|||
}
|
||||
case VIDEO_PALETTE_YUYV :
|
||||
case VIDEO_PALETTE_YUV422 :
|
||||
case V4L2_PIX_FMT_YUYV :
|
||||
{
|
||||
int size = width*height*2;
|
||||
unsigned char *s_ptr = buffer;
|
||||
|
@ -1255,6 +1422,7 @@ int LocalCamera::PostCapture( Image &image )
|
|||
break;
|
||||
}
|
||||
case VIDEO_PALETTE_RGB555 :
|
||||
case V4L2_PIX_FMT_RGB555 :
|
||||
{
|
||||
int size = width*height*2;
|
||||
unsigned char r,g,b;
|
||||
|
@ -1275,6 +1443,7 @@ int LocalCamera::PostCapture( Image &image )
|
|||
break;
|
||||
}
|
||||
case VIDEO_PALETTE_RGB565 :
|
||||
case V4L2_PIX_FMT_RGB565 :
|
||||
{
|
||||
int size = width*height*2;
|
||||
unsigned char r,g,b;
|
||||
|
@ -1312,7 +1481,23 @@ int LocalCamera::PostCapture( Image &image )
|
|||
}
|
||||
break;
|
||||
}
|
||||
case V4L2_PIX_FMT_BGR24 :
|
||||
{
|
||||
int size = width*height*3;
|
||||
unsigned char *s_ptr = buffer;
|
||||
unsigned char *d_ptr = temp_buffer;
|
||||
for ( int i = 0; i < size; i += 3 )
|
||||
{
|
||||
*d_ptr++ = *(s_ptr+2);
|
||||
*d_ptr++ = *(s_ptr+1);
|
||||
*d_ptr++ = *s_ptr;
|
||||
s_ptr += 3;
|
||||
}
|
||||
buffer = temp_buffer;
|
||||
break;
|
||||
}
|
||||
case VIDEO_PALETTE_GREY :
|
||||
case V4L2_PIX_FMT_GREY :
|
||||
{
|
||||
//int size = width*height;
|
||||
//for ( int i = 0; i < size; i++ )
|
||||
|
@ -1328,6 +1513,7 @@ int LocalCamera::PostCapture( Image &image )
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif // HAVE_LIBSWSCALE
|
||||
}
|
||||
|
||||
Debug( 3, "Assigning image" );
|
||||
|
|
|
@ -611,6 +611,7 @@ $SLANG = array(
|
|||
'TurboTiltSpeed' => 'Turbo Tilt Speed',
|
||||
'Type' => 'Type',
|
||||
'Unarchive' => 'Unarchive',
|
||||
'Undefined' => 'Undefined',
|
||||
'Units' => 'Units',
|
||||
'Unknown' => 'Unknown',
|
||||
'UpdateAvailable' => 'An update to ZoneMinder is available.',
|
||||
|
|
|
@ -179,7 +179,8 @@ if ( !ZM_PCRE )
|
|||
// Currently unsupported
|
||||
unset($httpMethods['jpegTags']);
|
||||
|
||||
$deviceFormats = array(
|
||||
$v4l1DeviceFormats = array(
|
||||
$SLANG['Undefined'] => -1,
|
||||
"PAL" => 0,
|
||||
"NTSC" => 1,
|
||||
"SECAM" => 2,
|
||||
|
@ -190,21 +191,132 @@ $deviceFormats = array(
|
|||
"FMT7" => 7
|
||||
);
|
||||
|
||||
$deviceChannels = array();
|
||||
for ( $i = 0; $i <= 15; $i++ )
|
||||
$deviceChannels["$i"] = $i;
|
||||
$v4l1MaxChannels = 15;
|
||||
$v4l1DeviceChannels = array();
|
||||
for ( $i = 0; $i <= $v4l1MaxChannels; $i++ )
|
||||
$v4l1DeviceChannels["$i"] = $i;
|
||||
|
||||
$localPalettes = array(
|
||||
$SLANG['Grey'] => 1,
|
||||
"RGB24" => 4,
|
||||
"RGB565" => 3,
|
||||
"RGB555" => 6,
|
||||
"YUV422" => 7,
|
||||
"YUYV" => 8,
|
||||
"YUV422P" => 13,
|
||||
"YUV420P" => 15
|
||||
$v4l1LocalPalettes = array(
|
||||
$SLANG['Undefined'] => 0,
|
||||
$SLANG['Grey'] => 1,
|
||||
"RGB24" => 4,
|
||||
"RGB565" => 3,
|
||||
"RGB555" => 6,
|
||||
"YUV422" => 7,
|
||||
"YUYV" => 8,
|
||||
"YUV422P" => 13,
|
||||
"YUV420P" => 15
|
||||
);
|
||||
|
||||
if ( ZM_V4L2 )
|
||||
{
|
||||
$v4l2DeviceFormats = array(
|
||||
$SLANG['Undefined'] => 0,
|
||||
"PAL B" => 0x00000001,
|
||||
"PAL B1" => 0x00000002,
|
||||
"PAL G" => 0x00000004,
|
||||
"PAL H" => 0x00000008,
|
||||
"PAL I" => 0x00000010,
|
||||
"PAL D" => 0x00000020,
|
||||
"PAL D1" => 0x00000040,
|
||||
"PAL K" => 0x00000080,
|
||||
"PAL M" => 0x00000100,
|
||||
"PAL N" => 0x00000200,
|
||||
"PAL Nc" => 0x00000400,
|
||||
"PAL 60" => 0x00000800,
|
||||
"NTSC M" => 0x00001000,
|
||||
"NTSC M JP" => 0x00002000,
|
||||
"NTSC 443" => 0x00004000,
|
||||
"NTSC M KR" => 0x00008000,
|
||||
"SECAM B" => 0x00010000,
|
||||
"SECAM D" => 0x00020000,
|
||||
"SECAM G" => 0x00040000,
|
||||
"SECAM H" => 0x00080000,
|
||||
"SECAM K" => 0x00100000,
|
||||
"SECAM K1" => 0x00200000,
|
||||
"SECAM L" => 0x00400000,
|
||||
"SECAM LC" => 0x00800000,
|
||||
"ATSC 8 VSB" => 0x01000000,
|
||||
"ATSC 16 VSB" => 0x02000000,
|
||||
);
|
||||
|
||||
$v4l2MaxChannels = 31;
|
||||
$v4l2DeviceChannels = array();
|
||||
for ( $i = 0; $i <= $v4l2MaxChannels; $i++ )
|
||||
$v4l2DeviceChannels["$i"] = $i;
|
||||
|
||||
function fourcc( $a, $b, $c, $d )
|
||||
{
|
||||
return( ord($a) | (ord($b) << 8) | (ord($c) << 16) | (ord($d) << 24) );
|
||||
}
|
||||
|
||||
$v4l2LocalPalettes = array(
|
||||
$SLANG['Undefined'] => 0,
|
||||
|
||||
/* Pixel format FOURCC depth Description */
|
||||
"RGB332" => fourcc('R','G','B','1'), /* 8 RGB-3-3-2 */
|
||||
"RGB444" => fourcc('R','4','4','4'), /* 16 xxxxrrrr ggggbbbb */
|
||||
"RGB555" => fourcc('R','G','B','O'), /* 16 RGB-5-5-5 */
|
||||
"RGB565" => fourcc('R','G','B','P'), /* 16 RGB-5-6-5 */
|
||||
"RGB555X" => fourcc('R','G','B','Q'), /* 16 RGB-5-5-5 BE */
|
||||
"RGB565X" => fourcc('R','G','B','R'), /* 16 RGB-5-6-5 BE */
|
||||
"BGR24" => fourcc('B','G','R','3'), /* 24 BGR-8-8-8 */
|
||||
"RGB24" => fourcc('R','G','B','3'), /* 24 RGB-8-8-8 */
|
||||
"BGR32" => fourcc('B','G','R','4'), /* 32 BGR-8-8-8-8 */
|
||||
"RGB32" => fourcc('R','G','B','4'), /* 32 RGB-8-8-8-8 */
|
||||
"GREY" => fourcc('G','R','E','Y'), /* 8 Greyscale */
|
||||
"Y16" => fourcc('Y','1','6',''), /* 16 Greyscale */
|
||||
"PAL8" => fourcc('P','A','L','8'), /* 8 8-bit palette */
|
||||
"YVU410" => fourcc('Y','V','U','9'), /* 9 YVU 4:1:0 */
|
||||
"YVU420" => fourcc('Y','V','1','2'), /* 12 YVU 4:2:0 */
|
||||
"YUYV" => fourcc('Y','U','Y','V'), /* 16 YUV 4:2:2 */
|
||||
"UYVY" => fourcc('U','Y','V','Y'), /* 16 YUV 4:2:2 */
|
||||
"YUV422P" => fourcc('4','2','2','P'), /* 16 YVU422 planar */
|
||||
"YUV411P" => fourcc('4','1','1','P'), /* 16 YVU411 planar */
|
||||
"Y41P" => fourcc('Y','4','1','P'), /* 12 YUV 4:1:1 */
|
||||
"YUV444" => fourcc('Y','4','4','4'), /* 16 xxxxyyyy uuuuvvvv */
|
||||
"YUV555" => fourcc('Y','U','V','O'), /* 16 YUV-5-5-5 */
|
||||
"YUV565" => fourcc('Y','U','V','P'), /* 16 YUV-5-6-5 */
|
||||
"YUV32" => fourcc('Y','U','V','4'), /* 32 YUV-8-8-8-8 */
|
||||
|
||||
/* two planes -- one Y, one Cr + Cb interleaved */
|
||||
"NV12" => fourcc('N','V','1','2'), /* 12 Y/CbCr 4:2:0 */
|
||||
"NV21" => fourcc('N','V','2','1'), /* 12 Y/CrCb 4:2:0 */
|
||||
|
||||
/* The following formats are not defined in the V4L2 specification */
|
||||
"YUV410" => fourcc('Y','U','V','9'), /* 9 YUV 4:1:0 */
|
||||
"YUV420" => fourcc('Y','U','1','2'), /* 12 YUV 4:2:0 */
|
||||
"YYUV" => fourcc('Y','Y','U','V'), /* 16 YUV 4:2:2 */
|
||||
"HI240" => fourcc('H','I','2','4'), /* 8 8-bit color */
|
||||
"HM12" => fourcc('H','M','1','2'), /* 8 YUV 4:2:0 16x16 macroblocks */
|
||||
|
||||
/* see http://www.siliconimaging.com/RGB%20Bayer.htm */
|
||||
"SBGGR8" => fourcc('B','A','8','1'), /* 8 BGBG.. GRGR.. */
|
||||
"SGBRG8" => fourcc('G','B','R','G'), /* 8 GBGB.. RGRG.. */
|
||||
"SBGGR16" => fourcc('B','Y','R','2'), /* 16 BGBG.. GRGR.. */
|
||||
|
||||
/* compressed formats */
|
||||
"MJPEG" => fourcc('M','J','P','G'), /* Motion-JPEG */
|
||||
"JPEG" => fourcc('J','P','E','G'), /* JFIF JPEG */
|
||||
"DV" => fourcc('d','v','s','d'), /* 1394 */
|
||||
"MPEG" => fourcc('M','P','E','G'), /* MPEG-1/2/4 */
|
||||
|
||||
/* Vendor-specific formats */
|
||||
"WNVA" => fourcc('W','N','V','A'), /* Winnov hw compress */
|
||||
"SN9C10X" => fourcc('S','9','1','0'), /* SN9C10x compression */
|
||||
"PWC1" => fourcc('P','W','C','1'), /* pwc older webcam */
|
||||
"PWC2" => fourcc('P','W','C','2'), /* pwc newer webcam */
|
||||
"ET61X251" => fourcc('E','6','2','5'), /* ET61X251 compression */
|
||||
"SPCA501" => fourcc('S','5','0','1'), /* YUYV per line */
|
||||
"SPCA505" => fourcc('S','5','0','5'), /* YYUV per line */
|
||||
"SPCA508" => fourcc('S','5','0','8'), /* YUVY per line */
|
||||
"SPCA561" => fourcc('S','5','6','1'), /* compressed GBRG bayer */
|
||||
"PAC207" => fourcc('P','2','0','7'), /* compressed BGGR bayer */
|
||||
"PJPG" => fourcc('P','J','P','G'), /* Pixart 73xx JPEG */
|
||||
"YVYU" => fourcc('Y','V','Y','U'), /* 16 YVU 4:2:2 */
|
||||
);
|
||||
}
|
||||
|
||||
$remoteColours = $fileColours = array(
|
||||
$SLANG['8BitGrey'] => 1,
|
||||
$SLANG['24BitColour'] => 3
|
||||
|
@ -474,11 +586,24 @@ switch ( $tab )
|
|||
{
|
||||
?>
|
||||
<tr><td><?= $SLANG['DevicePath'] ?></td><td><input type="text" name="newMonitor[Device]" value="<?= validHtmlStr($newMonitor['Device']) ?>" size="24"/></td></tr>
|
||||
<tr><td><?= $SLANG['DeviceChannel'] ?></td><td><select name="newMonitor[Channel]"><?php foreach ( $deviceChannels as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Channel'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?= $SLANG['DeviceFormat'] ?></td><td><select name="newMonitor[Format]"><?php foreach ( $deviceFormats as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Format'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?= $SLANG['CaptureMethod'] ?></td><td><?= buildSelect( "newMonitor[Method]", $localMethods ); ?></td></tr>
|
||||
<tr><td><?= $SLANG['CapturePalette'] ?></td><td><select name="newMonitor[Palette]"><?php foreach ( $localPalettes as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Palette'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?= $SLANG['CaptureMethod'] ?></td><td><?= buildSelect( "newMonitor[Method]", $localMethods, "submitTab( '$tab' )" ); ?></td></tr>
|
||||
<?php
|
||||
if ( ZM_V4L2 && $newMonitor['Method'] == 'v4l2' )
|
||||
{
|
||||
?>
|
||||
<tr><td><?= $SLANG['DeviceChannel'] ?></td><td><select name="newMonitor[Channel]"><?php foreach ( $v4l2DeviceChannels as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Channel'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?= $SLANG['DeviceFormat'] ?></td><td><select name="newMonitor[Format]"><?php foreach ( $v4l2DeviceFormats as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Format'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?= $SLANG['CapturePalette'] ?></td><td><select name="newMonitor[Palette]"><?php foreach ( $v4l2LocalPalettes as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Palette'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
?>
|
||||
<tr><td><?= $SLANG['DeviceChannel'] ?></td><td><select name="newMonitor[Channel]"><?php foreach ( $v4l1DeviceChannels as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Channel'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?= $SLANG['DeviceFormat'] ?></td><td><select name="newMonitor[Format]"><?php foreach ( $v4l1DeviceFormats as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Format'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<tr><td><?= $SLANG['CapturePalette'] ?></td><td><select name="newMonitor[Palette]"><?php foreach ( $v4l1LocalPalettes as $name => $value ) { ?><option value="<?= $value ?>"<?php if ( $value == $newMonitor['Palette'] ) { ?> selected="selected"<?php } ?>><?= $name ?></option><?php } ?></select></td></tr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
elseif ( $newMonitor['Type'] == "Remote" )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue