summaryrefslogtreecommitdiff
path: root/linux/drivers
diff options
context:
space:
mode:
authorMichael Hunold <devnull@localhost>2003-07-31 14:30:57 +0000
committerMichael Hunold <devnull@localhost>2003-07-31 14:30:57 +0000
commit0e60b88a6e1ac6fd543fc3e8f4f71774c280c958 (patch)
tree3c368aff18650733d9702414fb0311c5e38c6db4 /linux/drivers
parent1ff92b55d10927b3043355b0aec3c5fe681dd42d (diff)
downloadmediapointer-dvb-s2-0e60b88a6e1ac6fd543fc3e8f4f71774c280c958.tar.gz
mediapointer-dvb-s2-0e60b88a6e1ac6fd543fc3e8f4f71774c280c958.tar.bz2
Improvements regarding streaming capture to gfx card memory.
Diffstat (limited to 'linux/drivers')
-rw-r--r--linux/drivers/media/common/saa7146_core.c7
-rw-r--r--linux/drivers/media/common/saa7146_fops.c4
-rw-r--r--linux/drivers/media/common/saa7146_hlp.c15
-rw-r--r--linux/drivers/media/common/saa7146_vbi.c2
-rw-r--r--linux/drivers/media/common/saa7146_video.c156
5 files changed, 157 insertions, 27 deletions
diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c
index 0bc053a2e..c1573e0cb 100644
--- a/linux/drivers/media/common/saa7146_core.c
+++ b/linux/drivers/media/common/saa7146_core.c
@@ -142,7 +142,7 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
void saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length )
{
u32 *ptr, fill;
- int i,p;
+ int i,j,p;
//fm DEB_EE(("pci:%p, pt:%p, sl:%p, len:%d\n",pci,pt,list,length));
@@ -163,12 +163,11 @@ void saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *p
for(;i<1024;i++) {
*ptr++ = fill;
}
-/*
+
ptr = pt->cpu;
for(j=0;j<60;j++) {
printk("ptr1 %d: 0x%08x\n",j,ptr[j]);
}
-*/
}
/********************************************************************************/
@@ -309,8 +308,8 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
/* we don't do a master reset here anymore, it screws up
some boards that don't have an i2c-eeprom for configuration
values */
-/*
saa7146_write(dev, MC1, MASK_31);
+/*
*/
/* disable alle irqs */
diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c
index 5562f93c0..b9d320250 100644
--- a/linux/drivers/media/common/saa7146_fops.c
+++ b/linux/drivers/media/common/saa7146_fops.c
@@ -304,6 +304,7 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
return videobuf_poll_stream(file, &fh->vbi_q, wait);
q = &fh->vbi_q;
} else {
+ DEB_D(("using video queue.\n"));
q = &fh->video_q;
}
@@ -311,14 +312,17 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
if (!buf) {
+ DEB_D(("buf == NULL!\n"));
return POLLERR;
}
poll_wait(file, &buf->done, wait);
if (buf->state == STATE_DONE || buf->state == STATE_ERROR) {
+ DEB_D(("poll succeeded!\n"));
return POLLIN|POLLRDNORM;
}
+ DEB_D(("nothing to poll for, buf->state:%d\n",buf->state));
return 0;
}
diff --git a/linux/drivers/media/common/saa7146_hlp.c b/linux/drivers/media/common/saa7146_hlp.c
index 1c60a1bcc..6ed3b13cf 100644
--- a/linux/drivers/media/common/saa7146_hlp.c
+++ b/linux/drivers/media/common/saa7146_hlp.c
@@ -742,6 +742,7 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71
int width = buf->fmt->width;
int height = buf->fmt->height;
+ int bytesperline = buf->fmt->bytesperline;
enum v4l2_field field = buf->fmt->field;
int depth = sfmt->depth;
@@ -749,7 +750,11 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71
DEB_CAP(("[size=%dx%d,fields=%s]\n",
width,height,v4l2_field_names[field]));
- vdma1.pitch = (width*depth*2)/8;
+ if( bytesperline != 0) {
+ vdma1.pitch = bytesperline*2;
+ } else {
+ vdma1.pitch = (width*depth*2)/8;
+ }
vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels);
vdma1.base_page = buf->pt[0].dma | ME1;
@@ -799,6 +804,8 @@ static int calc_planar_422(struct saa7146_vv *vv, struct saa7146_buf *buf, struc
vdma2->pitch = width;
vdma3->pitch = width;
+ /* fixme: look at bytesperline! */
+
if( 0 != vv->vflip ) {
vdma2->prot_addr = buf->pt[1].offset;
vdma2->base_even = ((vdma2->pitch/2)*height)+buf->pt[1].offset;
@@ -871,6 +878,8 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71
DEB_CAP(("[size=%dx%d,fields=%s]\n",
width,height,v4l2_field_names[field]));
+ /* fixme: look at bytesperline! */
+
/* fixme: what happens for user space buffers here?. The offsets are
most likely wrong, this version here only works for page-aligned
buffers, modifications to the pagetable-functions are necessary...*/
@@ -997,10 +1006,10 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar)
WRITE_RPS0(CMD_PAUSE | o_wait);
WRITE_RPS0(CMD_PAUSE | e_wait);
} else if ( vv->last_field == V4L2_FIELD_TOP ) {
- WRITE_RPS0(CMD_PAUSE | vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09);
+ WRITE_RPS0(CMD_PAUSE | (vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09));
WRITE_RPS0(CMD_PAUSE | o_wait);
} else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
- WRITE_RPS0(CMD_PAUSE | vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09);
+ WRITE_RPS0(CMD_PAUSE | (vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09));
WRITE_RPS0(CMD_PAUSE | e_wait);
}
diff --git a/linux/drivers/media/common/saa7146_vbi.c b/linux/drivers/media/common/saa7146_vbi.c
index 73051e784..48893bf37 100644
--- a/linux/drivers/media/common/saa7146_vbi.c
+++ b/linux/drivers/media/common/saa7146_vbi.c
@@ -235,7 +235,7 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,enum v4l
saa7146_pgtable_free(dev->pci, &buf->pt[2]);
saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
- err = videobuf_iolock(dev->pci,&buf->vb);
+ err = videobuf_iolock(dev->pci,&buf->vb, NULL);
if (err)
goto oops;
saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c
index 921622aad..f83caee1b 100644
--- a/linux/drivers/media/common/saa7146_video.c
+++ b/linux/drivers/media/common/saa7146_video.c
@@ -211,8 +211,21 @@ static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
f->fmt.pix.width = maxw;
if (f->fmt.pix.height > maxh)
f->fmt.pix.height = maxh;
- f->fmt.pix.sizeimage =
- (f->fmt.pix.width * f->fmt.pix.height * fmt->depth)/8;
+
+ if (f->fmt.pix.bytesperline == 0) {
+ f->fmt.pix.sizeimage = (f->fmt.pix.width * f->fmt.pix.height * fmt->depth)/8;
+ } else {
+ DEB_D(("bytesperline: %d\n",f->fmt.pix.bytesperline));
+ if (f->fmt.pix.bytesperline < (f->fmt.pix.width * fmt->depth)/8)
+ f->fmt.pix.bytesperline = f->fmt.pix.width;
+ DEB_D(("bytesperline: %d\n",f->fmt.pix.bytesperline));
+ if (f->fmt.pix.bytesperline > (2*PAGE_SIZE* fmt->depth)/8)
+ f->fmt.pix.bytesperline = f->fmt.pix.width;
+ f->fmt.pix.sizeimage = (f->fmt.pix.width * f->fmt.pix.bytesperline);
+ }
+
+ DEB_D(("bytesperline: %d\n",f->fmt.pix.bytesperline));
+
return 0;
}
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -549,7 +562,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
int length = buf->vb.dma.sglen;
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
- DEB_EE(("dev:%p, buf:%p\n",dev,buf));
+ DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
if( 0 != IS_PLANAR(sfmt->trans)) {
struct saa7146_pgtable *pt1 = &buf->pt[0];
@@ -729,6 +742,81 @@ static int video_end(struct saa7146_fh *fh)
return 0;
}
+/* capturing to framebuffer */
+
+int overlay_reqbufs(struct saa7146_dev *dev, struct v4l2_requestbuffers *req)
+{
+/* struct saa7146_fh *fh = file->private_data;
+
+ if (req->count > VIDEO_MAX_FRAME)
+ req->count = VIDEO_MAX_FRAME;
+
+ *size = fh->video_fmt.sizeimage;
+
+*/
+ return 0;
+}
+int overlay_querybuf(struct saa7146_dev *dev, struct v4l2_buffer *buf)
+{
+ return 0;
+}
+int overlay_qbuf(struct saa7146_dev *dev, struct v4l2_buffer *b)
+{
+/* if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) {
+ DEB_D(("index %d out of bounds.\n",b->index));
+ goto -EINVAL;
+ }
+
+ buf = q->bufs[b->index];
+ if (NULL == buf) {
+ printk("videobuf_qbuf: NULL == buf\n");
+ goto done;
+ }
+ if (0 == buf->baddr) {
+ printk("videobuf_qbuf: 0 == buf->baddr\n");
+ goto done;
+ }
+ if (buf->state == STATE_QUEUED ||
+ buf->state == STATE_ACTIVE) {
+ printk("videobuf_qbuf: already queued or activated.\n");
+ goto done;
+ }
+
+ field = videobuf_next_field(q);
+ retval = q->ops->buf_prepare(file,buf,field);
+ if (0 != retval) {
+ printk("videobuf_qbuf: buf_prepare() failed.\n");
+ goto done;
+ }
+
+ list_add_tail(&buf->stream,&q->stream);
+ if (q->streaming) {
+ spin_lock_irqsave(q->irqlock,flags);
+ q->ops->buf_queue(file,buf);
+ spin_unlock_irqrestore(q->irqlock,flags);
+ }
+ retval = 0;
+
+ done:
+ up(&q->lock);
+ return retval;
+*/
+ return 0;
+}
+int overlay_dqbuf(struct saa7146_dev *dev, struct v4l2_buffer *buf)
+{
+ return 0;
+}
+int overlay_streamon(struct saa7146_dev *dev)
+{
+ return 0;
+}
+int overlay_streamoff(struct saa7146_dev *dev)
+{
+ return 0;
+}
+
+
/*
* This function is _not_ called directly, but from
* video_generic_ioctl (and maybe others). userspace
@@ -1037,44 +1125,71 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
return err;
}
case VIDIOC_REQBUFS: {
- DEB_D(("VIDIOC_REQBUFS \n"));
- return videobuf_reqbufs(file,q,arg);
+ struct v4l2_requestbuffers *req = arg;
+ DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type));
+/*
+ if( req->type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+ return overlay_reqbufs(dev,req);
+ }
+*/
+ return videobuf_reqbufs(file,q,req);
}
case VIDIOC_QUERYBUF: {
- DEB_D(("VIDIOC_QUERYBUF \n"));
- return videobuf_querybuf(q,arg);
+ struct v4l2_buffer *buf = arg;
+ DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset));
+/* if( buf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+ return overlay_querybuf(dev,buf);
+ }
+ */ return videobuf_querybuf(q,buf);
}
case VIDIOC_QBUF: {
- struct v4l2_buffer *b = arg;
+ struct v4l2_buffer *buf = arg;
int ret = 0;
- ret = videobuf_qbuf(file,q,b);
- DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,b->index));
+/* if( buf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+ return overlay_qbuf(dev,buf);
+ }
+ */ ret = videobuf_qbuf(file,q,buf);
+ DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index));
return ret;
}
case VIDIOC_DQBUF: {
- struct v4l2_buffer *b = arg;
+ struct v4l2_buffer *buf = arg;
int ret = 0;
- ret = videobuf_dqbuf(file,q,b);
- DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,b->index));
+/* if( buf->type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+ return overlay_dqbuf(dev,buf);
+ }
+ */ ret = videobuf_dqbuf(file,q,buf);
+ DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index));
return ret;
}
case VIDIOC_STREAMON: {
- DEB_D(("VIDIOC_STREAMON \n"));
+ int *type = arg;
+ DEB_D(("VIDIOC_STREAMON, type:%d\n",*type));
+
if( 0 != ops->capture_begin ) {
if( 0 != (err = ops->capture_begin(fh))) {
return err;
}
}
- err = videobuf_streamon(file,q);
+/* if( *type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+ err = overlay_streamon(dev);
+ } else { */
+ err = videobuf_streamon(file,q);
+/* } */
return err;
}
case VIDIOC_STREAMOFF: {
- DEB_D(("VIDIOC_STREAMOFF \n"));
+ int *type = arg;
+
+ DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type));
if( 0 != ops->capture_end ) {
ops->capture_end(fh);
}
- err = videobuf_streamoff(file,q);
- return 0;
+/* if( *type == V4L2_BUF_TYPE_VIDEO_OVERLAY ) {
+ return overlay_streamoff(dev);
+ }
+ */ err = videobuf_streamoff(file,q);
+ return err;
}
case VIDIOCGMBUF:
{
@@ -1152,6 +1267,7 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, enum v4
DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
if (buf->vb.width != fh->video_fmt.width ||
+ buf->vb.bytesperline != fh->video_fmt.bytesperline ||
buf->vb.height != fh->video_fmt.height ||
buf->vb.size != size ||
buf->vb.field != field ||
@@ -1163,6 +1279,7 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, enum v4
if (STATE_NEEDS_INIT == buf->vb.state) {
struct saa7146_format *sfmt;
+ buf->vb.bytesperline = fh->video_fmt.bytesperline;
buf->vb.width = fh->video_fmt.width;
buf->vb.height = fh->video_fmt.height;
buf->vb.size = size;
@@ -1185,7 +1302,7 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, enum v4
saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
}
- err = videobuf_iolock(dev->pci,&buf->vb);
+ err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
if (err)
goto oops;
err = saa7146_pgtable_build(dev,buf);
@@ -1280,6 +1397,7 @@ static void video_open(struct saa7146_dev *dev, struct saa7146_fh *fh)
fh->video_fmt.width = 384;
fh->video_fmt.height = 288;
fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
+ fh->video_fmt.bytesperline = 0;
fh->video_fmt.field = V4L2_FIELD_ANY;
sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;