Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Andy Walls and committed by
Mauro Carvalho Chehab
dd073434 abb096de

+21 -17
+3 -2
drivers/media/video/cx18/cx18-av-vbi.c
··· 141 141 u8 lcr[24]; 142 142 143 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 146 return -EINVAL; 146 147 svbi = &fmt->fmt.sliced; 147 - if (svbi->service_set == 0) { 148 + if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 148 149 /* raw VBI */ 149 150 memset(svbi, 0, sizeof(*svbi)); 150 151
+1 -1
drivers/media/video/cx18/cx18-driver.c
··· 594 594 init_waitqueue_head(&cx->dma_waitq); 595 595 596 596 /* VBI */ 597 - cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 597 + cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; 598 598 cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; 599 599 cx->vbi.raw_size = 1456; 600 600 cx->vbi.raw_decoder_line_size = 1456;
+6
drivers/media/video/cx18/cx18-driver.h
··· 504 504 /* First-open initialization: load firmware, etc. */ 505 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 513 #endif /* CX18_DRIVER_H */
+4 -6
drivers/media/video/cx18/cx18-fileops.c
··· 67 67 } 68 68 s->id = id->open_id; 69 69 70 - /* CX18_DEC_STREAM_TYPE_MPG needs to claim CX18_DEC_STREAM_TYPE_VBI, 71 - CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI 70 + /* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI 72 71 (provided VBI insertion is on and sliced VBI is selected), for all 73 72 other streams we're done */ 74 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 75 vbi_type = CX18_ENC_STREAM_TYPE_VBI; 77 76 } else { 78 77 return 0; ··· 257 258 if (len > ucount) 258 259 len = ucount; 259 260 if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && 260 - cx->vbi.sliced_in->service_set && buf != &cx->vbi.sliced_mpeg_buf) { 261 + !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) { 261 262 const char *start = buf->buf + buf->readpos; 262 263 const char *p = start + 1; 263 264 const u8 *q; ··· 332 333 /* Each VBI buffer is one frame, the v4l2 API says that for VBI the 333 334 frames should arrive one-by-one, so make sure we never output more 334 335 than one VBI frame at a time */ 335 - if (s->type == CX18_ENC_STREAM_TYPE_VBI && 336 - cx->vbi.sliced_in->service_set) 336 + if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx)) 337 337 single_frame = 1; 338 338 339 339 for (;;) {
+3 -4
drivers/media/video/cx18/cx18-ioctl.c
··· 238 238 if (ret) 239 239 return ret; 240 240 241 - if (id->type == CX18_ENC_STREAM_TYPE_VBI && 242 - cx->vbi.sliced_in->service_set && 243 - atomic_read(&cx->ana_capturing) > 0) 241 + if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) 244 242 return -EBUSY; 245 243 246 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 247 return cx18_g_fmt_vbi_cap(file, fh, fmt); 249 248 } 250 249
+3 -3
drivers/media/video/cx18/cx18-streams.c
··· 340 340 static void cx18_vbi_setup(struct cx18_stream *s) 341 341 { 342 342 struct cx18 *cx = s->cx; 343 - int raw = cx->vbi.sliced_in->service_set == 0; 343 + int raw = cx18_raw_vbi(cx); 344 344 u32 data[CX2341X_MBOX_MAX_DATA]; 345 345 int lines; 346 346 ··· 471 471 captype = CAPTURE_CHANNEL_TYPE_PCM; 472 472 break; 473 473 case CX18_ENC_STREAM_TYPE_VBI: 474 - captype = cx->vbi.sliced_in->service_set ? 475 - CAPTURE_CHANNEL_TYPE_SLICED_VBI : CAPTURE_CHANNEL_TYPE_VBI; 474 + captype = cx18_raw_vbi(cx) ? 475 + CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI; 476 476 cx->vbi.frame = 0; 477 477 cx->vbi.inserted_frame = 0; 478 478 memset(cx->vbi.sliced_mpeg_size,
+1 -1
drivers/media/video/cx18/cx18-vbi.c
··· 160 160 return; 161 161 162 162 /* Raw VBI data */ 163 - if (cx->vbi.sliced_in->service_set == 0) { 163 + if (cx18_raw_vbi(cx)) { 164 164 u8 type; 165 165 166 166 cx18_buf_swap(buf);