/*APP调用ioctl VIDIOC_REQBUFS时会导致此函数被调用 * */ static int myvivi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { /*0. */ vb->size = myvivi_format.fmt.pix.sizeimage; /* These properties only change when queue is idle, see s_fmt */ vb->width = myvivi_format.fmt.pix.width; vb->height = myvivi_format.fmt.pix.height; vb->field = field; /*1. 做些准备工作*/ myvivi_precalculate_bars(0); #if 0 /*2. 调用videobuf_iolock 为类型为V4L2_MEMORY_USERPTR的video_buf分配内存*/ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { rc = videobuf_iolock(vq, &buf->vb, NULL); if (rc < 0) goto fail; } #endif /*3. 设置状态*/ vb->state = VIDEOBUF_PREPARED; return 0; }
static int vpbe_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct vpbe_fh *fh = q->priv_data; struct vpbe_layer *layer = fh->layer; struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev; unsigned long addr; int ret; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_prepare\n"); if (VIDEOBUF_NEEDS_INIT == vb->state) { vb->width = layer->pix_fmt.width; vb->height = layer->pix_fmt.height; vb->size = layer->pix_fmt.sizeimage; vb->field = field; ret = videobuf_iolock(q, vb, NULL); if (ret < 0) { v4l2_err(&vpbe_dev->v4l2_dev, "Failed to map \ user address\n"); return -EINVAL; }
/* app调用ioctl VIDIOC_QBUF时导致此函数被调用.它会填充video_buffer结构体并调用 * videobuf_iolock()来分配内存.以前分析时内存是用mmap调用时才会分配. * */ static int myvivi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { /*1.做些准备工作*/ /*2.调用 videobuf_iolock 分配内存: * 从分析videobuf-vmalloc.c这个核心层文件: 若videobuf_buffer的类型是"case V4L2_MEMORY_USERPTR:"才会分配. 在vivi.c这个虚拟摄像头驱动中,使用的类型是"case V4L2_MEMORY_MMAP:" 所以"videobuf_iolock()"是为类型为"case V4L2_MEMORY_USERPTR"的videobuf分配内存.而 在vivi.c这个虚拟摄像头中,因为使用的"videobuf_buffer"类型为"V4L2_MEMORY_MMAP",所以 videobuf_iolock()根本用不着,因为"__videobuf_iolock()"当类型为"V4L2_MEMORY_MMAP" 时,只是作了点判断工作就退出了.所以我们写自忆的myvivi时,可以注释掉这个 "videobuf_iolock()". */ #if 0 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { rc = videobuf_iolock(vq, &buf->vb, NULL); if (rc < 0) goto fail; } #endif /*3.设置状态:将状态修改为VIDEOBUF_PREPARED.表示已经准备好了.*/ vb->state = VIDEOBUF_PREPARED; return 0; }
static int vbi_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct bttv_fh *fh = q->priv_data; struct bttv *btv = fh->btv; struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); int rc; buf->vb.size = fh->lines * 2 * 2048; if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) return -EINVAL; if (STATE_NEEDS_INIT == buf->vb.state) { if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL))) goto fail; if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines))) goto fail; } buf->vb.state = STATE_PREPARED; buf->vb.field = field; dprintk("buf prepare %p: top=%p bottom=%p field=%s\n", vb, &buf->top, &buf->bottom, v4l2_field_names[buf->vb.field]); return 0; fail: bttv_dma_free(q,btv,buf); return rc; }
static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { int rc; struct marucam_device *dev = vq->priv_data; marucam_dbg(1, "field=%d\n", field); vb->size = get_image_size(dev); if (0 != vb->baddr && vb->bsize < vb->size) { marucam_err("The video buffer size is invalid\n"); return -EINVAL; } if (vb->state == VIDEOBUF_NEEDS_INIT) { rc = videobuf_iolock(vq, vb, NULL); if (rc < 0) { marucam_err("Failed to videobuf_iolock\n"); vb->state = VIDEOBUF_NEEDS_INIT; return rc; } } vb->width = dev->width; vb->height = dev->height; vb->field = field; vb->state = VIDEOBUF_PREPARED; return 0; }
static int vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); int rc = 0; unsigned int size; size = 720 * 12 * 2; buf->vb.size = size; if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) return -EINVAL; buf->vb.width = 720; buf->vb.height = 12; buf->vb.field = field; if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { rc = videobuf_iolock(q, &buf->vb, NULL); if (rc < 0) goto fail; } buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: free_buffer(q, buf); return rc; }
static int vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct em28xx_fh *fh = q->priv_data; struct em28xx *dev = fh->dev; struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); int rc = 0; buf->vb.size = dev->vbi_width * dev->vbi_height * 2; if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) return -EINVAL; buf->vb.width = dev->vbi_width; buf->vb.height = dev->vbi_height; buf->vb.field = field; if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { rc = videobuf_iolock(q, &buf->vb, NULL); if (rc < 0) goto fail; } buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: free_buffer(q, buf); return rc; }
static int camera_core_vbq_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct camera_device *cam = q->priv_data; int err = 0; spin_lock(&cam->img_lock); if (cam->pix.sizeimage > vb->bsize) { spin_unlock(&cam->img_lock); return -EINVAL; } vb->size = cam->pix.sizeimage; vb->width = cam->pix.width; vb->height = cam->pix.height; vb->field = field; spin_unlock(&cam->img_lock); if (vb->state == STATE_NEEDS_INIT) err = videobuf_iolock(NULL, vb, NULL); if (!err) { /* Size is aligned to PAGE_SIZE by video-buf lib, * we should read exact pix.sizeimage bytes */ sg_dma_len((struct scatterlist *)(vb->dma.sglist + vb->dma.sglen - 1)) = cam->pix.sizeimage%PAGE_SIZE; vb->state = STATE_PREPARED; } else camera_core_vbq_release (q, vb); return err; }
static int solo_buf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct solo_filehandle *fh = vq->priv_data; struct solo6010_dev *solo_dev = fh->solo_dev; vb->size = solo_image_size(solo_dev); if (vb->baddr != 0 && vb->bsize < vb->size) return -EINVAL; /* XXX: These properties only change when queue is idle */ vb->width = solo_dev->video_hsize; vb->height = solo_vlines(solo_dev); vb->bytesperline = solo_bytesperline(solo_dev); vb->field = field; if (vb->state == VIDEOBUF_NEEDS_INIT) { int rc = videobuf_iolock(vq, vb, NULL); if (rc < 0) { videobuf_dma_contig_free(vq, vb); vb->state = VIDEOBUF_NEEDS_INIT; return rc; } } vb->state = VIDEOBUF_PREPARED; return 0; }
static int cx18_prepare_buffer(struct videobuf_queue *q, struct cx18_stream *s, struct cx18_videobuf_buffer *buf, u32 pixelformat, unsigned int width, unsigned int height, enum v4l2_field field) { struct cx18 *cx = s->cx; int rc = 0; /* check settings */ buf->bytes_used = 0; if ((width < 48) || (height < 32)) return -EINVAL; buf->vb.size = (width * height * 2); if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size)) return -EINVAL; /* alloc + fill struct (if changed) */ if (buf->vb.width != width || buf->vb.height != height || buf->vb.field != field || s->pixelformat != pixelformat || buf->tvnorm != cx->std) { buf->vb.width = width; buf->vb.height = height; buf->vb.field = field; buf->tvnorm = cx->std; s->pixelformat = pixelformat; cx18_dma_free(q, s, buf); } if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size)) return -EINVAL; if (buf->vb.field == 0) buf->vb.field = V4L2_FIELD_INTERLACED; if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { buf->vb.width = width; buf->vb.height = height; buf->vb.field = field; buf->tvnorm = cx->std; s->pixelformat = pixelformat; rc = videobuf_iolock(q, &buf->vb, NULL); if (rc != 0) goto fail; } buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: cx18_dma_free(q, s, buf); return rc; }
static int mx1_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct soc_camera_device *icd = vq->priv_data; struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); int ret; int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); if (bytes_per_line < 0) return bytes_per_line; dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); WARN_ON(!list_empty(&vb->queue)); BUG_ON(NULL == icd->current_fmt); buf->inwork = 1; if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } vb->size = bytes_per_line * vb->height; if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; } if (vb->state == VIDEOBUF_NEEDS_INIT) { ret = videobuf_iolock(vq, vb, NULL); if (ret) goto fail; vb->state = VIDEOBUF_PREPARED; } buf->inwork = 0; return 0; fail: free_buffer(vq, buf); out: buf->inwork = 0; return ret; }
static int mx1_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct soc_camera_device *icd = vq->priv_data; struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); int ret; dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); /* Added list head initialization on alloc */ WARN_ON(!list_empty(&vb->queue)); BUG_ON(NULL == icd->current_fmt); /* * I think, in buf_prepare you only have to protect global data, * the actual buffer is yours */ buf->inwork = 1; if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } vb->size = icd->sizeimage; if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; } if (vb->state == VIDEOBUF_NEEDS_INIT) { ret = videobuf_iolock(vq, vb, NULL); if (ret) goto fail; vb->state = VIDEOBUF_PREPARED; } buf->inwork = 0; return 0; fail: free_buffer(vq, buf); out: buf->inwork = 0; return ret; }
static int mx2_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct soc_camera_device *icd = vq->priv_data; struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb); int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); int ret = 0; dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); if (bytes_per_line < 0) return bytes_per_line; #ifdef DEBUG /* * This can be useful if you want to see if we actually fill * the buffer with something */ memset((void *)vb->baddr, 0xaa, vb->bsize); #endif if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } vb->size = bytes_per_line * vb->height; if (vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; } if (vb->state == VIDEOBUF_NEEDS_INIT) { ret = videobuf_iolock(vq, vb, NULL); if (ret) goto fail; vb->state = VIDEOBUF_PREPARED; } return 0; fail: free_buffer(vq, buf); out: return ret; }
static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct soc_camera_device *icd = vq->priv_data; struct sh_mobile_ceu_buffer *buf; int ret; buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, vb, vb->baddr, vb->bsize); /* Added list head initialization on alloc */ WARN_ON(!list_empty(&vb->queue)); #ifdef DEBUG /* This can be useful if you want to see if we actually fill * the buffer with something */ memset((void *)vb->baddr, 0xaa, vb->bsize); #endif BUG_ON(NULL == icd->current_fmt); if (buf->fmt != icd->current_fmt || vb->width != icd->width || vb->height != icd->height || vb->field != field) { buf->fmt = icd->current_fmt; vb->width = icd->width; vb->height = icd->height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; } if (vb->state == VIDEOBUF_NEEDS_INIT) { ret = videobuf_iolock(vq, vb, NULL); if (ret) goto fail; vb->state = VIDEOBUF_PREPARED; } return 0; fail: free_buffer(vq, buf); out: return ret; }
static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field) { struct file *file = q->priv_data; struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; struct saa7146_buf *buf = (struct saa7146_buf *)vb; int err = 0; int lines, llength, size; lines = 16 * 2 ; /* 2 fields */ llength = vbi_pixel_to_capture; size = lines * llength; DEB_VBI("vb:%p\n", vb); if (0 != buf->vb.baddr && buf->vb.bsize < size) { DEB_VBI("size mismatch\n"); return -EINVAL; } if (buf->vb.size != size) saa7146_dma_free(dev,q,buf); if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = llength; buf->vb.height = lines; buf->vb.size = size; buf->vb.field = field; // FIXME: check this saa7146_pgtable_free(dev->pci, &buf->pt[2]); saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); err = videobuf_iolock(q,&buf->vb, NULL); if (err) goto oops; err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], dma->sglist, dma->sglen); if (0 != err) return err; } buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; return 0; oops: DEB_VBI("error out\n"); saa7146_dma_free(dev,q,buf); return err; }
static int omap1_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct soc_camera_device *icd = vq->priv_data; struct omap1_cam_buf *buf = container_of(vb, struct omap1_cam_buf, vb); int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct omap1_cam_dev *pcdev = ici->priv; int ret; if (bytes_per_line < 0) return bytes_per_line; WARN_ON(!list_empty(&vb->queue)); BUG_ON(NULL == icd->current_fmt); buf->inwork = 1; if (buf->code != icd->current_fmt->code || vb->field != field || vb->width != icd->user_width || vb->height != icd->user_height) { buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } vb->size = bytes_per_line * vb->height; if (vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; } if (vb->state == VIDEOBUF_NEEDS_INIT) { ret = videobuf_iolock(vq, vb, NULL); if (ret) goto fail; vb->state = VIDEOBUF_PREPARED; } buf->inwork = 0; return 0; fail: free_buffer(vq, buf, pcdev->vb_mode); out: buf->inwork = 0; return ret; }
static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct saa7134_dev *dev = q->priv_data; struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); unsigned int lines, llength, size; int err; dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); llength = TS_PACKET_SIZE; lines = dev->ts.nr_packets; size = lines * llength; if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; if (buf->vb.size != size) { saa7134_dma_free(q,buf); } if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); dprintk("buffer_prepare: needs_init\n"); buf->vb.width = llength; buf->vb.height = lines; buf->vb.size = size; buf->pt = &dev->ts.pt_ts; err = videobuf_iolock(q,&buf->vb,NULL); if (err) goto oops; err = saa7134_pgtable_build(dev->pci,buf->pt, dma->sglist, dma->sglen, saa7134_buffer_startpage(buf)); if (err) goto oops; } buf->vb.state = VIDEOBUF_PREPARED; buf->activate = buffer_activate; buf->vb.field = field; return 0; oops: saa7134_dma_free(q,buf); return err; }
static int vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct cx231xx_fh *fh = vq->priv_data; struct cx231xx_buffer *buf = container_of(vb, struct cx231xx_buffer, vb); struct cx231xx *dev = fh->dev; int rc = 0, urb_init = 0; u32 height = 0; height = ((dev->norm & V4L2_STD_625_50) ? PAL_VBI_LINES : NTSC_VBI_LINES); buf->vb.size = ((dev->width << 1) * height * 2); if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) return -EINVAL; buf->vb.width = dev->width; buf->vb.height = height; buf->vb.field = field; buf->vb.field = V4L2_FIELD_SEQ_TB; if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { rc = videobuf_iolock(vq, &buf->vb, NULL); if (rc < 0) goto fail; } if (!dev->vbi_mode.bulk_ctl.num_bufs) urb_init = 1; if (urb_init) { rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS, CX231XX_NUM_VBI_BUFS, dev->vbi_mode.alt_max_pkt_size[0], cx231xx_isoc_vbi_copy); if (rc < 0) goto fail; } buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: free_buffer(vq, buf); return rc; }
/* APP调用ioctl VIDIOC_QBUF 时: 1,先调用‘buffer_prepare()’作准备工作,会去填充video_bufer 结构体--即头部信息。 当内存为V4L2_MEMORY_USERPTR类型时,调用 videobuf_iolock来分配内存。 2,将buffer放入队列:list_add_tail(&buf->stream, &q->stream); 3,调用‘buf_queue()’起通知作用。 */ static int myvivi_buffer_prepare(struct vb2_buffer *vb) { /* 1,做准备工作 */ /* 2, 调用 videobuf_iolock为类型为V4L2_MEMORY_USERPTR的vudeo_buf分配内存。 但是在vivi中其实并用不着,可以去掉,VIVI是用V4L2_MEMORY_MMAP。。*/ #if 0 if(VIDEOBUF_NEEDS_INIT == buf->vb.state){ rc = videobuf_iolock(vq, &buf->vb, NULL); if (rc < 0) goto fail; } #endif //buffer_prepare函数是要填充video_buf结构体 -- struct vb2_buffer /* 3,设置状态:这里将结构中的状态填充为VIDEOBUF_PREPARED,表示已准备好。 */ vb->state = VB2_BUF_STATE_PREPARED;//2.6中是VIDEOBUF_PREPARED return 0; }
static int vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct cx8800_fh *fh = q->priv_data; struct cx8800_dev *dev = fh->dev; struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); unsigned int size; int rc; size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); buf->vb.width = VBI_LINE_LENGTH; buf->vb.height = VBI_LINE_COUNT; buf->vb.size = size; buf->vb.field = V4L2_FIELD_SEQ_TB; if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL))) goto fail; cx88_risc_buffer(dev->pci, &buf->risc, dma->sglist, 0, buf->vb.width * buf->vb.height, buf->vb.width, 0, buf->vb.height); } buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: cx88_free_buffer(q,buf); return rc; }
static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct file *file = q->priv_data; struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; struct saa7146_buf *buf = (struct saa7146_buf *)vb; int size,err = 0; DEB_CAP(("vbuf:%p\n",vb)); /* sanity checks */ if (fh->video_fmt.width < 48 || fh->video_fmt.height < 32 || fh->video_fmt.width > vv->standard->h_max_out || fh->video_fmt.height > vv->standard->v_max_out) { DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height)); return -EINVAL; } size = fh->video_fmt.sizeimage; if (0 != buf->vb.baddr && buf->vb.bsize < size) { DEB_D(("size mismatch.\n")); return -EINVAL; } 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 || buf->vb.field != fh->video_fmt.field || buf->fmt != &fh->video_fmt) { saa7146_dma_free(dev,buf); } 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; buf->vb.field = field; buf->fmt = &fh->video_fmt; buf->vb.field = fh->video_fmt.field; sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); if( 0 != IS_PLANAR(sfmt->trans)) { saa7146_pgtable_free(dev->pci, &buf->pt[0]); saa7146_pgtable_free(dev->pci, &buf->pt[1]); saa7146_pgtable_free(dev->pci, &buf->pt[2]); saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); saa7146_pgtable_alloc(dev->pci, &buf->pt[1]); saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); } else { saa7146_pgtable_free(dev->pci, &buf->pt[0]); saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); } err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb); if (err) goto oops; err = saa7146_pgtable_build(dev,buf); if (err) goto oops; } buf->vb.state = STATE_PREPARED; buf->activate = buffer_activate; return 0; oops: DEB_D(("error out.\n")); saa7146_dma_free(dev,buf); return err; }
static int omap24xxcam_vbq_prepare(struct videobuf_queue *vbq, struct videobuf_buffer *vb, enum v4l2_field field) { struct omap24xxcam_fh *fh = vbq->priv_data; int err = 0; /* * Accessing pix here is okay since it's constant while * streaming is on (and we only get called then). */ if (vb->baddr) { /* This is a userspace buffer. */ if (fh->pix.sizeimage > vb->bsize) { /* The buffer isn't big enough. */ err = -EINVAL; } else vb->size = fh->pix.sizeimage; } else { if (vb->state != VIDEOBUF_NEEDS_INIT) { /* * We have a kernel bounce buffer that has * already been allocated. */ if (fh->pix.sizeimage > vb->size) { /* * The image size has been changed to * a larger size since this buffer was * allocated, so we need to free and * reallocate it. */ omap24xxcam_vbq_release(vbq, vb); vb->size = fh->pix.sizeimage; } } else { /* We need to allocate a new kernel bounce buffer. */ vb->size = fh->pix.sizeimage; } } if (err) return err; vb->width = fh->pix.width; vb->height = fh->pix.height; vb->field = field; if (vb->state == VIDEOBUF_NEEDS_INIT) { if (vb->memory == V4L2_MEMORY_MMAP) /* * we have built the scatter-gather list by ourself so * do the scatter-gather mapping as well */ err = omap24xxcam_dma_iolock(vbq, videobuf_to_dma(vb)); else err = videobuf_iolock(vbq, vb, NULL); } if (!err) vb->state = VIDEOBUF_PREPARED; else omap24xxcam_vbq_release(vbq, vb); return err; }
static int jz4780_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct soc_camera_device *icd = vq->priv_data; struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct jz4780_camera_dev *pcdev = ici->priv; struct jz4780_buffer *buf = container_of(vb, struct jz4780_buffer, vb); int ret; int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); if (bytes_per_line < 0) return bytes_per_line; dprintk(7, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); /* Added list head initialization on alloc */ WARN_ON(!list_empty(&vb->queue)); BUG_ON(NULL == icd->current_fmt); /* * I think, in buf_prepare you only have to protect global data, * the actual buffer is yours */ buf->inwork = 1; if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } vb->size = bytes_per_line * vb->height; if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; } if (vb->state == VIDEOBUF_NEEDS_INIT) { if(pcdev->is_tlb_enabled == 0) { ret = videobuf_iolock(vq, vb, NULL); if (ret) { dprintk(3, "%s error!\n", __FUNCTION__); goto fail; } } vb->state = VIDEOBUF_PREPARED; } buf->inwork = 0; return 0; fail: free_buffer(vq, buf); out: buf->inwork = 0; return ret; }
static int usbcam_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct usbcam_fh *ufp = container_of(vq, struct usbcam_fh, ufh_vbq); struct usbcam_dev *udp = ufp->ufh_dev; struct usbcam_frame *framep = container_of(vb, struct usbcam_frame, vbb); struct videobuf_dmabuf *dma = usbframe_get_dmabuf(&framep->vbb); int res; framep->vbb.size = udp->ud_format.sizeimage; if (framep->vbb.baddr && (framep->vbb.bsize < framep->vbb.size)) { usbcam_warn(udp, "process %s requested capture of a frame " "larger than its", current->comm); usbcam_warn(udp, "allocated frame buffer, fix it!"); return -EINVAL; } if (framep->vbb.state == STATE_NEEDS_INIT) { /* * This is the place where we initialize the rest of * the usbcam_frame structure. */ INIT_LIST_HEAD(&framep->cap_links); framep->vmap_base = NULL; framep->vmap_sof = NULL; usbcam_dbg(udp, VIDEOBUF, "preparing frame %d/%p", framep->vbb.i, framep); /* We also lock down the memory that was allocated for it */ res = videobuf_iolock(vq, &framep->vbb, NULL); if (res) goto fail; /* If there's no kernel mapping, we must create one */ if (!dma->vmalloc) { framep->vmap_base = vmap(dma->pages, dma->nr_pages, VM_MAP, PAGE_KERNEL); if (!framep->vmap_base) { res = -ENOMEM; goto fail; } framep->vmap_sof = ((char *)framep->vmap_base) + dma->offset; } } framep->vbb.field = field; framep->vbb.state = STATE_PREPARED; return 0; fail: usbcam_videobuf_free(vq, framep); return res; }
/** * previewer_vbq_prepare - Videobuffer is prepared and mmapped. * @q: Structure containing the videobuffer queue. * @vb: Structure containing the videobuffer used for previewer processing. * @field: Type of field to set in videobuffer device. * * Returns 0 if successful, or -EINVAL if buffer couldn't get allocated, or * -EIO if the ISP MMU mapping fails **/ static int previewer_vbq_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct prev_fh *fh = q->priv_data; struct prev_device *device = fh->device; int err = -EINVAL; unsigned int isp_addr; struct videobuf_dmabuf *dma = videobuf_to_dma(vb); dev_dbg(prev_dev, "previewer_vbq_prepare E\n"); if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { spin_lock(&device->inout_vbq_lock); if (vb->baddr) { vb->size = prev_bufsize; vb->bsize = prev_bufsize; DPRINTK_PREVIEWER("[%s] bsize = %d\n", __func__, vb->bsize); } else { spin_unlock(&device->inout_vbq_lock); dev_err(prev_dev, "No user buffer allocated\n"); goto out; } vb->width = device->params->size_params.hsize; vb->height = device->params->size_params.vsize; vb->field = field; spin_unlock(&device->inout_vbq_lock); if (vb->state == VIDEOBUF_NEEDS_INIT) { DPRINTK_PREVIEWER("[%s] baddr = %08x\n", __func__, (int)vb->baddr); err = videobuf_iolock(q, vb, NULL); if (!err) { isp_addr = ispmmu_map_sg(dma->sglist, dma->sglen); if (!isp_addr) { err = -EIO; } else { device->isp_addr_read = isp_addr; DPRINTK_PREVIEWER("[%s] " "isp_addr_read = %08x\n", __func__, isp_addr); } } } if (!err) { vb->state = VIDEOBUF_PREPARED; flush_cache_user_range(NULL, vb->baddr, (vb->baddr + vb->bsize)); } else { previewer_vbq_release(q, vb); } } else if (q->type == V4L2_BUF_TYPE_PRIVATE) { spin_lock(&device->lsc_vbq_lock); if (vb->baddr) { vb->size = lsc_bufsize; vb->bsize = lsc_bufsize; DPRINTK_PREVIEWER("[%s] bsize = %d\n", __func__, vb->bsize); } else { spin_unlock(&device->lsc_vbq_lock); dev_err(prev_dev, "No user buffer allocated\n"); goto out; } vb->width = device->params->size_params.hsize; vb->height = device->params->size_params.vsize; vb->field = field; spin_unlock(&device->lsc_vbq_lock); if (vb->state == VIDEOBUF_NEEDS_INIT) { DPRINTK_PREVIEWER("[%s] baddr = %08x\n", __func__, (int)vb->baddr); err = videobuf_iolock(q, vb, NULL); if (!err) { isp_addr = ispmmu_map_sg(dma->sglist, dma->sglen); if (!isp_addr) { err = -EIO; } else { device->isp_addr_lsc = isp_addr; DPRINTK_PREVIEWER("[%s] isp_addr_lsc =" " %08x\n", __func__, isp_addr); } } } if (!err) { vb->state = VIDEOBUF_PREPARED; flush_cache_user_range(NULL, vb->baddr, (vb->baddr + vb->bsize)); } else { previewer_vbq_release(q, vb); } } else { return -EINVAL; } dev_dbg(prev_dev, "previewer_vbq_prepare L\n"); out: return err; }
/** * prev2resz_vbq_prepare - Videobuffer is prepared and mmapped. */ static int prev2resz_vbq_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct prev2resz_fhdl *fhdl = q->priv_data; struct videobuf_dmabuf *dma = videobuf_to_dma(vb); dma_addr_t isp_addr; int err = 0; if (!vb->baddr) { dev_err(p2r_device, "%s: No user buffer allocated\n", __func__); return -EINVAL; } if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { spin_lock(&fhdl->dst_vbq_lock); vb->size = fhdl->pipe.out.image.bytesperline * fhdl->pipe.out.image.height; vb->width = fhdl->pipe.out.image.width; vb->height = fhdl->pipe.out.image.height; vb->bsize = vb->size; vb->field = field; spin_unlock(&fhdl->dst_vbq_lock); } else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { spin_lock(&fhdl->src_vbq_lock); vb->size = fhdl->pipe.in.image.bytesperline * fhdl->pipe.in.image.height; vb->width = fhdl->pipe.in.image.width; vb->height = fhdl->pipe.in.image.height; vb->bsize = vb->size; vb->field = field; spin_unlock(&fhdl->src_vbq_lock); } else { return -EINVAL; } if (vb->state == VIDEOBUF_NEEDS_INIT) { dev_dbg(p2r_device, "baddr = %08x\n", (int)vb->baddr); err = videobuf_iolock(q, vb, NULL); if (!err) { isp_addr = ispmmu_vmap(fhdl->isp, dma->sglist, dma->sglen); if (!isp_addr) { err = -EIO; } else { if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) fhdl->dst_buff_addr = isp_addr; else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) fhdl->src_buff_addr = isp_addr; else return -EINVAL; } } } if (!err) { if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { spin_lock(&fhdl->dst_vbq_lock); vb->state = VIDEOBUF_PREPARED; spin_unlock(&fhdl->dst_vbq_lock); } else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { spin_lock(&fhdl->src_vbq_lock); vb->state = VIDEOBUF_PREPARED; spin_unlock(&fhdl->src_vbq_lock); } } else { prev2resz_vbq_release(q, vb); } return err; }
/** * @brief: Called when application apply buffers, camera buffer initial. * * @author: caolianming * @date: 2014-01-06 * @param [in] *vq: V4L2 buffer queue information structure * @param [in] *vb: V4L2 buffer information structure * @param [in] field: V4L2_FIELD_ANY */ static int ak_videobuf_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, enum v4l2_field field) { struct soc_camera_device *icd = vq->priv_data; struct ak_buffer *buf = container_of(vb, struct ak_buffer, vb); int ret; int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); isp_dbg("%s (vb=0x%p) buf[%d] vb->baddr=0x%08lx vb->bsize=%d bytes_per_line=%d\n", __func__, vb, vb->i, vb->baddr, vb->bsize, bytes_per_line); bytes_per_line = icd->user_width * 3 /2; if (bytes_per_line < 0) return bytes_per_line; /* Added list head initialization on alloc */ WARN_ON(!list_empty(&vb->queue)); #if 0 //#ifdef ISP_DEBUG /* * This can be useful if you want to see if we actually fill * the buffer with something */ memset((void *)vb->baddr, 0xaa, vb->bsize); #endif BUG_ON(NULL == icd->current_fmt); /* I think, in buf_prepare you only have to protect global data, * the actual buffer is yours */ buf->inwork = 1; if (buf->code != icd->current_fmt->code || vb->width != icd->user_width || vb->height != icd->user_height || vb->field != field) { buf->code = icd->current_fmt->code; vb->width = icd->user_width; vb->height = icd->user_height; vb->field = field; vb->state = VIDEOBUF_NEEDS_INIT; } vb->size = bytes_per_line * vb->height; if (0 != vb->baddr && vb->bsize < vb->size) { ret = -EINVAL; goto out; } if (vb->state == VIDEOBUF_NEEDS_INIT) { ret = videobuf_iolock(vq, vb, NULL); if (ret) goto fail; vb->state = VIDEOBUF_PREPARED; } buf->inwork = 0; return 0; fail: free_buffer(vq, buf); out: buf->inwork = 0; return ret; }