[media] em28xx: prefer bulk mode on webcams
Using bulk mode allows more than one webcam, as the maximum fps is low at 640x480 resolution. So, prefer it, if the device is a webcam. Tested with Silvercrest 1.3 Mpixel webcam (em2710) on both bulk and isoc modes. Tested analog with HVR-950 model 65201/A1C0 (em2883), where only ISOC endpoints are available for both DVB and Analog. Tested on Hauppauge WinTV USB 2 (em2840) on both bulk and isoc modes. It should be noticed that enabling bulk mode by default with TV boards is a bad idea; what happens is that, while with ISOC the USB logic will prevent the concurrent usage of two devices that spends more than 100% of the USB2 traffic, it doesn't care with bulk transfers. On my tests, I started two streams, one with a WinTV at 640x480x30fps and the other one with a Silvercrest webcam at 640x480, on a lower fps) both on bulk mode. One of the streams always silently failed. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
a3efa1cc0e
commit
8b2aea7878
|
@ -61,9 +61,9 @@ static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
|||
module_param_array(card, int, NULL, 0444);
|
||||
MODULE_PARM_DESC(card, "card type");
|
||||
|
||||
static unsigned int prefer_bulk;
|
||||
static int prefer_bulk = -1;
|
||||
module_param(prefer_bulk, int, 0444);
|
||||
MODULE_PARM_DESC(prefer_bulk, "prefer USB bulk transfers");
|
||||
MODULE_PARM_DESC(prefer_bulk, "prefer USB bulk transfers (-1 = auto, 0 = isoc, 1 = bulk)");
|
||||
|
||||
|
||||
/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */
|
||||
|
@ -3170,7 +3170,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
|
|||
struct em28xx *dev = NULL;
|
||||
int retval;
|
||||
bool has_audio = false, has_video = false, has_dvb = false;
|
||||
int i, nr;
|
||||
int i, nr, try_bulk;
|
||||
const int ifnum = interface->altsetting[0].desc.bInterfaceNumber;
|
||||
char *speed;
|
||||
|
||||
|
@ -3344,14 +3344,6 @@ static int em28xx_usb_probe(struct usb_interface *interface,
|
|||
goto err_free;
|
||||
}
|
||||
|
||||
/* Select USB transfer types to use */
|
||||
if (has_video &&
|
||||
(!dev->analog_ep_isoc || (prefer_bulk && dev->analog_ep_bulk)))
|
||||
dev->analog_xfer_bulk = 1;
|
||||
if (has_dvb &&
|
||||
(!dev->dvb_ep_isoc || (prefer_bulk && dev->dvb_ep_bulk)))
|
||||
dev->dvb_xfer_bulk = 1;
|
||||
|
||||
dev->devno = nr;
|
||||
dev->model = id->driver_info;
|
||||
dev->alt = -1;
|
||||
|
@ -3402,7 +3394,29 @@ static int em28xx_usb_probe(struct usb_interface *interface,
|
|||
goto unlock_and_free;
|
||||
}
|
||||
|
||||
if (prefer_bulk < 0) {
|
||||
if (dev->board.is_webcam)
|
||||
try_bulk = 1;
|
||||
else
|
||||
try_bulk = 0;
|
||||
} else {
|
||||
try_bulk = prefer_bulk > 0;
|
||||
}
|
||||
|
||||
/* Select USB transfer types to use */
|
||||
if (has_video) {
|
||||
if (!dev->analog_ep_isoc || (try_bulk && dev->analog_ep_bulk))
|
||||
dev->analog_xfer_bulk = 1;
|
||||
em28xx_info("analog set to %s mode.\n",
|
||||
dev->analog_xfer_bulk ? "bulk" : "isoc");
|
||||
}
|
||||
if (has_dvb) {
|
||||
if (!dev->dvb_ep_isoc || (try_bulk && dev->dvb_ep_bulk))
|
||||
dev->dvb_xfer_bulk = 1;
|
||||
|
||||
em28xx_info("dvb set to %s mode.\n",
|
||||
dev->dvb_xfer_bulk ? "bulk" : "isoc");
|
||||
|
||||
/* pre-allocate DVB usb transfer buffers */
|
||||
if (dev->dvb_xfer_bulk) {
|
||||
retval = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
|
||||
|
|
Loading…
Reference in New Issue