V4L/DVB (12199): remove redundant tests on unsigned
[safe/jmp/linux-2.6] / drivers / media / video / cx18 / cx18-vbi.c
index d8e7d37..c2aef4a 100644 (file)
@@ -25,7 +25,6 @@
 #include "cx18-vbi.h"
 #include "cx18-ioctl.h"
 #include "cx18-queue.h"
-#include "cx18-av-core.h"
 
 /*
  * Raster Reference/Protection (RP) bytes, used in Start/End Active
@@ -89,6 +88,8 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
                size = 4 + ((43 * line + 3) & ~3);
        } else {
                memcpy(dst + sd, "itv0", 4);
+               cpu_to_le32s(&linemask[0]);
+               cpu_to_le32s(&linemask[1]);
                memcpy(dst + sd + 4, &linemask[0], 8);
                size = 12 + ((43 * line + 3) & ~3);
        }
@@ -103,59 +104,76 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
 }
 
 /* Compress raw VBI format, removes leading SAV codes and surplus space
-   after the field.
-   Returns new compressed size. */
-static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
+   after the frame.  Returns new compressed size. */
+static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
 {
        u32 line_size = vbi_active_samples;
-       u32 lines = cx->vbi.count;
-       u8 sav1 = raw_vbi_sav_rp[0];
-       u8 sav2 = raw_vbi_sav_rp[1];
+       u32 lines = cx->vbi.count * 2;
        u8 *q = buf;
        u8 *p;
        int i;
 
+       /* Skip the header */
+       buf += hdr_size;
+
        for (i = 0; i < lines; i++) {
                p = buf + i * line_size;
 
                /* Look for SAV code */
                if (p[0] != 0xff || p[1] || p[2] ||
-                   (p[3] != sav1 && p[3] != sav2))
+                   (p[3] != raw_vbi_sav_rp[0] &&
+                    p[3] != raw_vbi_sav_rp[1]))
                        break;
-               memcpy(q, p + 4, line_size - 4);
-               q += line_size - 4;
+               if (i == lines - 1) {
+                       /* last line is hdr_size bytes short - extrapolate it */
+                       memcpy(q, p + 4, line_size - 4 - hdr_size);
+                       q += line_size - 4 - hdr_size;
+                       p += line_size - hdr_size - 1;
+                       memset(q, (int) *p, hdr_size);
+               } else {
+                       memcpy(q, p + 4, line_size - 4);
+                       q += line_size - 4;
+               }
        }
        return lines * (line_size - 4);
 }
 
-
-/* Compressed VBI format, all found sliced blocks put next to one another
-   Returns new compressed size */
-static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
-                              u32 size, u8 eav)
+static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
+                              const u32 hdr_size)
 {
        struct v4l2_decode_vbi_line vbi;
        int i;
+       u32 line = 0;
        u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
                                    : vbi_hblank_samples_50Hz;
 
        /* find the first valid line */
-       for (i = 0; i < size; i++, buf++) {
-               if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == eav)
+       for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
+               if (buf[0] == 0xff && !buf[1] && !buf[2] &&
+                   (buf[3] == sliced_vbi_eav_rp[0] ||
+                    buf[3] == sliced_vbi_eav_rp[1]))
                        break;
        }
 
-       size -= i;
+       /*
+        * The last line is short by hdr_size bytes, but for the remaining
+        * checks against size, we pretend that it is not, by counting the
+        * header bytes we knowingly skipped
+        */
+       size -= (i - hdr_size);
        if (size < line_size)
                return line;
+
        for (i = 0; i < size / line_size; i++) {
                u8 *p = buf + i * line_size;
 
                /* Look for EAV code  */
-               if (p[0] != 0xff || p[1] || p[2] || p[3] != eav)
+               if (p[0] != 0xff || p[1] || p[2] ||
+                   (p[3] != sliced_vbi_eav_rp[0] &&
+                    p[3] != sliced_vbi_eav_rp[1]))
                        continue;
                vbi.p = p + 4;
-               cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
+               v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi);
                if (vbi.type) {
                        cx->vbi.sliced_data[line].id = vbi.type;
                        cx->vbi.sliced_data[line].field = vbi.is_second_field;
@@ -170,8 +188,17 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
 void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
                           int streamtype)
 {
+       /*
+        * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
+        * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp]
+        */
+       struct vbi_data_hdr {
+               __be32 magic;
+               __be32 unknown;
+               __be32 pts;
+       } *hdr = (struct vbi_data_hdr *) buf->buf;
+
        u8 *p = (u8 *) buf->buf;
-       u32 *q = (u32 *) buf->buf;
        u32 size = buf->bytesused;
        u32 pts;
        int lines;
@@ -180,61 +207,35 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
                return;
 
        /*
-        * The CX23418 sends us data that is 32 bit LE swapped, but we want
-        * the raw VBI bytes in the order they were in the raster line
+        * The CX23418 sends us data that is 32 bit little-endian swapped,
+        * but we want the raw VBI bytes in the order they were in the raster
+        * line.  This has a side effect of making the header big endian
         */
        cx18_buf_swap(buf);
 
-       /*
-        * The CX23418 provides a 12 byte header in it's raw VBI buffers to us:
-        * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp?]
-        */
-
        /* Raw VBI data */
        if (cx18_raw_vbi(cx)) {
-               u8 type;
+
+               size = buf->bytesused =
+                    compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr));
 
                /*
-                * We've set up to get a field's worth of VBI data at a time.
-                * Skip 12 bytes of header prefixing the first field or the
-                * last 12 bytes in the last VBI line from the first field that
-                * prefixes the second field.
+                * Hack needed for compatibility with old VBI software.
+                * Write the frame # at the last 4 bytes of the frame
                 */
-               size -= 12;
-               memcpy(p, &buf->buf[12], size);
-               type = p[3];
-
-               /* Extrapolate the last 12 bytes of the field's last line */
-               memset(&p[size], (int) p[size - 1], 12);
-
-               size = buf->bytesused = compress_raw_buf(cx, p, size);
-
-               if (type == raw_vbi_sav_rp[1]) {
-                       /*
-                        * Hack needed for compatibility with old VBI software.
-                        * Write the frame # at the end of the last line of the
-                        * second field
-                        */
-                       p += size - 4;
-                       memcpy(p, &cx->vbi.frame, 4);
-                       cx->vbi.frame++;
-               }
+               p += size - 4;
+               memcpy(p, &cx->vbi.frame, 4);
+               cx->vbi.frame++;
                return;
        }
 
        /* Sliced VBI data with data insertion */
 
-       pts = (be32_to_cpu(q[0] == 0x3fffffff)) ? be32_to_cpu(q[2]) : 0;
-
-       /* first field */
-       /* compress_sliced_buf() will skip the 12 bytes of header */
-       lines = compress_sliced_buf(cx, 0, p, size / 2, sliced_vbi_eav_rp[0]);
-       /* second field */
-       /* experimentation shows that the second half does not always
-          begin at the exact address. So start a bit earlier
-          (hence 32). */
-       lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
-                       size / 2 + 32, sliced_vbi_eav_rp[1]);
+       pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts)
+                                                     : 0;
+
+       lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr));
+
        /* always return at least one empty line */
        if (lines == 0) {
                cx->vbi.sliced_data[0].id = 0;