V4L/DVB (9805): cx18: Port fix for raw/sliced VBI mixup from ivtv and cx25840
authorAndy Walls <awalls@radix.net>
Fri, 12 Dec 2008 19:24:04 +0000 (16:24 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 30 Dec 2008 11:38:32 +0000 (09:38 -0200)
This is a port of the fixes Hans Verkuil made for ivtv/cx25840:
The service_set field was used to determine whether raw or sliced VBI was
desired. This is incorrect since it is perfectly valid to select sliced VBI
with a service_set of 0.

Instead the driver should check on VIDIOC_S_FMT whether the type
field matches the raw or sliced VBI type.

Updated the cx18 driver accordingly, including an additional check in
cx18_start_v4l2_encode_stream() that didn't exist in ivtv.

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

index 02fdf57bb678f1faf5ed0f1671ee435bd1db252b..1527ea4f6b06b83be93e4cdadc6eb9d73537c677 100644 (file)
@@ -141,10 +141,11 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
                u8 lcr[24];
 
                fmt = arg;
-               if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+               if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+                   fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
                        return -EINVAL;
                svbi = &fmt->fmt.sliced;
-               if (svbi->service_set == 0) {
+               if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
                        /* raw VBI */
                        memset(svbi, 0, sizeof(*svbi));
 
index 255d5477567d0c70ffa4a783b6de8dca8557905c..e845cd653bb87964ab609b688f8e21ddc33f58d3 100644 (file)
@@ -594,7 +594,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
        init_waitqueue_head(&cx->dma_waitq);
 
        /* VBI */
-       cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+       cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
        cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
        cx->vbi.raw_size = 1456;
        cx->vbi.raw_decoder_line_size = 1456;
index 29c296f39f915d03dcb50538727c3445fd8ffdd9..018d98f94f97095f29abbd540bf8204f30fa3ffb 100644 (file)
@@ -504,4 +504,10 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv);
 /* First-open initialization: load firmware, etc. */
 int cx18_init_on_first_open(struct cx18 *cx);
 
+/* Test if the current VBI mode is raw (1) or sliced (0) */
+static inline int cx18_raw_vbi(const struct cx18 *cx)
+{
+       return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
+}
+
 #endif /* CX18_DRIVER_H */
index 61192e62a80f37df383302474fbc4299952b905c..1856d59e0cf62791ce18be9525c4f661a5effaa6 100644 (file)
@@ -67,12 +67,11 @@ static int cx18_claim_stream(struct cx18_open_id *id, int type)
        }
        s->id = id->open_id;
 
-       /* CX18_DEC_STREAM_TYPE_MPG needs to claim CX18_DEC_STREAM_TYPE_VBI,
-          CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI
+       /* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI
           (provided VBI insertion is on and sliced VBI is selected), for all
           other streams we're done */
        if (type == CX18_ENC_STREAM_TYPE_MPG &&
-                  cx->vbi.insert_mpeg && cx->vbi.sliced_in->service_set) {
+           cx->vbi.insert_mpeg && !cx18_raw_vbi(cx)) {
                vbi_type = CX18_ENC_STREAM_TYPE_VBI;
        } else {
                return 0;
@@ -258,7 +257,7 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
        if (len > ucount)
                len = ucount;
        if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
-           cx->vbi.sliced_in->service_set && buf != &cx->vbi.sliced_mpeg_buf) {
+           !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
                const char *start = buf->buf + buf->readpos;
                const char *p = start + 1;
                const u8 *q;
@@ -333,8 +332,7 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf,
        /* Each VBI buffer is one frame, the v4l2 API says that for VBI the
           frames should arrive one-by-one, so make sure we never output more
           than one VBI frame at a time */
-       if (s->type == CX18_ENC_STREAM_TYPE_VBI &&
-           cx->vbi.sliced_in->service_set)
+       if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx))
                single_frame = 1;
 
        for (;;) {
index ece799ec37aad31bd04472686dbdb06bb1b72f86..e6087486f889d77b997c9eafd62ae01d69f0fbfa 100644 (file)
@@ -238,13 +238,12 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
        if (ret)
                return ret;
 
-       if (id->type == CX18_ENC_STREAM_TYPE_VBI &&
-                       cx->vbi.sliced_in->service_set &&
-                       atomic_read(&cx->ana_capturing) > 0)
+       if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
                return -EBUSY;
 
        cx->vbi.sliced_in->service_set = 0;
-       cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
+       cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
+       cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
        return cx18_g_fmt_vbi_cap(file, fh, fmt);
 }
 
index 9ead4591b1d2ca6a24150932989ee6d419fa7dc5..c87cd5369a4f228e0ead53cb08e18b193a9ce83d 100644 (file)
@@ -340,7 +340,7 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
 static void cx18_vbi_setup(struct cx18_stream *s)
 {
        struct cx18 *cx = s->cx;
-       int raw = cx->vbi.sliced_in->service_set == 0;
+       int raw = cx18_raw_vbi(cx);
        u32 data[CX2341X_MBOX_MAX_DATA];
        int lines;
 
@@ -471,8 +471,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
                captype = CAPTURE_CHANNEL_TYPE_PCM;
                break;
        case CX18_ENC_STREAM_TYPE_VBI:
-               captype = cx->vbi.sliced_in->service_set ?
-                   CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI;
+               captype = cx18_raw_vbi(cx) ?
+                    CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
                cx->vbi.frame = 0;
                cx->vbi.inserted_frame = 0;
                memset(cx->vbi.sliced_mpeg_size,
index 22e76ee3f4475341a9246b66c6659ce8478aa586..03f0e81307fa2eb1dd34906f344be59a83985c63 100644 (file)
@@ -160,7 +160,7 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
                return;
 
        /* Raw VBI data */
-       if (cx->vbi.sliced_in->service_set == 0) {
+       if (cx18_raw_vbi(cx)) {
                u8 type;
 
                cx18_buf_swap(buf);