diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-08-23 16:48:41 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-09-14 12:13:40 -0400 |
commit | 5614b02143171a99e0e6eb6c7d1d2f8750d2957f (patch) | |
tree | d282d9a88bb11694e548040953bddb8321cf0abf /drivers/media/video/ivtv/ivtv-fileops.c | |
parent | 19299b1a722198830e39264a0f2edadd3fde74c2 (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-fileops.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 5dd519caf81d..0285c4a830eb 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -190,7 +190,9 @@ static void ivtv_update_pgm_info(struct ivtv *itv) | |||
190 | int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num; | 190 | int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num; |
191 | struct v4l2_enc_idx_entry *e = itv->pgm_info + idx; | 191 | struct v4l2_enc_idx_entry *e = itv->pgm_info + idx; |
192 | u32 addr = itv->pgm_info_offset + 4 + idx * 24; | 192 | u32 addr = itv->pgm_info_offset + 4 + idx * 24; |
193 | const int mapping[] = { V4L2_ENC_IDX_FRAME_P, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_B, 0 }; | 193 | const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P, -1, |
194 | V4L2_ENC_IDX_FRAME_B, -1, -1, -1 }; | ||
195 | // 1=I, 2=P, 4=B | ||
194 | 196 | ||
195 | e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32); | 197 | e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 32); |
196 | if (e->offset > itv->mpg_data_received) { | 198 | if (e->offset > itv->mpg_data_received) { |
@@ -199,7 +201,7 @@ static void ivtv_update_pgm_info(struct ivtv *itv) | |||
199 | e->offset += itv->vbi_data_inserted; | 201 | e->offset += itv->vbi_data_inserted; |
200 | e->length = read_enc(addr); | 202 | e->length = read_enc(addr); |
201 | e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32); | 203 | e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) << 32); |
202 | e->flags = mapping[read_enc(addr + 12) & 3]; | 204 | e->flags = mapping[read_enc(addr + 12) & 7]; |
203 | i++; | 205 | i++; |
204 | } | 206 | } |
205 | itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num; | 207 | itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num; |