diff options
author | Andy Walls <awalls@radix.net> | 2008-12-12 14:24:04 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:38:32 -0500 |
commit | dd073434b5285121007860914a004320d644ee7e (patch) | |
tree | 8ead658f43d30b68c07bea8b8f868835da7e5331 /drivers | |
parent | abb096de82f6f920a06ca935f76925261e66b556 (diff) |
V4L/DVB (9805): cx18: Port fix for raw/sliced VBI mixup from ivtv and cx25840
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/cx18/cx18-av-vbi.c | 5 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 6 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-fileops.c | 10 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-ioctl.c | 7 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 6 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-vbi.c | 2 |
7 files changed, 21 insertions, 17 deletions
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c index 02fdf57bb678..1527ea4f6b06 100644 --- a/drivers/media/video/cx18/cx18-av-vbi.c +++ b/drivers/media/video/cx18/cx18-av-vbi.c | |||
@@ -141,10 +141,11 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) | |||
141 | u8 lcr[24]; | 141 | u8 lcr[24]; |
142 | 142 | ||
143 | fmt = arg; | 143 | fmt = arg; |
144 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) | 144 | if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && |
145 | fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) | ||
145 | return -EINVAL; | 146 | return -EINVAL; |
146 | svbi = &fmt->fmt.sliced; | 147 | svbi = &fmt->fmt.sliced; |
147 | if (svbi->service_set == 0) { | 148 | if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { |
148 | /* raw VBI */ | 149 | /* raw VBI */ |
149 | memset(svbi, 0, sizeof(*svbi)); | 150 | memset(svbi, 0, sizeof(*svbi)); |
150 | 151 | ||
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 255d5477567d..e845cd653bb8 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -594,7 +594,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) | |||
594 | init_waitqueue_head(&cx->dma_waitq); | 594 | init_waitqueue_head(&cx->dma_waitq); |
595 | 595 | ||
596 | /* VBI */ | 596 | /* VBI */ |
597 | cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; | 597 | cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; |
598 | cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; | 598 | cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; |
599 | cx->vbi.raw_size = 1456; | 599 | cx->vbi.raw_size = 1456; |
600 | cx->vbi.raw_decoder_line_size = 1456; | 600 | cx->vbi.raw_decoder_line_size = 1456; |
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 29c296f39f91..018d98f94f97 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -504,4 +504,10 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv); | |||
504 | /* First-open initialization: load firmware, etc. */ | 504 | /* First-open initialization: load firmware, etc. */ |
505 | int cx18_init_on_first_open(struct cx18 *cx); | 505 | int cx18_init_on_first_open(struct cx18 *cx); |
506 | 506 | ||
507 | /* Test if the current VBI mode is raw (1) or sliced (0) */ | ||
508 | static inline int cx18_raw_vbi(const struct cx18 *cx) | ||
509 | { | ||
510 | return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; | ||
511 | } | ||
512 | |||
507 | #endif /* CX18_DRIVER_H */ | 513 | #endif /* CX18_DRIVER_H */ |
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 61192e62a80f..1856d59e0cf6 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -67,12 +67,11 @@ static int cx18_claim_stream(struct cx18_open_id *id, int type) | |||
67 | } | 67 | } |
68 | s->id = id->open_id; | 68 | s->id = id->open_id; |
69 | 69 | ||
70 | /* CX18_DEC_STREAM_TYPE_MPG needs to claim CX18_DEC_STREAM_TYPE_VBI, | 70 | /* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI |
71 | CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI | ||
72 | (provided VBI insertion is on and sliced VBI is selected), for all | 71 | (provided VBI insertion is on and sliced VBI is selected), for all |
73 | other streams we're done */ | 72 | other streams we're done */ |
74 | if (type == CX18_ENC_STREAM_TYPE_MPG && | 73 | if (type == CX18_ENC_STREAM_TYPE_MPG && |
75 | cx->vbi.insert_mpeg && cx->vbi.sliced_in->service_set) { | 74 | cx->vbi.insert_mpeg && !cx18_raw_vbi(cx)) { |
76 | vbi_type = CX18_ENC_STREAM_TYPE_VBI; | 75 | vbi_type = CX18_ENC_STREAM_TYPE_VBI; |
77 | } else { | 76 | } else { |
78 | return 0; | 77 | return 0; |
@@ -258,7 +257,7 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s, | |||
258 | if (len > ucount) | 257 | if (len > ucount) |
259 | len = ucount; | 258 | len = ucount; |
260 | if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && | 259 | if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && |
261 | cx->vbi.sliced_in->service_set && buf != &cx->vbi.sliced_mpeg_buf) { | 260 | !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) { |
262 | const char *start = buf->buf + buf->readpos; | 261 | const char *start = buf->buf + buf->readpos; |
263 | const char *p = start + 1; | 262 | const char *p = start + 1; |
264 | const u8 *q; | 263 | const u8 *q; |
@@ -333,8 +332,7 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, | |||
333 | /* Each VBI buffer is one frame, the v4l2 API says that for VBI the | 332 | /* Each VBI buffer is one frame, the v4l2 API says that for VBI the |
334 | frames should arrive one-by-one, so make sure we never output more | 333 | frames should arrive one-by-one, so make sure we never output more |
335 | than one VBI frame at a time */ | 334 | than one VBI frame at a time */ |
336 | if (s->type == CX18_ENC_STREAM_TYPE_VBI && | 335 | if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx)) |
337 | cx->vbi.sliced_in->service_set) | ||
338 | single_frame = 1; | 336 | single_frame = 1; |
339 | 337 | ||
340 | for (;;) { | 338 | for (;;) { |
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index ece799ec37aa..e6087486f889 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -238,13 +238,12 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, | |||
238 | if (ret) | 238 | if (ret) |
239 | return ret; | 239 | return ret; |
240 | 240 | ||
241 | if (id->type == CX18_ENC_STREAM_TYPE_VBI && | 241 | if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) |
242 | cx->vbi.sliced_in->service_set && | ||
243 | atomic_read(&cx->ana_capturing) > 0) | ||
244 | return -EBUSY; | 242 | return -EBUSY; |
245 | 243 | ||
246 | cx->vbi.sliced_in->service_set = 0; | 244 | cx->vbi.sliced_in->service_set = 0; |
247 | cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); | 245 | cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; |
246 | cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); | ||
248 | return cx18_g_fmt_vbi_cap(file, fh, fmt); | 247 | return cx18_g_fmt_vbi_cap(file, fh, fmt); |
249 | } | 248 | } |
250 | 249 | ||
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 9ead4591b1d2..c87cd5369a4f 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -340,7 +340,7 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) | |||
340 | static void cx18_vbi_setup(struct cx18_stream *s) | 340 | static void cx18_vbi_setup(struct cx18_stream *s) |
341 | { | 341 | { |
342 | struct cx18 *cx = s->cx; | 342 | struct cx18 *cx = s->cx; |
343 | int raw = cx->vbi.sliced_in->service_set == 0; | 343 | int raw = cx18_raw_vbi(cx); |
344 | u32 data[CX2341X_MBOX_MAX_DATA]; | 344 | u32 data[CX2341X_MBOX_MAX_DATA]; |
345 | int lines; | 345 | int lines; |
346 | 346 | ||
@@ -471,8 +471,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) | |||
471 | captype = CAPTURE_CHANNEL_TYPE_PCM; | 471 | captype = CAPTURE_CHANNEL_TYPE_PCM; |
472 | break; | 472 | break; |
473 | case CX18_ENC_STREAM_TYPE_VBI: | 473 | case CX18_ENC_STREAM_TYPE_VBI: |
474 | captype = cx->vbi.sliced_in->service_set ? | 474 | captype = cx18_raw_vbi(cx) ? |
475 | CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI; | 475 | CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI; |
476 | cx->vbi.frame = 0; | 476 | cx->vbi.frame = 0; |
477 | cx->vbi.inserted_frame = 0; | 477 | cx->vbi.inserted_frame = 0; |
478 | memset(cx->vbi.sliced_mpeg_size, | 478 | memset(cx->vbi.sliced_mpeg_size, |
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c index 22e76ee3f447..03f0e81307fa 100644 --- a/drivers/media/video/cx18/cx18-vbi.c +++ b/drivers/media/video/cx18/cx18-vbi.c | |||
@@ -160,7 +160,7 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, | |||
160 | return; | 160 | return; |
161 | 161 | ||
162 | /* Raw VBI data */ | 162 | /* Raw VBI data */ |
163 | if (cx->vbi.sliced_in->service_set == 0) { | 163 | if (cx18_raw_vbi(cx)) { |
164 | u8 type; | 164 | u8 type; |
165 | 165 | ||
166 | cx18_buf_swap(buf); | 166 | cx18_buf_swap(buf); |