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 | |
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')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 7 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 53 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 24 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-irq.c | 15 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 5 |
5 files changed, 87 insertions, 17 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 851f07de5296..5b45fd2b2645 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <media/v4l2-common.h> | 63 | #include <media/v4l2-common.h> |
64 | #include <media/v4l2-ioctl.h> | 64 | #include <media/v4l2-ioctl.h> |
65 | #include <media/v4l2-device.h> | 65 | #include <media/v4l2-device.h> |
66 | #include <media/v4l2-fh.h> | ||
66 | #include <media/tuner.h> | 67 | #include <media/tuner.h> |
67 | #include <media/cx2341x.h> | 68 | #include <media/cx2341x.h> |
68 | #include <media/ir-kbd-i2c.h> | 69 | #include <media/ir-kbd-i2c.h> |
@@ -375,6 +376,7 @@ struct ivtv_stream { | |||
375 | }; | 376 | }; |
376 | 377 | ||
377 | struct ivtv_open_id { | 378 | struct ivtv_open_id { |
379 | struct v4l2_fh fh; | ||
378 | u32 open_id; /* unique ID for this file descriptor */ | 380 | u32 open_id; /* unique ID for this file descriptor */ |
379 | int type; /* stream type */ | 381 | int type; /* stream type */ |
380 | int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ | 382 | int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ |
@@ -382,6 +384,11 @@ struct ivtv_open_id { | |||
382 | struct ivtv *itv; | 384 | struct ivtv *itv; |
383 | }; | 385 | }; |
384 | 386 | ||
387 | static inline struct ivtv_open_id *fh2id(struct v4l2_fh *fh) | ||
388 | { | ||
389 | return container_of(fh, struct ivtv_open_id, fh); | ||
390 | } | ||
391 | |||
385 | struct yuv_frame_info | 392 | struct yuv_frame_info |
386 | { | 393 | { |
387 | u32 update; | 394 | u32 update; |
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 | ||
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 6422cf8f189d..e95ebdeaa72f 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <media/saa7127.h> | 35 | #include <media/saa7127.h> |
36 | #include <media/tveeprom.h> | 36 | #include <media/tveeprom.h> |
37 | #include <media/v4l2-chip-ident.h> | 37 | #include <media/v4l2-chip-ident.h> |
38 | #include <media/v4l2-event.h> | ||
38 | #include <linux/dvb/audio.h> | 39 | #include <linux/dvb/audio.h> |
39 | #include <linux/i2c-id.h> | 40 | #include <linux/i2c-id.h> |
40 | 41 | ||
@@ -1452,6 +1453,18 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on) | |||
1452 | return 0; | 1453 | return 0; |
1453 | } | 1454 | } |
1454 | 1455 | ||
1456 | static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub) | ||
1457 | { | ||
1458 | switch (sub->type) { | ||
1459 | case V4L2_EVENT_VSYNC: | ||
1460 | case V4L2_EVENT_EOS: | ||
1461 | break; | ||
1462 | default: | ||
1463 | return -EINVAL; | ||
1464 | } | ||
1465 | return v4l2_event_subscribe(fh, sub); | ||
1466 | } | ||
1467 | |||
1455 | static int ivtv_log_status(struct file *file, void *fh) | 1468 | static int ivtv_log_status(struct file *file, void *fh) |
1456 | { | 1469 | { |
1457 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 1470 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
@@ -1560,7 +1573,7 @@ static int ivtv_log_status(struct file *file, void *fh) | |||
1560 | 1573 | ||
1561 | static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | 1574 | static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) |
1562 | { | 1575 | { |
1563 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | 1576 | struct ivtv_open_id *id = fh2id(filp->private_data); |
1564 | struct ivtv *itv = id->itv; | 1577 | struct ivtv *itv = id->itv; |
1565 | int nonblocking = filp->f_flags & O_NONBLOCK; | 1578 | int nonblocking = filp->f_flags & O_NONBLOCK; |
1566 | struct ivtv_stream *s = &itv->streams[id->type]; | 1579 | struct ivtv_stream *s = &itv->streams[id->type]; |
@@ -1820,7 +1833,7 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | |||
1820 | unsigned int cmd, unsigned long arg) | 1833 | unsigned int cmd, unsigned long arg) |
1821 | { | 1834 | { |
1822 | struct video_device *vfd = video_devdata(filp); | 1835 | struct video_device *vfd = video_devdata(filp); |
1823 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | 1836 | struct ivtv_open_id *id = fh2id(filp->private_data); |
1824 | long ret; | 1837 | long ret; |
1825 | 1838 | ||
1826 | /* check priority */ | 1839 | /* check priority */ |
@@ -1852,10 +1865,13 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | |||
1852 | 1865 | ||
1853 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 1866 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1854 | { | 1867 | { |
1855 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | 1868 | struct ivtv_open_id *id = fh2id(filp->private_data); |
1856 | struct ivtv *itv = id->itv; | 1869 | struct ivtv *itv = id->itv; |
1857 | long res; | 1870 | long res; |
1858 | 1871 | ||
1872 | /* DQEVENT can block, so this should not run with the serialize lock */ | ||
1873 | if (cmd == VIDIOC_DQEVENT) | ||
1874 | return ivtv_serialized_ioctl(itv, filp, cmd, arg); | ||
1859 | mutex_lock(&itv->serialize_lock); | 1875 | mutex_lock(&itv->serialize_lock); |
1860 | res = ivtv_serialized_ioctl(itv, filp, cmd, arg); | 1876 | res = ivtv_serialized_ioctl(itv, filp, cmd, arg); |
1861 | mutex_unlock(&itv->serialize_lock); | 1877 | mutex_unlock(&itv->serialize_lock); |
@@ -1926,6 +1942,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { | |||
1926 | .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls, | 1942 | .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls, |
1927 | .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls, | 1943 | .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls, |
1928 | .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls, | 1944 | .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls, |
1945 | .vidioc_subscribe_event = ivtv_subscribe_event, | ||
1946 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1929 | }; | 1947 | }; |
1930 | 1948 | ||
1931 | void ivtv_set_funcs(struct video_device *vdev) | 1949 | void ivtv_set_funcs(struct video_device *vdev) |
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index dbd46c5d6975..fea1ec33b0df 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "ivtv-mailbox.h" | 25 | #include "ivtv-mailbox.h" |
26 | #include "ivtv-vbi.h" | 26 | #include "ivtv-vbi.h" |
27 | #include "ivtv-yuv.h" | 27 | #include "ivtv-yuv.h" |
28 | #include <media/v4l2-event.h> | ||
28 | 29 | ||
29 | #define DMA_MAGIC_COOKIE 0x000001fe | 30 | #define DMA_MAGIC_COOKIE 0x000001fe |
30 | 31 | ||
@@ -778,6 +779,14 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
778 | } | 779 | } |
779 | } | 780 | } |
780 | if (frame != (itv->last_vsync_field & 1)) { | 781 | if (frame != (itv->last_vsync_field & 1)) { |
782 | static const struct v4l2_event evtop = { | ||
783 | .type = V4L2_EVENT_VSYNC, | ||
784 | .u.vsync.field = V4L2_FIELD_TOP, | ||
785 | }; | ||
786 | static const struct v4l2_event evbottom = { | ||
787 | .type = V4L2_EVENT_VSYNC, | ||
788 | .u.vsync.field = V4L2_FIELD_BOTTOM, | ||
789 | }; | ||
781 | struct ivtv_stream *s = ivtv_get_output_stream(itv); | 790 | struct ivtv_stream *s = ivtv_get_output_stream(itv); |
782 | 791 | ||
783 | itv->last_vsync_field += 1; | 792 | itv->last_vsync_field += 1; |
@@ -791,10 +800,12 @@ static void ivtv_irq_vsync(struct ivtv *itv) | |||
791 | if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) { | 800 | if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) { |
792 | set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags); | 801 | set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags); |
793 | wake_up(&itv->event_waitq); | 802 | wake_up(&itv->event_waitq); |
803 | if (s) | ||
804 | wake_up(&s->waitq); | ||
794 | } | 805 | } |
806 | if (s && s->vdev) | ||
807 | v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom); | ||
795 | wake_up(&itv->vsync_waitq); | 808 | wake_up(&itv->vsync_waitq); |
796 | if (s) | ||
797 | wake_up(&s->waitq); | ||
798 | 809 | ||
799 | /* Send VBI to saa7127 */ | 810 | /* Send VBI to saa7127 */ |
800 | if (frame && (itv->output_mode == OUT_PASSTHROUGH || | 811 | if (frame && (itv->output_mode == OUT_PASSTHROUGH || |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 6917c497fb7e..def507ee106a 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include "ivtv-yuv.h" | 42 | #include "ivtv-yuv.h" |
43 | #include "ivtv-cards.h" | 43 | #include "ivtv-cards.h" |
44 | #include "ivtv-streams.h" | 44 | #include "ivtv-streams.h" |
45 | #include <media/v4l2-event.h> | ||
45 | 46 | ||
46 | static const struct v4l2_file_operations ivtv_v4l2_enc_fops = { | 47 | static const struct v4l2_file_operations ivtv_v4l2_enc_fops = { |
47 | .owner = THIS_MODULE, | 48 | .owner = THIS_MODULE, |
@@ -840,6 +841,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | |||
840 | 841 | ||
841 | int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) | 842 | int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) |
842 | { | 843 | { |
844 | static const struct v4l2_event ev = { | ||
845 | .type = V4L2_EVENT_EOS, | ||
846 | }; | ||
843 | struct ivtv *itv = s->itv; | 847 | struct ivtv *itv = s->itv; |
844 | 848 | ||
845 | if (s->vdev == NULL) | 849 | if (s->vdev == NULL) |
@@ -891,6 +895,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts) | |||
891 | 895 | ||
892 | set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); | 896 | set_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags); |
893 | wake_up(&itv->event_waitq); | 897 | wake_up(&itv->event_waitq); |
898 | v4l2_event_queue(s->vdev, &ev); | ||
894 | 899 | ||
895 | /* wake up wait queues */ | 900 | /* wake up wait queues */ |
896 | wake_up(&s->waitq); | 901 | wake_up(&s->waitq); |