aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-01-04 16:48:05 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-01-06 07:47:37 -0500
commit5bbe18d74f0c163090cd16bd25e252e8806a6c75 (patch)
treed9cfb7ef008861cd4fefaf90f1c47eb064068235 /drivers
parent795e6eb3262d3b7247ce450835eea6df6571d103 (diff)
[media] pwc: Get rid of compression module parameter
Instead of making this a module parameter, automatically fallback to higher compression settings if there is not enough bandwidth. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c47
-rw-r--r--drivers/media/video/pwc/pwc-if.c48
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c12
-rw-r--r--drivers/media/video/pwc/pwc.h3
4 files changed, 56 insertions, 54 deletions
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 6b9c97fff277..905d41d90c6a 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -168,7 +168,8 @@ int send_control_msg(struct pwc_device *pdev,
168 request, value, pdev->vcinterface, buf, buflen); 168 request, value, pdev->vcinterface, buf, buflen);
169} 169}
170 170
171static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) 171static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames,
172 int *compression)
172{ 173{
173 unsigned char buf[3]; 174 unsigned char buf[3];
174 int ret, fps; 175 int ret, fps;
@@ -234,32 +235,35 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames)
234 } 235 }
235 else 236 else
236 pdev->vbandlength = 0; 237 pdev->vbandlength = 0;
238
239 /* Let pwc-if.c:isoc_init know we don't support higher compression */
240 *compression = 3;
241
237 return 0; 242 return 0;
238} 243}
239 244
240 245
241static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, 246static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames,
242 int compression) 247 int *compression)
243{ 248{
244 unsigned char buf[13]; 249 unsigned char buf[13];
245 const struct Timon_table_entry *pChoose; 250 const struct Timon_table_entry *pChoose;
246 int ret, fps; 251 int ret, fps;
247 252
248 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3) 253 if (size >= PSZ_MAX || frames < 5 || frames > 30 ||
254 *compression < 0 || *compression > 3)
249 return -EINVAL; 255 return -EINVAL;
250 if (size == PSZ_VGA && frames > 15) 256 if (size == PSZ_VGA && frames > 15)
251 return -EINVAL; 257 return -EINVAL;
252 fps = (frames / 5) - 1; 258 fps = (frames / 5) - 1;
253 259
254 /* Find a supported framerate with progressively higher compression ratios 260 /* Find a supported framerate with progressively higher compression */
255 if the preferred ratio is not available.
256 */
257 pChoose = NULL; 261 pChoose = NULL;
258 while (compression <= 3) { 262 while (*compression <= 3) {
259 pChoose = &Timon_table[size][fps][compression]; 263 pChoose = &Timon_table[size][fps][*compression];
260 if (pChoose->alternate != 0) 264 if (pChoose->alternate != 0)
261 break; 265 break;
262 compression++; 266 (*compression)++;
263 } 267 }
264 if (pChoose == NULL || pChoose->alternate == 0) 268 if (pChoose == NULL || pChoose->alternate == 0)
265 return -ENOENT; /* Not supported. */ 269 return -ENOENT; /* Not supported. */
@@ -293,27 +297,25 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames,
293 297
294 298
295static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, 299static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames,
296 int compression) 300 int *compression)
297{ 301{
298 const struct Kiara_table_entry *pChoose = NULL; 302 const struct Kiara_table_entry *pChoose = NULL;
299 int fps, ret; 303 int fps, ret;
300 unsigned char buf[12]; 304 unsigned char buf[12];
301 305
302 if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3) 306 if (size >= PSZ_MAX || frames < 5 || frames > 30 ||
307 *compression < 0 || *compression > 3)
303 return -EINVAL; 308 return -EINVAL;
304 if (size == PSZ_VGA && frames > 15) 309 if (size == PSZ_VGA && frames > 15)
305 return -EINVAL; 310 return -EINVAL;
306 fps = (frames / 5) - 1; 311 fps = (frames / 5) - 1;
307 312
308 /* Find a supported framerate with progressively higher compression 313 /* Find a supported framerate with progressively higher compression */
309 ratios if the preferred ratio is not available. 314 while (*compression <= 3) {
310 Skip this step when using RAW modes. 315 pChoose = &Kiara_table[size][fps][*compression];
311 */
312 while (compression <= 3) {
313 pChoose = &Kiara_table[size][fps][compression];
314 if (pChoose->alternate != 0) 316 if (pChoose->alternate != 0)
315 break; 317 break;
316 compression++; 318 (*compression)++;
317 } 319 }
318 if (pChoose == NULL || pChoose->alternate == 0) 320 if (pChoose == NULL || pChoose->alternate == 0)
319 return -ENOENT; /* Not supported. */ 321 return -ENOENT; /* Not supported. */
@@ -352,7 +354,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames,
352} 354}
353 355
354int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, 356int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
355 int frames, int compression) 357 int frames, int *compression)
356{ 358{
357 int ret, size; 359 int ret, size;
358 360
@@ -361,7 +363,7 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
361 PWC_TRACE("decode_size = %d.\n", size); 363 PWC_TRACE("decode_size = %d.\n", size);
362 364
363 if (DEVICE_USE_CODEC1(pdev->type)) { 365 if (DEVICE_USE_CODEC1(pdev->type)) {
364 ret = set_video_mode_Nala(pdev, size, frames); 366 ret = set_video_mode_Nala(pdev, size, frames, compression);
365 367
366 } else if (DEVICE_USE_CODEC3(pdev->type)) { 368 } else if (DEVICE_USE_CODEC3(pdev->type)) {
367 ret = set_video_mode_Kiara(pdev, size, frames, compression); 369 ret = set_video_mode_Kiara(pdev, size, frames, compression);
@@ -373,7 +375,6 @@ int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
373 PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); 375 PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret);
374 return ret; 376 return ret;
375 } 377 }
376 pdev->vcompression = compression;
377 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; 378 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size;
378 PWC_DEBUG_SIZE("Set resolution to %dx%d\n", pdev->width, pdev->height); 379 PWC_DEBUG_SIZE("Set resolution to %dx%d\n", pdev->width, pdev->height);
379 return 0; 380 return 0;
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index be4406a7c80a..943d37ad0d33 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -134,7 +134,6 @@ static int default_fps = 10;
134#endif 134#endif
135static int power_save = -1; 135static int power_save = -1;
136static int led_on = 100, led_off; /* defaults to LED that is on while in use */ 136static int led_on = 100, led_off; /* defaults to LED that is on while in use */
137static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */
138static struct { 137static struct {
139 int type; 138 int type;
140 char serial_number[30]; 139 char serial_number[30];
@@ -372,6 +371,7 @@ static int pwc_isoc_init(struct pwc_device *pdev)
372 int i, j, ret; 371 int i, j, ret;
373 struct usb_interface *intf; 372 struct usb_interface *intf;
374 struct usb_host_interface *idesc = NULL; 373 struct usb_host_interface *idesc = NULL;
374 int compression = 0; /* 0..3 = uncompressed..high */
375 375
376 if (pdev->iso_init) 376 if (pdev->iso_init)
377 return 0; 377 return 0;
@@ -383,6 +383,12 @@ static int pwc_isoc_init(struct pwc_device *pdev)
383 pdev->visoc_errors = 0; 383 pdev->visoc_errors = 0;
384 udev = pdev->udev; 384 udev = pdev->udev;
385 385
386retry:
387 /* We first try with low compression and then retry with a higher
388 compression setting if there is not enough bandwidth. */
389 ret = pwc_set_video_mode(pdev, pdev->width, pdev->height,
390 pdev->vframes, &compression);
391
386 /* Get the current alternate interface, adjust packet size */ 392 /* Get the current alternate interface, adjust packet size */
387 intf = usb_ifnum_to_if(udev, 0); 393 intf = usb_ifnum_to_if(udev, 0);
388 if (intf) 394 if (intf)
@@ -405,9 +411,12 @@ static int pwc_isoc_init(struct pwc_device *pdev)
405 } 411 }
406 412
407 /* Set alternate interface */ 413 /* Set alternate interface */
408 ret = 0;
409 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate); 414 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate);
410 ret = usb_set_interface(pdev->udev, 0, pdev->valternate); 415 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
416 if (ret == -ENOSPC && compression < 3) {
417 compression++;
418 goto retry;
419 }
411 if (ret < 0) 420 if (ret < 0)
412 return ret; 421 return ret;
413 422
@@ -451,6 +460,12 @@ static int pwc_isoc_init(struct pwc_device *pdev)
451 /* link */ 460 /* link */
452 for (i = 0; i < MAX_ISO_BUFS; i++) { 461 for (i = 0; i < MAX_ISO_BUFS; i++) {
453 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL); 462 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
463 if (ret == -ENOSPC && compression < 3) {
464 compression++;
465 pdev->iso_init = 1;
466 pwc_isoc_cleanup(pdev);
467 goto retry;
468 }
454 if (ret) { 469 if (ret) {
455 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); 470 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
456 pdev->iso_init = 1; 471 pdev->iso_init = 1;
@@ -743,14 +758,16 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
743 758
744 /* Turn on camera and set LEDS on */ 759 /* Turn on camera and set LEDS on */
745 pwc_camera_power(pdev, 1); 760 pwc_camera_power(pdev, 1);
746 if (pdev->power_save) {
747 /* Restore video mode */
748 pwc_set_video_mode(pdev, pdev->width, pdev->height,
749 pdev->vframes, pdev->vcompression);
750 }
751 pwc_set_leds(pdev, led_on, led_off); 761 pwc_set_leds(pdev, led_on, led_off);
752 762
753 r = pwc_isoc_init(pdev); 763 r = pwc_isoc_init(pdev);
764 if (r) {
765 /* If we failed turn camera and LEDS back off */
766 pwc_set_leds(pdev, 0, 0);
767 pwc_camera_power(pdev, 0);
768 /* And cleanup any queued bufs!! */
769 pwc_cleanup_queued_bufs(pdev);
770 }
754leave: 771leave:
755 mutex_unlock(&pdev->udevlock); 772 mutex_unlock(&pdev->udevlock);
756 return r; 773 return r;
@@ -798,6 +815,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
798 int vendor_id, product_id, type_id; 815 int vendor_id, product_id, type_id;
799 int hint, rc; 816 int hint, rc;
800 int features = 0; 817 int features = 0;
818 int compression = 0;
801 int video_nr = -1; /* default: use next available device */ 819 int video_nr = -1; /* default: use next available device */
802 int my_power_save = power_save; 820 int my_power_save = power_save;
803 char serial_number[30], *name; 821 char serial_number[30], *name;
@@ -1068,7 +1086,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1068 INIT_LIST_HEAD(&pdev->queued_bufs); 1086 INIT_LIST_HEAD(&pdev->queued_bufs);
1069 1087
1070 pdev->udev = udev; 1088 pdev->udev = udev;
1071 pdev->vcompression = pwc_preferred_compression;
1072 pdev->power_save = my_power_save; 1089 pdev->power_save = my_power_save;
1073 1090
1074 /* Init videobuf2 queue structure */ 1091 /* Init videobuf2 queue structure */
@@ -1121,8 +1138,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1121 pwc_set_leds(pdev, 0, 0); 1138 pwc_set_leds(pdev, 0, 0);
1122 1139
1123 /* Setup intial videomode */ 1140 /* Setup intial videomode */
1124 rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, 1141 rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, pdev->vframes,
1125 pdev->vframes, pdev->vcompression); 1142 &compression);
1126 if (rc) 1143 if (rc)
1127 goto err_free_mem; 1144 goto err_free_mem;
1128 1145
@@ -1227,7 +1244,6 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1227 */ 1244 */
1228 1245
1229static int fps; 1246static int fps;
1230static int compression = -1;
1231static int leds[2] = { -1, -1 }; 1247static int leds[2] = { -1, -1 };
1232static unsigned int leds_nargs; 1248static unsigned int leds_nargs;
1233static char *dev_hint[MAX_DEV_HINTS]; 1249static char *dev_hint[MAX_DEV_HINTS];
@@ -1238,7 +1254,6 @@ module_param(fps, int, 0444);
1238module_param_named(trace, pwc_trace, int, 0644); 1254module_param_named(trace, pwc_trace, int, 0644);
1239#endif 1255#endif
1240module_param(power_save, int, 0644); 1256module_param(power_save, int, 0644);
1241module_param(compression, int, 0444);
1242module_param_array(leds, int, &leds_nargs, 0444); 1257module_param_array(leds, int, &leds_nargs, 0444);
1243module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); 1258module_param_array(dev_hint, charp, &dev_hint_nargs, 0444);
1244 1259
@@ -1247,7 +1262,6 @@ MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful rang
1247MODULE_PARM_DESC(trace, "For debugging purposes"); 1262MODULE_PARM_DESC(trace, "For debugging purposes");
1248#endif 1263#endif
1249MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); 1264MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off");
1250MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
1251MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); 1265MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
1252MODULE_PARM_DESC(dev_hint, "Device node hints"); 1266MODULE_PARM_DESC(dev_hint, "Device node hints");
1253 1267
@@ -1281,14 +1295,6 @@ static int __init usb_pwc_init(void)
1281 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); 1295 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps);
1282 } 1296 }
1283 1297
1284 if (compression >= 0) {
1285 if (compression > 3) {
1286 PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
1287 return -EINVAL;
1288 }
1289 pwc_preferred_compression = compression;
1290 PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression);
1291 }
1292 if (leds[0] >= 0) 1298 if (leds[0] >= 0)
1293 led_on = leds[0]; 1299 led_on = leds[0];
1294 if (leds[1] >= 0) 1300 if (leds[1] >= 0)
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 097ec582ee66..36da7d400907 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -469,7 +469,7 @@ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
469static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 469static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
470{ 470{
471 struct pwc_device *pdev = video_drvdata(file); 471 struct pwc_device *pdev = video_drvdata(file);
472 int ret, pixelformat; 472 int ret, pixelformat, compression = 0;
473 473
474 if (pwc_test_n_set_capt_file(pdev, file)) 474 if (pwc_test_n_set_capt_file(pdev, file))
475 return -EBUSY; 475 return -EBUSY;
@@ -497,19 +497,15 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
497 } 497 }
498 498
499 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " 499 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
500 "compression=%d format=%c%c%c%c\n", 500 "format=%c%c%c%c\n",
501 f->fmt.pix.width, f->fmt.pix.height, pdev->vframes, 501 f->fmt.pix.width, f->fmt.pix.height, pdev->vframes,
502 pdev->vcompression,
503 (pixelformat)&255, 502 (pixelformat)&255,
504 (pixelformat>>8)&255, 503 (pixelformat>>8)&255,
505 (pixelformat>>16)&255, 504 (pixelformat>>16)&255,
506 (pixelformat>>24)&255); 505 (pixelformat>>24)&255);
507 506
508 ret = pwc_set_video_mode(pdev, 507 ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height,
509 f->fmt.pix.width, 508 pdev->vframes, &compression);
510 f->fmt.pix.height,
511 pdev->vframes,
512 pdev->vcompression);
513 509
514 PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); 510 PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
515 511
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 5d013851ed2a..47c518fef179 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -243,7 +243,6 @@ struct pwc_device
243 int vmax_packet_size; /* USB maxpacket size */ 243 int vmax_packet_size; /* USB maxpacket size */
244 int vlast_packet_size; /* for frame synchronisation */ 244 int vlast_packet_size; /* for frame synchronisation */
245 int visoc_errors; /* number of contiguous ISOC errors */ 245 int visoc_errors; /* number of contiguous ISOC errors */
246 int vcompression; /* desired compression factor */
247 int vbandlength; /* compressed band length; 0 is uncompressed */ 246 int vbandlength; /* compressed band length; 0 is uncompressed */
248 char vsync; /* used by isoc handler */ 247 char vsync; /* used by isoc handler */
249 char vmirror; /* for ToUCaM series */ 248 char vmirror; /* for ToUCaM series */
@@ -365,7 +364,7 @@ void pwc_construct(struct pwc_device *pdev);
365/** Functions in pwc-ctrl.c */ 364/** Functions in pwc-ctrl.c */
366/* Request a certain video mode. Returns < 0 if not possible */ 365/* Request a certain video mode. Returns < 0 if not possible */
367extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, 366extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height,
368 int frames, int compression); 367 int frames, int *compression);
369extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size); 368extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size);
370extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); 369extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
371extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor); 370extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);