summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/ivtv
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2008-10-04 13:05:30 +0200
committerHans Verkuil <hverkuil@xs4all.nl>2008-10-04 13:05:30 +0200
commitaaf607f3c971b0096b4082f6dbd1d888f8b15f26 (patch)
tree135e8720489c7e7e0f46aea39af475129e504409 /linux/drivers/media/video/ivtv
parent046cd15a6775f8a911dd372ee50a9faec4239d0b (diff)
downloadmediapointer-dvb-s2-aaf607f3c971b0096b4082f6dbd1d888f8b15f26.tar.gz
mediapointer-dvb-s2-aaf607f3c971b0096b4082f6dbd1d888f8b15f26.tar.bz2
ivtv: fix raw/sliced VBI mixup
From: Hans Verkuil <hverkuil@xs4all.nl> 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. Priority: normal Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Diffstat (limited to 'linux/drivers/media/video/ivtv')
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-driver.h6
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-fileops.c6
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-ioctl.c8
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-streams.c2
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-vbi.c2
6 files changed, 18 insertions, 8 deletions
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c
index 8c07b9bc8..c9750a058 100644
--- a/linux/drivers/media/video/ivtv/ivtv-driver.c
+++ b/linux/drivers/media/video/ivtv/ivtv-driver.c
@@ -724,7 +724,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 */
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h
index 80673a3da..fb83736cc 100644
--- a/linux/drivers/media/video/ivtv/ivtv-driver.h
+++ b/linux/drivers/media/video/ivtv/ivtv-driver.h
@@ -751,6 +751,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
diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c
index 304261efc..b7457fc60 100644
--- a/linux/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c
@@ -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 (;;) {
diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
index f5b289ef4..3d0013bdd 100644
--- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -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;
diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c
index 24273fbea..5bbf31e39 100644
--- a/linux/drivers/media/video/ivtv/ivtv-streams.c
+++ b/linux/drivers/media/video/ivtv/ivtv-streams.c
@@ -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;
diff --git a/linux/drivers/media/video/ivtv/ivtv-vbi.c b/linux/drivers/media/video/ivtv/ivtv-vbi.c
index 1ce9deb11..4a37a7d2e 100644
--- a/linux/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/linux/drivers/media/video/ivtv/ivtv-vbi.c
@@ -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);