static int uvc_buffer_prepare(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf); if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); return -EINVAL; } if (unlikely(queue->flags & UVC_QUEUE_DISCONNECTED)) return -ENODEV; buf->state = UVC_BUF_STATE_QUEUED; buf->mem = vb2_plane_vaddr(vb, 0); buf->length = vb2_plane_size(vb, 0); if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) buf->bytesused = 0; else buf->bytesused = vb2_get_plane_payload(vb, 0); return 0; }
static int unicam_videobuf_prepare(struct vb2_buffer *vb) { struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, icd-> current_fmt->host_fmt); unsigned long size; pr_debug("-enter"); if (bytes_per_line < 0) return bytes_per_line; pr_debug("vb=0x%p buf=0x%p, size=%lu", vb, (void *)vb2_plane_dma_addr(vb, 0), vb2_get_plane_payload(vb, 0)); size = icd->user_height * bytes_per_line; if (vb2_plane_size(vb, 0) < size) { dev_err(icd->dev.parent, "Buffer too small (%lu < %lu)\n", vb2_plane_size(vb, 0), size); return -ENOBUFS; } vb2_set_plane_payload(vb, 0, size); pr_debug("-exit"); return 0; }
static void unicam_videobuf_queue(struct vb2_buffer *vb) { struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct unicam_camera_dev *unicam_dev = ici->priv; struct unicam_camera_buffer *buf = to_unicam_camera_vb(vb); unsigned long flags; dprintk("-enter"); dprintk("vb=0x%p vbuf=0x%p pbuf=0x%p size=%lu", vb, vb2_plane_vaddr(vb, 0), (void *)vb2_dma_contig_plane_dma_addr(vb, 0), vb2_get_plane_payload(vb, 0)); spin_lock_irqsave(&unicam_dev->lock, flags); list_add_tail(&buf->queue, &unicam_dev->capture); if (!unicam_dev->active) { unicam_dev->active = vb; /* use this buffer to trigger capture */ /* Configure HW only is streamon has been done * else only update active, HW would be configured * by streamon */ if(unicam_dev->streaming){ unicam_camera_update_buf(unicam_dev); if (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2) unicam_camera_capture(unicam_dev); } } spin_unlock_irqrestore(&unicam_dev->lock, flags); dprintk("-exit"); }
static int alsa_pb_fnc(struct vb2_buffer *vb, void *priv) { struct cobalt_stream *s = priv; if (s->alsa->alsa_pb_channel) cobalt_alsa_pb_pcm_data(s->alsa, vb2_plane_vaddr(vb, 0), 8 * 4, vb2_get_plane_payload(vb, 0) / (8 * 4)); return 0; }
static void bdisp_buf_queue(struct vb2_buffer *vb) { struct bdisp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); /* return to V4L2 any 0-size buffer so it can be dequeued by user */ if (!vb2_get_plane_payload(vb, 0)) { dev_dbg(ctx->bdisp_dev->dev, "0 data buffer, skip it\n"); vb2_buffer_done(vb, VB2_BUF_STATE_DONE); return; } if (ctx->fh.m2m_ctx) v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); }
static void unicam_videobuf_queue(struct vb2_buffer *vb) { struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct unicam_camera_dev *unicam_dev = ici->priv; struct unicam_camera_buffer *buf = to_unicam_camera_vb(vb); unsigned long flags; struct int_desc idesc; pr_debug("-enter"); pr_debug("vb=0x%p pbuf=0x%p size=%lu", vb, (void *)vb2_plane_dma_addr(vb, 0), vb2_get_plane_payload(vb, 0)); /* pr_info("Q 0x%x\n", vb2_plane_paddr(vb, 0)); */ spin_lock_irqsave(&unicam_dev->lock, flags); list_add_tail(&buf->queue, &unicam_dev->capture); if(unicam_dev->cap_mode && unicam_dev->cap_done){ pr_info("Cap mode and already captured\n"); spin_unlock_irqrestore(&unicam_dev->lock, flags); return; } if ((!unicam_dev->active)) { unicam_dev->active = vb; unicam_camera_update_buf(unicam_dev); if (atomic_read(&unicam_dev->streaming)) { mm_csi0_start_rx(); /* set data capture */ if (unicam_dev->if_params.if_mode == V4L2_SUBDEV_SENSOR_MODE_SERIAL_CSI2) { idesc.fsi = 1; idesc.fei = 1; idesc.lci = 0; idesc.die = 1; idesc.dataline = 2; mm_csi0_config_int(&idesc, IMAGE_BUFFER); mm_csi0_config_int(&idesc, DATA_BUFFER); unicam_camera_capture(unicam_dev); } else { idesc.fsi = 0; idesc.fei = 0; idesc.lci = unicam_dev->icd->user_height; idesc.die = 0; idesc.dataline = 0; mm_csi0_config_int(&idesc, IMAGE_BUFFER); } } } spin_unlock_irqrestore(&unicam_dev->lock, flags); pr_debug("-exit"); }
static void rcar_vin_videobuf_queue(struct vb2_buffer *vb) { struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct rcar_vin_priv *priv = ici->priv; unsigned long size; size = icd->sizeimage; if (vb2_plane_size(vb, 0) < size) { dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n", vb->v4l2_buf.index, vb2_plane_size(vb, 0), size); goto error; } vb2_set_plane_payload(vb, 0, size); dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); spin_lock_irq(&priv->lock); list_add_tail(to_buf_list(vb), &priv->capture); rcar_vin_fill_hw_slot(priv); /* If we weren't running, and have enough buffers, start capturing! */ if (priv->state != RUNNING && rcar_vin_hw_ready(priv)) { if (rcar_vin_setup(priv)) { /* Submit error */ list_del_init(to_buf_list(vb)); spin_unlock_irq(&priv->lock); goto error; } priv->request_to_stop = false; init_completion(&priv->capture_stop); priv->state = RUNNING; rcar_vin_capture(priv); } spin_unlock_irq(&priv->lock); return; error: vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); }
int coda_sps_parse_profile(struct coda_ctx *ctx, struct vb2_buffer *vb) { const u8 *buf = vb2_plane_vaddr(vb, 0); const u8 *end = buf + vb2_get_plane_payload(vb, 0); /* Find SPS header */ do { buf = coda_find_nal_header(buf, end); if (!buf) return -EINVAL; } while ((*buf++ & 0x1f) != 0x7); ctx->params.h264_profile_idc = buf[0]; ctx->params.h264_level_idc = buf[2]; return 0; }
void hva_dbg_perf_end(struct hva_ctx *ctx, struct hva_stream *stream) { struct device *dev = ctx_to_dev(ctx); u64 div; u32 duration; u32 bytesused; u32 timestamp; struct hva_ctx_dbg *dbg = &ctx->dbg; ktime_t end = ktime_get(); /* stream bytesused and timestamp in us */ bytesused = vb2_get_plane_payload(&stream->vbuf.vb2_buf, 0); div = stream->vbuf.vb2_buf.timestamp; do_div(div, 1000); timestamp = (u32)div; /* encoding duration */ div = (u64)ktime_us_delta(end, dbg->begin); dev_dbg(dev, "%s perf stream[%d] dts=%d encoded using %d bytes in %d us", ctx->name, stream->vbuf.sequence, timestamp, bytesused, (u32)div); do_div(div, 100); duration = (u32)div; dbg->min_duration = min(duration, dbg->min_duration); dbg->max_duration = max(duration, dbg->max_duration); dbg->total_duration += duration; dbg->cnt_duration++; /* * the average bitrate is based on the total stream size * and the total encoding periods */ dbg->total_stream_size += bytesused; dbg->window_stream_size += bytesused; dbg->is_valid_period = true; }
static int alsa_fnc(struct vb2_buffer *vb, void *priv) { struct cobalt_stream *s = priv; unsigned char *p = vb2_plane_vaddr(vb, 0); int i; if (pcm_debug) { pr_info("alsa: "); for (i = 0; i < 8 * 4; i++) { if (!(i & 3)) pr_cont(" "); pr_cont("%02x", p[i]); } pr_cont("\n"); } cobalt_alsa_announce_pcm_data(s->alsa, vb2_plane_vaddr(vb, 0), 8 * 4, vb2_get_plane_payload(vb, 0) / (8 * 4)); return 0; }
static void unicam_videobuf_release(struct vb2_buffer *vb) { struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct unicam_camera_dev *unicam_dev = ici->priv; struct unicam_camera_buffer *buf = to_unicam_camera_vb(vb); unsigned long flags; pr_debug("-enter"); pr_debug("vb=0x%p pbuf=0x%p size=%lu", vb, (void *)vb2_plane_dma_addr(vb, 0), vb2_get_plane_payload(vb, 0)); spin_lock_irqsave(&unicam_dev->lock, flags); if (buf->magic == UNICAM_BUF_MAGIC) list_del_init(&buf->queue); spin_unlock_irqrestore(&unicam_dev->lock, flags); pr_debug("-exit"); }
/** * __vb2_perform_fileio() - perform a single file io (read or write) operation * @q: videobuf2 queue * @data: pointed to target userspace buffer * @count: number of bytes to read or write * @ppos: file handle position tracking pointer * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking) * @read: access mode selector (1 means read, 0 means write) */ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count, loff_t *ppos, int nonblock, int read) { struct vb2_fileio_data *fileio; struct vb2_fileio_buf *buf; int ret, index; dprintk(3, "file io: mode %s, offset %ld, count %zd, %sblocking\n", read ? "read" : "write", (long)*ppos, count, nonblock ? "non" : ""); if (!data) return -EINVAL; /* * Initialize emulator on first call. */ if (!q->fileio) { ret = __vb2_init_fileio(q, read); dprintk(3, "file io: vb2_init_fileio result: %d\n", ret); if (ret) return ret; } fileio = q->fileio; /* * Hack fileio context to enable direct calls to vb2 ioctl interface. * The pointer will be restored before returning from this function. */ q->fileio = NULL; index = fileio->index; buf = &fileio->bufs[index]; /* * Check if we need to dequeue the buffer. */ if (buf->queued) { struct vb2_buffer *vb; /* * Call vb2_dqbuf to get buffer back. */ memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; fileio->b.index = index; ret = vb2_dqbuf(q, &fileio->b, nonblock); dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); if (ret) goto end; fileio->dq_count += 1; /* * Get number of bytes filled by the driver */ vb = q->bufs[index]; buf->size = vb2_get_plane_payload(vb, 0); buf->queued = 0; } /* * Limit count on last few bytes of the buffer. */ if (buf->pos + count > buf->size) { count = buf->size - buf->pos; dprintk(5, "reducing read count: %zd\n", count); } /* * Transfer data to userspace. */ dprintk(3, "file io: copying %zd bytes - buffer %d, offset %u\n", count, index, buf->pos); if (read) ret = copy_to_user(data, buf->vaddr + buf->pos, count); else ret = copy_from_user(buf->vaddr + buf->pos, data, count); if (ret) { dprintk(3, "file io: error copying data\n"); ret = -EFAULT; goto end; } /* * Update counters. */ buf->pos += count; *ppos += count; /* * Queue next buffer if required. */ if (buf->pos == buf->size || (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) { /* * Check if this is the last buffer to read. */ if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) && fileio->dq_count == 1) { dprintk(3, "file io: read limit reached\n"); /* * Restore fileio pointer and release the context. */ q->fileio = fileio; return __vb2_cleanup_fileio(q); } /* * Call vb2_qbuf and give buffer to the driver. */ memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; fileio->b.index = index; fileio->b.bytesused = buf->pos; ret = vb2_qbuf(q, &fileio->b); dprintk(5, "file io: vb2_dbuf result: %d\n", ret); if (ret) goto end; /* * Buffer has been queued, update the status */ buf->pos = 0; buf->queued = 1; buf->size = q->bufs[0]->v4l2_planes[0].length; fileio->q_count += 1; /* * Switch to the next buffer */ fileio->index = (index + 1) % q->num_buffers; /* * Start streaming if required. */ if (!read && !q->streaming) { ret = vb2_streamon(q, q->type); if (ret) goto end; } } /* * Return proper number of bytes processed. */ if (ret == 0) ret = count; end: /* * Restore the fileio context and block vb2 ioctl interface. */ q->fileio = fileio; return ret; }
static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count, loff_t *ppos, int nonblock, int read) { struct vb2_fileio_data *fileio; struct vb2_fileio_buf *buf; int ret, index; dprintk(3, "file io: mode %s, offset %ld, count %zd, %sblocking\n", read ? "read" : "write", (long)*ppos, count, nonblock ? "non" : ""); if (!data) return -EINVAL; if (!q->fileio) { ret = __vb2_init_fileio(q, read); dprintk(3, "file io: vb2_init_fileio result: %d\n", ret); if (ret) return ret; } fileio = q->fileio; q->fileio = NULL; index = fileio->index; buf = &fileio->bufs[index]; if (buf->queued) { struct vb2_buffer *vb; memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; fileio->b.index = index; ret = vb2_dqbuf(q, &fileio->b, nonblock); dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); if (ret) goto end; fileio->dq_count += 1; vb = q->bufs[index]; buf->size = vb2_get_plane_payload(vb, 0); buf->queued = 0; } if (buf->pos + count > buf->size) { count = buf->size - buf->pos; dprintk(5, "reducing read count: %zd\n", count); } dprintk(3, "file io: copying %zd bytes - buffer %d, offset %u\n", count, index, buf->pos); if (read) ret = copy_to_user(data, buf->vaddr + buf->pos, count); else ret = copy_from_user(buf->vaddr + buf->pos, data, count); if (ret) { dprintk(3, "file io: error copying data\n"); ret = -EFAULT; goto end; } buf->pos += count; *ppos += count; if (buf->pos == buf->size || (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) { if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) && fileio->dq_count == 1) { dprintk(3, "file io: read limit reached\n"); q->fileio = fileio; return __vb2_cleanup_fileio(q); } memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; fileio->b.index = index; fileio->b.bytesused = buf->pos; ret = vb2_qbuf(q, &fileio->b); dprintk(5, "file io: vb2_dbuf result: %d\n", ret); if (ret) goto end; buf->pos = 0; buf->queued = 1; buf->size = q->bufs[0]->v4l2_planes[0].length; fileio->q_count += 1; fileio->index = (index + 1) % q->num_buffers; if (!read && !q->streaming) { ret = vb2_streamon(q, q->type); if (ret) goto end; } } if (ret == 0) ret = count; end: q->fileio = fileio; return ret; }
static void mx3_videobuf_queue(struct vb2_buffer *vb) { struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct mx3_camera_dev *mx3_cam = ici->priv; struct mx3_camera_buffer *buf = to_mx3_vb(vb); struct dma_async_tx_descriptor *txd = buf->txd; struct idmac_channel *ichan = to_idmac_chan(txd->chan); struct idmac_video_param *video = &ichan->params.video; dma_cookie_t cookie; u32 fourcc = icd->current_fmt->host_fmt->fourcc; unsigned long flags; /* This is the configuration of one sg-element */ video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) { /* * If the IPU DMA channel is configured to transport * generic 8-bit data, we have to set up correctly the * geometry parameters upon the current pixel format. * So, since the DMA horizontal parameters are expressed * in bytes not pixels, convert these in the right unit. */ int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, icd->current_fmt->host_fmt); BUG_ON(bytes_per_line <= 0); video->out_width = bytes_per_line; video->out_height = icd->user_height; video->out_stride = bytes_per_line; } else { /* * For IPU known formats the pixel unit will be managed * successfully by the IPU code */ video->out_width = icd->user_width; video->out_height = icd->user_height; video->out_stride = icd->user_width; } #ifdef DEBUG /* helps to see what DMA actually has written */ if (vb2_plane_vaddr(vb, 0)) memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0)); #endif spin_lock_irqsave(&mx3_cam->lock, flags); list_add_tail(&buf->queue, &mx3_cam->capture); if (!mx3_cam->active) mx3_cam->active = buf; spin_unlock_irq(&mx3_cam->lock); cookie = txd->tx_submit(txd); dev_dbg(icd->dev.parent, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg)); if (cookie >= 0) return; spin_lock_irq(&mx3_cam->lock); /* Submit error */ list_del_init(&buf->queue); if (mx3_cam->active == buf) mx3_cam->active = NULL; spin_unlock_irqrestore(&mx3_cam->lock, flags); vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); }
/** * __vb2_perform_fileio() - perform a single file io (read or write) operation * @q: videobuf2 queue * @data: pointed to target userspace buffer * @count: number of bytes to read or write * @ppos: file handle position tracking pointer * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking) * @read: access mode selector (1 means read, 0 means write) */ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count, loff_t *ppos, int nonblock, int read) { struct vb2_fileio_data *fileio; struct vb2_fileio_buf *buf; bool is_multiplanar = q->is_multiplanar; /* * When using write() to write data to an output video node the vb2 core * should set timestamps if V4L2_BUF_FLAG_TIMESTAMP_COPY is set. Nobody * else is able to provide this information with the write() operation. */ bool set_timestamp = !read && (q->timestamp_flags & V4L2_BUF_FLAG_TIMESTAMP_MASK) == V4L2_BUF_FLAG_TIMESTAMP_COPY; int ret, index; dprintk(3, "mode %s, offset %ld, count %zd, %sblocking\n", read ? "read" : "write", (long)*ppos, count, nonblock ? "non" : ""); if (!data) return -EINVAL; /* * Initialize emulator on first call. */ if (!vb2_fileio_is_active(q)) { ret = __vb2_init_fileio(q, read); dprintk(3, "vb2_init_fileio result: %d\n", ret); if (ret) return ret; } fileio = q->fileio; /* * Check if we need to dequeue the buffer. */ index = fileio->cur_index; if (index >= q->num_buffers) { /* * Call vb2_dqbuf to get buffer back. */ memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; if (is_multiplanar) { memset(&fileio->p, 0, sizeof(fileio->p)); fileio->b.m.planes = &fileio->p; fileio->b.length = 1; } ret = vb2_internal_dqbuf(q, &fileio->b, nonblock); dprintk(5, "vb2_dqbuf result: %d\n", ret); if (ret) return ret; fileio->dq_count += 1; fileio->cur_index = index = fileio->b.index; buf = &fileio->bufs[index]; /* * Get number of bytes filled by the driver */ buf->pos = 0; buf->queued = 0; buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0) : vb2_plane_size(q->bufs[index], 0); /* Compensate for data_offset on read in the multiplanar case. */ if (is_multiplanar && read && fileio->b.m.planes[0].data_offset < buf->size) { buf->pos = fileio->b.m.planes[0].data_offset; buf->size -= buf->pos; } } else { buf = &fileio->bufs[index]; } /* * Limit count on last few bytes of the buffer. */ if (buf->pos + count > buf->size) { count = buf->size - buf->pos; dprintk(5, "reducing read count: %zd\n", count); } /* * Transfer data to userspace. */ dprintk(3, "copying %zd bytes - buffer %d, offset %u\n", count, index, buf->pos); if (read) ret = copy_to_user(data, buf->vaddr + buf->pos, count); else ret = copy_from_user(buf->vaddr + buf->pos, data, count); if (ret) { dprintk(3, "error copying data\n"); return -EFAULT; } /* * Update counters. */ buf->pos += count; *ppos += count; /* * Queue next buffer if required. */ if (buf->pos == buf->size || (!read && fileio->write_immediately)) { /* * Check if this is the last buffer to read. */ if (read && fileio->read_once && fileio->dq_count == 1) { dprintk(3, "read limit reached\n"); return __vb2_cleanup_fileio(q); } /* * Call vb2_qbuf and give buffer to the driver. */ memset(&fileio->b, 0, sizeof(fileio->b)); fileio->b.type = q->type; fileio->b.memory = q->memory; fileio->b.index = index; fileio->b.bytesused = buf->pos; if (is_multiplanar) { memset(&fileio->p, 0, sizeof(fileio->p)); fileio->p.bytesused = buf->pos; fileio->b.m.planes = &fileio->p; fileio->b.length = 1; } if (set_timestamp) v4l2_get_timestamp(&fileio->b.timestamp); ret = vb2_internal_qbuf(q, &fileio->b); dprintk(5, "vb2_dbuf result: %d\n", ret); if (ret) return ret; /* * Buffer has been queued, update the status */ buf->pos = 0; buf->queued = 1; buf->size = vb2_plane_size(q->bufs[index], 0); fileio->q_count += 1; /* * If we are queuing up buffers for the first time, then * increase initial_index by one. */ if (fileio->initial_index < q->num_buffers) fileio->initial_index++; /* * The next buffer to use is either a buffer that's going to be * queued for the first time (initial_index < q->num_buffers) * or it is equal to q->num_buffers, meaning that the next * time we need to dequeue a buffer since we've now queued up * all the 'first time' buffers. */ fileio->cur_index = fileio->initial_index; } /* * Return proper number of bytes processed. */ if (ret == 0) ret = count; return ret; }