summaryrefslogtreecommitdiff
path: root/drivers/media/video/ivtv/ivtv-ioctl.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-08-23 17:48:41 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-09-14 13:13:40 -0300
commit5614b02143171a99e0e6eb6c7d1d2f8750d2957f (patch)
treed282d9a88bb11694e548040953bddb8321cf0abf /drivers/media/video/ivtv/ivtv-ioctl.c
parent19299b1a722198830e39264a0f2edadd3fde74c2 (diff)
V4L/DVB (6095): ivtv: fix VIDIOC_G_ENC_INDEX flag handling
Due to a documentation bug (the type mask is 3 bits long, not 2) the wrong frame types were filled in: the B and P frame types were swapped. This bug also hid a second bug: when a capture is stopped a last entry is written into the pgm index buffer with internal type 0, denoting the end of the program. This entry wasn't ignored, instead it was accidentally returned to the caller as a P frame. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-ioctl.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 5977a79619c2..dfe0aedc60fd 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1099,14 +1099,21 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
case VIDIOC_G_ENC_INDEX: {
struct v4l2_enc_idx *idx = arg;
+ struct v4l2_enc_idx_entry *e = idx->entry;
+ int entries;
int i;
- idx->entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
+ entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
IVTV_MAX_PGM_INDEX;
- if (idx->entries > V4L2_ENC_IDX_ENTRIES)
- idx->entries = V4L2_ENC_IDX_ENTRIES;
- for (i = 0; i < idx->entries; i++) {
- idx->entry[i] = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
+ if (entries > V4L2_ENC_IDX_ENTRIES)
+ entries = V4L2_ENC_IDX_ENTRIES;
+ idx->entries = 0;
+ for (i = 0; i < entries; i++) {
+ *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
+ if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
+ idx->entries++;
+ e++;
+ }
}
itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
break;