diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2010-03-27 13:10:13 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:58:08 -0400 |
commit | 092501936fc128992456a086193746cf34642815 (patch) | |
tree | 6a6910b3fd4f9a1304adfb5af1a4e7a96085960d /drivers/media/video/ivtv/ivtv-fileops.c | |
parent | 1bcaf4bd53872e70c4fceec6bbb76044325f337f (diff) |
V4L/DVB: ivtv: support the new events API
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-fileops.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index babcabd73c08..bee9605bd273 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "ivtv-yuv.h" | 32 | #include "ivtv-yuv.h" |
33 | #include "ivtv-ioctl.h" | 33 | #include "ivtv-ioctl.h" |
34 | #include "ivtv-cards.h" | 34 | #include "ivtv-cards.h" |
35 | #include <media/v4l2-event.h> | ||
35 | #include <media/saa7115.h> | 36 | #include <media/saa7115.h> |
36 | 37 | ||
37 | /* This function tries to claim the stream for a specific file descriptor. | 38 | /* This function tries to claim the stream for a specific file descriptor. |
@@ -506,7 +507,7 @@ int ivtv_start_capture(struct ivtv_open_id *id) | |||
506 | 507 | ||
507 | ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos) | 508 | ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_t * pos) |
508 | { | 509 | { |
509 | struct ivtv_open_id *id = filp->private_data; | 510 | struct ivtv_open_id *id = fh2id(filp->private_data); |
510 | struct ivtv *itv = id->itv; | 511 | struct ivtv *itv = id->itv; |
511 | struct ivtv_stream *s = &itv->streams[id->type]; | 512 | struct ivtv_stream *s = &itv->streams[id->type]; |
512 | int rc; | 513 | int rc; |
@@ -541,7 +542,7 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed) | |||
541 | 542 | ||
542 | ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) | 543 | ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) |
543 | { | 544 | { |
544 | struct ivtv_open_id *id = filp->private_data; | 545 | struct ivtv_open_id *id = fh2id(filp->private_data); |
545 | struct ivtv *itv = id->itv; | 546 | struct ivtv *itv = id->itv; |
546 | struct ivtv_stream *s = &itv->streams[id->type]; | 547 | struct ivtv_stream *s = &itv->streams[id->type]; |
547 | struct yuv_playback_info *yi = &itv->yuv_info; | 548 | struct yuv_playback_info *yi = &itv->yuv_info; |
@@ -711,19 +712,31 @@ retry: | |||
711 | 712 | ||
712 | unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) | 713 | unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) |
713 | { | 714 | { |
714 | struct ivtv_open_id *id = filp->private_data; | 715 | struct ivtv_open_id *id = fh2id(filp->private_data); |
715 | struct ivtv *itv = id->itv; | 716 | struct ivtv *itv = id->itv; |
716 | struct ivtv_stream *s = &itv->streams[id->type]; | 717 | struct ivtv_stream *s = &itv->streams[id->type]; |
717 | int res = 0; | 718 | int res = 0; |
718 | 719 | ||
719 | /* add stream's waitq to the poll list */ | 720 | /* add stream's waitq to the poll list */ |
720 | IVTV_DEBUG_HI_FILE("Decoder poll\n"); | 721 | IVTV_DEBUG_HI_FILE("Decoder poll\n"); |
721 | poll_wait(filp, &s->waitq, wait); | ||
722 | 722 | ||
723 | set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); | 723 | /* If there are subscribed events, then only use the new event |
724 | if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) || | 724 | API instead of the old video.h based API. */ |
725 | test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags)) | 725 | if (!list_empty(&id->fh.events->subscribed)) { |
726 | res = POLLPRI; | 726 | poll_wait(filp, &id->fh.events->wait, wait); |
727 | /* Turn off the old-style vsync events */ | ||
728 | clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); | ||
729 | if (v4l2_event_pending(&id->fh)) | ||
730 | res = POLLPRI; | ||
731 | } else { | ||
732 | /* This is the old-style API which is here only for backwards | ||
733 | compatibility. */ | ||
734 | poll_wait(filp, &s->waitq, wait); | ||
735 | set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags); | ||
736 | if (test_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags) || | ||
737 | test_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags)) | ||
738 | res = POLLPRI; | ||
739 | } | ||
727 | 740 | ||
728 | /* Allow write if buffers are available for writing */ | 741 | /* Allow write if buffers are available for writing */ |
729 | if (s->q_free.buffers) | 742 | if (s->q_free.buffers) |
@@ -733,7 +746,7 @@ unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) | |||
733 | 746 | ||
734 | unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) | 747 | unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) |
735 | { | 748 | { |
736 | struct ivtv_open_id *id = filp->private_data; | 749 | struct ivtv_open_id *id = fh2id(filp->private_data); |
737 | struct ivtv *itv = id->itv; | 750 | struct ivtv *itv = id->itv; |
738 | struct ivtv_stream *s = &itv->streams[id->type]; | 751 | struct ivtv_stream *s = &itv->streams[id->type]; |
739 | int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | 752 | int eof = test_bit(IVTV_F_S_STREAMOFF, &s->s_flags); |
@@ -833,13 +846,16 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) | |||
833 | 846 | ||
834 | int ivtv_v4l2_close(struct file *filp) | 847 | int ivtv_v4l2_close(struct file *filp) |
835 | { | 848 | { |
836 | struct ivtv_open_id *id = filp->private_data; | 849 | struct v4l2_fh *fh = filp->private_data; |
850 | struct ivtv_open_id *id = fh2id(fh); | ||
837 | struct ivtv *itv = id->itv; | 851 | struct ivtv *itv = id->itv; |
838 | struct ivtv_stream *s = &itv->streams[id->type]; | 852 | struct ivtv_stream *s = &itv->streams[id->type]; |
839 | 853 | ||
840 | IVTV_DEBUG_FILE("close %s\n", s->name); | 854 | IVTV_DEBUG_FILE("close %s\n", s->name); |
841 | 855 | ||
842 | v4l2_prio_close(&itv->prio, &id->prio); | 856 | v4l2_prio_close(&itv->prio, &id->prio); |
857 | v4l2_fh_del(fh); | ||
858 | v4l2_fh_exit(fh); | ||
843 | 859 | ||
844 | /* Easy case first: this stream was never claimed by us */ | 860 | /* Easy case first: this stream was never claimed by us */ |
845 | if (s->id != id->open_id) { | 861 | if (s->id != id->open_id) { |
@@ -895,6 +911,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
895 | { | 911 | { |
896 | struct ivtv *itv = s->itv; | 912 | struct ivtv *itv = s->itv; |
897 | struct ivtv_open_id *item; | 913 | struct ivtv_open_id *item; |
914 | int res = 0; | ||
898 | 915 | ||
899 | IVTV_DEBUG_FILE("open %s\n", s->name); | 916 | IVTV_DEBUG_FILE("open %s\n", s->name); |
900 | 917 | ||
@@ -915,17 +932,27 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
915 | } | 932 | } |
916 | 933 | ||
917 | /* Allocate memory */ | 934 | /* Allocate memory */ |
918 | item = kmalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); | 935 | item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); |
919 | if (NULL == item) { | 936 | if (NULL == item) { |
920 | IVTV_DEBUG_WARN("nomem on v4l2 open\n"); | 937 | IVTV_DEBUG_WARN("nomem on v4l2 open\n"); |
921 | return -ENOMEM; | 938 | return -ENOMEM; |
922 | } | 939 | } |
940 | v4l2_fh_init(&item->fh, s->vdev); | ||
941 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV || | ||
942 | s->type == IVTV_DEC_STREAM_TYPE_MPG) { | ||
943 | res = v4l2_event_alloc(&item->fh, 60); | ||
944 | } | ||
945 | if (res < 0) { | ||
946 | v4l2_fh_exit(&item->fh); | ||
947 | kfree(item); | ||
948 | return res; | ||
949 | } | ||
923 | item->itv = itv; | 950 | item->itv = itv; |
924 | item->type = s->type; | 951 | item->type = s->type; |
925 | v4l2_prio_open(&itv->prio, &item->prio); | 952 | v4l2_prio_open(&itv->prio, &item->prio); |
926 | 953 | ||
927 | item->open_id = itv->open_id++; | 954 | item->open_id = itv->open_id++; |
928 | filp->private_data = item; | 955 | filp->private_data = &item->fh; |
929 | 956 | ||
930 | if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { | 957 | if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { |
931 | /* Try to claim this stream */ | 958 | /* Try to claim this stream */ |
@@ -940,6 +967,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
940 | /* switching to radio while capture is | 967 | /* switching to radio while capture is |
941 | in progress is not polite */ | 968 | in progress is not polite */ |
942 | ivtv_release_stream(s); | 969 | ivtv_release_stream(s); |
970 | v4l2_fh_exit(&item->fh); | ||
943 | kfree(item); | 971 | kfree(item); |
944 | return -EBUSY; | 972 | return -EBUSY; |
945 | } | 973 | } |
@@ -970,6 +998,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) | |||
970 | 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); | 998 | 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); |
971 | itv->yuv_info.stream_size = 0; | 999 | itv->yuv_info.stream_size = 0; |
972 | } | 1000 | } |
1001 | v4l2_fh_add(&item->fh); | ||
973 | return 0; | 1002 | return 0; |
974 | } | 1003 | } |
975 | 1004 | ||