diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 99595501d..e3e583e31 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -323,6 +323,8 @@ CREATE TABLE `Monitors` ( `Device` varchar(64) NOT NULL default '', `Channel` tinyint(3) unsigned NOT NULL default '0', `Format` int(10) unsigned NOT NULL default '0', + `V4LMultiBuffer` tinyint(1) unsigned NOT NULL default '0', + `V4LCapturesPerFrame` tinyint(3) unsigned NOT NULL default '1', `Protocol` varchar(16) NOT NULL default '', `Method` varchar(16) NOT NULL default '', `Host` varchar(64) NOT NULL default '', diff --git a/distros/ubuntu1204/changelog b/distros/ubuntu1204/changelog index 077bfb2c3..36cb99232 100644 --- a/distros/ubuntu1204/changelog +++ b/distros/ubuntu1204/changelog @@ -1,24 +1,5 @@ -zoneminder (1.27.1-1) precise; urgency=low +zoneminder (1.27.0+1-trusty-v4ltomonitor-1) trusty; urgency=high - * Convert from php mysql ext to PDO - - -- Isaac Connor Wed, 16 Oct 2013 15:51:39 -0400 - -zoneminder (1.26.4-2) precise; urgency=high - - * improvements to zmupdate.pl, cleanups - - -- Isaac Connor Thu, 03 Oct 2013 11:40:32 -0400 - -zoneminder (1.26.3-1) unstable; urgency=low - - * A 'minor' release focusing on performance improvement and bug fixes. - - -- Isaac Connor Sun, 22 Sep 2013 09:36:42 +0800 - -zoneminder (1.25.1-1) unstable; urgency=low - - * Initial Version. - - -- Isaac Connor Mon, 29 Apr 2013 12:38:00 -0400 + * Snapshot release - + -- Isaac Connor Wed, 09 Jul 2014 21:35:29 -0400 diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index 6fb7cbedb..b48ddd1b4 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -283,7 +283,7 @@ AVFrame **LocalCamera::capturePictures = 0; LocalCamera *LocalCamera::last_camera = NULL; -LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, int p_standard, const std::string &p_method, int p_width, int p_height, int p_colours, int p_palette, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, unsigned int p_extras) : +LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, int p_standard, bool p_v4l_multi_buffer, unsigned int p_v4l_captures_per_frame, const std::string &p_method, int p_width, int p_height, int p_colours, int p_palette, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, unsigned int p_extras) : Camera( p_id, LOCAL_SRC, p_width, p_height, p_colours, ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(p_colours), p_brightness, p_contrast, p_hue, p_colour, p_capture ), device( p_device ), channel( p_channel ), @@ -296,6 +296,8 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, // do the initial opening etc device_prime = (camera_count++ == 0); v4l_version = (p_method=="v4l2"?2:1); + v4l_multi_buffer = p_v4l_multi_buffer; + v4l_captures_per_frame = p_v4l_captures_per_frame; if ( capture ) { @@ -363,15 +365,13 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, if ( width != last_camera->width || height != last_camera->height ) Warning( "Different capture sizes defined for monitors sharing same device, results may be unpredictable or completely wrong" ); } - } #if HAVE_LIBSWSCALE - if( capture ) { /* Get ffmpeg pixel format based on capture palette and endianness */ capturePixFormat = getFfPixFormatFromV4lPalette( v4l_version, palette ); imagePixFormat = PIX_FMT_NONE; - } #endif // HAVE_LIBSWSCALE + } /* V4L2 format matching */ #if ZM_HAS_V4L2 @@ -781,13 +781,16 @@ void LocalCamera::Initialise() Debug( 3, "Setting up request buffers" ); memset( &v4l2_data.reqbufs, 0, sizeof(v4l2_data.reqbufs) ); - if ( channel_count > 1 ) - if ( config.v4l_multi_buffer ) + if ( channel_count > 1 ) { + if ( v4l_multi_buffer ){ v4l2_data.reqbufs.count = 2*channel_count; - else + } else { v4l2_data.reqbufs.count = 1; - else + } + } else { v4l2_data.reqbufs.count = 8; + } + v4l2_data.reqbufs.type = v4l2_data.fmt.type; v4l2_data.reqbufs.memory = V4L2_MEMORY_MMAP; @@ -803,10 +806,10 @@ void LocalCamera::Initialise() } } - if ( v4l2_data.reqbufs.count < (config.v4l_multi_buffer?2:1) ) + if ( v4l2_data.reqbufs.count < (v4l_multi_buffer?2:1) ) Fatal( "Insufficient buffer memory %d on video device", v4l2_data.reqbufs.count ); - Debug( 3, "Setting up %d data buffers", v4l2_data.reqbufs.count ); + Debug( 3, "Setting up data buffers: Channels %d MultiBuffer %d Buffers: %s", channel_count, v4l_multi_buffer, v4l2_data.reqbufs.count ); v4l2_data.buffers = new V4L2MappedBuffer[v4l2_data.reqbufs.count]; #if HAVE_LIBSWSCALE @@ -967,7 +970,7 @@ void LocalCamera::Initialise() Debug( 3, "Setting up request buffers" ); if ( ioctl( vid_fd, VIDIOCGMBUF, &v4l1_data.frames ) < 0 ) Fatal( "Failed to setup memory: %s", strerror(errno) ); - if ( channel_count > 1 && !config.v4l_multi_buffer ) + if ( channel_count > 1 && !v4l_multi_buffer ) v4l1_data.frames.frames = 1; v4l1_data.buffers = new video_mmap[v4l1_data.frames.frames]; Debug( 4, "vmb.frames = %d", v4l1_data.frames.frames ); @@ -1974,7 +1977,11 @@ int LocalCamera::Capture( Image &image ) int captures_per_frame = 1; if ( channel_count > 1 ) - captures_per_frame = config.captures_per_frame; + captures_per_frame = v4l_captures_per_frame; + if ( captures_per_frame <= 0 ) { + captures_per_frame = 1; + Warning( "Invalid Captures Per Frame setting: %d", captures_per_frame ); + } // Do the capture, unless we are the second or subsequent camera on a channel, in which case just reuse the buffer diff --git a/src/zm_local_camera.h b/src/zm_local_camera.h index 05f06fe44..0dbe44c21 100644 --- a/src/zm_local_camera.h +++ b/src/zm_local_camera.h @@ -86,13 +86,14 @@ protected: uint32_t AutoSelectFormat(int p_colours); -protected: static int camera_count; static int channel_count; static int channels[VIDEO_MAX_FRAME]; static int standards[VIDEO_MAX_FRAME]; static int vid_fd; static int v4l_version; + bool v4l_multi_buffer; + unsigned int v4l_captures_per_frame; #if ZM_HAS_V4L2 static V4L2Data v4l2_data; @@ -112,7 +113,7 @@ protected: static LocalCamera *last_camera; public: - LocalCamera( int p_id, const std::string &device, int p_channel, int p_format, const std::string &p_method, int p_width, int p_height, int p_colours, int p_palette, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, unsigned int p_extras = 0); + LocalCamera( int p_id, const std::string &device, int p_channel, int p_format, bool v4lmultibuffer, unsigned int v4lcapturesperframe, const std::string &p_method, int p_width, int p_height, int p_colours, int p_palette, int p_brightness, int p_contrast, int p_hue, int p_colour, bool p_capture, unsigned int p_extras = 0); ~LocalCamera(); void Initialise(); diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index bc9c3ec08..0fc2e35b9 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1827,11 +1827,11 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose static char sql[ZM_SQL_MED_BUFSIZ]; if ( !device[0] ) { - strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' order by Device, Channel", sizeof(sql) ); + strncpy( sql, "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' order by Device, Channel", sizeof(sql) ); } else { - snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' and Device = '%s' order by Channel", device ); + snprintf( sql, sizeof(sql), "select Id, Name, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Function != 'None' and Type = 'Local' and Device = '%s' order by Channel", device ); } if ( mysql_query( &dbconn, sql ) ) { @@ -1862,6 +1862,8 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose const char *device = dbrow[col]; col++; int channel = atoi(dbrow[col]); col++; int format = atoi(dbrow[col]); col++; + bool v4l_multi_buffer = (*dbrow[col] == 48 ? false : true); col++; + int v4l_captures_per_frame = atoi(dbrow[col]); col++; const char *method = dbrow[col]; col++; int width = atoi(dbrow[col]); col++; @@ -1914,6 +1916,8 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose device, channel, format, + v4l_multi_buffer, + v4l_captures_per_frame, method, cam_width, cam_height, @@ -2430,7 +2434,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) { static char sql[ZM_SQL_MED_BUFSIZ]; - snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = %d", id ); + snprintf( sql, sizeof(sql), "select Id, Name, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = %d", id ); if ( mysql_query( &dbconn, sql ) ) { Error( "Can't run query: %s", mysql_error( &dbconn ) ); @@ -2460,6 +2464,8 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) std::string device = dbrow[col]; col++; int channel = atoi(dbrow[col]); col++; int format = atoi(dbrow[col]); col++; + bool v4l_multi_buffer = (*dbrow[col] == 48 ? false : true); col++; + int v4l_captures_per_frame = atoi(dbrow[col]); col++; std::string protocol = dbrow[col]; col++; std::string method = dbrow[col]; col++; @@ -2523,6 +2529,8 @@ Monitor *Monitor::Load( int id, bool load_zones, Purpose purpose ) device.c_str(), channel, format, + v4l_multi_buffer, + v4l_captures_per_frame, method, cam_width, cam_height, diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 1347f283d..ef1a4d00a 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -215,6 +215,8 @@ protected: bool enabled; // Whether the monitor is enabled or asleep unsigned int width; // Normally the same as the camera, but not if partly rotated unsigned int height; // Normally the same as the camera, but not if partly rotated + bool v4l_multi_buffer; + unsigned int v4l_captures_per_frame; Orientation orientation; // Whether the image has to be rotated at all unsigned int deinterlacing; int brightness; // The statically saved brightness of the camera diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index 75082e541..ab3b35de6 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -700,6 +700,9 @@ $SLANG = array( 'ViewEvent' => 'View Event', 'ViewPaged' => 'View Paged', 'View' => 'View', + 'V4L' => 'V4L', + 'V4LCapturesPerFrame' => 'Captures Per Frame', + 'V4LMultiBuffer' => 'Multi Buffering', 'Wake' => 'Wake', 'WarmupFrames' => 'Warmup Frames', 'Watch' => 'Watch', diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 419cc37f3..dfcb6d6fc 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -34,20 +34,18 @@ if ( ZM_OPT_CONTROL && canView( 'Control' ) ) if ( ZM_OPT_X10 ) $tabs["x10"] = $SLANG['X10']; $tabs["misc"] = $SLANG['Misc']; +$tabs["v4l"] = $SLANG['V4L']; if ( isset($_REQUEST['tab']) ) $tab = validHtmlStr($_REQUEST['tab']); else $tab = "general"; -if ( !empty($_REQUEST['mid']) ) -{ +if ( ! empty($_REQUEST['mid']) ) { $monitor = dbFetchMonitor( $_REQUEST['mid'] ); if ( ZM_OPT_X10 ) - $x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array( $_REQUEST['mid']) ); -} -else -{ + $x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid']) ); +} else { $nextId = getTableAutoInc( 'Monitors' ); $monitor = array( 'Id' => 0, @@ -107,6 +105,8 @@ else 'SignalCheckColour' => '#0000c0', 'WebColour' => 'red', 'Triggers' => "", + 'V4LMultiBuffer' => '', + 'V4LCapturesPerFrame' => 1, ); } @@ -143,7 +143,8 @@ if ( $newMonitor['MaxFPS'] == '0.00' ) if ( $newMonitor['AlarmMaxFPS'] == '0.00' ) $newMonitor['AlarmMaxFPS'] = ''; -if ( !empty($_REQUEST['preset']) ) { +if ( !empty($_REQUEST['preset']) ) +{ $preset = dbFetchOne( 'SELECT Type, Device, Channel, Format, Protocol, Method, Host, Port, Path, Width, Height, Palette, MaxFPS, Controllable, ControlId, ControlDevice, ControlAddress, DefaultRate, DefaultScale FROM MonitorPresets WHERE Id = ?', NULL, array($_REQUEST['preset']) ); foreach ( $preset as $name=>$value ) { @@ -608,7 +609,7 @@ switch ( $tab ) foreach ( getEnumValues( 'Monitors', 'Function' ) as $optFunction ) { ?> - + @@ -705,6 +706,10 @@ switch ( $tab ) + /> + + 0, @@ -107,6 +105,8 @@ else 'SignalCheckColour' => '#0000c0', 'WebColour' => 'red', 'Triggers' => "", + 'V4LMultiBuffer' => '', + 'V4LCapturesPerFrame' => 1, ); } @@ -706,6 +706,10 @@ switch ( $tab ) + /> + +