aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/usbvision
diff options
context:
space:
mode:
authorThierry MERLE <thierry.merle@free.fr>2006-12-04 06:31:21 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-10 06:05:47 -0500
commit3084920b555b3ba73590430b2e03d9167db23e8e (patch)
tree005fcfefe5cb8edb6bf08c16ff35d1fb8aa268d0 /drivers/media/video/usbvision
parent5f7fb877be14da92803f0b5b60955e071ebe2d58 (diff)
V4L/DVB (4929): Read() implementation + format set/get simplifications
- implement read() entry point that works with linux list.h - rework of VIDIOC_ENUM_FMT/VIDIOC_S_FMT/VIDIOC_G_FMT - VIDIOC_STREAMON : allows streaming whereas there is no queued buffer (xdtv does VIDIOC_STREAMON before VIDIOC_QBUFs) Signed-off-by: Thierry MERLE <thierry.merle@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/usbvision')
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c323
1 files changed, 167 insertions, 156 deletions
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 5a61ed728b35..3833f3fbbdf0 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -409,7 +409,8 @@
409 409
410 410
411static int usbvision_nr = 0; // sequential number of usbvision device 411static int usbvision_nr = 0; // sequential number of usbvision device
412 412static unsigned long usbvision_timestamp = 0; // timestamp in jiffies of a hundred frame
413static unsigned long usbvision_counter = 0; // frame counter
413 414
414static const int max_imgwidth = MAX_FRAME_WIDTH; 415static const int max_imgwidth = MAX_FRAME_WIDTH;
415static const int max_imgheight = MAX_FRAME_HEIGHT; 416static const int max_imgheight = MAX_FRAME_HEIGHT;
@@ -4278,6 +4279,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
4278 list_add_tail(&usbvision->frame[vb->index].frame, &usbvision->inqueue); 4279 list_add_tail(&usbvision->frame[vb->index].frame, &usbvision->inqueue);
4279 spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); 4280 spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
4280 4281
4282 PDEBUG(DBG_IOCTL, "VIDIOC_QBUF frame #%d",vb->index);
4281 return 0; 4283 return 0;
4282 } 4284 }
4283 case VIDIOC_DQBUF: 4285 case VIDIOC_DQBUF:
@@ -4312,18 +4314,31 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
4312 vb->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE; 4314 vb->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE;
4313 vb->index = f->index; 4315 vb->index = f->index;
4314 vb->sequence = f->sequence; 4316 vb->sequence = f->sequence;
4317 vb->timestamp = f->timestamp;
4318 vb->field = V4L2_FIELD_NONE;
4319 vb->bytesused = f->scanlength;
4315 4320
4321 if(debug & DBG_IOCTL) { // do not spend computing time for debug stuff if not needed !
4322 if(usbvision_counter == 100) {
4323 PDEBUG(DBG_IOCTL, "VIDIOC_DQBUF delta=%d",(unsigned)(jiffies-usbvision_timestamp));
4324 usbvision_counter = 0;
4325 usbvision_timestamp = jiffies;
4326 }
4327 else {
4328 usbvision_counter++;
4329 }
4330 PDEBUG(DBG_IOCTL, "VIDIOC_DQBUF frame #%d",vb->index);
4331 }
4316 return 0; 4332 return 0;
4317 } 4333 }
4318 case VIDIOC_STREAMON: 4334 case VIDIOC_STREAMON:
4319 { 4335 {
4320 int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; 4336 int b=V4L2_BUF_TYPE_VIDEO_CAPTURE;
4321 4337
4322 if (list_empty(&usbvision->inqueue))
4323 return -EINVAL;
4324
4325 usbvision->streaming = Stream_On; 4338 usbvision->streaming = Stream_On;
4326 4339
4340 if(debug & DBG_IOCTL) usbvision_timestamp = jiffies;
4341
4327 call_i2c_clients(usbvision,VIDIOC_STREAMON , &b); 4342 call_i2c_clients(usbvision,VIDIOC_STREAMON , &b);
4328 4343
4329 PDEBUG(DBG_IOCTL, "VIDIOC_STREAMON"); 4344 PDEBUG(DBG_IOCTL, "VIDIOC_STREAMON");
@@ -4412,134 +4427,132 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file,
4412 { 4427 {
4413 struct v4l2_fmtdesc *vfd = arg; 4428 struct v4l2_fmtdesc *vfd = arg;
4414 4429
4415 if ( (dga == 0) &&
4416 (vfd->type == V4L2_BUF_TYPE_VIDEO_OVERLAY) &&
4417 (usbvision->palette.format != V4L2_PIX_FMT_YVU420) &&
4418 (usbvision->palette.format != V4L2_PIX_FMT_YUV422P) ) {
4419 return -EINVAL;
4420 }
4421 if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) { 4430 if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) {
4422 return -EINVAL; 4431 return -EINVAL;
4423 } 4432 }
4424 vfd->flags = 0; 4433 vfd->flags = 0;
4434 vfd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4425 strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc); 4435 strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc);
4426 vfd->pixelformat = usbvision_v4l2_format[vfd->index].format; 4436 vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
4437 memset(vfd->reserved, 0, sizeof(vfd->reserved));
4427 return 0; 4438 return 0;
4428 } 4439 }
4429 case VIDIOC_G_FMT: 4440 case VIDIOC_G_FMT:
4430 { 4441 {
4431 struct v4l2_format *vf = arg; 4442 struct v4l2_format *vf = arg;
4432 4443
4433 if ( (dga == 0) && 4444 switch (vf->type) {
4434 (vf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY) && 4445 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
4435 (usbvision->palette.format != V4L2_PIX_FMT_YVU420) && 4446 {
4436 (usbvision->palette.format != V4L2_PIX_FMT_YUV422P) ) { 4447 vf->fmt.pix.width = usbvision->curwidth;
4437 return -EINVAL; 4448 vf->fmt.pix.height = usbvision->curheight;
4449 vf->fmt.pix.pixelformat = usbvision->palette.format;
4450 vf->fmt.pix.bytesperline = usbvision->curwidth*usbvision->palette.bytes_per_pixel;
4451 vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*usbvision->curheight;
4452 vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
4453 vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */
4454 }
4455 return 0;
4456 default:
4457 PDEBUG(DBG_IOCTL, "VIDIOC_G_FMT invalid type %d",vf->type);
4458 return -EINVAL;
4438 } 4459 }
4439 down(&usbvision->lock); 4460 PDEBUG(DBG_IOCTL, "VIDIOC_G_FMT w=%d, h=%d",vf->fmt.win.w.width, vf->fmt.win.w.height);
4440 *vf = usbvision->vid_win;
4441 up(&usbvision->lock);
4442 PDEBUG(DBG_IOCTL, "VIDIOC_G_FMT x=%d, y=%d, w=%d, h=%d, chroma=%x, clips=%d",
4443 vf->fmt.win.w.left, vf->fmt.win.w.top, vf->fmt.win.w.width, vf->fmt.win.w.height, vf->fmt.win.chromakey, vf->fmt.win.clipcount);
4444 return 0; 4461 return 0;
4445 } 4462 }
4463 case VIDIOC_TRY_FMT:
4446 case VIDIOC_S_FMT: 4464 case VIDIOC_S_FMT:
4447 { 4465 {
4448 struct v4l2_format *vf = arg; 4466 struct v4l2_format *vf = arg;
4449 struct v4l2_clip *vc=NULL; 4467 struct v4l2_clip *vc=NULL;
4450 int on,formatIdx; 4468 int on,formatIdx;
4451 4469
4452 if ( (dga == 0) && 4470 switch(vf->type) {
4453 (vf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY) && 4471 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
4454 (usbvision->palette.format != V4L2_PIX_FMT_YVU420) && 4472 {
4455 (usbvision->palette.format != V4L2_PIX_FMT_YUV422P) ) { 4473 if (vf->fmt.win.clipcount>256) {
4456 return -EINVAL; 4474 return -EDOM; /* Too many clips! */
4457 } 4475 }
4458 if(vf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY) { 4476 // Do every clips.
4459 if (vf->fmt.win.clipcount>256) { 4477 vc = vmalloc(sizeof(struct v4l2_clip)*(vf->fmt.win.clipcount+4));
4460 return -EDOM; /* Too many clips! */ 4478 if (vc == NULL) {
4461 } 4479 return -ENOMEM;
4462 // Do every clips. 4480 }
4463 vc = vmalloc(sizeof(struct v4l2_clip)*(vf->fmt.win.clipcount+4)); 4481 if (vf->fmt.win.clipcount && copy_from_user(vc,vf->fmt.win.clips,sizeof(struct v4l2_clip)*vf->fmt.win.clipcount)) {
4464 if (vc == NULL) { 4482 return -EFAULT;
4465 return -ENOMEM; 4483 }
4466 } 4484 on = usbvision->overlay; // Save overlay state
4467 if (vf->fmt.win.clipcount && copy_from_user(vc,vf->fmt.win.clips,sizeof(struct v4l2_clip)*vf->fmt.win.clipcount)) { 4485 if (on) {
4468 return -EFAULT; 4486 usbvision_cap(usbvision, 0);
4469 } 4487 }
4470 on = usbvision->overlay; // Save overlay state
4471 if (on) {
4472 usbvision_cap(usbvision, 0);
4473 }
4474 4488
4475 // strange, it seems xawtv sometimes calls us with 0 4489 // strange, it seems xawtv sometimes calls us with 0
4476 // width and/or height. Ignore these values 4490 // width and/or height. Ignore these values
4477 if (vf->fmt.win.w.left == 0) { 4491 if (vf->fmt.win.w.left == 0) {
4478 vf->fmt.win.w.left = usbvision->vid_win.fmt.win.w.left; 4492 vf->fmt.win.w.left = usbvision->vid_win.fmt.win.w.left;
4479 } 4493 }
4480 if (vf->fmt.win.w.top == 0) { 4494 if (vf->fmt.win.w.top == 0) {
4481 vf->fmt.win.w.top = usbvision->vid_win.fmt.win.w.top; 4495 vf->fmt.win.w.top = usbvision->vid_win.fmt.win.w.top;
4482 } 4496 }
4483 4497
4484 // by now we are committed to the new data... 4498 // by now we are committed to the new data...
4485 down(&usbvision->lock); 4499 down(&usbvision->lock);
4486 RESTRICT_TO_RANGE(vf->fmt.win.w.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH); 4500 RESTRICT_TO_RANGE(vf->fmt.win.w.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
4487 RESTRICT_TO_RANGE(vf->fmt.win.w.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT); 4501 RESTRICT_TO_RANGE(vf->fmt.win.w.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
4488 usbvision->vid_win = *vf; 4502 usbvision->vid_win = *vf;
4489 usbvision->overlay_frame.width = vf->fmt.win.w.width; 4503 usbvision->overlay_frame.width = vf->fmt.win.w.width;
4490 usbvision->overlay_frame.height = vf->fmt.win.w.height; 4504 usbvision->overlay_frame.height = vf->fmt.win.w.height;
4491 usbvision_set_output(usbvision, vf->fmt.win.w.width, vf->fmt.win.w.height); 4505 usbvision_set_output(usbvision, vf->fmt.win.w.width, vf->fmt.win.w.height);
4492 up(&usbvision->lock); 4506 up(&usbvision->lock);
4493 4507
4494 // Impose display clips 4508 // Impose display clips
4495 if (vf->fmt.win.w.left+vf->fmt.win.w.width > (unsigned int)usbvision->vid_buf.fmt.width) { 4509 if (vf->fmt.win.w.left+vf->fmt.win.w.width > (unsigned int)usbvision->vid_buf.fmt.width) {
4496 usbvision_new_clip(vf, vc, usbvision->vid_buf.fmt.width-vf->fmt.win.w.left, 0, vf->fmt.win.w.width-1, vf->fmt.win.w.height-1); 4510 usbvision_new_clip(vf, vc, usbvision->vid_buf.fmt.width-vf->fmt.win.w.left, 0, vf->fmt.win.w.width-1, vf->fmt.win.w.height-1);
4497 } 4511 }
4498 if (vf->fmt.win.w.top+vf->fmt.win.w.height > (unsigned int)usbvision->vid_buf.fmt.height) { 4512 if (vf->fmt.win.w.top+vf->fmt.win.w.height > (unsigned int)usbvision->vid_buf.fmt.height) {
4499 usbvision_new_clip(vf, vc, 0, usbvision->vid_buf.fmt.height-vf->fmt.win.w.top, vf->fmt.win.w.width-1, vf->fmt.win.w.height-1); 4513 usbvision_new_clip(vf, vc, 0, usbvision->vid_buf.fmt.height-vf->fmt.win.w.top, vf->fmt.win.w.width-1, vf->fmt.win.w.height-1);
4500 } 4514 }
4501 4515
4502 // built the requested clipping zones 4516 // built the requested clipping zones
4503 usbvision_built_overlay(usbvision, vf->fmt.win.clipcount, vc); 4517 usbvision_built_overlay(usbvision, vf->fmt.win.clipcount, vc);
4504 vfree(vc); 4518 vfree(vc);
4505 4519
4506 // restore overlay state 4520 // restore overlay state
4507 if (on) { 4521 if (on) {
4508 usbvision_cap(usbvision, 1); 4522 usbvision_cap(usbvision, 1);
4523 }
4524 usbvision->vid_win_valid = 1;
4525 PDEBUG(DBG_IOCTL, "VIDIOC_S_FMT overlay x=%d, y=%d, w=%d, h=%d, chroma=%x, clips=%d",
4526 vf->fmt.win.w.left, vf->fmt.win.w.top, vf->fmt.win.w.width, vf->fmt.win.w.height, vf->fmt.win.chromakey, vf->fmt.win.clipcount);
4527 return 0;
4509 } 4528 }
4510 usbvision->vid_win_valid = 1; 4529 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
4511 PDEBUG(DBG_IOCTL, "VIDIOC_S_FMT overlay x=%d, y=%d, w=%d, h=%d, chroma=%x, clips=%d", 4530 {
4512 vf->fmt.win.w.left, vf->fmt.win.w.top, vf->fmt.win.w.width, vf->fmt.win.w.height, vf->fmt.win.chromakey, vf->fmt.win.clipcount); 4531 /* Find requested format in available ones */
4513 } 4532 for(formatIdx=0;formatIdx<USBVISION_SUPPORTED_PALETTES;formatIdx++) {
4514 else { 4533 if(vf->fmt.pix.pixelformat == usbvision_v4l2_format[formatIdx].format) {
4515 /* Find requested format in available ones */ 4534 usbvision->palette = usbvision_v4l2_format[formatIdx];
4516 for(formatIdx=0;formatIdx<USBVISION_SUPPORTED_PALETTES;formatIdx++) { 4535 break;
4517 if(vf->fmt.pix.pixelformat == usbvision_v4l2_format[formatIdx].format) { 4536 }
4518 usbvision->palette = usbvision_v4l2_format[formatIdx]; 4537 }
4519 break; 4538 /* robustness */
4539 if(formatIdx == USBVISION_SUPPORTED_PALETTES) {
4540 return -EINVAL;
4520 } 4541 }
4542 RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
4543 RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
4544 // by now we are committed to the new data...
4545 down(&usbvision->lock);
4546 usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height);
4547 up(&usbvision->lock);
4548
4549 PDEBUG(DBG_IOCTL, "VIDIOC_S_FMT grabdisplay w=%d, h=%d, format=%s",
4550 vf->fmt.pix.width, vf->fmt.pix.height,usbvision->palette.desc);
4551 return 0;
4521 } 4552 }
4522 /* robustness */ 4553 default:
4523 if(formatIdx == USBVISION_SUPPORTED_PALETTES) {
4524 return -EINVAL; 4554 return -EINVAL;
4525 }
4526 usbvision->vid_win.fmt.pix.pixelformat = vf->fmt.pix.pixelformat;
4527 usbvision->vid_win.fmt.pix.width = vf->fmt.pix.width; //Image width in pixels.
4528 usbvision->vid_win.fmt.pix.height = vf->fmt.pix.height; // Image height in pixels.
4529
4530 // by now we are committed to the new data...
4531 down(&usbvision->lock);
4532 RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
4533 RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
4534 usbvision->vid_win = *vf;
4535 usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height);
4536 up(&usbvision->lock);
4537
4538 usbvision->vid_win_valid = 1;
4539 PDEBUG(DBG_IOCTL, "VIDIOC_S_FMT grabdisplay w=%d, h=%d, ",
4540 vf->fmt.pix.width, vf->fmt.pix.height);
4541 } 4555 }
4542 return 0;
4543 } 4556 }
4544 case VIDIOC_OVERLAY: 4557 case VIDIOC_OVERLAY:
4545 { 4558 {
@@ -4586,99 +4599,97 @@ static ssize_t usbvision_v4l2_read(struct file *file, char *buf,
4586 struct video_device *dev = video_devdata(file); 4599 struct video_device *dev = video_devdata(file);
4587 struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); 4600 struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev);
4588 int noblock = file->f_flags & O_NONBLOCK; 4601 int noblock = file->f_flags & O_NONBLOCK;
4602 unsigned long lock_flags;
4589 4603
4590 int frmx = -1; 4604 int frmx = -1;
4591 int rc = 0; 4605 int ret,i;
4592 struct usbvision_frame *frame; 4606 struct usbvision_frame *frame;
4593return -EINVAL; 4607
4594 PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __FUNCTION__, (unsigned long)count, noblock); 4608 PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __FUNCTION__, (unsigned long)count, noblock);
4595 4609
4596 if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) 4610 if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL))
4597 return -EFAULT; 4611 return -EFAULT;
4598 4612
4599 down(&usbvision->lock); 4613 /* no stream is running, make it running ! */
4600 //code for testing compression 4614 usbvision->streaming = Stream_On;
4601 if (usbvision->isocMode == ISOC_MODE_COMPRESS) { 4615 call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL);
4602 usbvision->frame[0].v4l2_format = usbvision_v4l2_format[0]; //V4L2_PIX_FMT_GREY;
4603 usbvision->frame[1].v4l2_format = usbvision_v4l2_format[0]; // V4L2_PIX_FMT_GREY;
4604 }
4605 4616
4606 // See if a frame is completed, then use it. 4617 /* First, enqueue as many frames as possible (like a user of VIDIOC_QBUF would do) */
4607 if (usbvision->frame[0].grabstate >= FrameState_Done) // _Done or _Error 4618 for(i=0;i<USBVISION_NUMFRAMES;i++) {
4608 frmx = 0; 4619 frame = &usbvision->frame[i];
4609 else if (usbvision->frame[1].grabstate >= FrameState_Done)// _Done or _Error 4620 if(frame->grabstate == FrameState_Unused) {
4610 frmx = 1; 4621 /* Mark it as ready and enqueue frame */
4622 frame->grabstate = FrameState_Ready;
4623 frame->scanstate = ScanState_Scanning;
4624 frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */
4611 4625
4612 if (noblock && (frmx == -1)) { 4626 /* set v4l2_format index */
4613 count = -EAGAIN; 4627 frame->v4l2_format = usbvision->palette;
4614 goto usbvision_v4l2_read_done;
4615 }
4616 4628
4617 // If no FRAME_DONE, look for a FRAME_GRABBING state. 4629 spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
4618 // See if a frame is in process (grabbing), then use it. 4630 list_add_tail(&frame->frame, &usbvision->inqueue);
4619 if (frmx == -1) { 4631 spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
4620 if (usbvision->frame[0].grabstate == FrameState_Grabbing) 4632 }
4621 frmx = 0;
4622 else if (usbvision->frame[1].grabstate == FrameState_Grabbing)
4623 frmx = 1;
4624 } 4633 }
4625 4634
4626 // If no frame is active, start one. 4635 /* Then try to steal a frame (like a VIDIOC_DQBUF would do) */
4627 if (frmx == -1) 4636 if (list_empty(&(usbvision->outqueue))) {
4628 // FIXME: enqueue all inqueue... 4637 if(noblock)
4629 /* usbvision_new_frame(usbvision, frmx = 0); */ 4638 return -EAGAIN;
4630
4631 frame = &usbvision->frame[frmx];
4632 4639
4633 restart: 4640 ret = wait_event_interruptible
4634 if (!USBVISION_IS_OPERATIONAL(usbvision)) { 4641 (usbvision->wait_frame,
4635 count = -EIO; 4642 !list_empty(&(usbvision->outqueue)));
4636 goto usbvision_v4l2_read_done; 4643 if (ret)
4644 return ret;
4637 } 4645 }
4638 PDEBUG(DBG_IO, "Waiting frame grabbing"); 4646
4639 rc = wait_event_interruptible(usbvision->wait_frame, (frame->grabstate == FrameState_Done) || 4647 spin_lock_irqsave(&usbvision->queue_lock, lock_flags);
4640 (frame->grabstate == FrameState_Error)); 4648 frame = list_entry(usbvision->outqueue.next,
4641 if (rc) { 4649 struct usbvision_frame, frame);
4642 goto usbvision_v4l2_read_done; 4650 list_del(usbvision->outqueue.next);
4651 spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags);
4652
4653 if(debug & DBG_IOCTL) { // do not spend computing time for debug stuff if not needed !
4654 if(usbvision_counter == 100) {
4655 PDEBUG(DBG_IOCTL, "VIDIOC_DQBUF delta=%d",(unsigned)(jiffies-usbvision_timestamp));
4656 usbvision_counter = 0;
4657 usbvision_timestamp = jiffies;
4658 }
4659 else {
4660 usbvision_counter++;
4661 }
4643 } 4662 }
4644 4663
4664 /* An error returns an empty frame */
4645 if (frame->grabstate == FrameState_Error) { 4665 if (frame->grabstate == FrameState_Error) {
4646 frame->bytes_read = 0; 4666 frame->bytes_read = 0;
4647 // FIXME: enqueue all inqueue... 4667 return 0;
4648/* if (usbvision_new_frame(usbvision, frmx)) { */
4649/* err("%s: usbvision_new_frame() failed", __FUNCTION__); */
4650/* } */
4651 goto restart;
4652 } 4668 }
4653 4669
4654 PDEBUG(DBG_IO, "%s: frmx=%d, bytes_read=%ld, scanlength=%ld", __FUNCTION__, 4670 PDEBUG(DBG_IO, "%s: frmx=%d, bytes_read=%ld, scanlength=%ld", __FUNCTION__,
4655 frmx, frame->bytes_read, frame->scanlength); 4671 frame->index, frame->bytes_read, frame->scanlength);
4656 4672
4657 /* copy bytes to user space; we allow for partials reads */ 4673 /* copy bytes to user space; we allow for partials reads */
4658 if ((count + frame->bytes_read) > (unsigned long)frame->scanlength) 4674 if ((count + frame->bytes_read) > (unsigned long)frame->scanlength)
4659 count = frame->scanlength - frame->bytes_read; 4675 count = frame->scanlength - frame->bytes_read;
4660 4676
4661 if (copy_to_user(buf, frame->data + frame->bytes_read, count)) { 4677 if (copy_to_user(buf, frame->data + frame->bytes_read, count)) {
4662 count = -EFAULT; 4678 return -EFAULT;
4663 goto usbvision_v4l2_read_done;
4664 } 4679 }
4665 4680
4666 frame->bytes_read += count; 4681 frame->bytes_read += count;
4667 PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld", __FUNCTION__, 4682 PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld", __FUNCTION__,
4668 (unsigned long)count, frame->bytes_read); 4683 (unsigned long)count, frame->bytes_read);
4669 4684
4670 if (frame->bytes_read >= frame->scanlength) {// All data has been read 4685 // For now, forget the frame if it has not been read in one shot.
4686/* if (frame->bytes_read >= frame->scanlength) {// All data has been read */
4671 frame->bytes_read = 0; 4687 frame->bytes_read = 0;
4672 4688
4673 /* Mark it as available to be used again. */ 4689 /* Mark it as available to be used again. */
4674 usbvision->frame[frmx].grabstate = FrameState_Unused; 4690 usbvision->frame[frmx].grabstate = FrameState_Unused;
4675 // FIXME enqueue another frame 4691/* } */
4676/* if (usbvision_new_frame(usbvision, frmx ? 0 : 1)) */
4677/* err("%s: usbvision_new_frame() failed", __FUNCTION__); */
4678 }
4679 4692
4680usbvision_v4l2_read_done:
4681 up(&usbvision->lock);
4682 return count; 4693 return count;
4683} 4694}
4684 4695