aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/au0828/au0828-video.c
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2010-09-01 21:03:43 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:16:34 -0500
commit6e04b7b95a5bd2da0aa5df05fc09a1f0d6615666 (patch)
tree6ff016a1e6ba80408feeaef9ee5c5db8368565e0 /drivers/media/video/au0828/au0828-video.c
parent301c9f26d7ded6e274a99c3a447a9a36790a3f3e (diff)
[media] au0828: continue video streaming even when no ITU-656 coming in
We need the au0828 to continue delivering frames even when the device is not delivering video, or else applications such as tvtime will block indefinitely. Unfortunately, the au8522 doesn't have any sort of free-running mode or "blue screen on no video" like some other decoders. This work was sponsored by GetWellNetwork Inc. Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/au0828/au0828-video.c')
-rw-r--r--drivers/media/video/au0828/au0828-video.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 20ba5915542f..8d11e544c879 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -312,6 +312,9 @@ static inline void buffer_filled(struct au0828_dev *dev,
312 312
313 list_del(&buf->vb.queue); 313 list_del(&buf->vb.queue);
314 wake_up(&buf->vb.done); 314 wake_up(&buf->vb.done);
315
316 /* Reset the timer for "no video condition" */
317 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
315} 318}
316 319
317static inline void vbi_buffer_filled(struct au0828_dev *dev, 320static inline void vbi_buffer_filled(struct au0828_dev *dev,
@@ -329,6 +332,9 @@ static inline void vbi_buffer_filled(struct au0828_dev *dev,
329 332
330 list_del(&buf->vb.queue); 333 list_del(&buf->vb.queue);
331 wake_up(&buf->vb.done); 334 wake_up(&buf->vb.done);
335
336 /* Reset the timer for "no video condition" */
337 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
332} 338}
333 339
334/* 340/*
@@ -907,6 +913,50 @@ static int get_ressource(struct au0828_fh *fh)
907 } 913 }
908} 914}
909 915
916/* This function ensures that video frames continue to be delivered even if
917 the ITU-656 input isn't receiving any data (thereby preventing applications
918 such as tvtime from hanging) */
919void au0828_vid_buffer_timeout(unsigned long data)
920{
921 struct au0828_dev *dev = (struct au0828_dev *) data;
922 struct au0828_dmaqueue *dma_q = &dev->vidq;
923 struct au0828_buffer *buf;
924 unsigned char *vid_data;
925
926 spin_lock(&dev->slock);
927
928 buf = dev->isoc_ctl.buf;
929 if (buf != NULL) {
930 vid_data = videobuf_to_vmalloc(&buf->vb);
931 memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */
932 buffer_filled(dev, dma_q, buf);
933 get_next_buf(dma_q, &buf);
934 }
935
936 spin_unlock(&dev->slock);
937}
938
939void au0828_vbi_buffer_timeout(unsigned long data)
940{
941 struct au0828_dev *dev = (struct au0828_dev *) data;
942 struct au0828_dmaqueue *dma_q = &dev->vbiq;
943 struct au0828_buffer *buf;
944 unsigned char *vbi_data;
945
946 spin_lock(&dev->slock);
947
948 buf = dev->isoc_ctl.vbi_buf;
949 if (buf != NULL) {
950 vbi_data = videobuf_to_vmalloc(&buf->vb);
951 memset(vbi_data, 0x00, buf->vb.size);
952 vbi_buffer_filled(dev, dma_q, buf);
953 vbi_get_next_buf(dma_q, &buf);
954 }
955
956 spin_unlock(&dev->slock);
957}
958
959
910static int au0828_v4l2_open(struct file *filp) 960static int au0828_v4l2_open(struct file *filp)
911{ 961{
912 int ret = 0; 962 int ret = 0;
@@ -976,6 +1026,15 @@ static int au0828_v4l2_open(struct file *filp)
976 V4L2_FIELD_SEQ_TB, 1026 V4L2_FIELD_SEQ_TB,
977 sizeof(struct au0828_buffer), fh, NULL); 1027 sizeof(struct au0828_buffer), fh, NULL);
978 1028
1029 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1030 dev->vid_timeout.function = au0828_vid_buffer_timeout;
1031 dev->vid_timeout.data = (unsigned long) dev;
1032 init_timer(&dev->vid_timeout);
1033 } else {
1034 dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
1035 dev->vbi_timeout.data = (unsigned long) dev;
1036 init_timer(&dev->vbi_timeout);
1037 }
979 1038
980 return ret; 1039 return ret;
981} 1040}
@@ -987,11 +1046,13 @@ static int au0828_v4l2_close(struct file *filp)
987 struct au0828_dev *dev = fh->dev; 1046 struct au0828_dev *dev = fh->dev;
988 1047
989 if (res_check(fh, AU0828_RESOURCE_VIDEO)) { 1048 if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
1049 del_timer(&dev->vid_timeout);
990 videobuf_stop(&fh->vb_vidq); 1050 videobuf_stop(&fh->vb_vidq);
991 res_free(fh, AU0828_RESOURCE_VIDEO); 1051 res_free(fh, AU0828_RESOURCE_VIDEO);
992 } 1052 }
993 1053
994 if (res_check(fh, AU0828_RESOURCE_VBI)) { 1054 if (res_check(fh, AU0828_RESOURCE_VBI)) {
1055 del_timer(&dev->vbi_timeout);
995 videobuf_stop(&fh->vb_vbiq); 1056 videobuf_stop(&fh->vb_vbiq);
996 res_free(fh, AU0828_RESOURCE_VBI); 1057 res_free(fh, AU0828_RESOURCE_VBI);
997 } 1058 }