diff options
author | Thierry MERLE <thierry.merle@free.fr> | 2007-02-07 08:13:11 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:35:19 -0500 |
commit | 6f78e186fe5d29dbff5e34f950adb573c4808de4 (patch) | |
tree | 23297d74fceeaa3b9668fda9a429c17c57107213 /drivers/media/video/usbvision/usbvision-video.c | |
parent | c65eeaab1f04d1113b5c4fb21f7f61ded795d2bb (diff) |
V4L/DVB (5205): Usbvision: dynamic allocation for frames
- fix decoder route output
- dynamic frame buffer allocation
Signed-off-by: Thierry MERLE <thierry.merle@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/usbvision/usbvision-video.c')
-rw-r--r-- | drivers/media/video/usbvision/usbvision-video.c | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 6a61ebcdf130..cfbfda47ec4f 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -391,19 +391,14 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) | |||
391 | if (usbvision->user) | 391 | if (usbvision->user) |
392 | errCode = -EBUSY; | 392 | errCode = -EBUSY; |
393 | else { | 393 | else { |
394 | /* Allocate memory for the frame buffers */ | 394 | /* Allocate memory for the scratch ring buffer */ |
395 | errCode = usbvision_frames_alloc(usbvision); | 395 | errCode = usbvision_scratch_alloc(usbvision); |
396 | if(!errCode) { | 396 | if (isocMode==ISOC_MODE_COMPRESS) { |
397 | /* Allocate memory for the scratch ring buffer */ | 397 | /* Allocate intermediate decompression buffers only if needed */ |
398 | errCode = usbvision_scratch_alloc(usbvision); | 398 | errCode = usbvision_decompress_alloc(usbvision); |
399 | if ((!errCode) && (isocMode==ISOC_MODE_COMPRESS)) { | ||
400 | /* Allocate intermediate decompression buffers only if needed */ | ||
401 | errCode = usbvision_decompress_alloc(usbvision); | ||
402 | } | ||
403 | } | 399 | } |
404 | if (errCode) { | 400 | if (errCode) { |
405 | /* Deallocate all buffers if trouble */ | 401 | /* Deallocate all buffers if trouble */ |
406 | usbvision_frames_free(usbvision); | ||
407 | usbvision_scratch_free(usbvision); | 402 | usbvision_scratch_free(usbvision); |
408 | usbvision_decompress_free(usbvision); | 403 | usbvision_decompress_free(usbvision); |
409 | } | 404 | } |
@@ -476,6 +471,7 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) | |||
476 | 471 | ||
477 | usbvision_decompress_free(usbvision); | 472 | usbvision_decompress_free(usbvision); |
478 | usbvision_frames_free(usbvision); | 473 | usbvision_frames_free(usbvision); |
474 | usbvision_empty_framequeues(usbvision); | ||
479 | usbvision_scratch_free(usbvision); | 475 | usbvision_scratch_free(usbvision); |
480 | 476 | ||
481 | usbvision->user--; | 477 | usbvision->user--; |
@@ -809,7 +805,9 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
809 | return ret; | 805 | return ret; |
810 | } | 806 | } |
811 | 807 | ||
808 | usbvision_frames_free(usbvision); | ||
812 | usbvision_empty_framequeues(usbvision); | 809 | usbvision_empty_framequeues(usbvision); |
810 | vr->count = usbvision_frames_alloc(usbvision,vr->count); | ||
813 | 811 | ||
814 | usbvision->curFrame = NULL; | 812 | usbvision->curFrame = NULL; |
815 | 813 | ||
@@ -826,7 +824,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
826 | if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { | 824 | if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { |
827 | return -EINVAL; | 825 | return -EINVAL; |
828 | } | 826 | } |
829 | if(vb->index>=USBVISION_NUMFRAMES) { | 827 | if(vb->index>=usbvision->num_frames) { |
830 | return -EINVAL; | 828 | return -EINVAL; |
831 | } | 829 | } |
832 | // Updating the corresponding frame state | 830 | // Updating the corresponding frame state |
@@ -840,7 +838,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
840 | vb->flags |= V4L2_BUF_FLAG_MAPPED; | 838 | vb->flags |= V4L2_BUF_FLAG_MAPPED; |
841 | vb->memory = V4L2_MEMORY_MMAP; | 839 | vb->memory = V4L2_MEMORY_MMAP; |
842 | 840 | ||
843 | vb->m.offset = vb->index*usbvision->max_frame_size; | 841 | vb->m.offset = vb->index*PAGE_ALIGN(usbvision->max_frame_size); |
844 | 842 | ||
845 | vb->memory = V4L2_MEMORY_MMAP; | 843 | vb->memory = V4L2_MEMORY_MMAP; |
846 | vb->field = V4L2_FIELD_NONE; | 844 | vb->field = V4L2_FIELD_NONE; |
@@ -859,7 +857,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
859 | if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { | 857 | if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { |
860 | return -EINVAL; | 858 | return -EINVAL; |
861 | } | 859 | } |
862 | if(vb->index>=USBVISION_NUMFRAMES) { | 860 | if(vb->index>=usbvision->num_frames) { |
863 | return -EINVAL; | 861 | return -EINVAL; |
864 | } | 862 | } |
865 | 863 | ||
@@ -1029,6 +1027,7 @@ static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, | |||
1029 | if ((ret = usbvision_stream_interrupt(usbvision))) | 1027 | if ((ret = usbvision_stream_interrupt(usbvision))) |
1030 | return ret; | 1028 | return ret; |
1031 | } | 1029 | } |
1030 | usbvision_frames_free(usbvision); | ||
1032 | usbvision_empty_framequeues(usbvision); | 1031 | usbvision_empty_framequeues(usbvision); |
1033 | 1032 | ||
1034 | usbvision->curFrame = NULL; | 1033 | usbvision->curFrame = NULL; |
@@ -1075,12 +1074,24 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1075 | if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) | 1074 | if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) |
1076 | return -EFAULT; | 1075 | return -EFAULT; |
1077 | 1076 | ||
1078 | /* no stream is running, make it running ! */ | 1077 | /* This entry point is compatible with the mmap routines so that a user can do either |
1079 | usbvision->streaming = Stream_On; | 1078 | VIDIOC_QBUF/VIDIOC_DQBUF to get frames or call read on the device. */ |
1080 | call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL); | 1079 | if(!usbvision->num_frames) { |
1080 | /* First, allocate some frames to work with if this has not been done with | ||
1081 | VIDIOC_REQBUF */ | ||
1082 | usbvision_frames_free(usbvision); | ||
1083 | usbvision_empty_framequeues(usbvision); | ||
1084 | usbvision_frames_alloc(usbvision,USBVISION_NUMFRAMES); | ||
1085 | } | ||
1086 | |||
1087 | if(usbvision->streaming != Stream_On) { | ||
1088 | /* no stream is running, make it running ! */ | ||
1089 | usbvision->streaming = Stream_On; | ||
1090 | call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL); | ||
1091 | } | ||
1081 | 1092 | ||
1082 | /* First, enqueue as many frames as possible (like a user of VIDIOC_QBUF would do) */ | 1093 | /* Then, enqueue as many frames as possible (like a user of VIDIOC_QBUF would do) */ |
1083 | for(i=0;i<USBVISION_NUMFRAMES;i++) { | 1094 | for(i=0;i<usbvision->num_frames;i++) { |
1084 | frame = &usbvision->frame[i]; | 1095 | frame = &usbvision->frame[i]; |
1085 | if(frame->grabstate == FrameState_Unused) { | 1096 | if(frame->grabstate == FrameState_Unused) { |
1086 | /* Mark it as ready and enqueue frame */ | 1097 | /* Mark it as ready and enqueue frame */ |
@@ -1157,6 +1168,8 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1157 | struct video_device *dev = video_devdata(file); | 1168 | struct video_device *dev = video_devdata(file); |
1158 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | 1169 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); |
1159 | 1170 | ||
1171 | PDEBUG(DBG_MMAP, "mmap"); | ||
1172 | |||
1160 | down(&usbvision->lock); | 1173 | down(&usbvision->lock); |
1161 | 1174 | ||
1162 | if (!USBVISION_IS_OPERATIONAL(usbvision)) { | 1175 | if (!USBVISION_IS_OPERATIONAL(usbvision)) { |
@@ -1165,16 +1178,16 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1165 | } | 1178 | } |
1166 | 1179 | ||
1167 | if (!(vma->vm_flags & VM_WRITE) || | 1180 | if (!(vma->vm_flags & VM_WRITE) || |
1168 | size != PAGE_ALIGN(usbvision->curwidth*usbvision->curheight*usbvision->palette.bytes_per_pixel)) { | 1181 | size != PAGE_ALIGN(usbvision->max_frame_size)) { |
1169 | up(&usbvision->lock); | 1182 | up(&usbvision->lock); |
1170 | return -EINVAL; | 1183 | return -EINVAL; |
1171 | } | 1184 | } |
1172 | 1185 | ||
1173 | for (i = 0; i < USBVISION_NUMFRAMES; i++) { | 1186 | for (i = 0; i < usbvision->num_frames; i++) { |
1174 | if (((usbvision->max_frame_size*i) >> PAGE_SHIFT) == vma->vm_pgoff) | 1187 | if (((PAGE_ALIGN(usbvision->max_frame_size)*i) >> PAGE_SHIFT) == vma->vm_pgoff) |
1175 | break; | 1188 | break; |
1176 | } | 1189 | } |
1177 | if (i == USBVISION_NUMFRAMES) { | 1190 | if (i == usbvision->num_frames) { |
1178 | PDEBUG(DBG_MMAP, "mmap: user supplied mapping address is out of range"); | 1191 | PDEBUG(DBG_MMAP, "mmap: user supplied mapping address is out of range"); |
1179 | up(&usbvision->lock); | 1192 | up(&usbvision->lock); |
1180 | return -EINVAL; | 1193 | return -EINVAL; |