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 void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct cx18_videobuf_buffer *buf = container_of(vb, struct cx18_videobuf_buffer, vb); struct cx18_stream *s = q->priv_data; cx18_dma_free(q, s, buf); }