usbcam_buf.c (18729B)
1 /* 2 * USBCAM abstraction library for USB webcam drivers 3 * 4 * Copyright (c) 2007 Sam Revitch <samr7 cs washington edu> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include "usbcam_priv.h" 22 23 /* 24 * This file contains videobuf frame buffer interface routines, and 25 * current frame access functions. 26 */ 27 28 /* 29 * APPBUG: Some applications expect VIDIOCGMBUF to provide a buffer 30 * large enough to accommodate whatever image format they choose in the 31 * future. We enable fixed size buffer mode from VIDIOCGMBUF, and 32 * disable it from VIDIOC_REQBUFS. 33 */ 34 static int fixed_fbsize = 1024 * 1024; 35 module_param(fixed_fbsize, int, S_IRUGO|S_IWUSR); 36 MODULE_PARM_DESC(fixed_fbsize, "Size in bytes of fixed-length framebuffers"); 37 38 /* 39 * naresh <cyan_00391@yahoo.co.in> 40 * Define the various codes to permit compilation of this on 41 * 2.6.25 and higher kernels, we use gcc preprocessors for backward 42 * compatibility 43 * CREDITS: Thanks to stefano.brivio for his patch. 44 * Refer bug @ http://bugs.mediati.org/r5u870/issue2 45 */ 46 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) 47 #define STATE_ACTIVE VIDEOBUF_ACTIVE 48 #define STATE_DONE VIDEOBUF_DONE 49 #define STATE_ERROR VIDEOBUF_ERROR 50 #define STATE_NEEDS_INIT VIDEOBUF_NEEDS_INIT 51 #define STATE_PREPARED VIDEOBUF_PREPARED 52 #endif 53 54 /* 55 * Frame capture handling helpers follow 56 */ 57 58 static inline struct usbcam_frame * 59 usbcam_capture_curframe(struct usbcam_dev *udp) 60 { 61 return list_empty(&udp->ud_frame_cap_queue) 62 ? NULL 63 : list_entry(udp->ud_frame_cap_queue.next, 64 struct usbcam_frame, cap_links); 65 } 66 67 static void usbcam_capture_abortall(struct usbcam_dev *udp) 68 { 69 struct usbcam_frame *framep; 70 71 /* Abort all frames on the capture queue */ 72 while (1) { 73 framep = usbcam_capture_curframe(udp); 74 if (!framep) 75 break; 76 usbcam_dbg(udp, VIDEOBUF, "completing frame %d STATE_ERROR", 77 framep->vbb.i); 78 list_del_init(&framep->cap_links); 79 framep->vbb.state = STATE_ERROR; 80 wake_up_all(&framep->vbb.done); 81 } 82 } 83 84 static inline void usbcam_capture_complete_frame(struct usbcam_dev *udp, 85 struct usbcam_frame *framep, 86 int is_error) 87 { 88 usbcam_chklock(udp); 89 usbcam_dbg(udp, VIDEOBUF, "completing frame %d/%p %s", framep->vbb.i, 90 framep, is_error ? "STATE_ERROR" : "STATE_DONE"); 91 list_del_init(&framep->cap_links); 92 framep->vbb.state = is_error ? STATE_ERROR : STATE_DONE; 93 wake_up_all(&framep->vbb.done); 94 } 95 96 static int usbcam_capture_start(struct usbcam_dev *udp) 97 { 98 int res; 99 100 if (udp->ud_capturing) { 101 usbcam_warn(udp, "%s: already capturing", __FUNCTION__); 102 return 0; 103 } 104 105 if (list_empty(&udp->ud_frame_cap_queue)) { 106 usbcam_warn(udp, "%s: no frames queued to capture", 107 __FUNCTION__); 108 return -ENOENT; 109 } 110 111 if (udp->ud_disconnected) { 112 /* 113 * We can't let any frames through if the device has 114 * been disconnected 115 */ 116 usbcam_capture_abortall(udp); 117 return -ENODEV; 118 } 119 120 usbcam_dbg(udp, CAPTURE, "invoking minidriver cap_start"); 121 122 res = usbcam_minidrv_op(udp, cap_start); 123 if (res) { 124 usbcam_dbg(udp, CAPTURE, 125 "%s: could not start capture for %s: %d", 126 __FUNCTION__, usbcam_drvname(udp->ud_minidrv), res); 127 128 if (udp->ud_capturing) { 129 usbcam_warn(udp, 130 "%s: minidriver left ud_capturing set\n", 131 __FUNCTION__); 132 } 133 134 usbcam_capture_abortall(udp); 135 return res; 136 } 137 138 if (!udp->ud_capturing && usbcam_capture_curframe(udp)) { 139 usbcam_warn(udp, "%s: minidriver failed to set ud_capturing!", 140 __FUNCTION__); 141 } else { 142 usbcam_dbg(udp, CAPTURE, "minidriver capture started"); 143 } 144 145 return 0; 146 } 147 148 void usbcam_capture_stop(struct usbcam_dev *udp) 149 { 150 if (udp->ud_capturing) { 151 usbcam_dbg(udp, CAPTURE, "invoking minidriver cap_stop"); 152 usbcam_minidrv_op(udp, cap_stop); 153 154 if (udp->ud_capturing) { 155 usbcam_warn(udp, "%s: minidriver failed to clear " 156 "ud_capturing!", __FUNCTION__); 157 } else { 158 usbcam_dbg(udp, CAPTURE, "minidriver capture stopped"); 159 } 160 } 161 } 162 163 static inline struct videobuf_dmabuf* usbframe_get_dmabuf(struct videobuf_buffer *buf) 164 { 165 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 166 return &buf->dma; 167 #else 168 return videobuf_to_dma(buf); 169 #endif 170 } 171 172 /* 173 * External APIs for minidriver access to the frame queue 174 */ 175 176 int usbcam_curframe_get(struct usbcam_dev *udp, struct usbcam_curframe *cf) 177 { 178 struct usbcam_frame *framep = usbcam_capture_curframe(udp); 179 struct videobuf_dmabuf *dma; 180 181 usbcam_chklock(udp); 182 183 if (!framep) 184 return -ENOENT; 185 186 dma = usbframe_get_dmabuf(&framep->vbb); 187 188 cf->uf_base = (u8 *) (framep->vmap_sof 189 ? framep->vmap_sof 190 : dma->vmalloc); 191 cf->uf_size = framep->vbb.size; 192 cf->uf_field = framep->vbb.field; 193 memset(&cf->uf_timestamp, 0, sizeof(cf->uf_timestamp)); 194 195 return 0; 196 } 197 USBCAM_EXPORT_SYMBOL(usbcam_curframe_get); 198 199 void usbcam_curframe_complete_detail(struct usbcam_dev *udp, 200 struct usbcam_curframe *cf) 201 { 202 struct usbcam_frame *framep; 203 204 usbcam_chklock(udp); 205 206 framep = usbcam_capture_curframe(udp); 207 if (!framep) { 208 usbcam_warn(udp, "%s: no current frame!", __FUNCTION__); 209 return; 210 } 211 212 if (framep->vbb.state != STATE_ACTIVE) { 213 usbcam_err(udp, "%s: current frame is in unexpected state %d", 214 __FUNCTION__, framep->vbb.state); 215 } 216 217 if (cf) { 218 framep->vbb.size = cf->uf_size; 219 framep->vbb.field = cf->uf_field; 220 framep->vbb.ts = cf->uf_timestamp; 221 222 if (framep->vbb.bsize < cf->uf_size) { 223 usbcam_warn(udp, "%s: minidriver supplied " 224 "excessive size %zu", 225 __FUNCTION__, cf->uf_size); 226 framep->vbb.size = framep->vbb.bsize; 227 } 228 } 229 230 usbcam_capture_complete_frame(udp, framep, 0); 231 } 232 USBCAM_EXPORT_SYMBOL(usbcam_curframe_complete_detail); 233 234 void usbcam_curframe_abortall(struct usbcam_dev *udp) 235 { 236 usbcam_dbg(udp, CAPTURE, "minidriver aborting all frames"); 237 238 usbcam_chklock(udp); 239 240 if (udp->ud_capturing) { 241 usbcam_warn(udp, "%s: minidriver left ud_capturing set", 242 __FUNCTION__); 243 } 244 usbcam_capture_abortall(udp); 245 } 246 USBCAM_EXPORT_SYMBOL(usbcam_curframe_abortall); 247 248 249 /* 250 * Test pattern code 251 */ 252 253 void usbcam_curframe_fill(struct usbcam_dev *udp, size_t offset, 254 const void *pattern, int patlen, int nrecs) 255 { 256 struct usbcam_curframe cf; 257 size_t end; 258 259 usbcam_chklock(udp); 260 261 if (usbcam_curframe_get(udp, &cf)) { 262 usbcam_warn(udp, "%s: no current frame", __FUNCTION__); 263 return; 264 } 265 266 end = offset + (patlen * nrecs); 267 if (end > cf.uf_size) { 268 usbcam_warn(udp, "%s(offs=%zu patlen=%d nrecs=%d) would " 269 "write past end of %zu byte framebuffer", 270 __FUNCTION__, 271 offset, patlen, nrecs, cf.uf_size); 272 if (offset > cf.uf_size) 273 nrecs = 0; 274 else 275 nrecs = (cf.uf_size - offset) / patlen; 276 } 277 else if (end > udp->ud_format.sizeimage) 278 usbcam_warn(udp, "%s(offs=%zu patlen=%d nrecs=%d) writing " 279 "beyond %u-byte sizeimage", __FUNCTION__, 280 offset, patlen, nrecs, udp->ud_format.sizeimage); 281 282 if (!nrecs) 283 return; 284 285 if (patlen == 1) { 286 memset(cf.uf_base + offset, *(char *)pattern, nrecs); 287 return; 288 } 289 290 while (nrecs--) { 291 memcpy(cf.uf_base + offset, pattern, patlen); 292 offset += patlen; 293 } 294 } 295 USBCAM_EXPORT_SYMBOL(usbcam_curframe_fill); 296 297 void usbcam_curframe_fill_lines(struct usbcam_dev *udp, 298 const char *pat, int patlen, 299 int pixperpat) 300 { 301 int line, nrecperline, stride; 302 size_t offset = 0; 303 304 nrecperline = (udp->ud_format.width + pixperpat - 1) / pixperpat; 305 stride = udp->ud_format.bytesperline 306 ? udp->ud_format.bytesperline 307 : (nrecperline * patlen); 308 309 if ((patlen * nrecperline) == stride) { 310 usbcam_curframe_fill(udp, 0, pat, patlen, 311 nrecperline * udp->ud_format.height); 312 return; 313 } 314 315 for (line = 0; line < udp->ud_format.height; line++) { 316 usbcam_curframe_fill(udp, offset, pat, patlen, nrecperline); 317 offset += stride; 318 } 319 } 320 321 void usbcam_curframe_fill_interleaved(struct usbcam_dev *udp, 322 const char *pat_even, 323 const char *pat_odd, 324 int patlen, int pixperpat) 325 { 326 int line, nrecperline, stride; 327 size_t offset = 0; 328 329 nrecperline = (udp->ud_format.width + pixperpat - 1) / pixperpat; 330 stride = udp->ud_format.bytesperline 331 ? udp->ud_format.bytesperline 332 : (nrecperline * patlen); 333 334 for (line = 0; line < udp->ud_format.height; line++) { 335 usbcam_curframe_fill(udp, offset, 336 (line & 1) ? pat_odd : pat_even, 337 patlen, nrecperline); 338 offset += stride; 339 } 340 } 341 342 void usbcam_curframe_fill_planar(struct usbcam_dev *udp, 343 const char *pat0, int pat0len, int pixperpat0, 344 const char *pat1, int pat1len, int pixperpat1, 345 const char *pat2, int pat2len, int pixperpat2) 346 { 347 int nrecperline; 348 size_t offset = 0; 349 350 if (pat0 && pat0len) { 351 nrecperline = ((udp->ud_format.width + pixperpat0 - 1) / 352 pixperpat0); 353 usbcam_curframe_fill(udp, offset, pat0, pat0len, 354 nrecperline * udp->ud_format.height); 355 offset += (nrecperline * udp->ud_format.height * pat0len); 356 } 357 if (pat1 && pat1len) { 358 nrecperline = ((udp->ud_format.width + pixperpat1 - 1) / 359 pixperpat1); 360 usbcam_curframe_fill(udp, offset, pat1, pat1len, 361 nrecperline * udp->ud_format.height); 362 offset += (nrecperline * udp->ud_format.height * pat1len); 363 } 364 if (pat2 && pat2len) { 365 nrecperline = ((udp->ud_format.width + pixperpat2 - 1) / 366 pixperpat2); 367 usbcam_curframe_fill(udp, offset, pat2, pat2len, 368 nrecperline * udp->ud_format.height); 369 offset += (nrecperline * udp->ud_format.height * pat2len); 370 } 371 } 372 373 /* 374 * The goal is to be able to come up with a solid blue image in all 375 * basic uncompressed formats. No JPEG or compressed formats, at least 376 * not yet. 377 */ 378 int usbcam_curframe_testpattern(struct usbcam_dev *udp) 379 { 380 usbcam_chklock(udp); 381 382 #define DO_FILL(PIXPERPAT, TP...) { \ 383 const char tp[] = {TP}; \ 384 usbcam_curframe_fill_lines(udp, tp, sizeof(tp), PIXPERPAT); \ 385 } 386 switch (udp->ud_format.pixelformat) { 387 case V4L2_PIX_FMT_RGB332: 388 DO_FILL(1, 0x03) 389 return 0; 390 case V4L2_PIX_FMT_RGB555: 391 case V4L2_PIX_FMT_RGB565: 392 DO_FILL(1, 0x1f, 0x00) 393 return 0; 394 case V4L2_PIX_FMT_RGB555X: 395 case V4L2_PIX_FMT_RGB565X: 396 DO_FILL(1, 0x00, 0x1f) 397 return 0; 398 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) 399 case V4L2_PIX_FMT_RGB444: 400 DO_FILL(1, 0x00, 0x0f) 401 return 0; 402 #endif 403 case V4L2_PIX_FMT_BGR24: 404 DO_FILL(1, 0xff, 0x00, 0x00); 405 return 0; 406 case V4L2_PIX_FMT_RGB24: 407 DO_FILL(1, 0x00, 0x00, 0xff); 408 return 0; 409 case V4L2_PIX_FMT_BGR32: 410 DO_FILL(1, 0xff, 0x00, 0x00, 0x00); 411 return 0; 412 case V4L2_PIX_FMT_RGB32: 413 DO_FILL(1, 0x00, 0x00, 0xff, 0x00); 414 return 0; 415 case V4L2_PIX_FMT_GREY: 416 DO_FILL(1, 0x1f); 417 return 0; 418 case V4L2_PIX_FMT_YUYV: 419 DO_FILL(2, 0x29, 0xf0, 0x29, 0x6e); 420 return 0; 421 case V4L2_PIX_FMT_UYVY: 422 DO_FILL(2, 0xf0, 0x29, 0x6e, 0x29); 423 return 0; 424 case V4L2_PIX_FMT_YYUV: 425 DO_FILL(2, 0x29, 0x29, 0xf0, 0x6e); 426 return 0; 427 case V4L2_PIX_FMT_Y41P: 428 DO_FILL(8, 429 0xf0, 0x29, 0x6e, 0x29, 0xf0, 0x29, 0x6e, 0x29, 430 0x29, 0x29, 0x29, 0x29); 431 return 0; 432 #undef DO_FILL 433 434 case V4L2_PIX_FMT_SBGGR8: { 435 const char tp0[] = { 0xff, 0x00 }, tp1[] = { 0x00, 0x00 }; 436 usbcam_curframe_fill_interleaved(udp, tp0, tp1, 2, 2); 437 return 0; 438 } 439 case V4L2_PIX_FMT_YVU410: { 440 const char tp0[] = {0x29}, tp1[] = {0x6e}, tp2[] = {0xf0}; 441 usbcam_curframe_fill_planar(udp, tp0, sizeof(tp0), 1, 442 tp1, sizeof(tp1), 16, 443 tp2, sizeof(tp2), 16); 444 return 0; 445 } 446 case V4L2_PIX_FMT_YUV410: { 447 const char tp0[] = {0x29}, tp1[] = {0xf0}, tp2[] = {0x6e}; 448 usbcam_curframe_fill_planar(udp, tp0, sizeof(tp0), 1, 449 tp1, sizeof(tp1), 16, 450 tp2, sizeof(tp2), 16); 451 return 0; 452 } 453 case V4L2_PIX_FMT_YVU420: { 454 const char tp0[] = {0x29}, tp1[] = {0x6e}, tp2[] = {0xf0}; 455 usbcam_curframe_fill_planar(udp, tp0, sizeof(tp0), 1, 456 tp1, sizeof(tp1), 4, 457 tp2, sizeof(tp2), 4); 458 return 0; 459 } 460 case V4L2_PIX_FMT_YUV411P: 461 case V4L2_PIX_FMT_YUV420: { 462 const char tp0[] = {0x29}, tp1[] = {0xf0}, tp2[] = {0x6e}; 463 usbcam_curframe_fill_planar(udp, tp0, sizeof(tp0), 1, 464 tp1, sizeof(tp1), 4, 465 tp2, sizeof(tp2), 4); 466 return 0; 467 } 468 case V4L2_PIX_FMT_YUV422P: { 469 const char tp0[] = {0x29}, tp1[] = {0xf0}, tp2[] = {0x6e}; 470 usbcam_curframe_fill_planar(udp, tp0, sizeof(tp0), 1, 471 tp1, sizeof(tp1), 2, 472 tp2, sizeof(tp2), 2); 473 return 0; 474 } 475 case V4L2_PIX_FMT_NV12: { 476 const char tp0[] = {0x29}, tp1[] = {0xf0, 0x6e}; 477 usbcam_curframe_fill_planar(udp, tp0, sizeof(tp0), 1, 478 tp1, sizeof(tp1), 4, 479 NULL, 0, 0); 480 return 0; 481 } 482 case V4L2_PIX_FMT_NV21: { 483 const char tp0[] = {0x29}, tp1[] = {0x6e, 0xf0}; 484 usbcam_curframe_fill_planar(udp, tp0, sizeof(tp0), 1, 485 tp1, sizeof(tp1), 4, 486 NULL, 0, 0); 487 return 0; 488 } 489 } 490 491 return -EINVAL; 492 } 493 USBCAM_EXPORT_SYMBOL(usbcam_curframe_testpattern); 494 495 496 /* 497 * video-buf interfaces for managing frame buffers 498 * The device mutex is not held on entry to _any_ of these functions. 499 */ 500 501 static int usbcam_videobuf_setup(struct videobuf_queue *vq, 502 unsigned int *count, unsigned int *size) 503 { 504 struct usbcam_fh *ufp = container_of(vq, struct usbcam_fh, ufh_vbq); 505 struct usbcam_dev *udp = ufp->ufh_dev; 506 507 usbcam_lock(udp); 508 509 /* APPBUG: possibly request larger buffers than necessary */ 510 if ((ufp->ufh_flags & USBCAM_FH_USE_FIXED_FB) && 511 (fixed_fbsize > udp->ud_format.sizeimage)) 512 *size = fixed_fbsize; 513 else 514 *size = udp->ud_format.sizeimage; 515 516 if (!*count) 517 *count = 2; 518 519 usbcam_dbg(udp, VIDEOBUF, "videobuf setup: size=%u count=%u", 520 *size, *count); 521 522 usbcam_unlock(udp); 523 return 0; 524 } 525 526 static void usbcam_videobuf_free(struct videobuf_queue *vq, 527 struct usbcam_frame *framep) 528 { 529 struct videobuf_dmabuf *dma = usbframe_get_dmabuf(&framep->vbb); 530 531 videobuf_waiton(&framep->vbb, 0, 0); 532 videobuf_dma_unmap(vq, dma); 533 videobuf_dma_free(dma); 534 if (framep->vbb.state != STATE_NEEDS_INIT) { 535 if (framep->vmap_base) { 536 vunmap(framep->vmap_base); 537 framep->vmap_base = NULL; 538 framep->vmap_sof = NULL; 539 } 540 assert(list_empty(&framep->cap_links)); 541 framep->vbb.state = STATE_NEEDS_INIT; 542 } 543 } 544 545 static int usbcam_videobuf_prepare(struct videobuf_queue *vq, 546 struct videobuf_buffer *vb, 547 enum v4l2_field field) 548 { 549 struct usbcam_fh *ufp = container_of(vq, struct usbcam_fh, ufh_vbq); 550 struct usbcam_dev *udp = ufp->ufh_dev; 551 struct usbcam_frame *framep = 552 container_of(vb, struct usbcam_frame, vbb); 553 struct videobuf_dmabuf *dma = usbframe_get_dmabuf(&framep->vbb); 554 int res; 555 556 framep->vbb.size = udp->ud_format.sizeimage; 557 if (framep->vbb.baddr && (framep->vbb.bsize < framep->vbb.size)) { 558 usbcam_warn(udp, "process %s requested capture of a frame " 559 "larger than its", current->comm); 560 usbcam_warn(udp, "allocated frame buffer, fix it!"); 561 return -EINVAL; 562 } 563 564 if (framep->vbb.state == STATE_NEEDS_INIT) { 565 /* 566 * This is the place where we initialize the rest of 567 * the usbcam_frame structure. 568 */ 569 INIT_LIST_HEAD(&framep->cap_links); 570 framep->vmap_base = NULL; 571 framep->vmap_sof = NULL; 572 573 usbcam_dbg(udp, VIDEOBUF, 574 "preparing frame %d/%p", framep->vbb.i, framep); 575 576 /* We also lock down the memory that was allocated for it */ 577 res = videobuf_iolock(vq, &framep->vbb, NULL); 578 if (res) 579 goto fail; 580 581 /* If there's no kernel mapping, we must create one */ 582 if (!dma->vmalloc) { 583 framep->vmap_base = vmap(dma->pages, 584 dma->nr_pages, 585 VM_MAP, 586 PAGE_KERNEL); 587 if (!framep->vmap_base) { 588 res = -ENOMEM; 589 goto fail; 590 } 591 592 framep->vmap_sof = 593 ((char *)framep->vmap_base) + 594 dma->offset; 595 } 596 } 597 598 framep->vbb.field = field; 599 framep->vbb.state = STATE_PREPARED; 600 return 0; 601 602 fail: 603 usbcam_videobuf_free(vq, framep); 604 return res; 605 } 606 607 static void usbcam_videobuf_queue(struct videobuf_queue *vq, 608 struct videobuf_buffer *vb) 609 { 610 struct usbcam_fh *ufp = container_of(vq, struct usbcam_fh, ufh_vbq); 611 struct usbcam_dev *udp = ufp->ufh_dev; 612 struct usbcam_frame *framep = 613 container_of(vb, struct usbcam_frame, vbb); 614 int was_empty = 0; 615 616 assert(framep->vbb.state != STATE_NEEDS_INIT); 617 618 usbcam_lock(udp); 619 620 if (list_empty(&udp->ud_frame_cap_queue)) 621 was_empty = 1; 622 623 usbcam_dbg(udp, VIDEOBUF, "queueing frame %d/%p", 624 framep->vbb.i, framep); 625 626 /* 627 * We always set buffers to STATE_ACTIVE to prevent them from 628 * being manipulated / dequeued by the videobuf code. 629 */ 630 list_add_tail(&framep->cap_links, &udp->ud_frame_cap_queue); 631 framep->vbb.state = STATE_ACTIVE; 632 633 if (was_empty && !udp->ud_capturing) 634 (void) usbcam_capture_start(udp); 635 636 usbcam_unlock(udp); 637 } 638 639 static void usbcam_videobuf_release(struct videobuf_queue *vq, 640 struct videobuf_buffer *vb) 641 { 642 struct usbcam_fh *ufp = container_of(vq, struct usbcam_fh, ufh_vbq); 643 struct usbcam_dev *udp = ufp->ufh_dev; 644 struct usbcam_frame *framep = 645 container_of(vb, struct usbcam_frame, vbb); 646 int stopped_capture = 0; 647 648 usbcam_lock(udp); 649 650 if ((framep->vbb.state != STATE_NEEDS_INIT) && 651 !list_empty(&framep->cap_links)) { 652 653 usbcam_dbg(udp, VIDEOBUF, 654 "aborting frame %d/%p", framep->vbb.i, framep); 655 656 /* 657 * An active frame is being shot down here, most 658 * likely by videobuf_queue_cancel. 659 */ 660 assert(framep->vbb.state == STATE_ACTIVE); 661 662 if (udp->ud_capturing && 663 !list_empty(&udp->ud_frame_cap_queue) && 664 (framep == usbcam_capture_curframe(udp))) { 665 /* 666 * The current frame has been user-aborted. 667 * We will stop capturing. The minidriver may complete 668 * it with an error, or may leave it alone, in which 669 * case we will complete it with an error. 670 */ 671 usbcam_dbg(udp, VIDEOBUF, 672 "current frame aborted, stopping capture"); 673 674 usbcam_capture_stop(udp); 675 stopped_capture = 1; 676 } 677 678 if (!list_empty(&framep->cap_links)) 679 usbcam_capture_complete_frame(udp, framep, 1); 680 681 /* 682 * Ideally, if we stopped capturing, and there are frames 683 * still in the queue, we would restart. 684 * 685 * In reality, we only take this code path if all frames 686 * from the owning file handle are aborted, and restarting 687 * would pointlessly slow down this process. 688 */ 689 } 690 691 usbcam_unlock(udp); 692 usbcam_videobuf_free(vq, framep); 693 } 694 695 struct videobuf_queue_ops usbcam_videobuf_qops = { 696 .buf_setup = usbcam_videobuf_setup, 697 .buf_prepare = usbcam_videobuf_prepare, 698 .buf_queue = usbcam_videobuf_queue, 699 .buf_release = usbcam_videobuf_release, 700 };