diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-fileops.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-fileops.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index e9802d99439b..07411f34885a 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -597,6 +597,13 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
597 | mutex_unlock(&cx->serialize_lock); | 597 | mutex_unlock(&cx->serialize_lock); |
598 | if (rc) | 598 | if (rc) |
599 | return rc; | 599 | return rc; |
600 | |||
601 | if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && | ||
602 | (id->type == CX18_ENC_STREAM_TYPE_YUV)) { | ||
603 | return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0, | ||
604 | filp->f_flags & O_NONBLOCK); | ||
605 | } | ||
606 | |||
600 | return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); | 607 | return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); |
601 | } | 608 | } |
602 | 609 | ||
@@ -622,6 +629,15 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) | |||
622 | CX18_DEBUG_FILE("Encoder poll started capture\n"); | 629 | CX18_DEBUG_FILE("Encoder poll started capture\n"); |
623 | } | 630 | } |
624 | 631 | ||
632 | if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && | ||
633 | (id->type == CX18_ENC_STREAM_TYPE_YUV)) { | ||
634 | int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait); | ||
635 | if (eof && videobuf_poll == POLLERR) | ||
636 | return POLLHUP; | ||
637 | else | ||
638 | return videobuf_poll; | ||
639 | } | ||
640 | |||
625 | /* add stream's waitq to the poll list */ | 641 | /* add stream's waitq to the poll list */ |
626 | CX18_DEBUG_HI_FILE("Encoder poll\n"); | 642 | CX18_DEBUG_HI_FILE("Encoder poll\n"); |
627 | poll_wait(filp, &s->waitq, wait); | 643 | poll_wait(filp, &s->waitq, wait); |
@@ -633,6 +649,58 @@ unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) | |||
633 | return 0; | 649 | return 0; |
634 | } | 650 | } |
635 | 651 | ||
652 | int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | ||
653 | { | ||
654 | struct cx18_open_id *id = file->private_data; | ||
655 | struct cx18 *cx = id->cx; | ||
656 | struct cx18_stream *s = &cx->streams[id->type]; | ||
657 | int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); | ||
658 | |||
659 | if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && | ||
660 | (id->type == CX18_ENC_STREAM_TYPE_YUV)) { | ||
661 | |||
662 | /* Start a capture if there is none */ | ||
663 | if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) { | ||
664 | int rc; | ||
665 | |||
666 | mutex_lock(&cx->serialize_lock); | ||
667 | rc = cx18_start_capture(id); | ||
668 | mutex_unlock(&cx->serialize_lock); | ||
669 | if (rc) { | ||
670 | CX18_DEBUG_INFO( | ||
671 | "Could not start capture for %s (%d)\n", | ||
672 | s->name, rc); | ||
673 | return -EINVAL; | ||
674 | } | ||
675 | CX18_DEBUG_FILE("Encoder mmap started capture\n"); | ||
676 | } | ||
677 | |||
678 | return videobuf_mmap_mapper(&s->vbuf_q, vma); | ||
679 | } | ||
680 | |||
681 | return -EINVAL; | ||
682 | } | ||
683 | |||
684 | void cx18_vb_timeout(unsigned long data) | ||
685 | { | ||
686 | struct cx18_stream *s = (struct cx18_stream *)data; | ||
687 | struct cx18_videobuf_buffer *buf; | ||
688 | unsigned long flags; | ||
689 | |||
690 | /* Return all of the buffers in error state, so the vbi/vid inode | ||
691 | * can return from blocking. | ||
692 | */ | ||
693 | spin_lock_irqsave(&s->vb_lock, flags); | ||
694 | while (!list_empty(&s->vb_capture)) { | ||
695 | buf = list_entry(s->vb_capture.next, | ||
696 | struct cx18_videobuf_buffer, vb.queue); | ||
697 | list_del(&buf->vb.queue); | ||
698 | buf->vb.state = VIDEOBUF_ERROR; | ||
699 | wake_up(&buf->vb.done); | ||
700 | } | ||
701 | spin_unlock_irqrestore(&s->vb_lock, flags); | ||
702 | } | ||
703 | |||
636 | void cx18_stop_capture(struct cx18_open_id *id, int gop_end) | 704 | void cx18_stop_capture(struct cx18_open_id *id, int gop_end) |
637 | { | 705 | { |
638 | struct cx18 *cx = id->cx; | 706 | struct cx18 *cx = id->cx; |
@@ -716,6 +784,8 @@ int cx18_v4l2_close(struct file *filp) | |||
716 | cx18_release_stream(s); | 784 | cx18_release_stream(s); |
717 | } else { | 785 | } else { |
718 | cx18_stop_capture(id, 0); | 786 | cx18_stop_capture(id, 0); |
787 | if (id->type == CX18_ENC_STREAM_TYPE_YUV) | ||
788 | videobuf_mmap_free(&id->vbuf_q); | ||
719 | } | 789 | } |
720 | kfree(id); | 790 | kfree(id); |
721 | mutex_unlock(&cx->serialize_lock); | 791 | mutex_unlock(&cx->serialize_lock); |