aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt8xx/bttv-vbi.c
diff options
context:
space:
mode:
authorMichael Schimek <mschimek@gmx.at>2007-01-18 14:17:39 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-02-21 10:34:36 -0500
commite5bd0260e7d3d806e66c12859f50733dca43bbcf (patch)
tree7a726da52b8155357a08e4feb7e0e79084673fa0 /drivers/media/video/bt8xx/bttv-vbi.c
parent13071f0a58f285eee81f63c917078bb2a48cf51e (diff)
V4L/DVB (5077): Bttv cropping support
Adds the missing VIDIOC_CROPCAP, G_CROP and S_CROP ioctls, permitting applications to capture or overlay a subsection of the picture or to extend the capture window beyond active video, into the VBI area and the horizontal blanking. VBI capturing can start and end on any line, including the picture area, and apps can capture different lines of each field and single fields. For compatibility with existing applications, the open() function resets the cropping and VBI capturing parameters and a VIDIOC_S_CROP call is necessary to actually enable cropping. Regrettably in PAL-M, PAL-N, PAL-Nc and NTSC-JP mode the maximum image width will increase from 640 and 768 to 747 and 923 pixels respectively. Like the VBI changes however, this should only affect applications which depend on former driver limitations, such as never getting more than 640 pixels regardless of the requested width. Also, new freedoms require additional checks for conflicts and some applications may not expect an EBUSY error from the VIDIOC_QBUF and VIDIOCMCAPTURE ioctls. These errors should be rare though. So far, the patch has been tested on a UP machine with a bt878 in PAL- BGHI and NTSC-M mode using xawtv, tvtime, mplayer/mencoder, zapping/ libzvbi and these tools: http://zapping.sf.net/bttv-crop-test.tar.bz2 I'd be grateful about comments or bug reports. Signed-off-by: Michael H. Schimek <mschimek@gmx.at> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/bt8xx/bttv-vbi.c')
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c366
1 files changed, 298 insertions, 68 deletions
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
index 6fc6b0260056..754f66bfdf46 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -5,6 +5,9 @@
5 5
6 (c) 2002 Gerd Knorr <kraxel@bytesex.org> 6 (c) 2002 Gerd Knorr <kraxel@bytesex.org>
7 7
8 Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at>
9 Sponsored by OPQ Systems AB
10
8 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 12 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 13 the Free Software Foundation; either version 2 of the License, or
@@ -41,8 +44,15 @@
41 to be about 244. */ 44 to be about 244. */
42#define VBI_OFFSET 244 45#define VBI_OFFSET 244
43 46
47/* 2048 for compatibility with earlier driver versions. The driver
48 really stores 1024 + tvnorm->vbipack * 4 samples per line in the
49 buffer. Note tvnorm->vbipack is <= 0xFF (limit of VBIPACK_LO + HI
50 is 0x1FF DWORDs) and VBI read()s store a frame counter in the last
51 four bytes of the VBI image. */
52#define VBI_BPL 2048
53
54/* Compatibility. */
44#define VBI_DEFLINES 16 55#define VBI_DEFLINES 16
45#define VBI_MAXLINES 32
46 56
47static unsigned int vbibufs = 4; 57static unsigned int vbibufs = 4;
48static unsigned int vbi_debug = 0; 58static unsigned int vbi_debug = 0;
@@ -58,21 +68,12 @@ MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
58#define dprintk(fmt, arg...) if (vbi_debug) \ 68#define dprintk(fmt, arg...) if (vbi_debug) \
59 printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg) 69 printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg)
60 70
71#define IMAGE_SIZE(fmt) \
72 (((fmt)->count[0] + (fmt)->count[1]) * (fmt)->samples_per_line)
73
61/* ----------------------------------------------------------------------- */ 74/* ----------------------------------------------------------------------- */
62/* vbi risc code + mm */ 75/* vbi risc code + mm */
63 76
64static int
65vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines)
66{
67 int bpl = 2048;
68
69 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
70 0, bpl-4, 4, lines);
71 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
72 lines * bpl, bpl-4, 4, lines);
73 return 0;
74}
75
76static int vbi_buffer_setup(struct videobuf_queue *q, 77static int vbi_buffer_setup(struct videobuf_queue *q,
77 unsigned int *count, unsigned int *size) 78 unsigned int *count, unsigned int *size)
78{ 79{
@@ -81,8 +82,16 @@ static int vbi_buffer_setup(struct videobuf_queue *q,
81 82
82 if (0 == *count) 83 if (0 == *count)
83 *count = vbibufs; 84 *count = vbibufs;
84 *size = fh->lines * 2 * 2048; 85
85 dprintk("setup: lines=%d\n",fh->lines); 86 *size = IMAGE_SIZE(&fh->vbi_fmt.fmt);
87
88 dprintk("setup: samples=%u start=%d,%d count=%u,%u\n",
89 fh->vbi_fmt.fmt.samples_per_line,
90 fh->vbi_fmt.fmt.start[0],
91 fh->vbi_fmt.fmt.start[1],
92 fh->vbi_fmt.fmt.count[0],
93 fh->vbi_fmt.fmt.count[1]);
94
86 return 0; 95 return 0;
87} 96}
88 97
@@ -93,18 +102,93 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
93 struct bttv_fh *fh = q->priv_data; 102 struct bttv_fh *fh = q->priv_data;
94 struct bttv *btv = fh->btv; 103 struct bttv *btv = fh->btv;
95 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); 104 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
105 const struct bttv_tvnorm *tvnorm;
106 unsigned int skip_lines0, skip_lines1, min_vdelay;
107 int redo_dma_risc;
96 int rc; 108 int rc;
97 109
98 buf->vb.size = fh->lines * 2 * 2048; 110 buf->vb.size = IMAGE_SIZE(&fh->vbi_fmt.fmt);
99 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 111 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
100 return -EINVAL; 112 return -EINVAL;
101 113
114 tvnorm = fh->vbi_fmt.tvnorm;
115
116 /* There's no VBI_VDELAY register, RISC must skip the lines
117 we don't want. With default parameters we skip zero lines
118 as earlier driver versions did. The driver permits video
119 standard changes while capturing, so we use vbi_fmt.tvnorm
120 instead of btv->tvnorm to skip zero lines after video
121 standard changes as well. */
122
123 skip_lines0 = 0;
124 skip_lines1 = 0;
125
126 if (fh->vbi_fmt.fmt.count[0] > 0)
127 skip_lines0 = max(0, (fh->vbi_fmt.fmt.start[0]
128 - tvnorm->vbistart[0]));
129 if (fh->vbi_fmt.fmt.count[1] > 0)
130 skip_lines1 = max(0, (fh->vbi_fmt.fmt.start[1]
131 - tvnorm->vbistart[1]));
132
133 redo_dma_risc = 0;
134
135 if (buf->vbi_skip[0] != skip_lines0 ||
136 buf->vbi_skip[1] != skip_lines1 ||
137 buf->vbi_count[0] != fh->vbi_fmt.fmt.count[0] ||
138 buf->vbi_count[1] != fh->vbi_fmt.fmt.count[1]) {
139 buf->vbi_skip[0] = skip_lines0;
140 buf->vbi_skip[1] = skip_lines1;
141 buf->vbi_count[0] = fh->vbi_fmt.fmt.count[0];
142 buf->vbi_count[1] = fh->vbi_fmt.fmt.count[1];
143 redo_dma_risc = 1;
144 }
145
102 if (STATE_NEEDS_INIT == buf->vb.state) { 146 if (STATE_NEEDS_INIT == buf->vb.state) {
147 redo_dma_risc = 1;
103 if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) 148 if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
104 goto fail; 149 goto fail;
105 if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
106 goto fail;
107 } 150 }
151
152 if (redo_dma_risc) {
153 unsigned int bpl, padding, offset;
154
155 bpl = 2044; /* max. vbipack */
156 padding = VBI_BPL - bpl;
157
158 if (fh->vbi_fmt.fmt.count[0] > 0) {
159 rc = bttv_risc_packed(btv, &buf->top,
160 buf->vb.dma.sglist,
161 /* offset */ 0, bpl,
162 padding, skip_lines0,
163 fh->vbi_fmt.fmt.count[0]);
164 if (0 != rc)
165 goto fail;
166 }
167
168 if (fh->vbi_fmt.fmt.count[1] > 0) {
169 offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL;
170
171 rc = bttv_risc_packed(btv, &buf->bottom,
172 buf->vb.dma.sglist,
173 offset, bpl,
174 padding, skip_lines1,
175 fh->vbi_fmt.fmt.count[1]);
176 if (0 != rc)
177 goto fail;
178 }
179 }
180
181 /* VBI capturing ends at VDELAY, start of video capturing,
182 no matter where the RISC program ends. VDELAY minimum is 2,
183 bounds.top is the corresponding first field line number
184 times two. VDELAY counts half field lines. */
185 min_vdelay = MIN_VDELAY;
186 if (fh->vbi_fmt.end >= tvnorm->cropcap.bounds.top)
187 min_vdelay += fh->vbi_fmt.end - tvnorm->cropcap.bounds.top;
188
189 /* For bttv_buffer_activate_vbi(). */
190 buf->geo.vdelay = min_vdelay;
191
108 buf->vb.state = STATE_PREPARED; 192 buf->vb.state = STATE_PREPARED;
109 buf->vb.field = field; 193 buf->vb.field = field;
110 dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", 194 dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
@@ -152,69 +236,215 @@ struct videobuf_queue_ops bttv_vbi_qops = {
152 236
153/* ----------------------------------------------------------------------- */ 237/* ----------------------------------------------------------------------- */
154 238
155void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines) 239static int
240try_fmt (struct v4l2_vbi_format * f,
241 const struct bttv_tvnorm * tvnorm,
242 __s32 crop_start)
156{ 243{
157 int vdelay; 244 __s32 min_start, max_start, max_end, f2_offset;
158 245 unsigned int i;
159 if (lines < 1) 246
160 lines = 1; 247 /* For compatibility with earlier driver versions we must pretend
161 if (lines > VBI_MAXLINES) 248 the VBI and video capture window may overlap. In reality RISC
162 lines = VBI_MAXLINES; 249 magic aborts VBI capturing at the first line of video capturing,
163 fh->lines = lines; 250 leaving the rest of the buffer unchanged, usually all zero.
164 251 VBI capturing must always start before video capturing. >> 1
165 vdelay = btread(BT848_E_VDELAY_LO); 252 because cropping counts field lines times two. */
166 if (vdelay < lines*2) { 253 min_start = tvnorm->vbistart[0];
167 vdelay = lines*2; 254 max_start = (crop_start >> 1) - 1;
168 btwrite(vdelay,BT848_E_VDELAY_LO); 255 max_end = (tvnorm->cropcap.bounds.top
169 btwrite(vdelay,BT848_O_VDELAY_LO); 256 + tvnorm->cropcap.bounds.height) >> 1;
257
258 if (min_start > max_start)
259 return -EBUSY;
260
261 BUG_ON(max_start >= max_end);
262
263 f->sampling_rate = tvnorm->Fsc;
264 f->samples_per_line = VBI_BPL;
265 f->sample_format = V4L2_PIX_FMT_GREY;
266 f->offset = VBI_OFFSET;
267
268 f2_offset = tvnorm->vbistart[1] - tvnorm->vbistart[0];
269
270 for (i = 0; i < 2; ++i) {
271 if (0 == f->count[i]) {
272 /* No data from this field. We leave f->start[i]
273 alone because VIDIOCSVBIFMT is w/o and EINVALs
274 when a driver does not support exactly the
275 requested parameters. */
276 } else {
277 s64 start, count;
278
279 start = clamp(f->start[i], min_start, max_start);
280 /* s64 to prevent overflow. */
281 count = (s64) f->start[i] + f->count[i] - start;
282 f->start[i] = start;
283 f->count[i] = clamp(count, (s64) 1,
284 max_end - start);
285 }
286
287 min_start += f2_offset;
288 max_start += f2_offset;
289 max_end += f2_offset;
170 } 290 }
291
292 if (0 == (f->count[0] | f->count[1])) {
293 /* As in earlier driver versions. */
294 f->start[0] = tvnorm->vbistart[0];
295 f->start[1] = tvnorm->vbistart[1];
296 f->count[0] = 1;
297 f->count[1] = 1;
298 }
299
300 f->flags = 0;
301
302 f->reserved[0] = 0;
303 f->reserved[1] = 0;
304
305 return 0;
171} 306}
172 307
173void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) 308int
309bttv_vbi_try_fmt (struct bttv_fh * fh,
310 struct v4l2_vbi_format * f)
174{ 311{
312 struct bttv *btv = fh->btv;
175 const struct bttv_tvnorm *tvnorm; 313 const struct bttv_tvnorm *tvnorm;
176 s64 count0,count1,count; 314 __s32 crop_start;
177 315
178 tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; 316 mutex_lock(&btv->lock);
179 f->type = V4L2_BUF_TYPE_VBI_CAPTURE; 317
180 f->fmt.vbi.sampling_rate = tvnorm->Fsc; 318 tvnorm = &bttv_tvnorms[btv->tvnorm];
181 f->fmt.vbi.samples_per_line = 2048; 319 crop_start = btv->crop_start;
182 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 320
183 f->fmt.vbi.offset = VBI_OFFSET; 321 mutex_unlock(&btv->lock);
184 f->fmt.vbi.flags = 0; 322
185 323 return try_fmt(f, tvnorm, crop_start);
186 /* s64 to prevent overflow. */
187 count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0]
188 - tvnorm->vbistart[0];
189 count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1]
190 - tvnorm->vbistart[1];
191 count = clamp (max (count0, count1), (s64) 1, (s64) VBI_MAXLINES);
192
193 f->fmt.vbi.start[0] = tvnorm->vbistart[0];
194 f->fmt.vbi.start[1] = tvnorm->vbistart[1];
195 f->fmt.vbi.count[0] = count;
196 f->fmt.vbi.count[1] = count;
197
198 f->fmt.vbi.reserved[0] = 0;
199 f->fmt.vbi.reserved[1] = 0;
200} 324}
201 325
202void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) 326int
327bttv_vbi_set_fmt (struct bttv_fh * fh,
328 struct v4l2_vbi_format * f)
203{ 329{
330 struct bttv *btv = fh->btv;
204 const struct bttv_tvnorm *tvnorm; 331 const struct bttv_tvnorm *tvnorm;
332 __s32 start1, end;
333 int rc;
334
335 mutex_lock(&btv->lock);
336
337 rc = -EBUSY;
338 if (fh->resources & RESOURCE_VBI)
339 goto fail;
340
341 tvnorm = &bttv_tvnorms[btv->tvnorm];
342
343 rc = try_fmt(f, tvnorm, btv->crop_start);
344 if (0 != rc)
345 goto fail;
346
347 start1 = f->start[1] - tvnorm->vbistart[1] + tvnorm->vbistart[0];
348
349 /* First possible line of video capturing. Should be
350 max(f->start[0] + f->count[0], start1 + f->count[1]) * 2
351 when capturing both fields. But for compatibility we must
352 pretend the VBI and video capture window may overlap,
353 so end = start + 1, the lowest possible value, times two
354 because vbi_fmt.end counts field lines times two. */
355 end = max(f->start[0], start1) * 2 + 2;
356
357 mutex_lock(&fh->vbi.lock);
358
359 fh->vbi_fmt.fmt = *f;
360 fh->vbi_fmt.tvnorm = tvnorm;
361 fh->vbi_fmt.end = end;
362
363 mutex_unlock(&fh->vbi.lock);
364
365 rc = 0;
366
367 fail:
368 mutex_unlock(&btv->lock);
369
370 return rc;
371}
372
373void
374bttv_vbi_get_fmt (struct bttv_fh * fh,
375 struct v4l2_vbi_format * f)
376{
377 const struct bttv_tvnorm *tvnorm;
378
379 *f = fh->vbi_fmt.fmt;
205 380
206 tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; 381 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
207 memset(f,0,sizeof(*f)); 382
208 f->type = V4L2_BUF_TYPE_VBI_CAPTURE; 383 if (tvnorm != fh->vbi_fmt.tvnorm) {
209 f->fmt.vbi.sampling_rate = tvnorm->Fsc; 384 __s32 max_end;
210 f->fmt.vbi.samples_per_line = 2048; 385 unsigned int i;
211 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; 386
212 f->fmt.vbi.offset = VBI_OFFSET; 387 /* As in vbi_buffer_prepare() this imitates the
213 f->fmt.vbi.start[0] = tvnorm->vbistart[0]; 388 behaviour of earlier driver versions after video
214 f->fmt.vbi.start[1] = tvnorm->vbistart[1]; 389 standard changes, with default parameters anyway. */
215 f->fmt.vbi.count[0] = fh->lines; 390
216 f->fmt.vbi.count[1] = fh->lines; 391 max_end = (tvnorm->cropcap.bounds.top
217 f->fmt.vbi.flags = 0; 392 + tvnorm->cropcap.bounds.height) >> 1;
393
394 f->sampling_rate = tvnorm->Fsc;
395
396 for (i = 0; i < 2; ++i) {
397 __s32 new_start;
398
399 new_start = f->start[i]
400 + tvnorm->vbistart[i]
401 - fh->vbi_fmt.tvnorm->vbistart[i];
402
403 f->start[i] = min(new_start, max_end - 1);
404 f->count[i] = min((__s32) f->count[i],
405 max_end - f->start[i]);
406
407 max_end += tvnorm->vbistart[1]
408 - tvnorm->vbistart[0];
409 }
410 }
411}
412
413void
414bttv_vbi_fmt_reset (struct bttv_vbi_fmt * f,
415 int norm)
416{
417 const struct bttv_tvnorm *tvnorm;
418 unsigned int real_samples_per_line;
419 unsigned int real_count;
420
421 tvnorm = &bttv_tvnorms[norm];
422
423 f->fmt.sampling_rate = tvnorm->Fsc;
424 f->fmt.samples_per_line = VBI_BPL;
425 f->fmt.sample_format = V4L2_PIX_FMT_GREY;
426 f->fmt.offset = VBI_OFFSET;
427 f->fmt.start[0] = tvnorm->vbistart[0];
428 f->fmt.start[1] = tvnorm->vbistart[1];
429 f->fmt.count[0] = VBI_DEFLINES;
430 f->fmt.count[1] = VBI_DEFLINES;
431 f->fmt.flags = 0;
432 f->fmt.reserved[0] = 0;
433 f->fmt.reserved[1] = 0;
434
435 /* For compatibility the buffer size must be 2 * VBI_DEFLINES *
436 VBI_BPL regardless of the current video standard. */
437 real_samples_per_line = 1024 + tvnorm->vbipack * 4;
438 real_count = ((tvnorm->cropcap.defrect.top >> 1)
439 - tvnorm->vbistart[0]);
440
441 BUG_ON(real_samples_per_line > VBI_BPL);
442 BUG_ON(real_count > VBI_DEFLINES);
443
444 f->tvnorm = tvnorm;
445
446 /* See bttv_vbi_fmt_set(). */
447 f->end = tvnorm->vbistart[0] * 2 + 2;
218} 448}
219 449
220/* ----------------------------------------------------------------------- */ 450/* ----------------------------------------------------------------------- */