Page 1 of 1
Start zmc failed
Posted: Tue May 25, 2004 7:32 pm
by oskin
... with error "... zmc-d0[11496]: ERR [Failed to set window attributes: Invalid argument]".
But if to eliminate call "ioctl( m_videohandle, VIDIOCGWIN, &vid_win)" zmc will start and works normal. IMHO this part of a code is not meaningful also her possible to delete simply. Here a patch:
Code: Select all
--- zm_local_camera.cpp.orig 2004-04-19 20:02:17.000000000 +0400
+++ zm_local_camera.cpp 2004-05-25 22:52:47.000000000 +0400
@@ -71,15 +71,15 @@
struct video_window vid_win;
memset( &vid_win, 0, sizeof(vid_win) );
- if ( ioctl( m_videohandle, VIDIOCGWIN, &vid_win) < 0 )
- {
- Error(( "Failed to get window attributes: %s", strerror(errno) ));
- exit(-1);
- }
- Debug( 1, ( "Old X:%d", vid_win.x ));
- Debug( 1, ( "Old Y:%d", vid_win.y ));
- Debug( 1, ( "Old W:%d", vid_win.width ));
- Debug( 1, ( "Old H:%d", vid_win.height ));
+// if ( ioctl( m_videohandle, VIDIOCGWIN, &vid_win) < 0 )
+// {
+// Error(( "Failed to get window attributes: %s", strerror(errno) ));
+// exit(-1);
+// }
+// Debug( 1, ( "Old X:%d", vid_win.x ));
+// Debug( 1, ( "Old Y:%d", vid_win.y ));
+// Debug( 1, ( "Old W:%d", vid_win.width ));
+// Debug( 1, ( "Old H:%d", vid_win.height ));
vid_win.x = 0;
vid_win.y = 0;
Posted: Wed May 26, 2004 8:30 am
by zoneminder
Hi,
The error you are reporting refers to a failure to 'set' the window attributes which is important whereas your patch just removes code which is used to 'get' the attributes. This is also potentially important in that it prepopulates the structure with the existing settings.
If you wan't to avoid getting the error you are seeing the best way is to clear the ZM_STRICT_VIDEO_CONFIG option as per
this faq.
Also, on a general point, if you want to submit any patches please also include what version of ZM your patch applies to.
Cheers,
Phil,
Posted: Wed May 26, 2004 6:32 pm
by oskin
Clearing of option ZM_STRICT_VIDEO_CONFIG certainly will prevent abort zmc, but it will not place the necessary sizes of capture.
At the further research of a problem, namely a code of kernels Linux has shown interesting parts of a code in some drivers, including bttv (such chip for me):
Code: Select all
case VIDIOCGWIN:
...
if(btv->win.interlace)
vw.flags|=VIDEO_WINDOW_INTERLACE;
...
case VIDIOCSWIN:
...
if(vw.flags || vw.width < 16 || vw.height < 16)
{
...
return -EINVAL;
}
...
It in kernels of versions 2.4.x. And in kernels of versions 2.6.x similar "strangenesses" already are not present (during a week I shall check up operation ZoneMinder with a kernels 2.6.x).
In the total for normal operation it is enough to make so:
Code: Select all
--- zm_local_camera.cpp.orig 2004-04-19 20:02:17.000000000 +0400
+++ zm_local_camera.cpp 2004-05-26 22:24:18.000000000 +0400
@@ -85,6 +85,7 @@
vid_win.y = 0;
vid_win.width = width;
vid_win.height = height;
+ vid_win.flags = 0;
if ( ioctl( m_videohandle, VIDIOCSWIN, &vid_win ) < 0 )
{
However and previous my variant is quite efficient, as operation "get" in drivers fills in this structure only the data on sizes of a window.
Posted: Wed May 26, 2004 11:09 pm
by lazyleopard
The error suppressed by ZM_STRICT_VIDEO_CONFIG seems to be thrown when the interlace flag and the size don't match, especially if the flag says the image should be interlaced and the size implies it shouldn't. I have noticed that the camera sometimes doesn't work as expected if the error has occurred and been suppressed.
While adding "vid_win.flags = 0;" fixes it for bttv cards, some Phillips cameras apparently (if various code examples I've seen are anything to go by) seem to use other parts of vid_win.flags for something else, so may end up broken by "vid_win.flags = 0;", so just clearing the VIDEO_WINDOW_INTERLACE bit would probably be better.
See also
http://www.zoneminder.com/forums/viewtopic.php?t=3303
Posted: Thu May 27, 2004 6:01 am
by oskin
Probably it is an error in a code of the driver as in versions 2.6.x similar checks are not present... And, IMHO, the chip bttv does not support a size of a window less 16x16.
Reset bit VIDEO_WINDOW_INTERLACE probably it is more correct. Thanks.
Code: Select all
--- zm_local_camera.cpp.orig 2004-04-19 20:02:17.000000000 +0400
+++ zm_local_camera.cpp 2004-05-26 22:24:18.000000000 +0400
@@ -85,6 +85,7 @@
vid_win.y = 0;
vid_win.width = width;
vid_win.height = height;
+ vid_win.flags &= ~VIDEO_WINDOW_INTERLACE;
if ( ioctl( m_videohandle, VIDIOCSWIN, &vid_win ) < 0 )
{
Posted: Thu May 27, 2004 8:49 am
by zoneminder
This seems eminently sensible so I will include it in the next release. I assume it does actually remove the error, is that correct?
Phil,
Posted: Fri May 28, 2004 12:00 pm
by oskin
I have once again viewed a code of drivers of all supported chips in kernel 2.4.22 and is later - should work correctly. In 2.6.x I shall check up next week.
Posted: Wed Jun 02, 2004 9:18 pm
by oskin
Has checked up with kernel-2.6.5 - any of variants does not work.
Code: Select all
$ strace ./zmc -m 1
...
read(5, "\24ZM_DYN_NEXT_REMINDER\0\6string", 29) = 29
read(5, "\5\0\0\177", 4) = 4
read(5, "\376\0\0\2\0", 5) = 5
brk(0) = 0xd21b000
brk(0xd249000) = 0xd249000
open("/dev/video0", O_RDWR) = 7
ioctl(7, VIDIOCGWIN, 0xfef564b0) = 0
ioctl(7, VIDIOCSWIN, 0xfef564b0) = -1 EINVAL (Invalid argument)
gettimeofday({1086210709, 741972}, {4294967056, 0}) = 0
time([1086210709]) = 1086210709
rt_sigaction(SIGPIPE, {0x754450, [], 0}, {SIG_IGN}, 8) = 0
send(3, "<139>Jun 3 01:11:49 zmc-m1[1471"..., 91, 0) = 91
rt_sigaction(SIGPIPE, {SIG_IGN}, NULL, 8) = 0
exit_group(-1) = ?
$
After a while I shall try to find a reason...
Posted: Mon Jun 07, 2004 9:08 pm
by oskin
For correct operation zmc with kernel-2.6.x (v4l2) it is necessary before VIDIOCSWIN to initialize some structures with VIDIOCGPICT+VIDIOCSPICT. For this purpose it is enough in zm_local_camera.cpp to swap pairs calls VIDIOCGWIN+VIDIOCSWIN and VIDIOCGPICT+VIDIOCSPICT. Here patch:
Code: Select all
--- zm_local_camera.cpp.orig 2004-06-03 00:02:45.000000000 +0400
+++ zm_local_camera.cpp 2004-06-07 23:59:51.601419144 +0400
@@ -69,29 +69,6 @@
exit(-1);
}
- struct video_window vid_win;
- memset( &vid_win, 0, sizeof(vid_win) );
- if ( ioctl( m_videohandle, VIDIOCGWIN, &vid_win) < 0 )
- {
- Error(( "Failed to get window attributes: %s", strerror(errno) ));
- exit(-1);
- }
- Debug( 1, ( "Old X:%d", vid_win.x ));
- Debug( 1, ( "Old Y:%d", vid_win.y ));
- Debug( 1, ( "Old W:%d", vid_win.width ));
- Debug( 1, ( "Old H:%d", vid_win.height ));
-
- vid_win.x = 0;
- vid_win.y = 0;
- vid_win.width = width;
- vid_win.height = height;
-
- if ( ioctl( m_videohandle, VIDIOCSWIN, &vid_win ) < 0 )
- {
- Error(( "Failed to set window attributes: %s", strerror(errno) ));
- if ( (bool)config.Item( ZM_STRICT_VIDEO_CONFIG ) ) exit(-1);
- }
-
struct video_picture vid_pic;
memset( &vid_pic, 0, sizeof(vid_pic) );
if ( ioctl( m_videohandle, VIDIOCGPICT, &vid_pic) < 0 )
@@ -132,6 +109,33 @@
Error(( "Failed to set picture attributes: %s", strerror(errno) ));
if ( (bool)config.Item( ZM_STRICT_VIDEO_CONFIG ) ) exit(-1);
}
+
+ struct video_window vid_win;
+ memset( &vid_win, 0, sizeof(vid_win) );
+ if ( ioctl( m_videohandle, VIDIOCGWIN, &vid_win) < 0 )
+ {
+ Error(( "Failed to get window attributes: %s", strerror(errno) ));
+ exit(-1);
+ }
+ Debug( 1, ( "Old X:%d", vid_win.x ));
+ Debug( 1, ( "Old Y:%d", vid_win.y ));
+ Debug( 1, ( "Old W:%d", vid_win.width ));
+ Debug( 1, ( "Old H:%d", vid_win.height ));
+
+ vid_win.x = 0;
+ vid_win.y = 0;
+ vid_win.width = width;
+ vid_win.height = height;
+#ifndef HAVE_V4L2
+ vid_win.flags &= ~VIDEO_WINDOW_INTERLACE;
+#endif
+
+ if ( ioctl( m_videohandle, VIDIOCSWIN, &vid_win ) < 0 )
+ {
+ Error(( "Failed to set window attributes: %s", strerror(errno) ));
+ if ( (bool)config.Item( ZM_STRICT_VIDEO_CONFIG ) ) exit(-1);
+ }
+
if ( ioctl(m_videohandle, VIDIOCGMBUF, &m_vmb) < 0 )
{
Error(( "Failed to setup memory: %s", strerror(errno) ));
The previous correction (vid_win.flags and = ~VIDEO_WINDOW_INTERLACE) for v4l2 it is not necessary.
Posted: Wed Jun 30, 2004 2:41 pm
by zoneminder
Hi Oskin,
Di dyou decide this version was the final one that worked on both 2.4 and 2.6 kernels and with V4L and V4L2? Does the HAVE_V4L2 directive come from V4L2 itself or does it require changes to the configure script?
Cheers,
phil,
Posted: Wed Jun 30, 2004 5:43 pm
by oskin
Yes, it works both with V4L and with V4L2 (in compatibility mode with V4L). HAVE_V4L2 directive is defined in/usr/include/linux/videodev.h. However she is defined not in all systems (distribution) supporting V4L2, in such cases authentically to detect support V4L2 very difficultly, but zmc will work not worse, than in systems without V4L2.
P.S. And what solution on
http://www.zoneminder.com/forums/viewtopic.php?t=3437 will be? IMHO it is the same part of a code.