Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/media/platform/qcom/iris/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  iris_vb2.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
 */


#include <media/videobuf2-dma-contig.h>
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>

#include "iris_instance.h"
#include "iris_vb2.h"
#include "iris_vdec.h"
#include "iris_power.h"

static int iris_check_core_mbpf(struct iris_inst *inst)
{
 struct iris_core *core = inst->core;
 struct iris_inst *instance;
 u32 total_mbpf = 0;

 mutex_lock(&core->lock);
 list_for_each_entry(instance, &core->instances, list)
  total_mbpf += iris_get_mbpf(instance);
 mutex_unlock(&core->lock);

 if (total_mbpf > core->iris_platform_data->max_core_mbpf)
  return -ENOMEM;

 return 0;
}

static int iris_check_inst_mbpf(struct iris_inst *inst)
{
 struct platform_inst_caps *caps;
 u32 mbpf, max_mbpf;

 caps = inst->core->iris_platform_data->inst_caps;
 max_mbpf = caps->max_mbpf;
 mbpf = iris_get_mbpf(inst);
 if (mbpf > max_mbpf)
  return -ENOMEM;

 return 0;
}

static int iris_check_resolution_supported(struct iris_inst *inst)
{
 u32 width, height, min_width, min_height, max_width, max_height;
 struct platform_inst_caps *caps;

 caps = inst->core->iris_platform_data->inst_caps;
 width = inst->fmt_src->fmt.pix_mp.width;
 height = inst->fmt_src->fmt.pix_mp.height;

 min_width = caps->min_frame_width;
 max_width = caps->max_frame_width;
 min_height = caps->min_frame_height;
 max_height = caps->max_frame_height;

 if (!(min_width <= width && width <= max_width) ||
     !(min_height <= height && height <= max_height))
  return -EINVAL;

 return 0;
}

static int iris_check_session_supported(struct iris_inst *inst)
{
 struct iris_core *core = inst->core;
 struct iris_inst *instance = NULL;
 bool found = false;
 int ret;

 list_for_each_entry(instance, &core->instances, list) {
  if (instance == inst)
   found = true;
 }

 if (!found) {
  ret = -EINVAL;
  goto exit;
 }

 ret = iris_check_core_mbpf(inst);
 if (ret)
  goto exit;

 ret = iris_check_inst_mbpf(inst);
 if (ret)
  goto exit;

 ret = iris_check_resolution_supported(inst);
 if (ret)
  goto exit;

 return 0;
exit:
 dev_err(inst->core->dev, "current session not supported(%d)\n", ret);

 return ret;
}

int iris_vb2_buf_init(struct vb2_buffer *vb2)
{
 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
 struct iris_buffer *buf = to_iris_buffer(vbuf);

 buf->device_addr = vb2_dma_contig_plane_dma_addr(vb2, 0);

 return 0;
}

int iris_vb2_queue_setup(struct vb2_queue *q,
    unsigned int *num_buffers, unsigned int *num_planes,
    unsigned int sizes[], struct device *alloc_devs[])
{
 struct iris_inst *inst;
 struct iris_core *core;
 struct v4l2_format *f;
 int ret = 0;

 inst = vb2_get_drv_priv(q);

 mutex_lock(&inst->lock);
 if (inst->state == IRIS_INST_ERROR) {
  ret = -EBUSY;
  goto unlock;
 }

 core = inst->core;
 f = V4L2_TYPE_IS_OUTPUT(q->type) ? inst->fmt_src : inst->fmt_dst;

 if (*num_planes) {
  if (*num_planes != f->fmt.pix_mp.num_planes ||
      sizes[0] < f->fmt.pix_mp.plane_fmt[0].sizeimage)
   ret = -EINVAL;
  goto unlock;
 }

 ret = iris_check_session_supported(inst);
 if (ret)
  goto unlock;

 if (!inst->once_per_session_set) {
  inst->once_per_session_set = true;

  ret = core->hfi_ops->session_open(inst);
  if (ret) {
   ret = -EINVAL;
   dev_err(core->dev, "session open failed\n");
   goto unlock;
  }

  ret = iris_inst_change_state(inst, IRIS_INST_INIT);
  if (ret)
   goto unlock;
 }

 *num_planes = 1;
 sizes[0] = f->fmt.pix_mp.plane_fmt[0].sizeimage;

unlock:
 mutex_unlock(&inst->lock);

 return ret;
}

int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
{
 enum iris_buffer_type buf_type;
 struct iris_inst *inst;
 int ret = 0;

 inst = vb2_get_drv_priv(q);

 mutex_lock(&inst->lock);
 if (inst->state == IRIS_INST_ERROR) {
  ret = -EBUSY;
  goto error;
 }

 if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
     !V4L2_TYPE_IS_CAPTURE(q->type)) {
  ret = -EINVAL;
  goto error;
 }

 iris_scale_power(inst);

 ret = iris_check_session_supported(inst);
 if (ret)
  goto error;

 if (V4L2_TYPE_IS_OUTPUT(q->type))
  ret = iris_vdec_streamon_input(inst);
 else if (V4L2_TYPE_IS_CAPTURE(q->type))
  ret = iris_vdec_streamon_output(inst);
 if (ret)
  goto error;

 buf_type = iris_v4l2_type_to_driver(q->type);

 if (inst->state == IRIS_INST_STREAMING)
  ret = iris_queue_internal_deferred_buffers(inst, BUF_DPB);
 if (!ret)
  ret = iris_queue_deferred_buffers(inst, buf_type);
 if (ret)
  goto error;

 mutex_unlock(&inst->lock);

 return ret;

error:
 iris_helper_buffers_done(inst, q->type, VB2_BUF_STATE_QUEUED);
 iris_inst_change_state(inst, IRIS_INST_ERROR);
 mutex_unlock(&inst->lock);

 return ret;
}

void iris_vb2_stop_streaming(struct vb2_queue *q)
{
 struct iris_inst *inst;
 int ret = 0;

 inst = vb2_get_drv_priv(q);

 if (V4L2_TYPE_IS_CAPTURE(q->type) && inst->state == IRIS_INST_INIT)
  return;

 mutex_lock(&inst->lock);

 if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
     !V4L2_TYPE_IS_CAPTURE(q->type))
  goto exit;

 ret = iris_vdec_session_streamoff(inst, q->type);
 if (ret)
  goto exit;

exit:
 iris_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR);
 if (ret)
  iris_inst_change_state(inst, IRIS_INST_ERROR);

 mutex_unlock(&inst->lock);
}

int iris_vb2_buf_prepare(struct vb2_buffer *vb)
{
 struct iris_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);

 if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
  if (vbuf->field == V4L2_FIELD_ANY)
   vbuf->field = V4L2_FIELD_NONE;
  if (vbuf->field != V4L2_FIELD_NONE)
   return -EINVAL;
 }

 if (!(inst->sub_state & IRIS_INST_SUB_DRC)) {
  if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
      vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_OUTPUT))
   return -EINVAL;
  if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
      vb2_plane_size(vb, 0) < iris_get_buffer_size(inst, BUF_INPUT))
   return -EINVAL;
 }
 return 0;
}

int iris_vb2_buf_out_validate(struct vb2_buffer *vb)
{
 struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb);

 v4l2_buf->field = V4L2_FIELD_NONE;

 return 0;
}

void iris_vb2_buf_queue(struct vb2_buffer *vb2)
{
 static const struct v4l2_event eos = { .type = V4L2_EVENT_EOS };
 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb2);
 struct v4l2_m2m_ctx *m2m_ctx;
 struct iris_inst *inst;
 int ret = 0;

 inst = vb2_get_drv_priv(vb2->vb2_queue);

 mutex_lock(&inst->lock);
 if (inst->state == IRIS_INST_ERROR) {
  ret = -EBUSY;
  goto exit;
 }

 if (vbuf->field == V4L2_FIELD_ANY)
  vbuf->field = V4L2_FIELD_NONE;

 m2m_ctx = inst->m2m_ctx;

 if (!vb2->planes[0].bytesused && V4L2_TYPE_IS_OUTPUT(vb2->type)) {
  ret = -EINVAL;
  goto exit;
 }

 if (!inst->last_buffer_dequeued && V4L2_TYPE_IS_CAPTURE(vb2->vb2_queue->type)) {
  if ((inst->sub_state & IRIS_INST_SUB_DRC &&
       inst->sub_state & IRIS_INST_SUB_DRC_LAST) ||
      (inst->sub_state & IRIS_INST_SUB_DRAIN &&
       inst->sub_state & IRIS_INST_SUB_DRAIN_LAST)) {
   vbuf->flags |= V4L2_BUF_FLAG_LAST;
   vbuf->sequence = inst->sequence_cap++;
   vbuf->field = V4L2_FIELD_NONE;
   vb2_set_plane_payload(vb2, 0, 0);
   v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
   if (!v4l2_m2m_has_stopped(m2m_ctx)) {
    v4l2_event_queue_fh(&inst->fh, &eos);
    v4l2_m2m_mark_stopped(m2m_ctx);
   }
   inst->last_buffer_dequeued = true;
   goto exit;
  }
 }

 v4l2_m2m_buf_queue(m2m_ctx, vbuf);

 ret = iris_vdec_qbuf(inst, vbuf);

exit:
 if (ret) {
  iris_inst_change_state(inst, IRIS_INST_ERROR);
  v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
 }
 mutex_unlock(&inst->lock);
}

Messung V0.5
C=96 H=96 G=95

¤ Dauer der Verarbeitung: 0.2 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.