Commit e5bd0260 authored by Michael Schimek's avatar Michael Schimek Committed by Mauro Carvalho Chehab

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: default avatarMichael H. Schimek <mschimek@gmx.at>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 13071f0a
This diff is collapsed.
...@@ -43,7 +43,8 @@ int ...@@ -43,7 +43,8 @@ int
bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
struct scatterlist *sglist, struct scatterlist *sglist,
unsigned int offset, unsigned int bpl, unsigned int offset, unsigned int bpl,
unsigned int padding, unsigned int lines) unsigned int padding, unsigned int skip_lines,
unsigned int store_lines)
{ {
u32 instructions,line,todo; u32 instructions,line,todo;
struct scatterlist *sg; struct scatterlist *sg;
...@@ -54,9 +55,11 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -54,9 +55,11 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
one write per scan line + sync + jump (all 2 dwords). padding one write per scan line + sync + jump (all 2 dwords). padding
can cause next bpl to start close to a page border. First DMA can cause next bpl to start close to a page border. First DMA
region may be smaller than PAGE_SIZE */ region may be smaller than PAGE_SIZE */
instructions = 1 + ((bpl + padding) * lines) / PAGE_SIZE + lines; instructions = skip_lines * 4;
instructions += 2; instructions += (1 + ((bpl + padding) * store_lines)
if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) / PAGE_SIZE + store_lines) * 8;
instructions += 2 * 8;
if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
return rc; return rc;
/* sync instruction */ /* sync instruction */
...@@ -64,11 +67,16 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -64,11 +67,16 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
*(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
*(rp++) = cpu_to_le32(0); *(rp++) = cpu_to_le32(0);
while (skip_lines-- > 0) {
*(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
BT848_RISC_EOL | bpl);
}
/* scan lines */ /* scan lines */
sg = sglist; sg = sglist;
for (line = 0; line < lines; line++) { for (line = 0; line < store_lines; line++) {
if ((btv->opt_vcr_hack) && if ((btv->opt_vcr_hack) &&
(line >= (lines - VCR_HACK_LINES))) (line >= (store_lines - VCR_HACK_LINES)))
continue; continue;
while (offset && offset >= sg_dma_len(sg)) { while (offset && offset >= sg_dma_len(sg)) {
offset -= sg_dma_len(sg); offset -= sg_dma_len(sg);
...@@ -130,7 +138,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -130,7 +138,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
/* estimate risc mem: worst case is one write per page border + /* estimate risc mem: worst case is one write per page border +
one write per scan line (5 dwords) one write per scan line (5 dwords)
plus sync + jump (2 dwords) */ plus sync + jump (2 dwords) */
instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines; instructions = ((3 + (ybpl + ypadding) * ylines * 2)
/ PAGE_SIZE) + ylines;
instructions += 2; instructions += 2;
if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0) if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
return rc; return rc;
...@@ -317,10 +326,10 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, ...@@ -317,10 +326,10 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
static void static void
bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
int width, int height, int interleaved, int norm) int width, int height, int interleaved,
const struct bttv_tvnorm *tvnorm)
{ {
const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
u32 xsf, sr; u32 xsf, sr;
int vdelay; int vdelay;
...@@ -360,6 +369,62 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, ...@@ -360,6 +369,62 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
} }
} }
static void
bttv_calc_geo (struct bttv * btv,
struct bttv_geometry * geo,
unsigned int width,
unsigned int height,
int both_fields,
const struct bttv_tvnorm * tvnorm,
const struct v4l2_rect * crop)
{
unsigned int c_width;
unsigned int c_height;
u32 sr;
if ((crop->left == tvnorm->cropcap.defrect.left
&& crop->top == tvnorm->cropcap.defrect.top
&& crop->width == tvnorm->cropcap.defrect.width
&& crop->height == tvnorm->cropcap.defrect.height
&& width <= tvnorm->swidth /* see PAL-Nc et al */)
|| bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
bttv_calc_geo_old(btv, geo, width, height,
both_fields, tvnorm);
return;
}
/* For bug compatibility the image size checks permit scale
factors > 16. See bttv_crop_calc_limits(). */
c_width = min((unsigned int) crop->width, width * 16);
c_height = min((unsigned int) crop->height, height * 16);
geo->width = width;
geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
/* Even to store Cb first, odd for Cr. */
geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
geo->sheight = c_height;
geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
sr = c_height >> !both_fields;
sr = (sr * 512U + (height >> 1)) / height - 512;
geo->vscale = (0x10000UL - sr) & 0x1fff;
geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
geo->vtotal = tvnorm->vtotal;
geo->crop = (((geo->width >> 8) & 0x03) |
((geo->hdelay >> 6) & 0x0c) |
((geo->sheight >> 4) & 0x30) |
((geo->vdelay >> 2) & 0xc0));
if (btv->opt_combfilter) {
geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
geo->comb = (width < 769) ? 1 : 0;
} else {
geo->vtc = 0;
geo->comb = 0;
}
}
static void static void
bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
{ {
...@@ -522,16 +587,51 @@ int ...@@ -522,16 +587,51 @@ int
bttv_buffer_activate_vbi(struct bttv *btv, bttv_buffer_activate_vbi(struct bttv *btv,
struct bttv_buffer *vbi) struct bttv_buffer *vbi)
{ {
/* vbi capture */ struct btcx_riscmem *top;
struct btcx_riscmem *bottom;
int top_irq_flags;
int bottom_irq_flags;
top = NULL;
bottom = NULL;
top_irq_flags = 0;
bottom_irq_flags = 0;
if (vbi) { if (vbi) {
unsigned int crop, vdelay;
vbi->vb.state = STATE_ACTIVE; vbi->vb.state = STATE_ACTIVE;
list_del(&vbi->vb.queue); list_del(&vbi->vb.queue);
bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0);
bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4); /* VDELAY is start of video, end of VBI capturing. */
} else { crop = btread(BT848_E_CROP);
bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0); vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
if (vbi->geo.vdelay > vdelay) {
vdelay = vbi->geo.vdelay & 0xfe;
crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
btwrite(vdelay, BT848_E_VDELAY_LO);
btwrite(crop, BT848_E_CROP);
btwrite(vdelay, BT848_O_VDELAY_LO);
btwrite(crop, BT848_O_CROP);
}
if (vbi->vbi_count[0] > 0) {
top = &vbi->top;
top_irq_flags = 4;
}
if (vbi->vbi_count[1] > 0) {
top_irq_flags = 0;
bottom = &vbi->bottom;
bottom_irq_flags = 4;
}
} }
bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
return 0; return 0;
} }
...@@ -611,28 +711,31 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) ...@@ -611,28 +711,31 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
int bpf = bpl * (buf->vb.height >> 1); int bpf = bpl * (buf->vb.height >> 1);
bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height, bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm); V4L2_FIELD_HAS_BOTH(buf->vb.field),
tvnorm,&buf->crop);
switch (buf->vb.field) { switch (buf->vb.field) {
case V4L2_FIELD_TOP: case V4L2_FIELD_TOP:
bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
0,bpl,0,buf->vb.height); /* offset */ 0,bpl,
/* padding */ 0,/* skip_lines */ 0,
buf->vb.height);
break; break;
case V4L2_FIELD_BOTTOM: case V4L2_FIELD_BOTTOM:
bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
0,bpl,0,buf->vb.height); 0,bpl,0,0,buf->vb.height);
break; break;
case V4L2_FIELD_INTERLACED: case V4L2_FIELD_INTERLACED:
bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
0,bpl,bpl,buf->vb.height >> 1); 0,bpl,bpl,0,buf->vb.height >> 1);
bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
bpl,bpl,bpl,buf->vb.height >> 1); bpl,bpl,bpl,0,buf->vb.height >> 1);
break; break;
case V4L2_FIELD_SEQ_TB: case V4L2_FIELD_SEQ_TB:
bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist, bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
0,bpl,0,buf->vb.height >> 1); 0,bpl,0,0,buf->vb.height >> 1);
bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist, bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
bpf,bpl,0,buf->vb.height >> 1); bpf,bpl,0,0,buf->vb.height >> 1);
break; break;
default: default:
BUG(); BUG();
...@@ -662,7 +765,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) ...@@ -662,7 +765,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
switch (buf->vb.field) { switch (buf->vb.field) {
case V4L2_FIELD_TOP: case V4L2_FIELD_TOP:
bttv_calc_geo(btv,&buf->geo,buf->vb.width, bttv_calc_geo(btv,&buf->geo,buf->vb.width,
buf->vb.height,0,buf->tvnorm); buf->vb.height,/* both_fields */ 0,
tvnorm,&buf->crop);
bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist, bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
0,buf->vb.width,0,buf->vb.height, 0,buf->vb.width,0,buf->vb.height,
uoffset,voffset,buf->fmt->hshift, uoffset,voffset,buf->fmt->hshift,
...@@ -670,7 +774,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) ...@@ -670,7 +774,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
break; break;
case V4L2_FIELD_BOTTOM: case V4L2_FIELD_BOTTOM:
bttv_calc_geo(btv,&buf->geo,buf->vb.width, bttv_calc_geo(btv,&buf->geo,buf->vb.width,
buf->vb.height,0,buf->tvnorm); buf->vb.height,0,
tvnorm,&buf->crop);
bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist, bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
0,buf->vb.width,0,buf->vb.height, 0,buf->vb.width,0,buf->vb.height,
uoffset,voffset,buf->fmt->hshift, uoffset,voffset,buf->fmt->hshift,
...@@ -678,7 +783,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) ...@@ -678,7 +783,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
break; break;
case V4L2_FIELD_INTERLACED: case V4L2_FIELD_INTERLACED:
bttv_calc_geo(btv,&buf->geo,buf->vb.width, bttv_calc_geo(btv,&buf->geo,buf->vb.width,
buf->vb.height,1,buf->tvnorm); buf->vb.height,1,
tvnorm,&buf->crop);
lines = buf->vb.height >> 1; lines = buf->vb.height >> 1;
ypadding = buf->vb.width; ypadding = buf->vb.width;
cpadding = buf->vb.width >> buf->fmt->hshift; cpadding = buf->vb.width >> buf->fmt->hshift;
...@@ -700,7 +806,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) ...@@ -700,7 +806,8 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
break; break;
case V4L2_FIELD_SEQ_TB: case V4L2_FIELD_SEQ_TB:
bttv_calc_geo(btv,&buf->geo,buf->vb.width, bttv_calc_geo(btv,&buf->geo,buf->vb.width,
buf->vb.height,1,buf->tvnorm); buf->vb.height,1,
tvnorm,&buf->crop);
lines = buf->vb.height >> 1; lines = buf->vb.height >> 1;
ypadding = buf->vb.width; ypadding = buf->vb.width;
cpadding = buf->vb.width >> buf->fmt->hshift; cpadding = buf->vb.width >> buf->fmt->hshift;
...@@ -731,11 +838,12 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) ...@@ -731,11 +838,12 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
/* build risc code */ /* build risc code */
buf->vb.field = V4L2_FIELD_SEQ_TB; buf->vb.field = V4L2_FIELD_SEQ_TB;
bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight, bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
1,buf->tvnorm); 1,tvnorm,&buf->crop);
bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist, bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
0, RAW_BPL, 0, RAW_LINES); /* offset */ 0, RAW_BPL, /* padding */ 0,
/* skip_lines */ 0, RAW_LINES);
bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist, bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
buf->vb.size/2 , RAW_BPL, 0, RAW_LINES); buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
} }
/* copy format info */ /* copy format info */
...@@ -761,7 +869,8 @@ bttv_overlay_risc(struct bttv *btv, ...@@ -761,7 +869,8 @@ bttv_overlay_risc(struct bttv *btv,
/* calculate geometry */ /* calculate geometry */
bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height, bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm); V4L2_FIELD_HAS_BOTH(ov->field),
&bttv_tvnorms[ov->tvnorm],&buf->crop);
/* build risc code */ /* build risc code */
switch (ov->field) { switch (ov->field) {
......
This diff is collapsed.
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define _BTTVP_H_ #define _BTTVP_H_
#include <linux/version.h> #include <linux/version.h>
#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16) #define BTTV_VERSION_CODE KERNEL_VERSION(0,9,17)
#include <linux/types.h> #include <linux/types.h>
#include <linux/wait.h> #include <linux/wait.h>
...@@ -66,14 +66,22 @@ ...@@ -66,14 +66,22 @@
#define RISC_SLOT_LOOP 14 #define RISC_SLOT_LOOP 14
#define RESOURCE_OVERLAY 1 #define RESOURCE_OVERLAY 1
#define RESOURCE_VIDEO 2 #define RESOURCE_VIDEO_STREAM 2
#define RESOURCE_VBI 4 #define RESOURCE_VBI 4
#define RESOURCE_VIDEO_READ 8
#define RAW_LINES 640 #define RAW_LINES 640
#define RAW_BPL 1024 #define RAW_BPL 1024
#define UNSET (-1U) #define UNSET (-1U)
/* Min. value in VDELAY register. */
#define MIN_VDELAY 2
/* Even to get Cb first, odd for Cr. */
#define MAX_HDELAY (0x3FF & -2)
/* Limits scaled width, which must be a multiple of 4. */
#define MAX_HACTIVE (0x3FF & -4)
#define clamp(x, low, high) min (max (low, x), high) #define clamp(x, low, high) min (max (low, x), high)
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
...@@ -92,8 +100,13 @@ struct bttv_tvnorm { ...@@ -92,8 +100,13 @@ struct bttv_tvnorm {
u16 vtotal; u16 vtotal;
int sram; int sram;
/* ITU-R frame line number of the first VBI line we can /* ITU-R frame line number of the first VBI line we can
capture, of the first and second field. */ capture, of the first and second field. The last possible line
is determined by cropcap.bounds. */
u16 vbistart[2]; u16 vbistart[2];
/* Horizontally this counts fCLKx1 samples following the leading
edge of the horizontal sync pulse, vertically ITU-R frame line
numbers of the first field times two (2, 4, 6, ... 524 or 624). */
struct v4l2_cropcap cropcap;
}; };
extern const struct bttv_tvnorm bttv_tvnorms[]; extern const struct bttv_tvnorm bttv_tvnorms[];
...@@ -128,6 +141,9 @@ struct bttv_buffer { ...@@ -128,6 +141,9 @@ struct bttv_buffer {
struct bttv_geometry geo; struct bttv_geometry geo;
struct btcx_riscmem top; struct btcx_riscmem top;
struct btcx_riscmem bottom; struct btcx_riscmem bottom;
struct v4l2_rect crop;
unsigned int vbi_skip[2];
unsigned int vbi_count[2];
}; };
struct bttv_buffer_set { struct bttv_buffer_set {
...@@ -146,6 +162,34 @@ struct bttv_overlay { ...@@ -146,6 +162,34 @@ struct bttv_overlay {
int setup_ok; int setup_ok;
}; };
struct bttv_vbi_fmt {
struct v4l2_vbi_format fmt;
/* fmt.start[] and count[] refer to this video standard. */
const struct bttv_tvnorm *tvnorm;
/* Earliest possible start of video capturing with this
v4l2_vbi_format, in struct bttv_crop.rect units. */
__s32 end;
};
/* bttv-vbi.c */
void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm);
struct bttv_crop {
/* A cropping rectangle in struct bttv_tvnorm.cropcap units. */
struct v4l2_rect rect;
/* Scaled image size limits with this crop rect. Divide
max_height, but not min_height, by two when capturing
single fields. See also bttv_crop_reset() and
bttv_crop_adjust() in bttv-driver.c. */
__s32 min_scaled_width;
__s32 min_scaled_height;
__s32 max_scaled_width;
__s32 max_scaled_height;
};
struct bttv_fh { struct bttv_fh {
struct bttv *btv; struct bttv *btv;
int resources; int resources;
...@@ -160,13 +204,19 @@ struct bttv_fh { ...@@ -160,13 +204,19 @@ struct bttv_fh {
int width; int width;
int height; int height;
/* current settings */ /* video overlay */
const struct bttv_format *ovfmt; const struct bttv_format *ovfmt;
struct bttv_overlay ov; struct bttv_overlay ov;
/* video overlay */ /* Application called VIDIOC_S_CROP. */
int do_crop;
/* vbi capture */
struct videobuf_queue vbi; struct videobuf_queue vbi;
int lines; /* Current VBI capture window as seen through this fh (cannot
be global for compatibility with earlier drivers). Protected
by struct bttv.lock and struct bttv_fh.vbi.lock. */
struct bttv_vbi_fmt vbi_fmt;
}; };
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
...@@ -176,7 +226,8 @@ struct bttv_fh { ...@@ -176,7 +226,8 @@ struct bttv_fh {
int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
struct scatterlist *sglist, struct scatterlist *sglist,
unsigned int offset, unsigned int bpl, unsigned int offset, unsigned int bpl,
unsigned int pitch, unsigned int lines); unsigned int pitch, unsigned int skip_lines,
unsigned int store_lines);
/* control dma register + risc main loop */ /* control dma register + risc main loop */
void bttv_set_dma(struct bttv *btv, int override); void bttv_set_dma(struct bttv *btv, int override);
...@@ -202,9 +253,9 @@ int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, ...@@ -202,9 +253,9 @@ int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
/* ---------------------------------------------------------- */ /* ---------------------------------------------------------- */
/* bttv-vbi.c */ /* bttv-vbi.c */
void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f); int bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f);
void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f); void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f);
void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines); int bttv_vbi_set_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f);
extern struct videobuf_queue_ops bttv_vbi_qops; extern struct videobuf_queue_ops bttv_vbi_qops;
...@@ -233,7 +284,6 @@ extern int fini_bttv_i2c(struct bttv *btv); ...@@ -233,7 +284,6 @@ extern int fini_bttv_i2c(struct bttv *btv);
#define d2printk if (bttv_debug >= 2) printk #define d2printk if (bttv_debug >= 2) printk
#define BTTV_MAX_FBUF 0x208000 #define BTTV_MAX_FBUF 0x208000
#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ #define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */
#define BTTV_FREE_IDLE (HZ) /* one second */ #define BTTV_FREE_IDLE (HZ) /* one second */
...@@ -314,7 +364,6 @@ struct bttv { ...@@ -314,7 +364,6 @@ struct bttv {
spinlock_t s_lock; spinlock_t s_lock;
struct mutex lock; struct mutex lock;
int resources; int resources;
struct mutex reslock;
#ifdef VIDIOC_G_PRIORITY #ifdef VIDIOC_G_PRIORITY
struct v4l2_prio_state prio; struct v4l2_prio_state prio;
#endif #endif
...@@ -384,6 +433,21 @@ struct bttv { ...@@ -384,6 +433,21 @@ struct bttv {
unsigned int users; unsigned int users;
struct bttv_fh init; struct bttv_fh init;
/* Default (0) and current (1) video capturing and overlay
cropping parameters in bttv_tvnorm.cropcap units. Protected
by bttv.lock. */
struct bttv_crop crop[2];
/* Earliest possible start of video capturing in
bttv_tvnorm.cropcap line units. Set by check_alloc_btres()
and free_btres(). Protected by bttv.lock. */
__s32 vbi_end;
/* Latest possible end of VBI capturing (= crop[x].rect.top when
VIDEO_RESOURCES are locked). Set by check_alloc_btres()
and free_btres(). Protected by bttv.lock. */
__s32 crop_start;
}; };
/* our devices */ /* our devices */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment