Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  wave5-helper.c   Sprache: C

 
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * Wave5 series multi-standard codec IP - decoder interface
 *
 * Copyright (C) 2021-2023 CHIPS&MEDIA INC
 */


#include "wave5-helper.h"

#define DEFAULT_BS_SIZE(width, height) ((width) * (height) / 8 * 3)

const char *state_to_str(enum vpu_instance_state state)
{
 switch (state) {
 case VPU_INST_STATE_NONE:
  return "NONE";
 case VPU_INST_STATE_OPEN:
  return "OPEN";
 case VPU_INST_STATE_INIT_SEQ:
  return "INIT_SEQ";
 case VPU_INST_STATE_PIC_RUN:
  return "PIC_RUN";
 case VPU_INST_STATE_STOP:
  return "STOP";
 default:
  return "UNKNOWN";
 }
}

void wave5_cleanup_instance(struct vpu_instance *inst)
{
 int i;

 /*
 * For Wave515 SRAM memory is allocated at
 * wave5_vpu_dec_register_device() and freed at
 * wave5_vpu_dec_unregister_device().
 */

 if (list_is_singular(&inst->list) &&
     inst->dev->product_code != WAVE515_CODE)
  wave5_vdi_free_sram(inst->dev);

 for (i = 0; i < inst->fbc_buf_count; i++)
  wave5_vpu_dec_reset_framebuffer(inst, i);

 wave5_vdi_free_dma_memory(inst->dev, &inst->bitstream_vbuf);
 v4l2_ctrl_handler_free(&inst->v4l2_ctrl_hdl);
 if (inst->v4l2_fh.vdev) {
  v4l2_fh_del(&inst->v4l2_fh);
  v4l2_fh_exit(&inst->v4l2_fh);
 }
 list_del_init(&inst->list);
 ida_free(&inst->dev->inst_ida, inst->id);
 kfree(inst->codec_info);
 kfree(inst);
}

int wave5_vpu_release_device(struct file *filp,
        int (*close_func)(struct vpu_instance *inst, u32 *fail_res),
        char *name)
{
 struct vpu_instance *inst = wave5_to_vpu_inst(filp->private_data);
 int ret = 0;

 v4l2_m2m_ctx_release(inst->v4l2_fh.m2m_ctx);
 if (inst->state != VPU_INST_STATE_NONE) {
  u32 fail_res;

  ret = close_func(inst, &fail_res);
  if (fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING) {
   dev_err(inst->dev->dev, "%s close failed, device is still running\n",
    name);
   return -EBUSY;
  }
  if (ret && ret != -EIO) {
   dev_err(inst->dev->dev, "%s close, fail: %d\n", name, ret);
   return ret;
  }
 }

 wave5_cleanup_instance(inst);

 return ret;
}

int wave5_vpu_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq,
    const struct vb2_ops *ops)
{
 struct vpu_instance *inst = priv;
 int ret;

 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
 src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
 src_vq->mem_ops = &vb2_dma_contig_memops;
 src_vq->ops = ops;
 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 src_vq->buf_struct_size = sizeof(struct vpu_src_buffer);
 src_vq->drv_priv = inst;
 src_vq->lock = &inst->dev->dev_lock;
 src_vq->dev = inst->dev->v4l2_dev.dev;
 ret = vb2_queue_init(src_vq);
 if (ret)
  return ret;

 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
 dst_vq->mem_ops = &vb2_dma_contig_memops;
 dst_vq->ops = ops;
 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 dst_vq->buf_struct_size = sizeof(struct vpu_src_buffer);
 dst_vq->drv_priv = inst;
 dst_vq->lock = &inst->dev->dev_lock;
 dst_vq->dev = inst->dev->v4l2_dev.dev;
 ret = vb2_queue_init(dst_vq);
 if (ret)
  return ret;

 return 0;
}

int wave5_vpu_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
{
 struct vpu_instance *inst = wave5_to_vpu_inst(fh);
 bool is_decoder = inst->type == VPU_INST_TYPE_DEC;

 dev_dbg(inst->dev->dev, "%s: [%s] type: %u id: %u | flags: %u\n", __func__,
  is_decoder ? "decoder" : "encoder", sub->type, sub->id, sub->flags);

 switch (sub->type) {
 case V4L2_EVENT_EOS:
  return v4l2_event_subscribe(fh, sub, 0, NULL);
 case V4L2_EVENT_SOURCE_CHANGE:
  if (is_decoder)
   return v4l2_src_change_event_subscribe(fh, sub);
  return -EINVAL;
 case V4L2_EVENT_CTRL:
  return v4l2_ctrl_subscribe_event(fh, sub);
 default:
  return -EINVAL;
 }
}

int wave5_vpu_g_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
{
 struct vpu_instance *inst = wave5_to_vpu_inst(fh);
 int i;

 f->fmt.pix_mp.width = inst->src_fmt.width;
 f->fmt.pix_mp.height = inst->src_fmt.height;
 f->fmt.pix_mp.pixelformat = inst->src_fmt.pixelformat;
 f->fmt.pix_mp.field = inst->src_fmt.field;
 f->fmt.pix_mp.flags = inst->src_fmt.flags;
 f->fmt.pix_mp.num_planes = inst->src_fmt.num_planes;
 for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
  f->fmt.pix_mp.plane_fmt[i].bytesperline = inst->src_fmt.plane_fmt[i].bytesperline;
  f->fmt.pix_mp.plane_fmt[i].sizeimage = inst->src_fmt.plane_fmt[i].sizeimage;
 }

 f->fmt.pix_mp.colorspace = inst->colorspace;
 f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc;
 f->fmt.pix_mp.quantization = inst->quantization;
 f->fmt.pix_mp.xfer_func = inst->xfer_func;

 return 0;
}

const struct vpu_format *wave5_find_vpu_fmt(unsigned int v4l2_pix_fmt,
         const struct vpu_format fmt_list[MAX_FMTS])
{
 unsigned int index;

 for (index = 0; index < MAX_FMTS; index++) {
  if (fmt_list[index].v4l2_pix_fmt == v4l2_pix_fmt)
   return &fmt_list[index];
 }

 return NULL;
}

const struct vpu_format *wave5_find_vpu_fmt_by_idx(unsigned int idx,
         const struct vpu_format fmt_list[MAX_FMTS])
{
 if (idx >= MAX_FMTS)
  return NULL;

 if (!fmt_list[idx].v4l2_pix_fmt)
  return NULL;

 return &fmt_list[idx];
}

enum wave_std wave5_to_vpu_std(unsigned int v4l2_pix_fmt, enum vpu_instance_type type)
{
 switch (v4l2_pix_fmt) {
 case V4L2_PIX_FMT_H264:
  return type == VPU_INST_TYPE_DEC ? W_AVC_DEC : W_AVC_ENC;
 case V4L2_PIX_FMT_HEVC:
  return type == VPU_INST_TYPE_DEC ? W_HEVC_DEC : W_HEVC_ENC;
 default:
  return STD_UNKNOWN;
 }
}

void wave5_return_bufs(struct vb2_queue *q, u32 state)
{
 struct vpu_instance *inst = vb2_get_drv_priv(q);
 struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
 struct v4l2_ctrl_handler v4l2_ctrl_hdl = inst->v4l2_ctrl_hdl;
 struct vb2_v4l2_buffer *vbuf;

 for (;;) {
  if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
   vbuf = v4l2_m2m_src_buf_remove(m2m_ctx);
  else
   vbuf = v4l2_m2m_dst_buf_remove(m2m_ctx);
  if (!vbuf)
   return;
  v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, &v4l2_ctrl_hdl);
  v4l2_m2m_buf_done(vbuf, state);
 }
}

void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp,
     int pix_fmt_type,
     unsigned int width,
     unsigned int height,
     const struct v4l2_frmsize_stepwise *frmsize)
{
 v4l2_apply_frmsize_constraints(&width, &height, frmsize);

 if (pix_fmt_type == VPU_FMT_TYPE_CODEC) {
  pix_mp->width = width;
  pix_mp->height = height;
  pix_mp->num_planes = 1;
  pix_mp->plane_fmt[0].bytesperline = 0;
  pix_mp->plane_fmt[0].sizeimage = max(DEFAULT_BS_SIZE(width, height),
           pix_mp->plane_fmt[0].sizeimage);
 } else {
  v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, width, height);
 }
 pix_mp->flags = 0;
 pix_mp->field = V4L2_FIELD_NONE;
}

Messung V0.5
C=98 H=93 G=95

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge