Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=5614b02143171a99e0e6eb6c7d1d2f8750d2957f
Commit:     5614b02143171a99e0e6eb6c7d1d2f8750d2957f
Parent:     19299b1a722198830e39264a0f2edadd3fde74c2
Author:     Hans Verkuil <[EMAIL PROTECTED]>
AuthorDate: Thu Aug 23 17:48:41 2007 -0300
Committer:  Mauro Carvalho Chehab <[EMAIL PROTECTED]>
CommitDate: Fri Sep 14 13:13:40 2007 -0300

    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 <[EMAIL PROTECTED]>
    Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>
---
 .../video4linux/cx2341x/fw-encoder-api.txt         |    4 +++-
 drivers/media/video/ivtv/ivtv-fileops.c            |    6 ++++--
 drivers/media/video/ivtv/ivtv-ioctl.c              |   17 ++++++++++++-----
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/Documentation/video4linux/cx2341x/fw-encoder-api.txt 
b/Documentation/video4linux/cx2341x/fw-encoder-api.txt
index 5dd3109..5a27af2 100644
--- a/Documentation/video4linux/cx2341x/fw-encoder-api.txt
+++ b/Documentation/video4linux/cx2341x/fw-encoder-api.txt
@@ -407,8 +407,10 @@ Description
                u32 length;             // Length of this frame
                u32 offset_low;         // Offset in the file of the
                u32 offset_high;        // start of this frame
-               u32 mask1;              // Bits 0-1 are the type mask:
+               u32 mask1;              // Bits 0-2 are the type mask:
                                        // 1=I, 2=P, 4=B
+                                       // 0=End of Program Index, other fields
+                                       //   are invalid.
                u32 pts;                // The PTS of the frame
                u32 mask2;              // Bit 0 is bit 32 of the pts.
        };
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c 
b/drivers/media/video/ivtv/ivtv-fileops.c
index 5dd519c..0285c4a 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)
                int idx = (itv->pgm_info_write_idx + i) % itv->pgm_info_num;
                struct v4l2_enc_idx_entry *e = itv->pgm_info + idx;
                u32 addr = itv->pgm_info_offset + 4 + idx * 24;
-               const int mapping[] = { V4L2_ENC_IDX_FRAME_P, 
V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_B, 0 };
+               const int mapping[8] = { -1, V4L2_ENC_IDX_FRAME_I, 
V4L2_ENC_IDX_FRAME_P, -1,
+                       V4L2_ENC_IDX_FRAME_B, -1, -1, -1 };
+                                       // 1=I, 2=P, 4=B
 
                e->offset = read_enc(addr + 4) + ((u64)read_enc(addr + 8) << 
32);
                if (e->offset > itv->mpg_data_received) {
@@ -199,7 +201,7 @@ static void ivtv_update_pgm_info(struct ivtv *itv)
                e->offset += itv->vbi_data_inserted;
                e->length = read_enc(addr);
                e->pts = read_enc(addr + 16) + ((u64)(read_enc(addr + 20) & 1) 
<< 32);
-               e->flags = mapping[read_enc(addr + 12) & 3];
+               e->flags = mapping[read_enc(addr + 12) & 7];
                i++;
        }
        itv->pgm_info_write_idx = (itv->pgm_info_write_idx + i) % 
itv->pgm_info_num;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c 
b/drivers/media/video/ivtv/ivtv-ioctl.c
index 5977a79..dfe0aed 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;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to