V4L/DVB (10445): cx18: Process Raw VBI on a whole frame basis; fix VBI buffer size
authorAndy Walls <awalls@radix.net>
Sat, 7 Feb 2009 18:47:28 +0000 (15:47 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 30 Mar 2009 15:42:39 +0000 (12:42 -0300)
The cx23418 appears to send Raw VBI buffers with a PTS on a per frame
basis, not per field, so process Raw VBI on a whole frame basis and reduce
some complexity.  Fix VBI buffer size computation to handle a whole
frame of Raw VBI for a 625 line system, which is the worst case and will
work for 525 lines systems as well.

Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/cx18/cx18-driver.c
drivers/media/video/cx18/cx18-vbi.c

index 842ce63..3cf8ddb 100644 (file)
@@ -448,34 +448,38 @@ static void cx18_process_options(struct cx18 *cx)
        cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
        cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
        cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
-       cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
+       cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
        cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
        cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
 
-       /* Except for VBI ensure stream_buffers & stream_buf_size are valid */
+       /* Ensure stream_buffers & stream_buf_size are valid */
        for (i = 0; i < CX18_MAX_STREAMS; i++) {
-               /* User said to use 0 buffers */
-               if (cx->stream_buffers[i] == 0) {
-                       cx->options.megabytes[i] = 0;
-                       cx->stream_buf_size[i] = 0;
-                       continue;
-               }
-               /* User said to use 0 MB total */
-               if (cx->options.megabytes[i] <= 0) {
+               if (cx->stream_buffers[i] == 0 ||     /* User said 0 buffers */
+                   cx->options.megabytes[i] <= 0 ||  /* User said 0 MB total */
+                   cx->stream_buf_size[i] <= 0) {    /* User said buf size 0 */
                        cx->options.megabytes[i] = 0;
                        cx->stream_buffers[i] = 0;
                        cx->stream_buf_size[i] = 0;
                        continue;
                }
-               /* VBI is computed later or user said buffer has size 0 */
-               if (cx->stream_buf_size[i] <= 0) {
-                       if (i != CX18_ENC_STREAM_TYPE_VBI) {
-                               cx->options.megabytes[i] = 0;
-                               cx->stream_buffers[i] = 0;
-                               cx->stream_buf_size[i] = 0;
+               /*
+                * VBI is a special case where the stream_buf_size is fixed
+                * and already in bytes
+                */
+               if (i == CX18_ENC_STREAM_TYPE_VBI) {
+                       if (cx->stream_buffers[i] < 0) {
+                               cx->stream_buffers[i] =
+                                       cx->options.megabytes[i] * 1024 * 1024
+                                       / cx->stream_buf_size[i];
+                       } else {
+                               /* N.B. This might round down to 0 */
+                               cx->options.megabytes[i] =
+                                       cx->stream_buffers[i]
+                                       * cx->stream_buf_size[i]/(1024 * 1024);
                        }
                        continue;
                }
+               /* All other streams have stream_buf_size in kB at this point */
                if (cx->stream_buffers[i] < 0) {
                        cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
                                                / cx->stream_buf_size[i];
@@ -732,7 +736,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
 {
        int retval = 0;
        int i;
-       int vbi_buf_size;
        u32 devtype;
        struct cx18 *cx;
 
@@ -888,23 +891,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
        }
        cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
 
-       /*
-        * FIXME: setting the buffer size based on the tuner standard is
-        * suboptimal, as the CVBS and SVideo inputs could use a different std
-        * and the buffer could end up being too small in that case.
-        */
-       vbi_buf_size = vbi_active_samples * (cx->is_60hz ? 24 : 36) / 2;
-       cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
-
-       if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
-               cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
-                  cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
-                  / vbi_buf_size;
-       else
-               cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
-                    cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
-                    / (1024 * 1024);
-
        if (cx->options.radio > 0)
                cx->v4l2_cap |= V4L2_CAP_RADIO;
 
index d8e7d37..52082d4 100644 (file)
@@ -103,12 +103,11 @@ 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. */
+   after the frame.  Returns new compressed size. */
 static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
 {
        u32 line_size = vbi_active_samples;
-       u32 lines = cx->vbi.count;
+       u32 lines = cx->vbi.count * 2;
        u8 sav1 = raw_vbi_sav_rp[0];
        u8 sav2 = raw_vbi_sav_rp[1];
        u8 *q = buf;
@@ -195,30 +194,26 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
                u8 type;
 
                /*
-                * 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.
+                * We've set up to get a frame's worth of VBI data at a time.
+                * Skip 12 bytes of header prefixing the first field.
                 */
                size -= 12;
                memcpy(p, &buf->buf[12], size);
                type = p[3];
 
-               /* Extrapolate the last 12 bytes of the field's last line */
+               /* Extrapolate the last 12 bytes of the frame's last line */
                memset(&p[size], (int) p[size - 1], 12);
+               size += 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++;
-               }
+               /*
+                * Hack needed for compatibility with old VBI software.
+                * Write the frame # at the last 4 bytes of the frame
+                */
+               p += size - 4;
+               memcpy(p, &cx->vbi.frame, 4);
+               cx->vbi.frame++;
                return;
        }