Re: [PATCH] media: vim2m: add bayer capture formats

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Mauro,

On Fri, Feb 1, 2019 at 11:19 PM Mauro Carvalho Chehab
<mchehab+samsung@xxxxxxxxxx> wrote:
>
> The vim2m device is interesting to simulate a webcam.

Hmm, how would you simulate a webcam with a mem2mem device? The same
process needs to control both OUTPUT and CAPTURE queues, so regular
webcam apps wouldn't work.

Best regards,
Tomasz

> As most
> sensors are arranged using bayer formats, the best is to support
> to output data using those formats.
>
> So, add support for them.
>
> All 4 8-bit bayer formats tested with:
>
>         $ qvidcap -p &
>         $ v4l2-ctl --stream-mmap --stream-out-mmap --stream-to-host localhost --stream-lossless --stream-out-hor-speed 1 -v pixelformat=RGGB
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@xxxxxxxxxx>
> ---
>  drivers/media/platform/vim2m.c | 97 ++++++++++++++++++++++++++++++++--
>  1 file changed, 92 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
> index e31c14c7d37f..6240878def80 100644
> --- a/drivers/media/platform/vim2m.c
> +++ b/drivers/media/platform/vim2m.c
> @@ -82,24 +82,47 @@ static struct platform_device vim2m_pdev = {
>  struct vim2m_fmt {
>         u32     fourcc;
>         int     depth;
> +       /* Types the format can be used for */
> +       u32     types;
>  };
>
>  static struct vim2m_fmt formats[] = {
>         {
>                 .fourcc = V4L2_PIX_FMT_RGB565,  /* rrrrrggg gggbbbbb */
>                 .depth  = 16,
> +               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
>         }, {
>                 .fourcc = V4L2_PIX_FMT_RGB565X, /* gggbbbbb rrrrrggg */
>                 .depth  = 16,
> +               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
>         }, {
>                 .fourcc = V4L2_PIX_FMT_RGB24,
>                 .depth  = 24,
> +               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
>         }, {
>                 .fourcc = V4L2_PIX_FMT_BGR24,
>                 .depth  = 24,
> +               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
>         }, {
>                 .fourcc = V4L2_PIX_FMT_YUYV,
>                 .depth  = 16,
> +               .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
> +       }, {
> +               .fourcc = V4L2_PIX_FMT_SBGGR8,
> +               .depth  = 8,
> +               .types  = MEM2MEM_CAPTURE,
> +       }, {
> +               .fourcc = V4L2_PIX_FMT_SGBRG8,
> +               .depth  = 8,
> +               .types  = MEM2MEM_CAPTURE,
> +       }, {
> +               .fourcc = V4L2_PIX_FMT_SGRBG8,
> +               .depth  = 8,
> +               .types  = MEM2MEM_CAPTURE,
> +       }, {
> +               .fourcc = V4L2_PIX_FMT_SRGGB8,
> +               .depth  = 8,
> +               .types  = MEM2MEM_CAPTURE,
>         },
>  };
>
> @@ -208,7 +231,7 @@ static struct vim2m_q_data *get_q_data(struct vim2m_ctx *ctx,
>         (u8)(((__color) > 0xff) ? 0xff : (((__color) < 0) ? 0 : (__color)))
>
>  static void copy_two_pixels(struct vim2m_fmt *in, struct vim2m_fmt *out,
> -                           u8 **src, u8 **dst, bool reverse)
> +                           u8 **src, u8 **dst, int y, bool reverse)
>  {
>         u8 _r[2], _g[2], _b[2], *r, *g, *b;
>         int i, step;
> @@ -379,7 +402,8 @@ static void copy_two_pixels(struct vim2m_fmt *in, struct vim2m_fmt *out,
>                         *(*dst)++ = *r++;
>                 }
>                 return;
> -       default: /* V4L2_PIX_FMT_YUYV */
> +       case V4L2_PIX_FMT_YUYV:
> +       default:
>         {
>                 u8 y, y1, u, v;
>
> @@ -399,6 +423,42 @@ static void copy_two_pixels(struct vim2m_fmt *in, struct vim2m_fmt *out,
>                 *(*dst)++ = v;
>                 return;
>         }
> +       case V4L2_PIX_FMT_SBGGR8:
> +               if (!(y & 1)) {
> +                       *(*dst)++ = *b;
> +                       *(*dst)++ = *++g;
> +               } else {
> +                       *(*dst)++ = *g;
> +                       *(*dst)++ = *++r;
> +               }
> +               return;
> +       case V4L2_PIX_FMT_SGBRG8:
> +               if (!(y & 1)) {
> +                       *(*dst)++ = *g;
> +                       *(*dst)++ = *++b;
> +               } else {
> +                       *(*dst)++ = *r;
> +                       *(*dst)++ = *++g;
> +               }
> +               return;
> +       case V4L2_PIX_FMT_SGRBG8:
> +               if (!(y & 1)) {
> +                       *(*dst)++ = *g;
> +                       *(*dst)++ = *++r;
> +               } else {
> +                       *(*dst)++ = *b;
> +                       *(*dst)++ = *++g;
> +               }
> +               return;
> +       case V4L2_PIX_FMT_SRGGB8:
> +               if (!(y & 1)) {
> +                       *(*dst)++ = *r;
> +                       *(*dst)++ = *++g;
> +               } else {
> +                       *(*dst)++ = *g;
> +                       *(*dst)++ = *++b;
> +               }
> +               return;
>         }
>  }
>
> @@ -449,7 +509,7 @@ static int device_process(struct vim2m_ctx *ctx,
>                         p += bytesperline - (q_data_in->fmt->depth >> 3);
>
>                 for (x = 0; x < width >> 1; x++)
> -                       copy_two_pixels(in, out, &p, &p_out,
> +                       copy_two_pixels(in, out, &p, &p_out, y,
>                                         ctx->mode & MEM2MEM_HFLIP);
>         }
>
> @@ -562,11 +622,25 @@ static int vidioc_querycap(struct file *file, void *priv,
>
>  static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
>  {
> +       int i, num;
>         struct vim2m_fmt *fmt;
>
> -       if (f->index < NUM_FORMATS) {
> +       num = 0;
> +
> +       for (i = 0; i < NUM_FORMATS; ++i) {
> +               if (formats[i].types & type) {
> +                       /* index-th format of type type found ? */
> +                       if (num == f->index)
> +                               break;
> +                       /* Correct type but haven't reached our index yet,
> +                        * just increment per-type index */
> +                       ++num;
> +               }
> +       }
> +
> +       if (i < NUM_FORMATS) {
>                 /* Format found */
> -               fmt = &formats[f->index];
> +               fmt = &formats[i];
>                 f->pixelformat = fmt->fourcc;
>                 return 0;
>         }
> @@ -657,6 +731,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
>                 f->fmt.pix.pixelformat = formats[0].fourcc;
>                 fmt = find_format(f);
>         }
> +       if (!(fmt->types & MEM2MEM_CAPTURE)) {
> +               v4l2_err(&ctx->dev->v4l2_dev,
> +                        "Fourcc format (0x%08x) invalid.\n",
> +                        f->fmt.pix.pixelformat);
> +               return -EINVAL;
> +       }
>         f->fmt.pix.colorspace = ctx->colorspace;
>         f->fmt.pix.xfer_func = ctx->xfer_func;
>         f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
> @@ -669,12 +749,19 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
>                                   struct v4l2_format *f)
>  {
>         struct vim2m_fmt *fmt;
> +       struct vim2m_ctx *ctx = file2ctx(file);
>
>         fmt = find_format(f);
>         if (!fmt) {
>                 f->fmt.pix.pixelformat = formats[0].fourcc;
>                 fmt = find_format(f);
>         }
> +       if (!(fmt->types & MEM2MEM_OUTPUT)) {
> +               v4l2_err(&ctx->dev->v4l2_dev,
> +                        "Fourcc format (0x%08x) invalid.\n",
> +                        f->fmt.pix.pixelformat);
> +               return -EINVAL;
> +       }
>         if (!f->fmt.pix.colorspace)
>                 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
>
> --
> 2.20.1
>



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux