summaryrefslogtreecommitdiffstats
path: root/sys/dev/bktr
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1998-08-31 18:31:36 +0000
committersos <sos@FreeBSD.org>1998-08-31 18:31:36 +0000
commit2cddefeee28308f18edd56895c39e86d02a449e8 (patch)
treee37accb86109a6a684df5a4303faa2ad78d00589 /sys/dev/bktr
parentbae4326618e3f49d770051d27112e1c7dde79d7e (diff)
downloadFreeBSD-src-2cddefeee28308f18edd56895c39e86d02a449e8.zip
FreeBSD-src-2cddefeee28308f18edd56895c39e86d02a449e8.tar.gz
Added Capture Area ioctl - BT848[SG]CAPAREA.
Normally the full 640x480 (768x576 PAL) image is grabbed. This ioctl allows a smaller area from anywhere within the video image to be grabbed, eg a 400x300 image from (50,10). See restrictions in BT848SCAPAREA. Submitted by: Roger Hardiman <roger@cs.strath.ac.uk>
Diffstat (limited to 'sys/dev/bktr')
-rw-r--r--sys/dev/bktr/bktr_core.c172
-rw-r--r--sys/dev/bktr/bktr_reg.h15
-rw-r--r--sys/dev/bktr/ioctl_bt848.h15
3 files changed, 175 insertions, 27 deletions
diff --git a/sys/dev/bktr/bktr_core.c b/sys/dev/bktr/bktr_core.c
index 780e60d..89919d9 100644
--- a/sys/dev/bktr/bktr_core.c
+++ b/sys/dev/bktr/bktr_core.c
@@ -1,4 +1,4 @@
-/* BT848 1.39 Driver for Brooktree's Bt848 based cards.
+/* BT848 1.40 Driver for Brooktree's Bt848 based cards.
The Brooktree BT848 Driver driver is based upon Mark Tinguely and
Jim Lowe's driver for the Matrox Meteor PCI card . The
Philips SAA 7116 and SAA 7196 are very different chipsets than
@@ -273,7 +273,14 @@
Updated Hauppauge detection code for Tuner ID 0x0a
for newer NTSC WinCastTV 404 with Bt878 chipset.
Tidied up PAL default in video_open()
-
+
+1.40 10 August 1998 Roger Hardiman <roger@cs.strath.ac.uk>
+ Added Capture Area ioctl - BT848[SG]CAPAREA.
+ Normally the full 640x480 (768x576 PAL) image
+ is grabbed. This ioctl allows a smaller area
+ from anywhere within the video image to be
+ grabbed, eg a 400x300 image from (50,10).
+ See restrictions in BT848SCAPAREA.
*/
#define DDB(x) x
@@ -1677,6 +1684,8 @@ video_open( bktr_ptr_t bktr )
bktr->format = METEOR_GEO_RGB16;
bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
+ bktr->capture_area_enabled = FALSE;
+
bt848->int_mask = BT848_INT_MYSTERYBIT; /* if you take this out triton
based motherboards will
operate unreliably */
@@ -1906,6 +1915,7 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
struct meteor_geomet *geo;
struct meteor_counts *cnt;
struct meteor_video *video;
+ struct bktr_capture_area *cap_area;
vm_offset_t buf;
struct format_params *fp;
int i;
@@ -2409,6 +2419,55 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
break;
/* end of METEORSETGEO */
+ /* FIXME. The Capture Area currently has the following restrictions
+ GENERAL
+ y_offset may need to be even in interlaced modes
+ RGB24 - Interlaced mode
+ x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
+ y_size must be greater than or equal to METEORSETGEO height (rows)
+ RGB24 - Even Only (or Odd Only) mode
+ x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
+ y_size must be greater than or equal to 2*METEORSETGEO height (rows)
+ YUV12 - Interlaced mode
+ x_size must be greater than or equal to METEORSETGEO width (cols)
+ y_size must be greater than or equal to METEORSETGEO height (rows)
+ YUV12 - Even Only (or Odd Only) mode
+ x_size must be greater than or equal to METEORSETGEO width (cols)
+ y_size must be greater than or equal to 2*METEORSETGEO height (rows)
+ */
+
+ case BT848SCAPAREA: /* set capture area of each video frame */
+ /* can't change parameters while capturing */
+ if (bktr->flags & METEOR_CAP_MASK)
+ return( EBUSY );
+
+ cap_area = (struct bktr_capture_area *) arg;
+ bktr->capture_area_x_offset = cap_area->x_offset;
+ bktr->capture_area_y_offset = cap_area->y_offset;
+ bktr->capture_area_x_size = cap_area->x_size;
+ bktr->capture_area_y_size = cap_area->y_size;
+ bktr->capture_area_enabled = TRUE;
+
+ bktr->dma_prog_loaded = FALSE;
+ break;
+
+ case BT848GCAPAREA: /* get capture area of each video frame */
+ cap_area = (struct bktr_capture_area *) arg;
+ if (bktr->capture_area_enabled == FALSE) {
+ cap_area->x_offset = 0;
+ cap_area->y_offset = 0;
+ cap_area->x_size = format_params[
+ bktr->format_params].scaled_hactive;
+ cap_area->y_size = format_params[
+ bktr->format_params].vactive;
+ } else {
+ cap_area->x_offset = bktr->capture_area_x_offset;
+ cap_area->y_offset = bktr->capture_area_y_offset;
+ cap_area->x_size = bktr->capture_area_x_size;
+ cap_area->y_size = bktr->capture_area_y_size;
+ }
+ break;
+
default:
return common_ioctl( bktr, bt848, cmd, arg );
}
@@ -3664,63 +3723,103 @@ build_dma_prog( bktr_ptr_t bktr, char i_flag )
bt848->gpio_dma_ctl &= ~FIFO_RISC_ENABLED;
/* set video parameters */
- temp = ((quad_t ) fp->htotal* (quad_t) fp->horizontal * 4096
- / fp->vertical / bktr->cols) - 4096;
+ if (bktr->capture_area_enabled)
+ temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
+ / fp->scaled_htotal / bktr->cols) - 4096;
+ else
+ temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
+ / fp->scaled_htotal / bktr->cols) - 4096;
+
+ /* printf("HSCALE value is %d\n",temp); */
bt848->e_hscale_lo = temp & 0xff;
bt848->o_hscale_lo = temp & 0xff;
bt848->e_hscale_hi = (temp >> 8) & 0xff;
bt848->o_hscale_hi = (temp >> 8) & 0xff;
-
+
/* horizontal active */
temp = bktr->cols;
+ /* printf("HACTIVE value is %d\n",temp); */
bt848->e_hactive_lo = temp & 0xff;
bt848->o_hactive_lo = temp & 0xff;
bt848->e_crop &= ~0x3;
bt848->o_crop &= ~0x3;
bt848->e_crop |= (temp >> 8) & 0x3;
bt848->o_crop |= (temp >> 8) & 0x3;
-
+
/* horizontal delay */
- temp = (fp->hdelay * bktr->cols) / fp->hactive;
+ if (bktr->capture_area_enabled)
+ temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
+ * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
+ else
+ temp = (fp->hdelay * bktr->cols) / fp->hactive;
+
temp = temp & 0x3fe;
+
+ /* printf("HDELAY value is %d\n",temp); */
bt848->e_delay_lo = temp & 0xff;
bt848->o_delay_lo = temp & 0xff;
bt848->e_crop &= ~0xc;
bt848->o_crop &= ~0xc;
bt848->e_crop |= (temp >> 6) & 0xc;
bt848->o_crop |= (temp >> 6) & 0xc;
-
+
/* vertical scale */
- if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
- bktr->flags & METEOR_ONLY_EVEN_FIELDS)
- tmp_int = 65536 -
+ if (bktr->capture_area_enabled) {
+ if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
+ bktr->flags & METEOR_ONLY_EVEN_FIELDS)
+ tmp_int = 65536 -
+ (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
+ else {
+ tmp_int = 65536 -
+ (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
+ }
+ } else {
+ if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
+ bktr->flags & METEOR_ONLY_EVEN_FIELDS)
+ tmp_int = 65536 -
(((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
- else {
- tmp_int = 65536 -
+ else {
+ tmp_int = 65536 -
(((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
+ }
}
-
+
tmp_int &= 0x1fff;
+ /* printf("VSCALE value is %d\n",tmp_int); */
bt848->e_vscale_lo = tmp_int & 0xff;
bt848->o_vscale_lo = tmp_int & 0xff;
bt848->e_vscale_hi &= ~0x1f;
bt848->o_vscale_hi &= ~0x1f;
bt848->e_vscale_hi |= (tmp_int >> 8) & 0x1f;
bt848->o_vscale_hi |= (tmp_int >> 8) & 0x1f;
-
+
/* vertical active */
+ if (bktr->capture_area_enabled)
+ temp = bktr->capture_area_y_size;
+ else
+ temp = fp->vactive;
+ /* printf("VACTIVE is %d\n",temp); */
bt848->e_crop &= ~0x30;
- bt848->e_crop |= (fp->vactive >> 4) & 0x30;
- bt848->e_vactive_lo = fp->vactive & 0xff;
+ bt848->e_crop |= (temp >> 4) & 0x30;
+ bt848->e_vactive_lo = temp & 0xff;
bt848->o_crop &= ~0x30;
- bt848->o_crop |= (fp->vactive >> 4) & 0x30;
- bt848->o_vactive_lo = fp->vactive & 0xff;
-
+ bt848->o_crop |= (temp >> 4) & 0x30;
+ bt848->o_vactive_lo = temp & 0xff;
+
/* vertical delay */
- bt848->e_vdelay_lo = fp->vdelay;
- bt848->o_vdelay_lo = fp->vdelay;
+ if (bktr->capture_area_enabled)
+ temp = fp->vdelay + (bktr->capture_area_y_offset);
+ else
+ temp = fp->vdelay;
+ /* printf("VDELAY is %d\n",temp); */
+ bt848->e_crop &= ~0xC0;
+ bt848->e_crop |= (temp >> 2) & 0xC0;
+ bt848->e_vdelay_lo = temp & 0xff;
+ bt848->o_crop &= ~0xC0;
+ bt848->o_crop |= (temp >> 2) & 0xC0;
+ bt848->o_vdelay_lo = temp & 0xff;
/* end of video params */
@@ -4394,6 +4493,35 @@ checkTuner:
}
}
+
+ /* The Hauppauge Windows driver gives the following Tuner Table */
+ /* To the right of this is the tuner models we select */
+ /*
+ 1 External
+ 2 Unspecified
+ 3 Phillips FI1216
+ 4 Phillips FI1216MF
+ 5 Phillips FI1236 PHILIPS_NTSC
+ 6 Phillips FI1246
+ 7 Phillips FI1256
+ 8 Phillips FI1216 MK2 PHILIPS_PALI
+ 9 Phillips FI1216MF MK2
+ a Phillips FI1236 MK2 PHILIPS_FR1236_NTSC
+ b Phillips FI1246 MK2 PHILIPS_PALI
+ c Phillips FI1256 MK2
+ d Temic 4032FY5
+ e Temic 4002FH5 TEMIC_PAL
+ f Temic 4062FY5 TEMIC_PALI
+ 10 Phillips FR1216 MK2
+ 11 Phillips FR1216MF MK2
+ 12 Phillips FR1236 MK2 PHILIPS_FR1236_NTSC
+ 13 Phillips FR1246 MK2
+ 14 Phillips FR1256 MK2
+ 15 Phillips FM1216 PHILIPS_FR1216_PAL
+ 16 Phillips FM1216MF
+ 17 Phillips FM1236 PHILIPS_FR1236_NTSC
+ */
+
if ( card == CARD_HAUPPAUGE ) {
bktr->card.tuner = &tuners[ TEMIC_PAL ];
readEEProm(bktr, 0, 128, (u_char *) &probe_eeprom );
diff --git a/sys/dev/bktr/bktr_reg.h b/sys/dev/bktr/bktr_reg.h
index 61a10d7..0acd003 100644
--- a/sys/dev/bktr/bktr_reg.h
+++ b/sys/dev/bktr/bktr_reg.h
@@ -343,13 +343,13 @@ struct format_params {
int vtotal, vdelay, vactive;
/* Total unscaled horizontal pixels, pixels before image, image pixels */
int htotal, hdelay, hactive;
- /* visible active horizontal and vertical : 480 640 for NTSC */
- int horizontal, vertical;
-/* frame rate . for ntsc is 30 frames per second */
+ /* Scaled horizontal image pixels, Total Scaled horizontal pixels */
+ int scaled_hactive, scaled_htotal;
+ /* frame rate . for ntsc is 30 frames per second */
int frame_rate;
-/* A-delay and B-delay */
+ /* A-delay and B-delay */
u_char adelay, bdelay;
-/* Iform XTSEL value */
+ /* Iform XTSEL value */
int iform_xtsel;
};
@@ -384,6 +384,11 @@ struct bktr_softc {
short current; /* frame number in buffer (1-frames) */
short rows; /* number of rows in a frame */
short cols; /* number of columns in a frame */
+ int capture_area_x_offset; /* Usually the full 640x480(NTSC) image is */
+ int capture_area_y_offset; /* captured. The capture area allows for */
+ int capture_area_x_size; /* example 320x200 pixels from the centre */
+ int capture_area_y_size; /* of the video image to be captured. */
+ char capture_area_enabled; /* When TRUE use user's capture area. */
int pixfmt; /* active pixel format (idx into fmt tbl) */
int pixfmt_compat; /* Y/N - in meteor pix fmt compat mode */
u_long format; /* frame format rgb, yuv, etc.. */
diff --git a/sys/dev/bktr/ioctl_bt848.h b/sys/dev/bktr/ioctl_bt848.h
index db09dc8..09a4a5e 100644
--- a/sys/dev/bktr/ioctl_bt848.h
+++ b/sys/dev/bktr/ioctl_bt848.h
@@ -197,6 +197,21 @@ struct _bktr_clip {
#define BT848SCBUF _IOW('x', 68, int)
#define BT848GCBUF _IOR('x', 68, int)
+/* set capture area */
+/* The capture area is the area of the video image which is grabbed */
+/* Usually the capture area is 640x480 (768x576 PAL) pixels */
+/* This area is then scaled to the dimensions the user requires */
+/* using the METEORGEO ioctl */
+/* However, the capture area could be 400x300 pixels from the top right */
+/* corner of the video image */
+struct bktr_capture_area {
+ int x_offset;
+ int y_offset;
+ int x_size;
+ int y_size;
+};
+#define BT848SCAPAREA _IOW('x', 69, struct bktr_capture_area)
+#define BT848GCAPAREA _IOR('x', 69, struct bktr_capture_area)
/* Read/Write the BT848's I2C bus directly
* b7-b0: data (read/write)
OpenPOWER on IntegriCloud