Start zmc failed

Support and queries relating to all previous versions of ZoneMinder
Locked
oskin
Posts: 84
Joined: Tue May 25, 2004 7:03 pm
Location: Moscow, Russia

Start zmc failed

Post 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;
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post 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,
oskin
Posts: 84
Joined: Tue May 25, 2004 7:03 pm
Location: Moscow, Russia

Post 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. :)
User avatar
lazyleopard
Posts: 403
Joined: Tue Mar 02, 2004 6:12 pm
Location: Gloucestershire, UK

Post 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
Rick Hewett
oskin
Posts: 84
Joined: Tue May 25, 2004 7:03 pm
Location: Moscow, Russia

Post 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 )
        { 
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post 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,
oskin
Posts: 84
Joined: Tue May 25, 2004 7:03 pm
Location: Moscow, Russia

Post 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.
oskin
Posts: 84
Joined: Tue May 25, 2004 7:03 pm
Location: Moscow, Russia

Post 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...
oskin
Posts: 84
Joined: Tue May 25, 2004 7:03 pm
Location: Moscow, Russia

Post 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.
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post 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,
oskin
Posts: 84
Joined: Tue May 25, 2004 7:03 pm
Location: Moscow, Russia

Post 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. :)
Locked