diff options
author | Michael Hunold <devnull@localhost> | 2003-07-31 14:30:57 +0000 |
---|---|---|
committer | Michael Hunold <devnull@localhost> | 2003-07-31 14:30:57 +0000 |
commit | 0e60b88a6e1ac6fd543fc3e8f4f71774c280c958 (patch) | |
tree | 3c368aff18650733d9702414fb0311c5e38c6db4 /linux/drivers | |
parent | 1ff92b55d10927b3043355b0aec3c5fe681dd42d (diff) | |
download | mediapointer-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.c | 7 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146_fops.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146_hlp.c | 15 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146_vbi.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/common/saa7146_video.c | 156 |
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; |