aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/vino.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/vino.c')
-rw-r--r--drivers/media/video/vino.c290
1 files changed, 114 insertions, 176 deletions
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 675067f92d96..8da4dd1e0e94 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -3102,22 +3102,14 @@ out:
3102static int vino_enum_fmt_vid_cap(struct file *file, void *__fh, 3102static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
3103 struct v4l2_fmtdesc *fd) 3103 struct v4l2_fmtdesc *fd)
3104{ 3104{
3105 enum v4l2_buf_type type = fd->type; 3105 dprintk("format index = %d\n", fd->index);
3106 int index = fd->index;
3107 3106
3108 dprintk("format index = %d\n", index); 3107 if (fd->index >= VINO_DATA_FMT_COUNT)
3109
3110 if ((fd->index < 0) ||
3111 (fd->index >= VINO_DATA_FMT_COUNT))
3112 return -EINVAL; 3108 return -EINVAL;
3113 dprintk("format name = %s\n", 3109 dprintk("format name = %s\n", vino_data_formats[fd->index].description);
3114 vino_data_formats[index].description); 3110
3115 3111 fd->pixelformat = vino_data_formats[fd->index].pixelformat;
3116 memset(fd, 0, sizeof(struct v4l2_fmtdesc)); 3112 strcpy(fd->description, vino_data_formats[fd->index].description);
3117 fd->index = index;
3118 fd->type = type;
3119 fd->pixelformat = vino_data_formats[index].pixelformat;
3120 strcpy(fd->description, vino_data_formats[index].description);
3121 return 0; 3113 return 0;
3122} 3114}
3123 3115
@@ -3327,28 +3319,18 @@ static int vino_g_parm(struct file *file, void *__fh,
3327{ 3319{
3328 struct vino_channel_settings *vcs = video_drvdata(file); 3320 struct vino_channel_settings *vcs = video_drvdata(file);
3329 unsigned long flags; 3321 unsigned long flags;
3322 struct v4l2_captureparm *cp = &sp->parm.capture;
3330 3323
3331 switch (sp->type) { 3324 cp->capability = V4L2_CAP_TIMEPERFRAME;
3332 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3325 cp->timeperframe.numerator = 1;
3333 struct v4l2_captureparm *cp = &sp->parm.capture;
3334 memset(cp, 0, sizeof(struct v4l2_captureparm));
3335 3326
3336 cp->capability = V4L2_CAP_TIMEPERFRAME; 3327 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3337 cp->timeperframe.numerator = 1;
3338 3328
3339 spin_lock_irqsave(&vino_drvdata->input_lock, flags); 3329 cp->timeperframe.denominator = vcs->fps;
3340 3330
3341 cp->timeperframe.denominator = vcs->fps; 3331 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3342 3332
3343 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags); 3333 /* TODO: cp->readbuffers = xxx; */
3344
3345 // TODO: cp->readbuffers = xxx;
3346 break;
3347 }
3348 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3349 default:
3350 return -EINVAL;
3351 }
3352 3334
3353 return 0; 3335 return 0;
3354} 3336}
@@ -3358,32 +3340,21 @@ static int vino_s_parm(struct file *file, void *__fh,
3358{ 3340{
3359 struct vino_channel_settings *vcs = video_drvdata(file); 3341 struct vino_channel_settings *vcs = video_drvdata(file);
3360 unsigned long flags; 3342 unsigned long flags;
3343 struct v4l2_captureparm *cp = &sp->parm.capture;
3361 3344
3362 switch (sp->type) { 3345 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3363 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3364 struct v4l2_captureparm *cp = &sp->parm.capture;
3365
3366 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3367
3368 if ((cp->timeperframe.numerator == 0) ||
3369 (cp->timeperframe.denominator == 0)) {
3370 /* reset framerate */
3371 vino_set_default_framerate(vcs);
3372 } else {
3373 vino_set_framerate(vcs, cp->timeperframe.denominator /
3374 cp->timeperframe.numerator);
3375 }
3376
3377 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3378 3346
3379 // TODO: set buffers according to cp->readbuffers 3347 if ((cp->timeperframe.numerator == 0) ||
3380 break; 3348 (cp->timeperframe.denominator == 0)) {
3381 } 3349 /* reset framerate */
3382 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3350 vino_set_default_framerate(vcs);
3383 default: 3351 } else {
3384 return -EINVAL; 3352 vino_set_framerate(vcs, cp->timeperframe.denominator /
3353 cp->timeperframe.numerator);
3385 } 3354 }
3386 3355
3356 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3357
3387 return 0; 3358 return 0;
3388} 3359}
3389 3360
@@ -3391,42 +3362,35 @@ static int vino_reqbufs(struct file *file, void *__fh,
3391 struct v4l2_requestbuffers *rb) 3362 struct v4l2_requestbuffers *rb)
3392{ 3363{
3393 struct vino_channel_settings *vcs = video_drvdata(file); 3364 struct vino_channel_settings *vcs = video_drvdata(file);
3365
3394 if (vcs->reading) 3366 if (vcs->reading)
3395 return -EBUSY; 3367 return -EBUSY;
3396 3368
3397 switch (rb->type) { 3369 /* TODO: check queue type */
3398 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3370 if (rb->memory != V4L2_MEMORY_MMAP) {
3399 // TODO: check queue type 3371 dprintk("type not mmap\n");
3400 if (rb->memory != V4L2_MEMORY_MMAP) { 3372 return -EINVAL;
3401 dprintk("type not mmap\n"); 3373 }
3402 return -EINVAL;
3403 }
3404 3374
3405 dprintk("count = %d\n", rb->count); 3375 dprintk("count = %d\n", rb->count);
3406 if (rb->count > 0) { 3376 if (rb->count > 0) {
3407 if (vino_is_capturing(vcs)) { 3377 if (vino_is_capturing(vcs)) {
3408 dprintk("busy, capturing\n"); 3378 dprintk("busy, capturing\n");
3409 return -EBUSY; 3379 return -EBUSY;
3410 } 3380 }
3411 3381
3412 if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) { 3382 if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
3413 dprintk("busy, buffers still mapped\n"); 3383 dprintk("busy, buffers still mapped\n");
3414 return -EBUSY; 3384 return -EBUSY;
3415 } else {
3416 vcs->streaming = 0;
3417 vino_queue_free(&vcs->fb_queue);
3418 vino_queue_init(&vcs->fb_queue, &rb->count);
3419 }
3420 } else { 3385 } else {
3421 vcs->streaming = 0; 3386 vcs->streaming = 0;
3422 vino_capture_stop(vcs);
3423 vino_queue_free(&vcs->fb_queue); 3387 vino_queue_free(&vcs->fb_queue);
3388 vino_queue_init(&vcs->fb_queue, &rb->count);
3424 } 3389 }
3425 break; 3390 } else {
3426 } 3391 vcs->streaming = 0;
3427 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3392 vino_capture_stop(vcs);
3428 default: 3393 vino_queue_free(&vcs->fb_queue);
3429 return -EINVAL;
3430 } 3394 }
3431 3395
3432 return 0; 3396 return 0;
@@ -3474,35 +3438,27 @@ static int vino_querybuf(struct file *file, void *__fh,
3474 struct v4l2_buffer *b) 3438 struct v4l2_buffer *b)
3475{ 3439{
3476 struct vino_channel_settings *vcs = video_drvdata(file); 3440 struct vino_channel_settings *vcs = video_drvdata(file);
3441 struct vino_framebuffer *fb;
3442
3477 if (vcs->reading) 3443 if (vcs->reading)
3478 return -EBUSY; 3444 return -EBUSY;
3479 3445
3480 switch (b->type) { 3446 /* TODO: check queue type */
3481 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3447 if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
3482 struct vino_framebuffer *fb; 3448 dprintk("invalid index = %d\n",
3483 3449 b->index);
3484 // TODO: check queue type 3450 return -EINVAL;
3485 if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
3486 dprintk("invalid index = %d\n",
3487 b->index);
3488 return -EINVAL;
3489 }
3490
3491 fb = vino_queue_get_buffer(&vcs->fb_queue,
3492 b->index);
3493 if (fb == NULL) {
3494 dprintk("vino_queue_get_buffer() failed");
3495 return -EINVAL;
3496 }
3497
3498 vino_v4l2_get_buffer_status(vcs, fb, b);
3499 break;
3500 } 3451 }
3501 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3452
3502 default: 3453 fb = vino_queue_get_buffer(&vcs->fb_queue,
3454 b->index);
3455 if (fb == NULL) {
3456 dprintk("vino_queue_get_buffer() failed");
3503 return -EINVAL; 3457 return -EINVAL;
3504 } 3458 }
3505 3459
3460 vino_v4l2_get_buffer_status(vcs, fb, b);
3461
3506 return 0; 3462 return 0;
3507} 3463}
3508 3464
@@ -3510,36 +3466,28 @@ static int vino_qbuf(struct file *file, void *__fh,
3510 struct v4l2_buffer *b) 3466 struct v4l2_buffer *b)
3511{ 3467{
3512 struct vino_channel_settings *vcs = video_drvdata(file); 3468 struct vino_channel_settings *vcs = video_drvdata(file);
3469 struct vino_framebuffer *fb;
3470 int ret;
3471
3513 if (vcs->reading) 3472 if (vcs->reading)
3514 return -EBUSY; 3473 return -EBUSY;
3515 3474
3516 switch (b->type) { 3475 /* TODO: check queue type */
3517 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3476 if (b->memory != V4L2_MEMORY_MMAP) {
3518 struct vino_framebuffer *fb; 3477 dprintk("type not mmap\n");
3519 int ret; 3478 return -EINVAL;
3520 3479 }
3521 // TODO: check queue type
3522 if (b->memory != V4L2_MEMORY_MMAP) {
3523 dprintk("type not mmap\n");
3524 return -EINVAL;
3525 }
3526 3480
3527 fb = vino_capture_enqueue(vcs, b->index); 3481 fb = vino_capture_enqueue(vcs, b->index);
3528 if (fb == NULL) 3482 if (fb == NULL)
3529 return -EINVAL; 3483 return -EINVAL;
3530 3484
3531 vino_v4l2_get_buffer_status(vcs, fb, b); 3485 vino_v4l2_get_buffer_status(vcs, fb, b);
3532 3486
3533 if (vcs->streaming) { 3487 if (vcs->streaming) {
3534 ret = vino_capture_next(vcs, 1); 3488 ret = vino_capture_next(vcs, 1);
3535 if (ret) 3489 if (ret)
3536 return ret; 3490 return ret;
3537 }
3538 break;
3539 }
3540 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3541 default:
3542 return -EINVAL;
3543 } 3491 }
3544 3492
3545 return 0; 3493 return 0;
@@ -3550,73 +3498,63 @@ static int vino_dqbuf(struct file *file, void *__fh,
3550{ 3498{
3551 struct vino_channel_settings *vcs = video_drvdata(file); 3499 struct vino_channel_settings *vcs = video_drvdata(file);
3552 unsigned int nonblocking = file->f_flags & O_NONBLOCK; 3500 unsigned int nonblocking = file->f_flags & O_NONBLOCK;
3501 struct vino_framebuffer *fb;
3502 unsigned int incoming, outgoing;
3503 int err;
3504
3553 if (vcs->reading) 3505 if (vcs->reading)
3554 return -EBUSY; 3506 return -EBUSY;
3555 3507
3556 switch (b->type) { 3508 /* TODO: check queue type */
3557 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3509
3558 struct vino_framebuffer *fb; 3510 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3559 unsigned int incoming, outgoing; 3511 if (err) {
3560 int err; 3512 dprintk("vino_queue_get_incoming() failed\n");
3513 return -EINVAL;
3514 }
3515 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
3516 if (err) {
3517 dprintk("vino_queue_get_outgoing() failed\n");
3518 return -EINVAL;
3519 }
3561 3520
3562 // TODO: check queue type 3521 dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
3563 3522
3564 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming); 3523 if (outgoing == 0) {
3565 if (err) { 3524 if (incoming == 0) {
3566 dprintk("vino_queue_get_incoming() failed\n"); 3525 dprintk("no incoming or outgoing buffers\n");
3567 return -EINVAL; 3526 return -EINVAL;
3568 } 3527 }
3569 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing); 3528 if (nonblocking) {
3570 if (err) { 3529 dprintk("non-blocking I/O was selected and "
3571 dprintk("vino_queue_get_outgoing() failed\n"); 3530 "there are no buffers to dequeue\n");
3572 return -EINVAL; 3531 return -EAGAIN;
3573 } 3532 }
3574 3533
3575 dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing); 3534 err = vino_wait_for_frame(vcs);
3576 3535 if (err) {
3577 if (outgoing == 0) {
3578 if (incoming == 0) {
3579 dprintk("no incoming or outgoing buffers\n");
3580 return -EINVAL;
3581 }
3582 if (nonblocking) {
3583 dprintk("non-blocking I/O was selected and "
3584 "there are no buffers to dequeue\n");
3585 return -EAGAIN;
3586 }
3587
3588 err = vino_wait_for_frame(vcs); 3536 err = vino_wait_for_frame(vcs);
3589 if (err) { 3537 if (err) {
3590 err = vino_wait_for_frame(vcs); 3538 /* interrupted or no frames captured because of
3591 if (err) { 3539 * frame skipping */
3592 /* interrupted or 3540 /* vino_capture_failed(vcs); */
3593 * no frames captured because 3541 return -EIO;
3594 * of frame skipping */
3595 // vino_capture_failed(vcs);
3596 return -EIO;
3597 }
3598 } 3542 }
3599 } 3543 }
3544 }
3600 3545
3601 fb = vino_queue_remove(&vcs->fb_queue, &b->index); 3546 fb = vino_queue_remove(&vcs->fb_queue, &b->index);
3602 if (fb == NULL) { 3547 if (fb == NULL) {
3603 dprintk("vino_queue_remove() failed\n"); 3548 dprintk("vino_queue_remove() failed\n");
3604 return -EINVAL; 3549 return -EINVAL;
3605 } 3550 }
3606
3607 err = vino_check_buffer(vcs, fb);
3608 3551
3609 vino_v4l2_get_buffer_status(vcs, fb, b); 3552 err = vino_check_buffer(vcs, fb);
3610 3553
3611 if (err) 3554 vino_v4l2_get_buffer_status(vcs, fb, b);
3612 return -EIO;
3613 3555
3614 break; 3556 if (err)
3615 } 3557 return -EIO;
3616 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3617 default:
3618 return -EINVAL;
3619 }
3620 3558
3621 return 0; 3559 return 0;
3622} 3560}