^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * vivid-meta-out.c - meta output support functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/usb/video.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "vivid-core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "vivid-kthread-out.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "vivid-meta-out.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) static int meta_out_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) unsigned int *nplanes, unsigned int sizes[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned int size = sizeof(struct vivid_meta_out_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) if (!vivid_is_webcam(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (*nplanes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (sizes[0] < size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) sizes[0] = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (vq->num_buffers + *nbuffers < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *nbuffers = 2 - vq->num_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *nplanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int meta_out_buf_prepare(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int size = sizeof(struct vivid_meta_out_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (dev->buf_prepare_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Error injection: test what happens if buf_prepare() returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) dev->buf_prepare_error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (vb2_plane_size(vb, 0) < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __func__, vb2_plane_size(vb, 0), size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) vb2_set_plane_payload(vb, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static void meta_out_buf_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) spin_lock(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) list_add_tail(&buf->list, &dev->meta_out_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) spin_unlock(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int meta_out_start_streaming(struct vb2_queue *vq, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) dev->meta_out_seq_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (dev->start_streaming_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) dev->start_streaming_error = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) err = vivid_start_generating_vid_out(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) &dev->meta_out_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct vivid_buffer *buf, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) list_for_each_entry_safe(buf, tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) &dev->meta_out_active, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) vb2_buffer_done(&buf->vb.vb2_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) VB2_BUF_STATE_QUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* abort streaming and wait for last buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static void meta_out_stop_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct vivid_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) dprintk(dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) vivid_stop_generating_vid_out(dev, &dev->meta_out_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void meta_out_buf_request_complete(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_meta_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) const struct vb2_ops vivid_meta_out_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .queue_setup = meta_out_queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .buf_prepare = meta_out_buf_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .buf_queue = meta_out_buf_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .start_streaming = meta_out_start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .stop_streaming = meta_out_stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .buf_request_complete = meta_out_buf_request_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int vidioc_enum_fmt_meta_out(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct v4l2_fmtdesc *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (!vivid_is_webcam(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (f->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) f->type = V4L2_BUF_TYPE_META_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) f->pixelformat = V4L2_META_FMT_VIVID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int vidioc_g_fmt_meta_out(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct vivid_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct v4l2_meta_format *meta = &f->fmt.meta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (!vivid_is_webcam(dev) || !dev->has_meta_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) meta->dataformat = V4L2_META_FMT_VIVID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) meta->buffersize = sizeof(struct vivid_meta_out_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) void vivid_meta_out_process(struct vivid_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct vivid_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct vivid_meta_out_buf *meta = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) v4l2_ctrl_s_ctrl(dev->brightness, meta->brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) v4l2_ctrl_s_ctrl(dev->contrast, meta->contrast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) v4l2_ctrl_s_ctrl(dev->saturation, meta->saturation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) v4l2_ctrl_s_ctrl(dev->hue, meta->hue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dprintk(dev, 2, " %s brightness %u contrast %u saturation %u hue %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) __func__, meta->brightness, meta->contrast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) meta->saturation, meta->hue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }