struct vimc_capture_device { struct vimc_ent_device ved; struct video_device vdev; struct v4l2_pix_format format; struct vb2_queue queue; struct list_head buf_list; /* * NOTE: in a real driver, a spin lock must be used to access the * queue because the frames are generated from a hardware interruption * and the isr is not allowed to sleep. * Even if it is not necessary a spinlock in the vimc driver, we * use it here as a code reference
*/
spinlock_t qlock; struct mutex lock;
u32 sequence; struct vimc_stream stream; struct media_pad pad;
};
struct vimc_capture_buffer { /* * struct vb2_v4l2_buffer must be the first element * the videobuf2 framework will allocate this struct based on * buf_struct_size and use the first sizeof(struct vb2_buffer) bytes of * memory as a vb2_buffer
*/ struct vb2_v4l2_buffer vb2; struct list_head list;
};
/* Don't accept a pixelformat that is not on the table */
vpix = vimc_pix_map_by_pixelformat(format->pixelformat); if (!vpix) {
format->pixelformat = fmt_default.pixelformat;
vpix = vimc_pix_map_by_pixelformat(format->pixelformat);
} /* TODO: Add support for custom bytesperline values */
format->bytesperline = format->width * vpix->bpp;
format->sizeimage = format->bytesperline * format->height;
if (format->field == V4L2_FIELD_ANY)
format->field = fmt_default.field;
vimc_colorimetry_clamp(format);
if (format->colorspace == V4L2_COLORSPACE_DEFAULT)
format->colorspace = fmt_default.colorspace;
/* Start the media pipeline */
ret = video_device_pipeline_start(&vcapture->vdev, &vcapture->stream.pipe); if (ret) {
vimc_capture_return_all_buffers(vcapture, VB2_BUF_STATE_QUEUED); return ret;
}
ret = vimc_streamer_s_stream(&vcapture->stream, &vcapture->ved, 1); if (ret) {
video_device_pipeline_stop(&vcapture->vdev);
vimc_capture_return_all_buffers(vcapture, VB2_BUF_STATE_QUEUED); return ret;
}
return 0;
}
/* * Stop the stream engine. Any remaining buffers in the stream queue are * dequeued and passed on to the vb2 framework marked as STATE_ERROR.
*/ staticvoid vimc_capture_stop_streaming(struct vb2_queue *vq)
{ struct vimc_capture_device *vcapture = vb2_get_drv_priv(vq);
if (*nplanes) return sizes[0] < vcapture->format.sizeimage ? -EINVAL : 0; /* We don't support multiplanes for now */
*nplanes = 1;
sizes[0] = vcapture->format.sizeimage;
/* Get the first entry of the list */
vimc_buf = list_first_entry_or_null(&vcapture->buf_list,
typeof(*vimc_buf), list); if (!vimc_buf) {
spin_unlock(&vcapture->qlock); return ERR_PTR(-EAGAIN);
}
/* Remove this entry from the list */
list_del(&vimc_buf->list);
spin_unlock(&vcapture->qlock);
/* Fill the buffer */
vimc_buf->vb2.vb2_buf.timestamp = ktime_get_ns();
vimc_buf->vb2.sequence = vcapture->sequence++;
vimc_buf->vb2.field = vcapture->format.field;
/* Set it as ready */
vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
vcapture->format.sizeimage);
vb2_buffer_done(&vimc_buf->vb2.vb2_buf, VB2_BUF_STATE_DONE); return NULL;
}
/* Register the video_device with the v4l2 and the media framework */
ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); if (ret) {
dev_err(vimc->mdev.dev, "%s: video register failed (err=%d)\n",
vcapture->vdev.name, ret); goto err_clean_m_ent;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.