Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Hans de Goede and committed by
Mauro Carvalho Chehab
5bbe18d7 795e6eb3

+56 -54
+24 -23
drivers/media/video/pwc/pwc-ctrl.c
··· 168 168 request, value, pdev->vcinterface, buf, buflen); 169 169 } 170 170 171 - static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames) 171 + static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames, 172 + int *compression) 172 173 { 173 174 unsigned char buf[3]; 174 175 int ret, fps; ··· 235 234 } 236 235 else 237 236 pdev->vbandlength = 0; 237 + 238 + /* Let pwc-if.c:isoc_init know we don't support higher compression */ 239 + *compression = 3; 240 + 238 241 return 0; 239 242 } 240 243 241 244 242 245 static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, 243 - int compression) 246 + int *compression) 244 247 { 245 248 unsigned char buf[13]; 246 249 const struct Timon_table_entry *pChoose; 247 250 int ret, fps; 248 251 249 - if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3) 252 + if (size >= PSZ_MAX || frames < 5 || frames > 30 || 253 + *compression < 0 || *compression > 3) 250 254 return -EINVAL; 251 255 if (size == PSZ_VGA && frames > 15) 252 256 return -EINVAL; 253 257 fps = (frames / 5) - 1; 254 258 255 - /* Find a supported framerate with progressively higher compression ratios 256 - if the preferred ratio is not available. 257 - */ 259 + /* Find a supported framerate with progressively higher compression */ 258 260 pChoose = NULL; 259 - while (compression <= 3) { 260 - pChoose = &Timon_table[size][fps][compression]; 261 - if (pChoose->alternate != 0) 262 - break; 263 - compression++; 261 + while (*compression <= 3) { 262 + pChoose = &Timon_table[size][fps][*compression]; 263 + if (pChoose->alternate != 0) 264 + break; 265 + (*compression)++; 264 266 } 265 267 if (pChoose == NULL || pChoose->alternate == 0) 266 268 return -ENOENT; /* Not supported. */ ··· 297 293 298 294 299 295 static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, 300 - int compression) 296 + int *compression) 301 297 { 302 298 const struct Kiara_table_entry *pChoose = NULL; 303 299 int fps, ret; 304 300 unsigned char buf[12]; 305 301 306 - if (size >= PSZ_MAX || frames < 5 || frames > 30 || compression < 0 || compression > 3) 302 + if (size >= PSZ_MAX || frames < 5 || frames > 30 || 303 + *compression < 0 || *compression > 3) 307 304 return -EINVAL; 308 305 if (size == PSZ_VGA && frames > 15) 309 306 return -EINVAL; 310 307 fps = (frames / 5) - 1; 311 308 312 - /* Find a supported framerate with progressively higher compression 313 - ratios if the preferred ratio is not available. 314 - Skip this step when using RAW modes. 315 - */ 316 - while (compression <= 3) { 317 - pChoose = &Kiara_table[size][fps][compression]; 309 + /* Find a supported framerate with progressively higher compression */ 310 + while (*compression <= 3) { 311 + pChoose = &Kiara_table[size][fps][*compression]; 318 312 if (pChoose->alternate != 0) 319 313 break; 320 - compression++; 314 + (*compression)++; 321 315 } 322 316 if (pChoose == NULL || pChoose->alternate == 0) 323 317 return -ENOENT; /* Not supported. */ ··· 354 352 } 355 353 356 354 int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, 357 - int frames, int compression) 355 + int frames, int *compression) 358 356 { 359 357 int ret, size; 360 358 ··· 363 361 PWC_TRACE("decode_size = %d.\n", size); 364 362 365 363 if (DEVICE_USE_CODEC1(pdev->type)) { 366 - ret = set_video_mode_Nala(pdev, size, frames); 364 + ret = set_video_mode_Nala(pdev, size, frames, compression); 367 365 368 366 } else if (DEVICE_USE_CODEC3(pdev->type)) { 369 367 ret = set_video_mode_Kiara(pdev, size, frames, compression); ··· 375 373 PWC_ERROR("Failed to set video mode %s@%d fps; return code = %d\n", size2name[size], frames, ret); 376 374 return ret; 377 375 } 378 - pdev->vcompression = compression; 379 376 pdev->frame_total_size = pdev->frame_size + pdev->frame_header_size + pdev->frame_trailer_size; 380 377 PWC_DEBUG_SIZE("Set resolution to %dx%d\n", pdev->width, pdev->height); 381 378 return 0;
+27 -21
drivers/media/video/pwc/pwc-if.c
··· 134 134 #endif 135 135 static int power_save = -1; 136 136 static int led_on = 100, led_off; /* defaults to LED that is on while in use */ 137 - static int pwc_preferred_compression = 1; /* 0..3 = uncompressed..high */ 138 137 static struct { 139 138 int type; 140 139 char serial_number[30]; ··· 371 372 int i, j, ret; 372 373 struct usb_interface *intf; 373 374 struct usb_host_interface *idesc = NULL; 375 + int compression = 0; /* 0..3 = uncompressed..high */ 374 376 375 377 if (pdev->iso_init) 376 378 return 0; ··· 382 382 pdev->vframe_count = 0; 383 383 pdev->visoc_errors = 0; 384 384 udev = pdev->udev; 385 + 386 + retry: 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); 385 391 386 392 /* Get the current alternate interface, adjust packet size */ 387 393 intf = usb_ifnum_to_if(udev, 0); ··· 411 405 } 412 406 413 407 /* Set alternate interface */ 414 - ret = 0; 415 408 PWC_DEBUG_OPEN("Setting alternate interface %d\n", pdev->valternate); 416 409 ret = usb_set_interface(pdev->udev, 0, pdev->valternate); 410 + if (ret == -ENOSPC && compression < 3) { 411 + compression++; 412 + goto retry; 413 + } 417 414 if (ret < 0) 418 415 return ret; 419 416 ··· 460 451 /* link */ 461 452 for (i = 0; i < MAX_ISO_BUFS; i++) { 462 453 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL); 454 + if (ret == -ENOSPC && compression < 3) { 455 + compression++; 456 + pdev->iso_init = 1; 457 + pwc_isoc_cleanup(pdev); 458 + goto retry; 459 + } 463 460 if (ret) { 464 461 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); 465 462 pdev->iso_init = 1; ··· 758 743 759 744 /* Turn on camera and set LEDS on */ 760 745 pwc_camera_power(pdev, 1); 761 - if (pdev->power_save) { 762 - /* Restore video mode */ 763 - pwc_set_video_mode(pdev, pdev->width, pdev->height, 764 - pdev->vframes, pdev->vcompression); 765 - } 766 746 pwc_set_leds(pdev, led_on, led_off); 767 747 768 748 r = pwc_isoc_init(pdev); 749 + if (r) { 750 + /* If we failed turn camera and LEDS back off */ 751 + pwc_set_leds(pdev, 0, 0); 752 + pwc_camera_power(pdev, 0); 753 + /* And cleanup any queued bufs!! */ 754 + pwc_cleanup_queued_bufs(pdev); 755 + } 769 756 leave: 770 757 mutex_unlock(&pdev->udevlock); 771 758 return r; ··· 815 798 int vendor_id, product_id, type_id; 816 799 int hint, rc; 817 800 int features = 0; 801 + int compression = 0; 818 802 int video_nr = -1; /* default: use next available device */ 819 803 int my_power_save = power_save; 820 804 char serial_number[30], *name; ··· 1086 1068 INIT_LIST_HEAD(&pdev->queued_bufs); 1087 1069 1088 1070 pdev->udev = udev; 1089 - pdev->vcompression = pwc_preferred_compression; 1090 1071 pdev->power_save = my_power_save; 1091 1072 1092 1073 /* Init videobuf2 queue structure */ ··· 1138 1121 pwc_set_leds(pdev, 0, 0); 1139 1122 1140 1123 /* Setup intial videomode */ 1141 - rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, 1142 - pdev->vframes, pdev->vcompression); 1124 + rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, pdev->vframes, 1125 + &compression); 1143 1126 if (rc) 1144 1127 goto err_free_mem; 1145 1128 ··· 1244 1227 */ 1245 1228 1246 1229 static int fps; 1247 - static int compression = -1; 1248 1230 static int leds[2] = { -1, -1 }; 1249 1231 static unsigned int leds_nargs; 1250 1232 static char *dev_hint[MAX_DEV_HINTS]; ··· 1254 1238 module_param_named(trace, pwc_trace, int, 0644); 1255 1239 #endif 1256 1240 module_param(power_save, int, 0644); 1257 - module_param(compression, int, 0444); 1258 1241 module_param_array(leds, int, &leds_nargs, 0444); 1259 1242 module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); 1260 1243 ··· 1262 1247 MODULE_PARM_DESC(trace, "For debugging purposes"); 1263 1248 #endif 1264 1249 MODULE_PARM_DESC(power_save, "Turn power saving for new cameras on or off"); 1265 - MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)"); 1266 1250 MODULE_PARM_DESC(leds, "LED on,off time in milliseconds"); 1267 1251 MODULE_PARM_DESC(dev_hint, "Device node hints"); 1268 1252 ··· 1295 1281 PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); 1296 1282 } 1297 1283 1298 - if (compression >= 0) { 1299 - if (compression > 3) { 1300 - PWC_ERROR("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n"); 1301 - return -EINVAL; 1302 - } 1303 - pwc_preferred_compression = compression; 1304 - PWC_DEBUG_MODULE("Preferred compression set to %d.\n", pwc_preferred_compression); 1305 - } 1306 1284 if (leds[0] >= 0) 1307 1285 led_on = leds[0]; 1308 1286 if (leds[1] >= 0)
+4 -8
drivers/media/video/pwc/pwc-v4l.c
··· 469 469 static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 470 470 { 471 471 struct pwc_device *pdev = video_drvdata(file); 472 - int ret, pixelformat; 472 + int ret, pixelformat, compression = 0; 473 473 474 474 if (pwc_test_n_set_capt_file(pdev, file)) 475 475 return -EBUSY; ··· 497 497 } 498 498 499 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 501 f->fmt.pix.width, f->fmt.pix.height, pdev->vframes, 502 - pdev->vcompression, 503 502 (pixelformat)&255, 504 503 (pixelformat>>8)&255, 505 504 (pixelformat>>16)&255, 506 505 (pixelformat>>24)&255); 507 506 508 - ret = pwc_set_video_mode(pdev, 509 - f->fmt.pix.width, 510 - f->fmt.pix.height, 511 - pdev->vframes, 512 - pdev->vcompression); 507 + ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height, 508 + pdev->vframes, &compression); 513 509 514 510 PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); 515 511
+1 -2
drivers/media/video/pwc/pwc.h
··· 243 243 int vmax_packet_size; /* USB maxpacket size */ 244 244 int vlast_packet_size; /* for frame synchronisation */ 245 245 int visoc_errors; /* number of contiguous ISOC errors */ 246 - int vcompression; /* desired compression factor */ 247 246 int vbandlength; /* compressed band length; 0 is uncompressed */ 248 247 char vsync; /* used by isoc handler */ 249 248 char vmirror; /* for ToUCaM series */ ··· 364 365 /** Functions in pwc-ctrl.c */ 365 366 /* Request a certain video mode. Returns < 0 if not possible */ 366 367 extern int pwc_set_video_mode(struct pwc_device *pdev, int width, int height, 367 - int frames, int compression); 368 + int frames, int *compression); 368 369 extern unsigned int pwc_get_fps(struct pwc_device *pdev, unsigned int index, unsigned int size); 369 370 extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value); 370 371 extern int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor);