Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/media/test-drivers/vivid/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 6 kB image not shown  

Quelle  vivid-vbi-out.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * vivid-vbi-out.c - vbi output support functions.
 *
 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
 */


#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>

#include "vivid-core.h"
#include "vivid-kthread-out.h"
#include "vivid-vbi-out.h"
#include "vivid-vbi-cap.h"

static int vbi_out_queue_setup(struct vb2_queue *vq,
         unsigned *nbuffers, unsigned *nplanes,
         unsigned sizes[], struct device *alloc_devs[])
{
 struct vivid_dev *dev = vb2_get_drv_priv(vq);
 bool is_60hz = dev->std_out & V4L2_STD_525_60;
 unsigned size = vq->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ?
  36 * sizeof(struct v4l2_sliced_vbi_data) :
  1440 * 2 * (is_60hz ? 12 : 18);

 if (!vivid_is_svid_out(dev))
  return -EINVAL;

 if (*nplanes)
  return sizes[0] < size ? -EINVAL : 0;
 sizes[0] = size;

 *nplanes = 1;
 return 0;
}

static int vbi_out_buf_prepare(struct vb2_buffer *vb)
{
 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 bool is_60hz = dev->std_out & V4L2_STD_525_60;
 unsigned size = vb->vb2_queue->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ?
  36 * sizeof(struct v4l2_sliced_vbi_data) :
  1440 * 2 * (is_60hz ? 12 : 18);

 dprintk(dev, 1, "%s\n", __func__);

 if (dev->buf_prepare_error) {
  /*
 * Error injection: test what happens if buf_prepare() returns
 * an error.
 */

  dev->buf_prepare_error = false;
  return -EINVAL;
 }
 if (vb2_plane_size(vb, 0) < size) {
  dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
    __func__, vb2_plane_size(vb, 0), size);
  return -EINVAL;
 }
 vb2_set_plane_payload(vb, 0, size);

 return 0;
}

static void vbi_out_buf_queue(struct vb2_buffer *vb)
{
 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 struct vivid_buffer *buf = container_of(vbuf, struct vivid_buffer, vb);

 dprintk(dev, 1, "%s\n", __func__);

 spin_lock(&dev->slock);
 list_add_tail(&buf->list, &dev->vbi_out_active);
 spin_unlock(&dev->slock);
}

static int vbi_out_start_streaming(struct vb2_queue *vq, unsigned count)
{
 struct vivid_dev *dev = vb2_get_drv_priv(vq);
 int err;

 dprintk(dev, 1, "%s\n", __func__);
 dev->vbi_out_seq_count = 0;
 if (dev->start_streaming_error) {
  dev->start_streaming_error = false;
  err = -EINVAL;
 } else {
  err = vivid_start_generating_vid_out(dev, &dev->vbi_out_streaming);
 }
 if (err) {
  struct vivid_buffer *buf, *tmp;

  list_for_each_entry_safe(buf, tmp, &dev->vbi_out_active, list) {
   list_del(&buf->list);
   vb2_buffer_done(&buf->vb.vb2_buf,
     VB2_BUF_STATE_QUEUED);
  }
 }
 return err;
}

/* abort streaming and wait for last buffer */
static void vbi_out_stop_streaming(struct vb2_queue *vq)
{
 struct vivid_dev *dev = vb2_get_drv_priv(vq);

 dprintk(dev, 1, "%s\n", __func__);
 vivid_stop_generating_vid_out(dev, &dev->vbi_out_streaming);
 dev->vbi_out_have_wss = false;
 dev->vbi_out_have_cc[0] = false;
 dev->vbi_out_have_cc[1] = false;
}

static void vbi_out_buf_request_complete(struct vb2_buffer *vb)
{
 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);

 v4l2_ctrl_request_complete(vb->req_obj.req, &dev->ctrl_hdl_vbi_out);
}

const struct vb2_ops vivid_vbi_out_qops = {
 .queue_setup  = vbi_out_queue_setup,
 .buf_prepare  = vbi_out_buf_prepare,
 .buf_queue  = vbi_out_buf_queue,
 .start_streaming = vbi_out_start_streaming,
 .stop_streaming  = vbi_out_stop_streaming,
 .buf_request_complete = vbi_out_buf_request_complete,
};

int vidioc_g_fmt_vbi_out(struct file *file, void *priv,
     struct v4l2_format *f)
{
 struct vivid_dev *dev = video_drvdata(file);
 struct v4l2_vbi_format *vbi = &f->fmt.vbi;
 bool is_60hz = dev->std_out & V4L2_STD_525_60;

 if (!vivid_is_svid_out(dev) || !dev->has_raw_vbi_out)
  return -EINVAL;

 vbi->sampling_rate = 25000000;
 vbi->offset = 24;
 vbi->samples_per_line = 1440;
 vbi->sample_format = V4L2_PIX_FMT_GREY;
 vbi->start[0] = is_60hz ? V4L2_VBI_ITU_525_F1_START + 9 : V4L2_VBI_ITU_625_F1_START + 5;
 vbi->start[1] = is_60hz ? V4L2_VBI_ITU_525_F2_START + 9 : V4L2_VBI_ITU_625_F2_START + 5;
 vbi->count[0] = vbi->count[1] = is_60hz ? 12 : 18;
 vbi->flags = dev->vbi_cap_interlaced ? V4L2_VBI_INTERLACED : 0;
 vbi->reserved[0] = 0;
 vbi->reserved[1] = 0;
 return 0;
}

int vidioc_s_fmt_vbi_out(struct file *file, void *priv,
     struct v4l2_format *f)
{
 struct vivid_dev *dev = video_drvdata(file);
 int ret = vidioc_g_fmt_vbi_out(file, priv, f);

 if (ret)
  return ret;
 if (vb2_is_busy(&dev->vb_vbi_out_q))
  return -EBUSY;
 dev->stream_sliced_vbi_out = false;
 dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_VBI_OUTPUT;
 return 0;
}

int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
 struct vivid_dev *dev = video_drvdata(file);
 struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;

 if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
  return -EINVAL;

 vivid_fill_service_lines(vbi, dev->service_set_out);
 return 0;
}

int vidioc_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
 struct vivid_dev *dev = video_drvdata(file);
 struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
 bool is_60hz = dev->std_out & V4L2_STD_525_60;
 u32 service_set = vbi->service_set;

 if (!vivid_is_svid_out(dev) || !dev->has_sliced_vbi_out)
  return -EINVAL;

 service_set &= is_60hz ? V4L2_SLICED_CAPTION_525 :
     V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B;
 vivid_fill_service_lines(vbi, service_set);
 return 0;
}

int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
  struct v4l2_format *fmt)
{
 struct vivid_dev *dev = video_drvdata(file);
 struct v4l2_sliced_vbi_format *vbi = &fmt->fmt.sliced;
 int ret = vidioc_try_fmt_sliced_vbi_out(file, fh, fmt);

 if (ret)
  return ret;
 if (vb2_is_busy(&dev->vb_vbi_out_q))
  return -EBUSY;
 dev->service_set_out = vbi->service_set;
 dev->stream_sliced_vbi_out = true;
 dev->vbi_out_dev.queue->type = V4L2_BUF_TYPE_SLICED_VBI_OUTPUT;
 return 0;
}

void vivid_sliced_vbi_out_process(struct vivid_dev *dev,
  struct vivid_buffer *buf)
{
 struct v4l2_sliced_vbi_data *vbi =
  vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
 unsigned elems =
  vb2_get_plane_payload(&buf->vb.vb2_buf, 0) / sizeof(*vbi);

 dev->vbi_out_have_cc[0] = false;
 dev->vbi_out_have_cc[1] = false;
 dev->vbi_out_have_wss = false;
 while (elems--) {
  switch (vbi->id) {
  case V4L2_SLICED_CAPTION_525:
   if ((dev->std_out & V4L2_STD_525_60) && vbi->line == 21) {
    dev->vbi_out_have_cc[!!vbi->field] = true;
    dev->vbi_out_cc[!!vbi->field][0] = vbi->data[0];
    dev->vbi_out_cc[!!vbi->field][1] = vbi->data[1];
   }
   break;
  case V4L2_SLICED_WSS_625:
   if ((dev->std_out & V4L2_STD_625_50) &&
       vbi->field == 0 && vbi->line == 23) {
    dev->vbi_out_have_wss = true;
    dev->vbi_out_wss[0] = vbi->data[0];
    dev->vbi_out_wss[1] = vbi->data[1];
   }
   break;
  }
  vbi++;
 }
}

Messung V0.5
C=96 H=91 G=93

¤ Dauer der Verarbeitung: 0.14 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.