V4L/DVB (9162): ivtv: fix raw/sliced VBI mixup
The service_set field was used in saa7115 and cx25840 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 these drivers should checked on VIDIOC_S_FMT whether the type field matches the raw or sliced VBI type. Updated ivtv accordingly. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
3c7b933bea
commit
a8b864354e
|
@ -141,10 +141,11 @@ int cx25840_vbi(struct i2c_client *client, 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));
|
||||
|
||||
|
|
|
@ -720,7 +720,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
|
|||
itv->speed = 1000;
|
||||
|
||||
/* VBI */
|
||||
itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
|
||||
itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
itv->vbi.sliced_in = &itv->vbi.in.fmt.sliced;
|
||||
|
||||
/* Init the sg table for osd/yuv output */
|
||||
|
|
|
@ -750,6 +750,12 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
|
|||
/* First-open initialization: load firmware, init cx25840, etc. */
|
||||
int ivtv_init_on_first_open(struct ivtv *itv);
|
||||
|
||||
/* Test if the current VBI mode is raw (1) or sliced (0) */
|
||||
static inline int ivtv_raw_vbi(const struct ivtv *itv)
|
||||
{
|
||||
return itv->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
}
|
||||
|
||||
/* This is a PCI post thing, where if the pci register is not read, then
|
||||
the write doesn't always take effect right away. By reading back the
|
||||
register any pending PCI writes will be performed (in order), and so
|
||||
|
|
|
@ -78,7 +78,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
|
|||
if (type == IVTV_DEC_STREAM_TYPE_MPG) {
|
||||
vbi_type = IVTV_DEC_STREAM_TYPE_VBI;
|
||||
} else if (type == IVTV_ENC_STREAM_TYPE_MPG &&
|
||||
itv->vbi.insert_mpeg && itv->vbi.sliced_in->service_set) {
|
||||
itv->vbi.insert_mpeg && !ivtv_raw_vbi(itv)) {
|
||||
vbi_type = IVTV_ENC_STREAM_TYPE_VBI;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -305,7 +305,7 @@ static size_t ivtv_copy_buf_to_user(struct ivtv_stream *s, struct ivtv_buffer *b
|
|||
|
||||
if (len > ucount) len = ucount;
|
||||
if (itv->vbi.insert_mpeg && s->type == IVTV_ENC_STREAM_TYPE_MPG &&
|
||||
itv->vbi.sliced_in->service_set && buf != &itv->vbi.sliced_mpeg_buf) {
|
||||
!ivtv_raw_vbi(itv) && buf != &itv->vbi.sliced_mpeg_buf) {
|
||||
const char *start = buf->buf + buf->readpos;
|
||||
const char *p = start + 1;
|
||||
const u8 *q;
|
||||
|
@ -372,7 +372,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co
|
|||
/* 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 == IVTV_DEC_STREAM_TYPE_VBI ||
|
||||
(s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set))
|
||||
(s->type == IVTV_ENC_STREAM_TYPE_VBI && !ivtv_raw_vbi(itv)))
|
||||
single_frame = 1;
|
||||
|
||||
for (;;) {
|
||||
|
|
|
@ -575,8 +575,11 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
|
|||
{
|
||||
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
|
||||
|
||||
if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
|
||||
return -EBUSY;
|
||||
itv->vbi.sliced_in->service_set = 0;
|
||||
itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
|
||||
itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
|
||||
itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
|
||||
return ivtv_g_fmt_vbi_cap(file, fh, fmt);
|
||||
}
|
||||
|
||||
|
@ -591,8 +594,9 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
|
|||
return ret;
|
||||
|
||||
check_service_set(vbifmt, itv->is_50hz);
|
||||
if (atomic_read(&itv->capturing) > 0)
|
||||
if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
|
||||
return -EBUSY;
|
||||
itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
|
||||
itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
|
||||
memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
|
||||
return 0;
|
||||
|
|
|
@ -334,7 +334,7 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
|
|||
|
||||
static void ivtv_vbi_setup(struct ivtv *itv)
|
||||
{
|
||||
int raw = itv->vbi.sliced_in->service_set == 0;
|
||||
int raw = ivtv_raw_vbi(itv);
|
||||
u32 data[CX2341X_MBOX_MAX_DATA];
|
||||
int lines;
|
||||
int i;
|
||||
|
|
|
@ -334,7 +334,7 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
|
|||
int y;
|
||||
|
||||
/* Raw VBI data */
|
||||
if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
|
||||
if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
|
||||
u8 type;
|
||||
|
||||
ivtv_buf_swap(buf);
|
||||
|
|
|
@ -1057,7 +1057,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
|
|||
for (i = 0; i <= 23; i++)
|
||||
lcr[i] = 0xff;
|
||||
|
||||
if (fmt->service_set == 0) {
|
||||
if (fmt == NULL) {
|
||||
/* raw VBI */
|
||||
if (is_50hz)
|
||||
for (i = 6; i <= 23; i++)
|
||||
|
@ -1113,7 +1113,7 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
|
|||
}
|
||||
|
||||
/* enable/disable raw VBI capturing */
|
||||
saa711x_writeregs(client, fmt->service_set == 0 ?
|
||||
saa711x_writeregs(client, fmt == NULL ?
|
||||
saa7115_cfg_vbi_on :
|
||||
saa7115_cfg_vbi_off);
|
||||
}
|
||||
|
@ -1153,6 +1153,10 @@ static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
|
|||
saa711x_set_lcr(client, &fmt->fmt.sliced);
|
||||
return 0;
|
||||
}
|
||||
if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
|
||||
saa711x_set_lcr(client, NULL);
|
||||
return 0;
|
||||
}
|
||||
if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue