Re: [ADVICE WANTED] by new cpia driver maintainer...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Hi,
two basic questions:
-- how can one test a usb port to find what bandwidth is available
   before opening a webcam stream?
-- how to clean up when a usb v4l1 webcam device is disconnected while 
   open for streaming video?
Thanks for any pointers to the answers..
Duncan

On 23-Nov-2002 Mark McClelland wrote:
>   Duncan Haldane wrote:
> 
>>On 18-Nov-2002 Mark McClelland wrote:
>>  
>>
>>>Duncan Haldane wrote:
>>>
>>> >If two cameras are registered, one on /dev/video0 and one on /dev/video1,
>>> >and I use e.g. xawtv or gqcam to monitor them, I cannot open /dev/video1
>>> >when /dev/video0 is open and vice-versa.  This happens for two cpia
>>> >devices and one cpia + one ov511 device.
>>>
>>>That's because both cameras are trying to use nearly all of the USB's
>>>bandwidth. Or, more precisely, each is trying to schedule an ISO packet
>>> 
   
I've now consulted the available CPiA developer's guide 
and see that the CPiA chip allows 4 alt settings of the USB interface
with MaxPacketSizes= {0,448,704,960} for alt={0,1,2,3}.   

The current cpia_usb driver only allowed alt=0 (non-streaming) and alt=3
(streaming) states.  I verified that two cameras on the same usb hub can work
together if both use alt=2, at about 8fps. On different hubs, both work with
alt=3 with a larger fps.

I've added an alt setting to the device structure so it can be set on a
per-camera basis.

The packetsize is only set by v4l function  cpia_usb_open()

Ideally the driver would find out from the usb port what
bandwidth was available so it could choose an appropriate alt setting 1,2,3
(or even 0) when starting.

I guess I would like to make the alt setting user-switchable though the
/proc/cpia/video<n> interface that can control the cpia driver so the camera
would start in some safe alt setting, and this could then be increased by the
user if the bandwidth became available. (e.g. by disconnecting or reducing the
bandwidth use of other cameras)

Clearly this needs some way for the driver to test what alt setiing is
currently safe.  Any suggestion?

>>
>>Yes, this seems correct: I have now traced the problem to disruption of
>>communication of commands to/from the cpia cam (ReadPacket() in cpia_usb.c/
>>cpia_usb_transferCmd()).  This eventually causes de/re-registration of
>>the camera, leaving a frozen viewer window that needs a reboot to clear
>>it.... (incomplete cleanup ?) -- nasty.
>>
>>At the very least I would hope to prevent hanging that requires a reboot!.
>>  
>>
> 
> Agreed. I'm not sure why that happens, but I suspect the cpia driver is 
> at fault since lots of drivers have no problem with random disconnects. 

Hmmm.  this seems to occur because the usb hub.c decided /dev/video<n> is 
dead: this bit of code in hub.c issues a warning message about "EMI"
(possible electromagnetic interference) when it tries to renable the port:


--------------snipped from usb/hub.c-----------------------------
else if (portchange & USB_PORT_STAT_C_ENABLE) {
     dbg("port %d enable change, status %x", i + 1,portstatus);
     usb_clear_port_feature(dev, i + 1,USB_PORT_FEAT_C_ENABLE);

    /* 
     * EM interference sometimes causes bad shielded USB devices to  
     * be shutdown by the hub, this hack enables them again.
     * Works at least with mouse driver.
     */
    if (!(portstatus & USB_PORT_STAT_ENABLE) &&
        (portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) {
             err("already running port %i disabled by hub(EMI?),re-enabling...",
             i +1);
             usb_hub_port_connect_change(hub, i,portstatus, portchange);
             }
   }
-------------------------------------------------------------


but the hanging problem also occurs if I simply yank the usb cable out of the
port when the camera is running.  The v4l application is gqcam-0.9 with a
small patch.  but i guess xawtv would also do it.
(BTW, the v4l app "camstream" stopped working with ov511 webcams with its last
release, and the author couldnt track this down.  Has Mark looked at this?)


The cpia driver skips some cleanups if it detects  that the disconnected
camera has an open_count > 0.

But if I try running an **ov511** camera and again disconnect the usb cable
while it's running I also get a similar frozen gqcam which can't be killed
and doesnt let the module be rmmod'ed.  (this was ov511 v1.50 for Linux 2.4.18)
AARGH: need to reboot from a console to clear it (X hangs if I just logout
with the hung gqcam) , and various file systems are unmounted while busy,
so lots of fscking at reboot....  So this doesnt seem to be cpia-specific...

Is this a problem of the v4l app (e.g. gqcam) or the camera driver?
Do _any_ v4l1 apps behave correctly (i.e. close down  gracefully if the usb
/dev/video<n> to which they are attached gets shut down?)

Or should the v4l usb driver be doing something more to shut down an open camera
that has been disconnected?

This is what the cpia driver does:
----------------cpia.c-------------------------
void cpia_unregister_camera(struct cam_data *cam)
{
        if (!cam->open_count) {
                DBG("unregistering video\n");
                video_unregister_device(&cam->vdev);
        } else {
                LOG("/dev/video%d removed while open, "
                    "deferring video_unregister_device\n", cam->vdev.minor);
                DBG("camera open -- setting ops to NULL\n");
                cam->ops = NULL;
        }
        
#ifdef CONFIG_PROC_FS
        DBG("destroying /proc/cpia/video%d\n", cam->vdev.minor);
        destroy_proc_cpia_cam(cam);
#endif  
        if (!cam->open_count) {
                DBG("freeing camera\n");
                kfree(cam);
        }
}
---------------------------------------------------


> It's possibly something to do with the synchronous calls (eg. 
> usb_control_msg()) being active when disconnect() gets called. There's 
> no solution to that currently, other than to use the async calls (ie. 
> usb_submit_urb()) and implement the necessary locking yourself. I'd also 
> check all of the codepaths that handle signals (eg. interrupted 
> syscalls), and check for function returns that don't drop all held 
> locks. I looked it over briefly, and nothing jumps out at me.
> 
> If you can't find anything, put a ton of printks in disconnect() and 
> close() and see where it hangs :)
> 
> <snip>
> 
>>>Check the descriptors. As long as there's an alternate setting where
>>>MxPS <= 1023 / 2 then you should be in business. You can either have the


Hmm.alt=2, MxPS=704 = 1408/2 > 512 works!


>>>packet size or alternate number be a module param, or you can do a
>>>"cams" thing like ov511. Or, you can allow the frame rate to be set
>>>somewhere, and have the driver automatically choose the minimum possible
>>>packet size that can still sustain that frame rate.
>>>    
>>>

> My idea about auto-adjusting the alternate setting based on the 
> framerate is probably too difficult for a driver this complex, since 
> features like compression make it difficult to know the minimum 
> necessary bandwidth. I recommend doing what ov511 does instead (allow 
> user to input the number of cameras in /proc or as a module param, 
> determine a packet size based on that, and set the corresponding 
> alternate setting in cpia_usb_open()).

I'll try to go with /proc input.  But I want to get the camera to determine the
maximum safe alt MaxPacketSize setting to start with when it first is opened.
How can I do this?   I also have to work out how to close the camera and
reopen it with a different alt setting, but I guess this should be 
relatively obvious using 
cpia_usb_close()
(change alt setting for camera)
cpia_usb_open()? 

The disconnect-while-camera-is-open=>needs-reboot problem seems the
most disturbing one, though....

Duncan





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux