mbox series

[RFC,v2,0/7] Add audio support in v4l2 framework

Message ID 1690265540-25999-1-git-send-email-shengjiu.wang@nxp.com
Headers show
Series Add audio support in v4l2 framework | expand

Message

Shengjiu Wang July 25, 2023, 6:12 a.m. UTC
Audio signal processing has the requirement for memory to
memory similar as Video.

This patch is to add this support in v4l2 framework, defined
new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
for audio case usage.

The created audio device is named "/dev/audioX".

And add memory to memory support for two kinds of i.MX ASRC
module

changes in v2:
- decouple the implementation in v4l2 and ALSA
- implement the memory to memory driver as a platfrom driver
  and move it to driver/media
- move fsl_asrc_common.h to include/sound folder

Shengjiu Wang (7):
  ASoC: fsl_asrc: define functions for memory to memory usage
  ASoC: fsl_easrc: define functions for memory to memory usage
  ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound
  media: v4l2: Add audio capture and output support
  media: imx: fsl_asrc: Add memory to memory driver
  ASoC: fsl_asrc: register m2m platform device
  ASoC: fsl_easrc: register m2m platform device

 .../media/common/videobuf2/videobuf2-v4l2.c   |   4 +
 drivers/media/platform/nxp/Kconfig            |  12 +
 drivers/media/platform/nxp/Makefile           |   1 +
 drivers/media/platform/nxp/fsl_asrc_m2m.c     | 962 ++++++++++++++++++
 drivers/media/v4l2-core/v4l2-dev.c            |  17 +
 drivers/media/v4l2-core/v4l2-ioctl.c          |  52 +
 include/media/v4l2-dev.h                      |   2 +
 include/media/v4l2-ioctl.h                    |  34 +
 .../fsl => include/sound}/fsl_asrc_common.h   |  48 +
 include/uapi/linux/videodev2.h                |  19 +
 sound/soc/fsl/fsl_asrc.c                      | 150 +++
 sound/soc/fsl/fsl_asrc.h                      |   4 +-
 sound/soc/fsl/fsl_asrc_dma.c                  |   2 +-
 sound/soc/fsl/fsl_easrc.c                     | 227 +++++
 sound/soc/fsl/fsl_easrc.h                     |   8 +-
 15 files changed, 1539 insertions(+), 3 deletions(-)
 create mode 100644 drivers/media/platform/nxp/fsl_asrc_m2m.c
 rename {sound/soc/fsl => include/sound}/fsl_asrc_common.h (63%)

Comments

Mark Brown July 28, 2023, 3:24 p.m. UTC | #1
On Fri, Jul 28, 2023 at 07:59:33AM +0000, Tomasz Figa wrote:
> On Tue, Jul 25, 2023 at 02:12:17PM +0800, Shengjiu Wang wrote:

> > +	case VFL_TYPE_AUDIO:
> > +		name_base = "audio";

> I think it was mentioned before that "audio" could be confusing. Wasn't
> there actually some other kind of /dev/audio device long ago?

OSS used /dev/audio.
Shengjiu Wang Aug. 1, 2023, 9:47 a.m. UTC | #2
On Fri, Jul 28, 2023 at 3:59 PM Tomasz Figa <tfiga@chromium.org> wrote:
>
> Hi Shengjiu,
>
> On Tue, Jul 25, 2023 at 02:12:17PM +0800, Shengjiu Wang wrote:
> > Audio signal processing has the requirement for memory to
> > memory similar as Video.
> >
> > This patch is to add this support in v4l2 framework, defined
> > new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> > V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> > for audio case usage.
> >
> > The created audio device is named "/dev/audioX".
> >
> > Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> > ---
> >  .../media/common/videobuf2/videobuf2-v4l2.c   |  4 ++
> >  drivers/media/v4l2-core/v4l2-dev.c            | 17 ++++++
> >  drivers/media/v4l2-core/v4l2-ioctl.c          | 52 +++++++++++++++++++
> >  include/media/v4l2-dev.h                      |  2 +
> >  include/media/v4l2-ioctl.h                    | 34 ++++++++++++
> >  include/uapi/linux/videodev2.h                | 19 +++++++
> >  6 files changed, 128 insertions(+)
> >
>
> Thanks for the patch! Please check my comments inline.

Thanks for reviewing.

Sorry for sending again for using the plain text mode.

>
> > diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> > index c7a54d82a55e..12f2be2773a2 100644
> > --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> > +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> > @@ -785,6 +785,10 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
> >       case V4L2_BUF_TYPE_META_OUTPUT:
> >               requested_sizes[0] = f->fmt.meta.buffersize;
> >               break;
> > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > +             requested_sizes[0] = f->fmt.audio.buffersize;
> > +             break;
> >       default:
> >               return -EINVAL;
> >       }
> > diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> > index f81279492682..67484f4c6eaf 100644
> > --- a/drivers/media/v4l2-core/v4l2-dev.c
> > +++ b/drivers/media/v4l2-core/v4l2-dev.c
> > @@ -553,6 +553,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
> >       bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;
> >       bool is_meta = vdev->vfl_type == VFL_TYPE_VIDEO &&
> >                      (vdev->device_caps & meta_caps);
> > +     bool is_audio = vdev->vfl_type == VFL_TYPE_AUDIO;
> >       bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
> >       bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
> >       bool is_io_mc = vdev->device_caps & V4L2_CAP_IO_MC;
> > @@ -664,6 +665,19 @@ static void determine_valid_ioctls(struct video_device *vdev)
> >               SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_out);
> >               SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_out);
> >       }
> > +     if (is_audio && is_rx) {
> > +             /* audio capture specific ioctls */
> > +             SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_audio_cap);
> > +             SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_audio_cap);
> > +             SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_audio_cap);
> > +             SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_audio_cap);
> > +     } else if (is_audio && is_tx) {
> > +             /* audio output specific ioctls */
> > +             SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_audio_out);
> > +             SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_audio_out);
> > +             SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_audio_out);
> > +             SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_audio_out);
> > +     }
> >       if (is_vbi) {
> >               /* vbi specific ioctls */
> >               if ((is_rx && (ops->vidioc_g_fmt_vbi_cap ||
> > @@ -927,6 +941,9 @@ int __video_register_device(struct video_device *vdev,
> >       case VFL_TYPE_TOUCH:
> >               name_base = "v4l-touch";
> >               break;
> > +     case VFL_TYPE_AUDIO:
> > +             name_base = "audio";
>
> I think it was mentioned before that "audio" could be confusing. Wasn't
> there actually some other kind of /dev/audio device long ago?
>
> Seems like for touch, "v4l-touch" was introduced. Maybe it would also
> make sense to call it "v4l-audio" for audio?

Ok,  will change to use "v4l-audio".

>
> > +             break;
> >       default:
> >               pr_err("%s called with unknown type: %d\n",
> >                      __func__, type);
> > diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> > index 01ba27f2ef87..aa9d872bba8d 100644
> > --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> > +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> > @@ -188,6 +188,8 @@ const char *v4l2_type_names[] = {
> >       [V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
> >       [V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
> >       [V4L2_BUF_TYPE_META_OUTPUT]        = "meta-out",
> > +     [V4L2_BUF_TYPE_AUDIO_CAPTURE]      = "audio-cap",
> > +     [V4L2_BUF_TYPE_AUDIO_OUTPUT]       = "audio-out",
> >  };
> >  EXPORT_SYMBOL(v4l2_type_names);
> >
> > @@ -276,6 +278,7 @@ static void v4l_print_format(const void *arg, bool write_only)
> >       const struct v4l2_sliced_vbi_format *sliced;
> >       const struct v4l2_window *win;
> >       const struct v4l2_meta_format *meta;
> > +     const struct v4l2_audio_format *audio;
> >       u32 pixelformat;
> >       u32 planes;
> >       unsigned i;
> > @@ -346,6 +349,12 @@ static void v4l_print_format(const void *arg, bool write_only)
> >               pr_cont(", dataformat=%p4cc, buffersize=%u\n",
> >                       &pixelformat, meta->buffersize);
> >               break;
> > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > +             audio = &p->fmt.audio;
> > +             pr_cont(", rate=%u, format=%u, channels=%u, buffersize=%u\n",
> > +                     audio->rate, audio->format, audio->channels, audio->buffersize);
> > +             break;
> >       }
> >  }
> >
> > @@ -927,6 +936,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
> >       bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
> >       bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
> >                      (vfd->device_caps & meta_caps);
> > +     bool is_audio = vfd->vfl_type == VFL_TYPE_AUDIO;
> >       bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
> >       bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
> >
> > @@ -992,6 +1002,14 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
> >               if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
> >                       return 0;
> >               break;
> > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > +             if (is_audio && is_rx && ops->vidioc_g_fmt_audio_cap)
> > +                     return 0;
> > +             break;
> > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > +             if (is_audio && is_tx && ops->vidioc_g_fmt_audio_out)
> > +                     return 0;
> > +             break;
> >       default:
> >               break;
> >       }
> > @@ -1594,6 +1612,16 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
> >                       break;
> >               ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
> >               break;
> > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > +             if (unlikely(!ops->vidioc_enum_fmt_audio_cap))
> > +                     break;
> > +             ret = ops->vidioc_enum_fmt_audio_cap(file, fh, arg);
> > +             break;
> > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > +             if (unlikely(!ops->vidioc_enum_fmt_audio_out))
> > +                     break;
> > +             ret = ops->vidioc_enum_fmt_audio_out(file, fh, arg);
> > +             break;
> >       }
> >       if (ret == 0)
> >               v4l_fill_fmtdesc(p);
> > @@ -1670,6 +1698,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
> >               return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
> >       case V4L2_BUF_TYPE_META_OUTPUT:
> >               return ops->vidioc_g_fmt_meta_out(file, fh, arg);
> > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > +             return ops->vidioc_g_fmt_audio_cap(file, fh, arg);
> > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > +             return ops->vidioc_g_fmt_audio_out(file, fh, arg);
> >       }
> >       return -EINVAL;
> >  }
> > @@ -1781,6 +1813,16 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
> >                       break;
> >               memset_after(p, 0, fmt.meta);
> >               return ops->vidioc_s_fmt_meta_out(file, fh, arg);
> > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > +             if (unlikely(!ops->vidioc_s_fmt_audio_cap))
> > +                     break;
> > +             memset_after(p, 0, fmt.audio);
> > +             return ops->vidioc_s_fmt_audio_cap(file, fh, arg);
> > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > +             if (unlikely(!ops->vidioc_s_fmt_audio_out))
> > +                     break;
> > +             memset_after(p, 0, fmt.audio);
> > +             return ops->vidioc_s_fmt_audio_out(file, fh, arg);
> >       }
> >       return -EINVAL;
> >  }
> > @@ -1889,6 +1931,16 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
> >                       break;
> >               memset_after(p, 0, fmt.meta);
> >               return ops->vidioc_try_fmt_meta_out(file, fh, arg);
> > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > +             if (unlikely(!ops->vidioc_try_fmt_audio_cap))
> > +                     break;
> > +             memset_after(p, 0, fmt.audio);
> > +             return ops->vidioc_try_fmt_audio_cap(file, fh, arg);
> > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > +             if (unlikely(!ops->vidioc_try_fmt_audio_out))
> > +                     break;
> > +             memset_after(p, 0, fmt.audio);
> > +             return ops->vidioc_try_fmt_audio_out(file, fh, arg);
> >       }
> >       return -EINVAL;
> >  }
> > diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
> > index e0a13505f88d..0924e6d1dab1 100644
> > --- a/include/media/v4l2-dev.h
> > +++ b/include/media/v4l2-dev.h
> > @@ -30,6 +30,7 @@
> >   * @VFL_TYPE_SUBDEV: for V4L2 subdevices
> >   * @VFL_TYPE_SDR:    for Software Defined Radio tuners
> >   * @VFL_TYPE_TOUCH:  for touch sensors
> > + * @VFL_TYPE_AUDIO:  for audio input/output devices
> >   * @VFL_TYPE_MAX:    number of VFL types, must always be last in the enum
> >   */
> >  enum vfl_devnode_type {
> > @@ -39,6 +40,7 @@ enum vfl_devnode_type {
> >       VFL_TYPE_SUBDEV,
> >       VFL_TYPE_SDR,
> >       VFL_TYPE_TOUCH,
> > +     VFL_TYPE_AUDIO,
> >       VFL_TYPE_MAX /* Shall be the last one */
> >  };
> >
> > diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> > index edb733f21604..f840cf740ce1 100644
> > --- a/include/media/v4l2-ioctl.h
> > +++ b/include/media/v4l2-ioctl.h
> > @@ -45,6 +45,12 @@ struct v4l2_fh;
> >   * @vidioc_enum_fmt_meta_out: pointer to the function that implements
> >   *   :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
> >   *   for metadata output
> > + * @vidioc_enum_fmt_audio_cap: pointer to the function that implements
> > + *   :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
> > + *   for audio capture
> > + * @vidioc_enum_fmt_audio_out: pointer to the function that implements
> > + *   :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
> > + *   for audio output
> >   * @vidioc_g_fmt_vid_cap: pointer to the function that implements
> >   *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture
> >   *   in single plane mode
> > @@ -79,6 +85,10 @@ struct v4l2_fh;
> >   *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
> >   * @vidioc_g_fmt_meta_out: pointer to the function that implements
> >   *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata output
> > + * @vidioc_g_fmt_audio_cap: pointer to the function that implements
> > + *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for audio capture
> > + * @vidioc_g_fmt_audio_out: pointer to the function that implements
> > + *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for audio output
> >   * @vidioc_s_fmt_vid_cap: pointer to the function that implements
> >   *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture
> >   *   in single plane mode
> > @@ -113,6 +123,10 @@ struct v4l2_fh;
> >   *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
> >   * @vidioc_s_fmt_meta_out: pointer to the function that implements
> >   *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata output
> > + * @vidioc_s_fmt_audio_cap: pointer to the function that implements
> > + *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for audio capture
> > + * @vidioc_s_fmt_audio_out: pointer to the function that implements
> > + *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for audio output
> >   * @vidioc_try_fmt_vid_cap: pointer to the function that implements
> >   *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture
> >   *   in single plane mode
> > @@ -149,6 +163,10 @@ struct v4l2_fh;
> >   *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
> >   * @vidioc_try_fmt_meta_out: pointer to the function that implements
> >   *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata output
> > + * @vidioc_try_fmt_audio_cap: pointer to the function that implements
> > + *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for audio capture
> > + * @vidioc_try_fmt_audio_out: pointer to the function that implements
> > + *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for audio output
> >   * @vidioc_reqbufs: pointer to the function that implements
> >   *   :ref:`VIDIOC_REQBUFS <vidioc_reqbufs>` ioctl
> >   * @vidioc_querybuf: pointer to the function that implements
> > @@ -315,6 +333,10 @@ struct v4l2_ioctl_ops {
> >                                       struct v4l2_fmtdesc *f);
> >       int (*vidioc_enum_fmt_meta_out)(struct file *file, void *fh,
> >                                       struct v4l2_fmtdesc *f);
> > +     int (*vidioc_enum_fmt_audio_cap)(struct file *file, void *fh,
> > +                                      struct v4l2_fmtdesc *f);
> > +     int (*vidioc_enum_fmt_audio_out)(struct file *file, void *fh,
> > +                                      struct v4l2_fmtdesc *f);
> >
> >       /* VIDIOC_G_FMT handlers */
> >       int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh,
> > @@ -345,6 +367,10 @@ struct v4l2_ioctl_ops {
> >                                    struct v4l2_format *f);
> >       int (*vidioc_g_fmt_meta_out)(struct file *file, void *fh,
> >                                    struct v4l2_format *f);
> > +     int (*vidioc_g_fmt_audio_cap)(struct file *file, void *fh,
> > +                                   struct v4l2_format *f);
> > +     int (*vidioc_g_fmt_audio_out)(struct file *file, void *fh,
> > +                                   struct v4l2_format *f);
> >
> >       /* VIDIOC_S_FMT handlers */
> >       int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh,
> > @@ -375,6 +401,10 @@ struct v4l2_ioctl_ops {
> >                                    struct v4l2_format *f);
> >       int (*vidioc_s_fmt_meta_out)(struct file *file, void *fh,
> >                                    struct v4l2_format *f);
> > +     int (*vidioc_s_fmt_audio_cap)(struct file *file, void *fh,
> > +                                   struct v4l2_format *f);
> > +     int (*vidioc_s_fmt_audio_out)(struct file *file, void *fh,
> > +                                   struct v4l2_format *f);
> >
> >       /* VIDIOC_TRY_FMT handlers */
> >       int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh,
> > @@ -405,6 +435,10 @@ struct v4l2_ioctl_ops {
> >                                      struct v4l2_format *f);
> >       int (*vidioc_try_fmt_meta_out)(struct file *file, void *fh,
> >                                      struct v4l2_format *f);
> > +     int (*vidioc_try_fmt_audio_cap)(struct file *file, void *fh,
> > +                                     struct v4l2_format *f);
> > +     int (*vidioc_try_fmt_audio_out)(struct file *file, void *fh,
> > +                                     struct v4l2_format *f);
> >
> >       /* Buffer handlers */
> >       int (*vidioc_reqbufs)(struct file *file, void *fh,
> > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> > index 3af6a82d0cad..e5051410928a 100644
> > --- a/include/uapi/linux/videodev2.h
> > +++ b/include/uapi/linux/videodev2.h
> > @@ -153,6 +153,8 @@ enum v4l2_buf_type {
> >       V4L2_BUF_TYPE_SDR_OUTPUT           = 12,
> >       V4L2_BUF_TYPE_META_CAPTURE         = 13,
> >       V4L2_BUF_TYPE_META_OUTPUT          = 14,
> > +     V4L2_BUF_TYPE_AUDIO_CAPTURE        = 15,
> > +     V4L2_BUF_TYPE_AUDIO_OUTPUT         = 16,
> >       /* Deprecated, do not use */
> >       V4L2_BUF_TYPE_PRIVATE              = 0x80,
> >  };
> > @@ -169,6 +171,7 @@ enum v4l2_buf_type {
> >        || (type) == V4L2_BUF_TYPE_VBI_OUTPUT                  \
> >        || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT           \
> >        || (type) == V4L2_BUF_TYPE_SDR_OUTPUT                  \
> > +      || (type) == V4L2_BUF_TYPE_AUDIO_OUTPUT                \
> >        || (type) == V4L2_BUF_TYPE_META_OUTPUT)
> >
> >  #define V4L2_TYPE_IS_CAPTURE(type) (!V4L2_TYPE_IS_OUTPUT(type))
> > @@ -2415,6 +2418,20 @@ struct v4l2_meta_format {
> >       __u32                           buffersize;
> >  } __attribute__ ((packed));
> >
> > +/**
> > + * struct v4l2_audio_format - audio data format definition
> > + * @rate:            sample rate
> > + * @format:          sample format
> > + * @channels:                channel numbers
> > + * @buffersize:              maximum size in bytes required for data
> > + */
> > +struct v4l2_audio_format {
> > +     __u32                           rate;
> > +     __u32                           format;
>
> What are the values for the rate and format fields? Since they are part
> of the UAPI, they need to be defined.
>

The range for sample rate is [5512, 768000].
The format is defined in include/uapi/sound/asound.h,  they are
SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_U8, ...

Where should I put these info?

Best regards
Wang shengjiu

> Best regards,
> Tomasz
>
> > +     __u32                           channels;
> > +     __u32                           buffersize;
> > +} __attribute__ ((packed));
> > +
> >  /**
> >   * struct v4l2_format - stream data format
> >   * @type:    enum v4l2_buf_type; type of the data stream
> > @@ -2423,6 +2440,7 @@ struct v4l2_meta_format {
> >   * @win:     definition of an overlaid image
> >   * @vbi:     raw VBI capture or output parameters
> >   * @sliced:  sliced VBI capture or output parameters
> > + * @audio:   definition of an audio format
> >   * @raw_data:        placeholder for future extensions and custom formats
> >   * @fmt:     union of @pix, @pix_mp, @win, @vbi, @sliced, @sdr, @meta
> >   *           and @raw_data
> > @@ -2437,6 +2455,7 @@ struct v4l2_format {
> >               struct v4l2_sliced_vbi_format   sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
> >               struct v4l2_sdr_format          sdr;     /* V4L2_BUF_TYPE_SDR_CAPTURE */
> >               struct v4l2_meta_format         meta;    /* V4L2_BUF_TYPE_META_CAPTURE */
> > +             struct v4l2_audio_format        audio;   /* V4L2_BUF_TYPE_AUDIO_CAPTURE */
> >               __u8    raw_data[200];                   /* user-defined */
> >       } fmt;
> >  };
> > --
> > 2.34.1
> >
Daniel Baluta Aug. 1, 2023, 1:58 p.m. UTC | #3
> +static int fsl_asrc_m2m_check_format(u8 dir, u32 rate, u32 channels, u32 format)
> +{
> +       u64 support_format = FSL_ASRC_FORMATS;
> +
> +       if (channels < 1 || channels > 10)
> +               return -EINVAL;
> +
> +       if (rate < 5512 || rate > 192000)
> +               return -EINVAL;
> +

I think we can avoid using magic numbers. Instead we could do:

#define FSL_ASRC_MIN_CHANNELS 1
/...
#define FSL_ASRC_MAX_RATE 192000


> +       if (dir == IN)
> +               support_format |= SNDRV_PCM_FMTBIT_S8;
> +
> +       if (!(1 << format & support_format))
> +               return -EINVAL;
> +
> +       return 0;
> +}
> +
> +/* calculate capture data length according to output data length and sample rate */
> +static int fsl_asrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int input_buffer_length)
> +{
> +       unsigned int in_width, out_width;
> +       unsigned int channels = pair->channels;
> +       unsigned int in_samples, out_samples;
> +       unsigned int out_length;
> +
> +       in_width = snd_pcm_format_physical_width(pair->sample_format[IN]) / 8;
> +       out_width = snd_pcm_format_physical_width(pair->sample_format[OUT]) / 8;
> +
> +       in_samples = input_buffer_length / in_width / channels;
> +       out_samples = pair->rate[OUT] * in_samples / pair->rate[IN];
> +       out_length = (out_samples - ASRC_OUTPUT_LAST_SAMPLE) * out_width * channels;
> +
> +       return out_length;
> +}
> +
> +static int fsl_asrc_m2m_get_maxburst(u8 dir, struct fsl_asrc_pair *pair)
> +{
> +       struct fsl_asrc *asrc = pair->asrc;
> +       struct fsl_asrc_priv *asrc_priv = asrc->private;
> +       int wml = (dir == IN) ? ASRC_M2M_INPUTFIFO_WML : ASRC_M2M_OUTPUTFIFO_WML;
> +
> +       if (!asrc_priv->soc->use_edma)
> +               return wml * pair->channels;
> +       else
> +               return 1;
> +}
> +
> +static int fsl_asrc_m2m_pair_resume(struct fsl_asrc_pair *pair)
> +{
> +       struct fsl_asrc *asrc = pair->asrc;
> +       int i;
> +
> +       for (i = 0; i < pair->channels * 4; i++)
> +               regmap_write(asrc->regmap, REG_ASRDI(pair->index), 0);
> +
> +       return 0;
> +}
> +
>  static int fsl_asrc_runtime_resume(struct device *dev);
>  static int fsl_asrc_runtime_suspend(struct device *dev);

<snip>

There is no implementation for _suspend although you mention it
in the commit message.

> + * @complete: dma task complete
> + * @sample_format: format of m2m
> + * @rate: rate of m2m
> + * @buf_len: buffer length of m2m
> + * @req_pair: flag for request pair


For example @complete field is not used in this patch. Maybe add it in the patch
that uses it?

I think is the same for other fields.
Daniel Baluta Aug. 1, 2023, 2:15 p.m. UTC | #4
On Tue, Jul 25, 2023 at 10:31 AM Shengjiu Wang <shengjiu.wang@nxp.com> wrote:
>
> Implement the ASRC memory to memory function using
> the v4l2 framework, user can use this function with
> v4l2 ioctl interface.
>
> User send the output and capture buffer to driver and
> driver store the converted data to the capture buffer.
>
> This feature can be shared by ASRC and EASRC drivers
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> ---
>  drivers/media/platform/nxp/Kconfig        |  12 +
>  drivers/media/platform/nxp/Makefile       |   1 +
>  drivers/media/platform/nxp/fsl_asrc_m2m.c | 962 ++++++++++++++++++++++
>  include/sound/fsl_asrc_common.h           |   9 +
>  4 files changed, 984 insertions(+)
>  create mode 100644 drivers/media/platform/nxp/fsl_asrc_m2m.c
>
> diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nxp/Kconfig
> index a0ca6b297fb8..359f11fe2a80 100644
> --- a/drivers/media/platform/nxp/Kconfig
> +++ b/drivers/media/platform/nxp/Kconfig
> @@ -56,3 +56,15 @@ config VIDEO_MX2_EMMAPRP
>
>  source "drivers/media/platform/nxp/dw100/Kconfig"
>  source "drivers/media/platform/nxp/imx-jpeg/Kconfig"
> +
> +config VIDEO_FSL_ASRC_M2M
> +       tristate "MXP i.MX ASRC M2M support"

s/MXP/NXP


> +       depends on V4L_MEM2MEM_DRIVERS
> +       depends on MEDIA_SUPPORT
> +       select VIDEOBUF2_DMA_CONTIG
> +       select V4L2_MEM2MEM_DEV
> +       help
> +           Say Y if you want to add ASRC M2M support for NXP CPUs.
> +           It is a completement for ASRC M2P and ASRC P2M features.

Complement for?
Tomasz Figa Aug. 2, 2023, 7:19 a.m. UTC | #5
On Tue, Aug 1, 2023 at 6:47 PM Shengjiu Wang <shengjiu.wang@gmail.com> wrote:
>
> On Fri, Jul 28, 2023 at 3:59 PM Tomasz Figa <tfiga@chromium.org> wrote:
> >
> > Hi Shengjiu,
> >
> > On Tue, Jul 25, 2023 at 02:12:17PM +0800, Shengjiu Wang wrote:
> > > Audio signal processing has the requirement for memory to
> > > memory similar as Video.
> > >
> > > This patch is to add this support in v4l2 framework, defined
> > > new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> > > V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> > > for audio case usage.
> > >
> > > The created audio device is named "/dev/audioX".
> > >
> > > Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> > > ---
> > >  .../media/common/videobuf2/videobuf2-v4l2.c   |  4 ++
> > >  drivers/media/v4l2-core/v4l2-dev.c            | 17 ++++++
> > >  drivers/media/v4l2-core/v4l2-ioctl.c          | 52 +++++++++++++++++++
> > >  include/media/v4l2-dev.h                      |  2 +
> > >  include/media/v4l2-ioctl.h                    | 34 ++++++++++++
> > >  include/uapi/linux/videodev2.h                | 19 +++++++
> > >  6 files changed, 128 insertions(+)
> > >
> >
> > Thanks for the patch! Please check my comments inline.
>
> Thanks for reviewing.
>
> Sorry for sending again for using the plain text mode.
>
> >
> > > diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> > > index c7a54d82a55e..12f2be2773a2 100644
> > > --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c
> > > +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
> > > @@ -785,6 +785,10 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
> > >       case V4L2_BUF_TYPE_META_OUTPUT:
> > >               requested_sizes[0] = f->fmt.meta.buffersize;
> > >               break;
> > > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > > +             requested_sizes[0] = f->fmt.audio.buffersize;
> > > +             break;
> > >       default:
> > >               return -EINVAL;
> > >       }
> > > diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> > > index f81279492682..67484f4c6eaf 100644
> > > --- a/drivers/media/v4l2-core/v4l2-dev.c
> > > +++ b/drivers/media/v4l2-core/v4l2-dev.c
> > > @@ -553,6 +553,7 @@ static void determine_valid_ioctls(struct video_device *vdev)
> > >       bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH;
> > >       bool is_meta = vdev->vfl_type == VFL_TYPE_VIDEO &&
> > >                      (vdev->device_caps & meta_caps);
> > > +     bool is_audio = vdev->vfl_type == VFL_TYPE_AUDIO;
> > >       bool is_rx = vdev->vfl_dir != VFL_DIR_TX;
> > >       bool is_tx = vdev->vfl_dir != VFL_DIR_RX;
> > >       bool is_io_mc = vdev->device_caps & V4L2_CAP_IO_MC;
> > > @@ -664,6 +665,19 @@ static void determine_valid_ioctls(struct video_device *vdev)
> > >               SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_out);
> > >               SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_out);
> > >       }
> > > +     if (is_audio && is_rx) {
> > > +             /* audio capture specific ioctls */
> > > +             SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_audio_cap);
> > > +             SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_audio_cap);
> > > +             SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_audio_cap);
> > > +             SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_audio_cap);
> > > +     } else if (is_audio && is_tx) {
> > > +             /* audio output specific ioctls */
> > > +             SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_audio_out);
> > > +             SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_audio_out);
> > > +             SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_audio_out);
> > > +             SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_audio_out);
> > > +     }
> > >       if (is_vbi) {
> > >               /* vbi specific ioctls */
> > >               if ((is_rx && (ops->vidioc_g_fmt_vbi_cap ||
> > > @@ -927,6 +941,9 @@ int __video_register_device(struct video_device *vdev,
> > >       case VFL_TYPE_TOUCH:
> > >               name_base = "v4l-touch";
> > >               break;
> > > +     case VFL_TYPE_AUDIO:
> > > +             name_base = "audio";
> >
> > I think it was mentioned before that "audio" could be confusing. Wasn't
> > there actually some other kind of /dev/audio device long ago?
> >
> > Seems like for touch, "v4l-touch" was introduced. Maybe it would also
> > make sense to call it "v4l-audio" for audio?
>
> Ok,  will change to use "v4l-audio".
>
> >
> > > +             break;
> > >       default:
> > >               pr_err("%s called with unknown type: %d\n",
> > >                      __func__, type);
> > > diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> > > index 01ba27f2ef87..aa9d872bba8d 100644
> > > --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> > > +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> > > @@ -188,6 +188,8 @@ const char *v4l2_type_names[] = {
> > >       [V4L2_BUF_TYPE_SDR_OUTPUT]         = "sdr-out",
> > >       [V4L2_BUF_TYPE_META_CAPTURE]       = "meta-cap",
> > >       [V4L2_BUF_TYPE_META_OUTPUT]        = "meta-out",
> > > +     [V4L2_BUF_TYPE_AUDIO_CAPTURE]      = "audio-cap",
> > > +     [V4L2_BUF_TYPE_AUDIO_OUTPUT]       = "audio-out",
> > >  };
> > >  EXPORT_SYMBOL(v4l2_type_names);
> > >
> > > @@ -276,6 +278,7 @@ static void v4l_print_format(const void *arg, bool write_only)
> > >       const struct v4l2_sliced_vbi_format *sliced;
> > >       const struct v4l2_window *win;
> > >       const struct v4l2_meta_format *meta;
> > > +     const struct v4l2_audio_format *audio;
> > >       u32 pixelformat;
> > >       u32 planes;
> > >       unsigned i;
> > > @@ -346,6 +349,12 @@ static void v4l_print_format(const void *arg, bool write_only)
> > >               pr_cont(", dataformat=%p4cc, buffersize=%u\n",
> > >                       &pixelformat, meta->buffersize);
> > >               break;
> > > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > > +             audio = &p->fmt.audio;
> > > +             pr_cont(", rate=%u, format=%u, channels=%u, buffersize=%u\n",
> > > +                     audio->rate, audio->format, audio->channels, audio->buffersize);
> > > +             break;
> > >       }
> > >  }
> > >
> > > @@ -927,6 +936,7 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
> > >       bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
> > >       bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO &&
> > >                      (vfd->device_caps & meta_caps);
> > > +     bool is_audio = vfd->vfl_type == VFL_TYPE_AUDIO;
> > >       bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
> > >       bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
> > >
> > > @@ -992,6 +1002,14 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type)
> > >               if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out)
> > >                       return 0;
> > >               break;
> > > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > > +             if (is_audio && is_rx && ops->vidioc_g_fmt_audio_cap)
> > > +                     return 0;
> > > +             break;
> > > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > > +             if (is_audio && is_tx && ops->vidioc_g_fmt_audio_out)
> > > +                     return 0;
> > > +             break;
> > >       default:
> > >               break;
> > >       }
> > > @@ -1594,6 +1612,16 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
> > >                       break;
> > >               ret = ops->vidioc_enum_fmt_meta_out(file, fh, arg);
> > >               break;
> > > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > > +             if (unlikely(!ops->vidioc_enum_fmt_audio_cap))
> > > +                     break;
> > > +             ret = ops->vidioc_enum_fmt_audio_cap(file, fh, arg);
> > > +             break;
> > > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > > +             if (unlikely(!ops->vidioc_enum_fmt_audio_out))
> > > +                     break;
> > > +             ret = ops->vidioc_enum_fmt_audio_out(file, fh, arg);
> > > +             break;
> > >       }
> > >       if (ret == 0)
> > >               v4l_fill_fmtdesc(p);
> > > @@ -1670,6 +1698,10 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
> > >               return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
> > >       case V4L2_BUF_TYPE_META_OUTPUT:
> > >               return ops->vidioc_g_fmt_meta_out(file, fh, arg);
> > > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > > +             return ops->vidioc_g_fmt_audio_cap(file, fh, arg);
> > > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > > +             return ops->vidioc_g_fmt_audio_out(file, fh, arg);
> > >       }
> > >       return -EINVAL;
> > >  }
> > > @@ -1781,6 +1813,16 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
> > >                       break;
> > >               memset_after(p, 0, fmt.meta);
> > >               return ops->vidioc_s_fmt_meta_out(file, fh, arg);
> > > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > > +             if (unlikely(!ops->vidioc_s_fmt_audio_cap))
> > > +                     break;
> > > +             memset_after(p, 0, fmt.audio);
> > > +             return ops->vidioc_s_fmt_audio_cap(file, fh, arg);
> > > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > > +             if (unlikely(!ops->vidioc_s_fmt_audio_out))
> > > +                     break;
> > > +             memset_after(p, 0, fmt.audio);
> > > +             return ops->vidioc_s_fmt_audio_out(file, fh, arg);
> > >       }
> > >       return -EINVAL;
> > >  }
> > > @@ -1889,6 +1931,16 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
> > >                       break;
> > >               memset_after(p, 0, fmt.meta);
> > >               return ops->vidioc_try_fmt_meta_out(file, fh, arg);
> > > +     case V4L2_BUF_TYPE_AUDIO_CAPTURE:
> > > +             if (unlikely(!ops->vidioc_try_fmt_audio_cap))
> > > +                     break;
> > > +             memset_after(p, 0, fmt.audio);
> > > +             return ops->vidioc_try_fmt_audio_cap(file, fh, arg);
> > > +     case V4L2_BUF_TYPE_AUDIO_OUTPUT:
> > > +             if (unlikely(!ops->vidioc_try_fmt_audio_out))
> > > +                     break;
> > > +             memset_after(p, 0, fmt.audio);
> > > +             return ops->vidioc_try_fmt_audio_out(file, fh, arg);
> > >       }
> > >       return -EINVAL;
> > >  }
> > > diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
> > > index e0a13505f88d..0924e6d1dab1 100644
> > > --- a/include/media/v4l2-dev.h
> > > +++ b/include/media/v4l2-dev.h
> > > @@ -30,6 +30,7 @@
> > >   * @VFL_TYPE_SUBDEV: for V4L2 subdevices
> > >   * @VFL_TYPE_SDR:    for Software Defined Radio tuners
> > >   * @VFL_TYPE_TOUCH:  for touch sensors
> > > + * @VFL_TYPE_AUDIO:  for audio input/output devices
> > >   * @VFL_TYPE_MAX:    number of VFL types, must always be last in the enum
> > >   */
> > >  enum vfl_devnode_type {
> > > @@ -39,6 +40,7 @@ enum vfl_devnode_type {
> > >       VFL_TYPE_SUBDEV,
> > >       VFL_TYPE_SDR,
> > >       VFL_TYPE_TOUCH,
> > > +     VFL_TYPE_AUDIO,
> > >       VFL_TYPE_MAX /* Shall be the last one */
> > >  };
> > >
> > > diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> > > index edb733f21604..f840cf740ce1 100644
> > > --- a/include/media/v4l2-ioctl.h
> > > +++ b/include/media/v4l2-ioctl.h
> > > @@ -45,6 +45,12 @@ struct v4l2_fh;
> > >   * @vidioc_enum_fmt_meta_out: pointer to the function that implements
> > >   *   :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
> > >   *   for metadata output
> > > + * @vidioc_enum_fmt_audio_cap: pointer to the function that implements
> > > + *   :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
> > > + *   for audio capture
> > > + * @vidioc_enum_fmt_audio_out: pointer to the function that implements
> > > + *   :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
> > > + *   for audio output
> > >   * @vidioc_g_fmt_vid_cap: pointer to the function that implements
> > >   *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture
> > >   *   in single plane mode
> > > @@ -79,6 +85,10 @@ struct v4l2_fh;
> > >   *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
> > >   * @vidioc_g_fmt_meta_out: pointer to the function that implements
> > >   *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for metadata output
> > > + * @vidioc_g_fmt_audio_cap: pointer to the function that implements
> > > + *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for audio capture
> > > + * @vidioc_g_fmt_audio_out: pointer to the function that implements
> > > + *   :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for audio output
> > >   * @vidioc_s_fmt_vid_cap: pointer to the function that implements
> > >   *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture
> > >   *   in single plane mode
> > > @@ -113,6 +123,10 @@ struct v4l2_fh;
> > >   *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
> > >   * @vidioc_s_fmt_meta_out: pointer to the function that implements
> > >   *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for metadata output
> > > + * @vidioc_s_fmt_audio_cap: pointer to the function that implements
> > > + *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for audio capture
> > > + * @vidioc_s_fmt_audio_out: pointer to the function that implements
> > > + *   :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for audio output
> > >   * @vidioc_try_fmt_vid_cap: pointer to the function that implements
> > >   *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture
> > >   *   in single plane mode
> > > @@ -149,6 +163,10 @@ struct v4l2_fh;
> > >   *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata capture
> > >   * @vidioc_try_fmt_meta_out: pointer to the function that implements
> > >   *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for metadata output
> > > + * @vidioc_try_fmt_audio_cap: pointer to the function that implements
> > > + *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for audio capture
> > > + * @vidioc_try_fmt_audio_out: pointer to the function that implements
> > > + *   :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for audio output
> > >   * @vidioc_reqbufs: pointer to the function that implements
> > >   *   :ref:`VIDIOC_REQBUFS <vidioc_reqbufs>` ioctl
> > >   * @vidioc_querybuf: pointer to the function that implements
> > > @@ -315,6 +333,10 @@ struct v4l2_ioctl_ops {
> > >                                       struct v4l2_fmtdesc *f);
> > >       int (*vidioc_enum_fmt_meta_out)(struct file *file, void *fh,
> > >                                       struct v4l2_fmtdesc *f);
> > > +     int (*vidioc_enum_fmt_audio_cap)(struct file *file, void *fh,
> > > +                                      struct v4l2_fmtdesc *f);
> > > +     int (*vidioc_enum_fmt_audio_out)(struct file *file, void *fh,
> > > +                                      struct v4l2_fmtdesc *f);
> > >
> > >       /* VIDIOC_G_FMT handlers */
> > >       int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh,
> > > @@ -345,6 +367,10 @@ struct v4l2_ioctl_ops {
> > >                                    struct v4l2_format *f);
> > >       int (*vidioc_g_fmt_meta_out)(struct file *file, void *fh,
> > >                                    struct v4l2_format *f);
> > > +     int (*vidioc_g_fmt_audio_cap)(struct file *file, void *fh,
> > > +                                   struct v4l2_format *f);
> > > +     int (*vidioc_g_fmt_audio_out)(struct file *file, void *fh,
> > > +                                   struct v4l2_format *f);
> > >
> > >       /* VIDIOC_S_FMT handlers */
> > >       int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh,
> > > @@ -375,6 +401,10 @@ struct v4l2_ioctl_ops {
> > >                                    struct v4l2_format *f);
> > >       int (*vidioc_s_fmt_meta_out)(struct file *file, void *fh,
> > >                                    struct v4l2_format *f);
> > > +     int (*vidioc_s_fmt_audio_cap)(struct file *file, void *fh,
> > > +                                   struct v4l2_format *f);
> > > +     int (*vidioc_s_fmt_audio_out)(struct file *file, void *fh,
> > > +                                   struct v4l2_format *f);
> > >
> > >       /* VIDIOC_TRY_FMT handlers */
> > >       int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh,
> > > @@ -405,6 +435,10 @@ struct v4l2_ioctl_ops {
> > >                                      struct v4l2_format *f);
> > >       int (*vidioc_try_fmt_meta_out)(struct file *file, void *fh,
> > >                                      struct v4l2_format *f);
> > > +     int (*vidioc_try_fmt_audio_cap)(struct file *file, void *fh,
> > > +                                     struct v4l2_format *f);
> > > +     int (*vidioc_try_fmt_audio_out)(struct file *file, void *fh,
> > > +                                     struct v4l2_format *f);
> > >
> > >       /* Buffer handlers */
> > >       int (*vidioc_reqbufs)(struct file *file, void *fh,
> > > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> > > index 3af6a82d0cad..e5051410928a 100644
> > > --- a/include/uapi/linux/videodev2.h
> > > +++ b/include/uapi/linux/videodev2.h
> > > @@ -153,6 +153,8 @@ enum v4l2_buf_type {
> > >       V4L2_BUF_TYPE_SDR_OUTPUT           = 12,
> > >       V4L2_BUF_TYPE_META_CAPTURE         = 13,
> > >       V4L2_BUF_TYPE_META_OUTPUT          = 14,
> > > +     V4L2_BUF_TYPE_AUDIO_CAPTURE        = 15,
> > > +     V4L2_BUF_TYPE_AUDIO_OUTPUT         = 16,
> > >       /* Deprecated, do not use */
> > >       V4L2_BUF_TYPE_PRIVATE              = 0x80,
> > >  };
> > > @@ -169,6 +171,7 @@ enum v4l2_buf_type {
> > >        || (type) == V4L2_BUF_TYPE_VBI_OUTPUT                  \
> > >        || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT           \
> > >        || (type) == V4L2_BUF_TYPE_SDR_OUTPUT                  \
> > > +      || (type) == V4L2_BUF_TYPE_AUDIO_OUTPUT                \
> > >        || (type) == V4L2_BUF_TYPE_META_OUTPUT)
> > >
> > >  #define V4L2_TYPE_IS_CAPTURE(type) (!V4L2_TYPE_IS_OUTPUT(type))
> > > @@ -2415,6 +2418,20 @@ struct v4l2_meta_format {
> > >       __u32                           buffersize;
> > >  } __attribute__ ((packed));
> > >
> > > +/**
> > > + * struct v4l2_audio_format - audio data format definition
> > > + * @rate:            sample rate
> > > + * @format:          sample format
> > > + * @channels:                channel numbers
> > > + * @buffersize:              maximum size in bytes required for data
> > > + */
> > > +struct v4l2_audio_format {
> > > +     __u32                           rate;
> > > +     __u32                           format;
> >
> > What are the values for the rate and format fields? Since they are part
> > of the UAPI, they need to be defined.
> >
>
> The range for sample rate is [5512, 768000].
> The format is defined in include/uapi/sound/asound.h,  they are
> SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_U8, ...
>
> Where should I put these info?
>

I see, so those are standard definitions of the sound subsystem. I
think we should refer to the right header and/or data types in the
kerneldoc comment for the struct. We also need to provide the sphinx
documentation for the new device type and extend the description of
relevant ioctls (e.g. VIDIOC_S_FMT) that accept the new structs. I.e.
the v4l2_format struct used by VIDIOC_S_FMT is documented in

https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/vidioc-g-fmt.html?highlight=g_fmt#c.V4L.v4l2_format

and there is documentation for each of the union members, like
v4l2_pix_format_mplane that is commonly used for video data:

https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/pixfmt-v4l2-mplane.html#c.v4l2_pix_format_mplane

We'll need a similar one for the new v4l2_audio_format.

Best regards,
Tomasz

> Best regards
> Wang shengjiu
>
> > Best regards,
> > Tomasz
> >
> > > +     __u32                           channels;
> > > +     __u32                           buffersize;
> > > +} __attribute__ ((packed));
> > > +
> > >  /**
> > >   * struct v4l2_format - stream data format
> > >   * @type:    enum v4l2_buf_type; type of the data stream
> > > @@ -2423,6 +2440,7 @@ struct v4l2_meta_format {
> > >   * @win:     definition of an overlaid image
> > >   * @vbi:     raw VBI capture or output parameters
> > >   * @sliced:  sliced VBI capture or output parameters
> > > + * @audio:   definition of an audio format
> > >   * @raw_data:        placeholder for future extensions and custom formats
> > >   * @fmt:     union of @pix, @pix_mp, @win, @vbi, @sliced, @sdr, @meta
> > >   *           and @raw_data
> > > @@ -2437,6 +2455,7 @@ struct v4l2_format {
> > >               struct v4l2_sliced_vbi_format   sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
> > >               struct v4l2_sdr_format          sdr;     /* V4L2_BUF_TYPE_SDR_CAPTURE */
> > >               struct v4l2_meta_format         meta;    /* V4L2_BUF_TYPE_META_CAPTURE */
> > > +             struct v4l2_audio_format        audio;   /* V4L2_BUF_TYPE_AUDIO_CAPTURE */
> > >               __u8    raw_data[200];                   /* user-defined */
> > >       } fmt;
> > >  };
> > > --
> > > 2.34.1
> > >
Hans Verkuil Aug. 2, 2023, 7:32 a.m. UTC | #6
Hi all,

On 25/07/2023 08:12, Shengjiu Wang wrote:
> Audio signal processing has the requirement for memory to
> memory similar as Video.
> 
> This patch is to add this support in v4l2 framework, defined
> new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> for audio case usage.
> 
> The created audio device is named "/dev/audioX".
> 
> And add memory to memory support for two kinds of i.MX ASRC
> module

Before I spend time on this: are the audio maintainers OK with doing
this in V4L2?

I do want to have a clear statement on this as it is not something I
can decide.

Regards,

	Hans

> 
> changes in v2:
> - decouple the implementation in v4l2 and ALSA
> - implement the memory to memory driver as a platfrom driver
>   and move it to driver/media
> - move fsl_asrc_common.h to include/sound folder
> 
> Shengjiu Wang (7):
>   ASoC: fsl_asrc: define functions for memory to memory usage
>   ASoC: fsl_easrc: define functions for memory to memory usage
>   ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound
>   media: v4l2: Add audio capture and output support
>   media: imx: fsl_asrc: Add memory to memory driver
>   ASoC: fsl_asrc: register m2m platform device
>   ASoC: fsl_easrc: register m2m platform device
> 
>  .../media/common/videobuf2/videobuf2-v4l2.c   |   4 +
>  drivers/media/platform/nxp/Kconfig            |  12 +
>  drivers/media/platform/nxp/Makefile           |   1 +
>  drivers/media/platform/nxp/fsl_asrc_m2m.c     | 962 ++++++++++++++++++
>  drivers/media/v4l2-core/v4l2-dev.c            |  17 +
>  drivers/media/v4l2-core/v4l2-ioctl.c          |  52 +
>  include/media/v4l2-dev.h                      |   2 +
>  include/media/v4l2-ioctl.h                    |  34 +
>  .../fsl => include/sound}/fsl_asrc_common.h   |  48 +
>  include/uapi/linux/videodev2.h                |  19 +
>  sound/soc/fsl/fsl_asrc.c                      | 150 +++
>  sound/soc/fsl/fsl_asrc.h                      |   4 +-
>  sound/soc/fsl/fsl_asrc_dma.c                  |   2 +-
>  sound/soc/fsl/fsl_easrc.c                     | 227 +++++
>  sound/soc/fsl/fsl_easrc.h                     |   8 +-
>  15 files changed, 1539 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/media/platform/nxp/fsl_asrc_m2m.c
>  rename {sound/soc/fsl => include/sound}/fsl_asrc_common.h (63%)
>
Takashi Iwai Aug. 2, 2023, 11:22 a.m. UTC | #7
On Wed, 02 Aug 2023 09:32:37 +0200,
Hans Verkuil wrote:
> 
> Hi all,
> 
> On 25/07/2023 08:12, Shengjiu Wang wrote:
> > Audio signal processing has the requirement for memory to
> > memory similar as Video.
> > 
> > This patch is to add this support in v4l2 framework, defined
> > new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> > V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> > for audio case usage.
> > 
> > The created audio device is named "/dev/audioX".
> > 
> > And add memory to memory support for two kinds of i.MX ASRC
> > module
> 
> Before I spend time on this: are the audio maintainers OK with doing
> this in V4L2?
> 
> I do want to have a clear statement on this as it is not something I
> can decide.

Well, I personally don't mind to have some audio capability in v4l2
layer.  But, the only uncertain thing for now is whether this is a
must-have or not.

IIRC, the implementation in the sound driver side was never done just
because there was no similar implementation?  If so, and if the
extension to the v4l2 core layer is needed, shouldn't it be more
considered for the possible other route?


thanks,

Takashi
Shengjiu Wang Aug. 2, 2023, 12:02 p.m. UTC | #8
On Wed, Aug 2, 2023 at 7:22 PM Takashi Iwai <tiwai@suse.de> wrote:
>
> On Wed, 02 Aug 2023 09:32:37 +0200,
> Hans Verkuil wrote:
> >
> > Hi all,
> >
> > On 25/07/2023 08:12, Shengjiu Wang wrote:
> > > Audio signal processing has the requirement for memory to
> > > memory similar as Video.
> > >
> > > This patch is to add this support in v4l2 framework, defined
> > > new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> > > V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> > > for audio case usage.
> > >
> > > The created audio device is named "/dev/audioX".
> > >
> > > And add memory to memory support for two kinds of i.MX ASRC
> > > module
> >
> > Before I spend time on this: are the audio maintainers OK with doing
> > this in V4L2?
> >
> > I do want to have a clear statement on this as it is not something I
> > can decide.
>
> Well, I personally don't mind to have some audio capability in v4l2
> layer.  But, the only uncertain thing for now is whether this is a
> must-have or not.
>

Thanks,  I am also not sure about this.  I am also confused that why
there is no m2m implementation for audio in the kernel.  Audio also
has similar decoder encoder post-processing as video.

>
> IIRC, the implementation in the sound driver side was never done just
> because there was no similar implementation?  If so, and if the
> extension to the v4l2 core layer is needed, shouldn't it be more
> considered for the possible other route?
>

Actually I'd like someone could point me to the other route. I'd like to
try.

The reason why I select to extend v4l2 for such audio usage is that v4l2
looks best for this audio m2m implementation.  v4l2 is designed for m2m
usage.  if we need implement another 'route',  I don't think it can do better
that v4l2.

I appreciate that someone can share his ideas or doable solutions.
And please don't ignore my request, ignore my patch.

Best regards
Wang shengjiu
Takashi Iwai Aug. 2, 2023, 12:08 p.m. UTC | #9
On Wed, 02 Aug 2023 14:02:29 +0200,
Shengjiu Wang wrote:
> 
> On Wed, Aug 2, 2023 at 7:22 PM Takashi Iwai <tiwai@suse.de> wrote:
> >
> > On Wed, 02 Aug 2023 09:32:37 +0200,
> > Hans Verkuil wrote:
> > >
> > > Hi all,
> > >
> > > On 25/07/2023 08:12, Shengjiu Wang wrote:
> > > > Audio signal processing has the requirement for memory to
> > > > memory similar as Video.
> > > >
> > > > This patch is to add this support in v4l2 framework, defined
> > > > new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> > > > V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> > > > for audio case usage.
> > > >
> > > > The created audio device is named "/dev/audioX".
> > > >
> > > > And add memory to memory support for two kinds of i.MX ASRC
> > > > module
> > >
> > > Before I spend time on this: are the audio maintainers OK with doing
> > > this in V4L2?
> > >
> > > I do want to have a clear statement on this as it is not something I
> > > can decide.
> >
> > Well, I personally don't mind to have some audio capability in v4l2
> > layer.  But, the only uncertain thing for now is whether this is a
> > must-have or not.
> >
> 
> Thanks,  I am also not sure about this.  I am also confused that why
> there is no m2m implementation for audio in the kernel.  Audio also
> has similar decoder encoder post-processing as video.
> 
> >
> > IIRC, the implementation in the sound driver side was never done just
> > because there was no similar implementation?  If so, and if the
> > extension to the v4l2 core layer is needed, shouldn't it be more
> > considered for the possible other route?
> >
> 
> Actually I'd like someone could point me to the other route. I'd like to
> try.
> 
> The reason why I select to extend v4l2 for such audio usage is that v4l2
> looks best for this audio m2m implementation.  v4l2 is designed for m2m
> usage.  if we need implement another 'route',  I don't think it can do better
> that v4l2.
> 
> I appreciate that someone can share his ideas or doable solutions.
> And please don't ignore my request, ignore my patch.

Can you explain a bit more details of your demand?
At least, a "big picture" showing how your hardware is implemented and
what is exactly necessary would be helpful for understanding the
problem.


thanks,

Takashi
Mark Brown Aug. 2, 2023, 12:09 p.m. UTC | #10
On Wed, Aug 02, 2023 at 08:02:29PM +0800, Shengjiu Wang wrote:
> On Wed, Aug 2, 2023 at 7:22 PM Takashi Iwai <tiwai@suse.de> wrote:

> > Well, I personally don't mind to have some audio capability in v4l2
> > layer.  But, the only uncertain thing for now is whether this is a
> > must-have or not.

> Thanks,  I am also not sure about this.  I am also confused that why
> there is no m2m implementation for audio in the kernel.  Audio also
> has similar decoder encoder post-processing as video.

This is the thing where we've been trying to persuade people to work on
replacing DPCM with full componentisation for about a decade now but
nobody's had time other than Morimoto-san who's been chipping away at
making everything component based for a good chunk of that time.  One
trick is that we don't just want this to work for things that are memory
to memory, we also want things where there's a direct interconnect that
bypasses memory for off-SoC case.

> The reason why I select to extend v4l2 for such audio usage is that v4l2
> looks best for this audio m2m implementation.  v4l2 is designed for m2m
> usage.  if we need implement another 'route',  I don't think it can do better
> that v4l2.

> I appreciate that someone can share his ideas or doable solutions.
> And please don't ignore my request, ignore my patch.

There's a bunch of presentations Lars-Peter did at ELC some considerable
time ago about this.
Hans Verkuil Aug. 2, 2023, 12:28 p.m. UTC | #11
On 02/08/2023 14:02, Shengjiu Wang wrote:
> On Wed, Aug 2, 2023 at 7:22 PM Takashi Iwai <tiwai@suse.de> wrote:
>>
>> On Wed, 02 Aug 2023 09:32:37 +0200,
>> Hans Verkuil wrote:
>>>
>>> Hi all,
>>>
>>> On 25/07/2023 08:12, Shengjiu Wang wrote:
>>>> Audio signal processing has the requirement for memory to
>>>> memory similar as Video.
>>>>
>>>> This patch is to add this support in v4l2 framework, defined
>>>> new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
>>>> V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
>>>> for audio case usage.
>>>>
>>>> The created audio device is named "/dev/audioX".
>>>>
>>>> And add memory to memory support for two kinds of i.MX ASRC
>>>> module
>>>
>>> Before I spend time on this: are the audio maintainers OK with doing
>>> this in V4L2?
>>>
>>> I do want to have a clear statement on this as it is not something I
>>> can decide.
>>
>> Well, I personally don't mind to have some audio capability in v4l2
>> layer.  But, the only uncertain thing for now is whether this is a
>> must-have or not.
>>
> 
> Thanks,  I am also not sure about this.  I am also confused that why
> there is no m2m implementation for audio in the kernel.  Audio also
> has similar decoder encoder post-processing as video.
> 
>>
>> IIRC, the implementation in the sound driver side was never done just
>> because there was no similar implementation?  If so, and if the
>> extension to the v4l2 core layer is needed, shouldn't it be more
>> considered for the possible other route?
>>
> 
> Actually I'd like someone could point me to the other route. I'd like to
> try.
> 
> The reason why I select to extend v4l2 for such audio usage is that v4l2
> looks best for this audio m2m implementation.  v4l2 is designed for m2m
> usage.  if we need implement another 'route',  I don't think it can do better
> that v4l2.
> 
> I appreciate that someone can share his ideas or doable solutions.
> And please don't ignore my request, ignore my patch.

To give a bit more background: if it is decided to use the v4l API for this
(and I have no objection to this from my side since API/framework-wise it is a
good fit for this), then there are a number of things that need to be done to
get this into the media subsystem:

- documentation for the new uAPI
- add support for this to v4l2-ctl
- add v4l2-compliance tests for the new device
- highly desirable: have a virtual driver (similar to vim2m) that supports this:
  it could be as simple as just copy input to output. This helps regression
  testing.
- it might need media controller support as well. TBD.

None of this is particularly complex, but taken all together it is a fair
amount of work that also needs a lot of review time from our side.

I want to add one more option to the mix: drivers/media/core/v4l2-mem2mem.c is
the main m2m framework, but it relies heavily on the videobuf2 framework for
the capture and output queues.

The core vb2 implementation in drivers/media/common/videobuf2/videobuf2-core.c
is independent of V4L2 and can be used by other subsystems (in our case, it is
also used by the DVB API). It is a possibility to create an alsa version of
v4l2-mem2mem.c that uses the core vb2 code with an ALSA uAPI on top.

So in drivers/media/common/videobuf2/ you would have a videobuf2-alsa.c besides
the already existing videobuf2-v4l2.c and -dvb.c.

Perhaps parts of v4l2-mem2mem.c can be reused as well in that case, but I am
not sure if it is worth the effort. I suspect copying it to an alsa-mem2mem.c
and adapting it for alsa is easiest if you want to go that way.

Regards,

	Hans
Shengjiu Wang Aug. 2, 2023, 2:41 p.m. UTC | #12
On Wed, Aug 2, 2023 at 8:08 PM Takashi Iwai <tiwai@suse.de> wrote:
>
> On Wed, 02 Aug 2023 14:02:29 +0200,
> Shengjiu Wang wrote:
> >
> > On Wed, Aug 2, 2023 at 7:22 PM Takashi Iwai <tiwai@suse.de> wrote:
> > >
> > > On Wed, 02 Aug 2023 09:32:37 +0200,
> > > Hans Verkuil wrote:
> > > >
> > > > Hi all,
> > > >
> > > > On 25/07/2023 08:12, Shengjiu Wang wrote:
> > > > > Audio signal processing has the requirement for memory to
> > > > > memory similar as Video.
> > > > >
> > > > > This patch is to add this support in v4l2 framework, defined
> > > > > new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> > > > > V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> > > > > for audio case usage.
> > > > >
> > > > > The created audio device is named "/dev/audioX".
> > > > >
> > > > > And add memory to memory support for two kinds of i.MX ASRC
> > > > > module
> > > >
> > > > Before I spend time on this: are the audio maintainers OK with doing
> > > > this in V4L2?
> > > >
> > > > I do want to have a clear statement on this as it is not something I
> > > > can decide.
> > >
> > > Well, I personally don't mind to have some audio capability in v4l2
> > > layer.  But, the only uncertain thing for now is whether this is a
> > > must-have or not.
> > >
> >
> > Thanks,  I am also not sure about this.  I am also confused that why
> > there is no m2m implementation for audio in the kernel.  Audio also
> > has similar decoder encoder post-processing as video.
> >
> > >
> > > IIRC, the implementation in the sound driver side was never done just
> > > because there was no similar implementation?  If so, and if the
> > > extension to the v4l2 core layer is needed, shouldn't it be more
> > > considered for the possible other route?
> > >
> >
> > Actually I'd like someone could point me to the other route. I'd like to
> > try.
> >
> > The reason why I select to extend v4l2 for such audio usage is that v4l2
> > looks best for this audio m2m implementation.  v4l2 is designed for m2m
> > usage.  if we need implement another 'route',  I don't think it can do better
> > that v4l2.
> >
> > I appreciate that someone can share his ideas or doable solutions.
> > And please don't ignore my request, ignore my patch.
>
> Can you explain a bit more details of your demand?
> At least, a "big picture" showing how your hardware is implemented and
> what is exactly necessary would be helpful for understanding the
> problem.
>

We have the hardware IP: ASRC,  asynchronous sample rate converter.

Currently the ASRC in ALSA is to connect to another I2S device as
a sound card.  But we'd like to the ASRC can be used by user space directly
that user space application can get the output after conversion from ASRC.

The ASRC can be integrated into a multimedia framework (gstreamer) as a plugin.

best regards
wang shengjiu
Mark Brown Aug. 2, 2023, 5:28 p.m. UTC | #13
On Wed, Aug 02, 2023 at 10:41:43PM +0800, Shengjiu Wang wrote:

> Currently the ASRC in ALSA is to connect to another I2S device as
> a sound card.  But we'd like to the ASRC can be used by user space directly
> that user space application can get the output after conversion from ASRC.

That sort of use case would be handled via DPCM at the minute, though
persuading it to connect two front ends together might be fun (which is
the sort of reason why we want to push digital information down into
DAPM and make everything a component).
Shengjiu Wang Aug. 3, 2023, 1:11 p.m. UTC | #14
On Thu, Aug 3, 2023 at 1:28 AM Mark Brown <broonie@kernel.org> wrote:
>
> On Wed, Aug 02, 2023 at 10:41:43PM +0800, Shengjiu Wang wrote:
>
> > Currently the ASRC in ALSA is to connect to another I2S device as
> > a sound card.  But we'd like to the ASRC can be used by user space directly
> > that user space application can get the output after conversion from ASRC.
>
> That sort of use case would be handled via DPCM at the minute, though
> persuading it to connect two front ends together might be fun (which is
> the sort of reason why we want to push digital information down into
> DAPM and make everything a component).

Thanks.

ASRC M2M case needs to run as fast as possible, no sync clock control.
If use sound card to handle ASRC M2M case,  the user application
should be aplay/arecord, then we need to consider xrun issue, buffer
may timeout, sync between aplay and arecord,  these should't be
considered by pure memory to memory operation.

DPCM may achitect all the audio things in components and sound
card,  it is good. but for the M2M case, it is complcated. not sure
it is doable.

best regards
wang shengjiu
Shengjiu Wang Aug. 4, 2023, 12:19 p.m. UTC | #15
On Wed, Aug 2, 2023 at 8:28 PM Hans Verkuil <hverkuil@xs4all.nl> wrote:
>
> On 02/08/2023 14:02, Shengjiu Wang wrote:
> > On Wed, Aug 2, 2023 at 7:22 PM Takashi Iwai <tiwai@suse.de> wrote:
> >>
> >> On Wed, 02 Aug 2023 09:32:37 +0200,
> >> Hans Verkuil wrote:
> >>>
> >>> Hi all,
> >>>
> >>> On 25/07/2023 08:12, Shengjiu Wang wrote:
> >>>> Audio signal processing has the requirement for memory to
> >>>> memory similar as Video.
> >>>>
> >>>> This patch is to add this support in v4l2 framework, defined
> >>>> new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
> >>>> V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
> >>>> for audio case usage.
> >>>>
> >>>> The created audio device is named "/dev/audioX".
> >>>>
> >>>> And add memory to memory support for two kinds of i.MX ASRC
> >>>> module
> >>>
> >>> Before I spend time on this: are the audio maintainers OK with doing
> >>> this in V4L2?
> >>>
> >>> I do want to have a clear statement on this as it is not something I
> >>> can decide.
> >>
> >> Well, I personally don't mind to have some audio capability in v4l2
> >> layer.  But, the only uncertain thing for now is whether this is a
> >> must-have or not.
> >>
> >
> > Thanks,  I am also not sure about this.  I am also confused that why
> > there is no m2m implementation for audio in the kernel.  Audio also
> > has similar decoder encoder post-processing as video.
> >
> >>
> >> IIRC, the implementation in the sound driver side was never done just
> >> because there was no similar implementation?  If so, and if the
> >> extension to the v4l2 core layer is needed, shouldn't it be more
> >> considered for the possible other route?
> >>
> >
> > Actually I'd like someone could point me to the other route. I'd like to
> > try.
> >
> > The reason why I select to extend v4l2 for such audio usage is that v4l2
> > looks best for this audio m2m implementation.  v4l2 is designed for m2m
> > usage.  if we need implement another 'route',  I don't think it can do better
> > that v4l2.
> >
> > I appreciate that someone can share his ideas or doable solutions.
> > And please don't ignore my request, ignore my patch.
>
> To give a bit more background: if it is decided to use the v4l API for this
> (and I have no objection to this from my side since API/framework-wise it is a
> good fit for this), then there are a number of things that need to be done to
> get this into the media subsystem:
>
> - documentation for the new uAPI
> - add support for this to v4l2-ctl
> - add v4l2-compliance tests for the new device
> - highly desirable: have a virtual driver (similar to vim2m) that supports this:
>   it could be as simple as just copy input to output. This helps regression
>   testing.
> - it might need media controller support as well. TBD.
>
> None of this is particularly complex, but taken all together it is a fair
> amount of work that also needs a lot of review time from our side.
>
> I want to add one more option to the mix: drivers/media/core/v4l2-mem2mem.c is
> the main m2m framework, but it relies heavily on the videobuf2 framework for
> the capture and output queues.
>
> The core vb2 implementation in drivers/media/common/videobuf2/videobuf2-core.c
> is independent of V4L2 and can be used by other subsystems (in our case, it is
> also used by the DVB API). It is a possibility to create an alsa version of
> v4l2-mem2mem.c that uses the core vb2 code with an ALSA uAPI on top.
>
> So in drivers/media/common/videobuf2/ you would have a videobuf2-alsa.c besides
> the already existing videobuf2-v4l2.c and -dvb.c.
>
> Perhaps parts of v4l2-mem2mem.c can be reused as well in that case, but I am
> not sure if it is worth the effort. I suspect copying it to an alsa-mem2mem.c
> and adapting it for alsa is easiest if you want to go that way.
>

Thanks.

Does this means that videobuf2-v4l2.c and v4l2-mem2mem.c are dedicate
for video device? if audio want to use v4l2 framework,  need to create
videobuf2-alsa.c and alsa-mem2mem.c, but it may cause a lot of function
duplicate.

Best regards
Wang Shengjiu
Hans Verkuil Aug. 4, 2023, 12:34 p.m. UTC | #16
On 04/08/2023 14:19, Shengjiu Wang wrote:
> On Wed, Aug 2, 2023 at 8:28 PM Hans Verkuil <hverkuil@xs4all.nl> wrote:
>>
>> On 02/08/2023 14:02, Shengjiu Wang wrote:
>>> On Wed, Aug 2, 2023 at 7:22 PM Takashi Iwai <tiwai@suse.de> wrote:
>>>>
>>>> On Wed, 02 Aug 2023 09:32:37 +0200,
>>>> Hans Verkuil wrote:
>>>>>
>>>>> Hi all,
>>>>>
>>>>> On 25/07/2023 08:12, Shengjiu Wang wrote:
>>>>>> Audio signal processing has the requirement for memory to
>>>>>> memory similar as Video.
>>>>>>
>>>>>> This patch is to add this support in v4l2 framework, defined
>>>>>> new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
>>>>>> V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
>>>>>> for audio case usage.
>>>>>>
>>>>>> The created audio device is named "/dev/audioX".
>>>>>>
>>>>>> And add memory to memory support for two kinds of i.MX ASRC
>>>>>> module
>>>>>
>>>>> Before I spend time on this: are the audio maintainers OK with doing
>>>>> this in V4L2?
>>>>>
>>>>> I do want to have a clear statement on this as it is not something I
>>>>> can decide.
>>>>
>>>> Well, I personally don't mind to have some audio capability in v4l2
>>>> layer.  But, the only uncertain thing for now is whether this is a
>>>> must-have or not.
>>>>
>>>
>>> Thanks,  I am also not sure about this.  I am also confused that why
>>> there is no m2m implementation for audio in the kernel.  Audio also
>>> has similar decoder encoder post-processing as video.
>>>
>>>>
>>>> IIRC, the implementation in the sound driver side was never done just
>>>> because there was no similar implementation?  If so, and if the
>>>> extension to the v4l2 core layer is needed, shouldn't it be more
>>>> considered for the possible other route?
>>>>
>>>
>>> Actually I'd like someone could point me to the other route. I'd like to
>>> try.
>>>
>>> The reason why I select to extend v4l2 for such audio usage is that v4l2
>>> looks best for this audio m2m implementation.  v4l2 is designed for m2m
>>> usage.  if we need implement another 'route',  I don't think it can do better
>>> that v4l2.
>>>
>>> I appreciate that someone can share his ideas or doable solutions.
>>> And please don't ignore my request, ignore my patch.
>>
>> To give a bit more background: if it is decided to use the v4l API for this
>> (and I have no objection to this from my side since API/framework-wise it is a
>> good fit for this), then there are a number of things that need to be done to
>> get this into the media subsystem:
>>
>> - documentation for the new uAPI
>> - add support for this to v4l2-ctl
>> - add v4l2-compliance tests for the new device
>> - highly desirable: have a virtual driver (similar to vim2m) that supports this:
>>   it could be as simple as just copy input to output. This helps regression
>>   testing.
>> - it might need media controller support as well. TBD.
>>
>> None of this is particularly complex, but taken all together it is a fair
>> amount of work that also needs a lot of review time from our side.
>>
>> I want to add one more option to the mix: drivers/media/core/v4l2-mem2mem.c is
>> the main m2m framework, but it relies heavily on the videobuf2 framework for
>> the capture and output queues.
>>
>> The core vb2 implementation in drivers/media/common/videobuf2/videobuf2-core.c
>> is independent of V4L2 and can be used by other subsystems (in our case, it is
>> also used by the DVB API). It is a possibility to create an alsa version of
>> v4l2-mem2mem.c that uses the core vb2 code with an ALSA uAPI on top.
>>
>> So in drivers/media/common/videobuf2/ you would have a videobuf2-alsa.c besides
>> the already existing videobuf2-v4l2.c and -dvb.c.
>>
>> Perhaps parts of v4l2-mem2mem.c can be reused as well in that case, but I am
>> not sure if it is worth the effort. I suspect copying it to an alsa-mem2mem.c
>> and adapting it for alsa is easiest if you want to go that way.
>>
> 
> Thanks.
> 
> Does this means that videobuf2-v4l2.c and v4l2-mem2mem.c are dedicate
> for video device? if audio want to use v4l2 framework,  need to create
> videobuf2-alsa.c and alsa-mem2mem.c, but it may cause a lot of function
> duplicate.

The videobuf2-v4l2.c sits on top of videobuf2-core.c and provides the V4L2
uAPI for the streaming functionality. If you don't want to use the V4L2
uAPI for this, then you would need a videobuf2-alsa.c that provides a
(possibly new) ALSA uAPI. Whether that makes sense is something I cannot
decide.

v4l2-mem2mem.c uses videobuf2-v4l2.c, so if you need a ALSA version, then
you probably need to create an alsa-mem2mem.c (possibly some functionality
can be shared).

It's just a third option, and it can be useful if there is a strong desire
to keep the uAPI for this functionality entirely within the ALSA subsystem,
but you want to reuse the streaming I/O functionality that the videobuf2
core provides.

If the decision is that it is fine to use the V4L2 uAPI for this type
of audio functionality through a /dev/v4l-audioX device, then just ignore
this option and use V4L2.

Regards,

	Hans
Shengjiu Wang Aug. 11, 2023, 11:05 a.m. UTC | #17
Hi Mark, Takashi

On Thu, Aug 3, 2023 at 9:11 PM Shengjiu Wang <shengjiu.wang@gmail.com> wrote:
>
> On Thu, Aug 3, 2023 at 1:28 AM Mark Brown <broonie@kernel.org> wrote:
> >
> > On Wed, Aug 02, 2023 at 10:41:43PM +0800, Shengjiu Wang wrote:
> >
> > > Currently the ASRC in ALSA is to connect to another I2S device as
> > > a sound card.  But we'd like to the ASRC can be used by user space directly
> > > that user space application can get the output after conversion from ASRC.
> >
> > That sort of use case would be handled via DPCM at the minute, though
> > persuading it to connect two front ends together might be fun (which is
> > the sort of reason why we want to push digital information down into
> > DAPM and make everything a component).
>
> Thanks.
>
> ASRC M2M case needs to run as fast as possible, no sync clock control.
> If use sound card to handle ASRC M2M case,  the user application
> should be aplay/arecord, then we need to consider xrun issue, buffer
> may timeout, sync between aplay and arecord,  these should't be
> considered by pure memory to memory operation.
>
> DPCM may achitect all the audio things in components and sound
> card,  it is good. but for the M2M case, it is complcated. not sure
> it is doable.
>

Beside the concern in previous mail,

DPCM needs to separate ASRC to be two substreams (playback and capture).

But the ASRC needs the sample rate & format of input and output first
then start conversion.

If the playback controls the rate & format of input,  capture substream
controls the rate & format of output,  as a result
one substream needs to get information(dma buffer address, size...
rate, format) from another substream, then start both substreams in the
last substream. How to synchronize these two substreams is a problem.
One stream can be released but another stream doesn't know .

So I don't think it is a good idea to use DPCM for pure M2M case.

So can I persuade you to consider the V4L2 solution?

Best regards
Wang Shengjiu
Shengjiu Wang Aug. 23, 2023, 2:33 p.m. UTC | #18
On Fri, Aug 11, 2023 at 7:05 PM Shengjiu Wang <shengjiu.wang@gmail.com> wrote:
>
> Hi Mark, Takashi
>
> On Thu, Aug 3, 2023 at 9:11 PM Shengjiu Wang <shengjiu.wang@gmail.com> wrote:
> >
> > On Thu, Aug 3, 2023 at 1:28 AM Mark Brown <broonie@kernel.org> wrote:
> > >
> > > On Wed, Aug 02, 2023 at 10:41:43PM +0800, Shengjiu Wang wrote:
> > >
> > > > Currently the ASRC in ALSA is to connect to another I2S device as
> > > > a sound card.  But we'd like to the ASRC can be used by user space directly
> > > > that user space application can get the output after conversion from ASRC.
> > >
> > > That sort of use case would be handled via DPCM at the minute, though
> > > persuading it to connect two front ends together might be fun (which is
> > > the sort of reason why we want to push digital information down into
> > > DAPM and make everything a component).
> >
> > Thanks.
> >
> > ASRC M2M case needs to run as fast as possible, no sync clock control.
> > If use sound card to handle ASRC M2M case,  the user application
> > should be aplay/arecord, then we need to consider xrun issue, buffer
> > may timeout, sync between aplay and arecord,  these should't be
> > considered by pure memory to memory operation.
> >
> > DPCM may achitect all the audio things in components and sound
> > card,  it is good. but for the M2M case, it is complcated. not sure
> > it is doable.
> >
>
> Beside the concern in previous mail,
>
> DPCM needs to separate ASRC to be two substreams (playback and capture).
>
> But the ASRC needs the sample rate & format of input and output first
> then start conversion.
>
> If the playback controls the rate & format of input,  capture substream
> controls the rate & format of output,  as a result
> one substream needs to get information(dma buffer address, size...
> rate, format) from another substream, then start both substreams in the
> last substream. How to synchronize these two substreams is a problem.
> One stream can be released but another stream doesn't know .
>
> So I don't think it is a good idea to use DPCM for pure M2M case.
>
> So can I persuade you to consider the V4L2 solution?
>

Just a summary:

Basic M2M conversion can work with DPCM, I have tried with some
workaround to make it work.

But there are several issues:
1. Need to create sound cards.  ASRC module support multi instances, then
need to create multi sound cards for each instance.

2. The ASRC is an entirety but with DPCM we need to separate input port and
output port to playback substream and capture stream. Synchronous between
playback substream and capture substream is a problem.
How to start them and stop them at the same time.

3. How to handle the xrun issue. pause or resume. which are brought by ALSA.

So shall we make the decision that we can go to the V4L2 solution?

Best regards
Wang Shengjiu
Takashi Iwai Aug. 24, 2023, 5:03 p.m. UTC | #19
On Wed, 23 Aug 2023 16:33:19 +0200,
Shengjiu Wang wrote:
> 
> On Fri, Aug 11, 2023 at 7:05 PM Shengjiu Wang <shengjiu.wang@gmail.com> wrote:
> >
> > Hi Mark, Takashi
> >
> > On Thu, Aug 3, 2023 at 9:11 PM Shengjiu Wang <shengjiu.wang@gmail.com> wrote:
> > >
> > > On Thu, Aug 3, 2023 at 1:28 AM Mark Brown <broonie@kernel.org> wrote:
> > > >
> > > > On Wed, Aug 02, 2023 at 10:41:43PM +0800, Shengjiu Wang wrote:
> > > >
> > > > > Currently the ASRC in ALSA is to connect to another I2S device as
> > > > > a sound card.  But we'd like to the ASRC can be used by user space directly
> > > > > that user space application can get the output after conversion from ASRC.
> > > >
> > > > That sort of use case would be handled via DPCM at the minute, though
> > > > persuading it to connect two front ends together might be fun (which is
> > > > the sort of reason why we want to push digital information down into
> > > > DAPM and make everything a component).
> > >
> > > Thanks.
> > >
> > > ASRC M2M case needs to run as fast as possible, no sync clock control.
> > > If use sound card to handle ASRC M2M case,  the user application
> > > should be aplay/arecord, then we need to consider xrun issue, buffer
> > > may timeout, sync between aplay and arecord,  these should't be
> > > considered by pure memory to memory operation.
> > >
> > > DPCM may achitect all the audio things in components and sound
> > > card,  it is good. but for the M2M case, it is complcated. not sure
> > > it is doable.
> > >
> >
> > Beside the concern in previous mail,
> >
> > DPCM needs to separate ASRC to be two substreams (playback and capture).
> >
> > But the ASRC needs the sample rate & format of input and output first
> > then start conversion.
> >
> > If the playback controls the rate & format of input,  capture substream
> > controls the rate & format of output,  as a result
> > one substream needs to get information(dma buffer address, size...
> > rate, format) from another substream, then start both substreams in the
> > last substream. How to synchronize these two substreams is a problem.
> > One stream can be released but another stream doesn't know .
> >
> > So I don't think it is a good idea to use DPCM for pure M2M case.
> >
> > So can I persuade you to consider the V4L2 solution?
> >
> 
> Just a summary:
> 
> Basic M2M conversion can work with DPCM, I have tried with some
> workaround to make it work.
> 
> But there are several issues:
> 1. Need to create sound cards.  ASRC module support multi instances, then
> need to create multi sound cards for each instance.

Hm, why can't it be multiple PCM instances instead?

> 2. The ASRC is an entirety but with DPCM we need to separate input port and
> output port to playback substream and capture stream. Synchronous between
> playback substream and capture substream is a problem.
> How to start them and stop them at the same time.

This could be done by enforcing the full duplex and linking the both
PCM streams, I suppose.

> 3. How to handle the xrun issue. pause or resume. which are brought by ALSA.

Doesn't V4L2 handle the overrun/underrun at all?  Also, no resume
support?

Pause and resume are optional in ALSA frame work, you don't need to
implement them unless you want/need.

> So shall we make the decision that we can go to the V4L2 solution?

Honestly speaking, I don't mind much whether it's implemented in V2L4
or not -- at least for the kernel part, we can reorganize / refactor
things internally.  But, the biggest remaining question to me is
whether this user-space interface is the most suitable one.  Is it
well defined, usable and maintained for the audio applications?  Or
is it meant to be a stop-gap for a specific use case?


thanks,

Takashi
Hans Verkuil Aug. 25, 2023, 2:15 p.m. UTC | #20
On 25/08/2023 15:54, Takashi Iwai wrote:
> On Fri, 25 Aug 2023 05:46:43 +0200,
> Shengjiu Wang wrote:
>>
>> On Fri, Aug 25, 2023 at 4:21 AM Mark Brown <broonie@kernel.org> wrote:
>>>
>>> On Thu, Aug 24, 2023 at 07:03:09PM +0200, Takashi Iwai wrote:
>>>> Shengjiu Wang wrote:
>>>
>>>>> But there are several issues:
>>>>> 1. Need to create sound cards.  ASRC module support multi instances, then
>>>>> need to create multi sound cards for each instance.
>>>
>>>> Hm, why can't it be multiple PCM instances instead?
>>>
>>> I'm having a hard time following this one too.
>>>
>>>>> 2. The ASRC is an entirety but with DPCM we need to separate input port and
>>>>> output port to playback substream and capture stream. Synchronous between
>>>>> playback substream and capture substream is a problem.
>>>>> How to start them and stop them at the same time.
>>>
>>>> This could be done by enforcing the full duplex and linking the both
>>>> PCM streams, I suppose.
>>>
>>>>> So shall we make the decision that we can go to the V4L2 solution?
>>>
>>>> Honestly speaking, I don't mind much whether it's implemented in V2L4
>>>> or not -- at least for the kernel part, we can reorganize / refactor
>>>> things internally.  But, the biggest remaining question to me is
>>>> whether this user-space interface is the most suitable one.  Is it
>>>> well defined, usable and maintained for the audio applications?  Or
>>>> is it meant to be a stop-gap for a specific use case?
>>>
>>> I'm having a really hard time summoning much enthusiasm for using v4l
>>> here, it feels like this is heading down the same bodge route as DPCM
>>> but directly as ABI so even harder to fix properly.  That said all the
>>> ALSA APIs are really intended to be used in real time and this sounds
>>> like a non real time application?  I don't fully understand what the
>>> actual use case is here.
>>
>> Thanks for your reply.
>>
>> This asrc memory to memory (memory ->asrc->memory) case is a non
>> real time use case.
>>
>> User fills the input buffer to the asrc module,  after conversion, then asrc
>> sends back the output buffer to user. So it is not a traditional ALSA playback
>> and capture case. I think it is not good to create sound card for it,  it is
>> not a sound card actually.
>>
>> It is a specific use case,  there is no reference in current kernel.
>> v4l2 memory to memory is the closed implementation,  v4l2 current
>> support video, image, radio, tuner, touch devices, so it is not
>> complicated to add support for this specific audio case.
>>
>> Maybe you can go through these patches first.  Because we
>> had implemented the "memory -> asrc ->i2s device-> codec"
>> use case in ALSA.  Now the "memory->asrc->memory" needs
>> to reuse the code in asrc driver, so the first 3 patches is for refining
>> the code to make it can be shared by the "memory->asrc->memory"
>> driver.
>>
>> The main change is in the v4l2 side, A /dev/vl42-audio will be created,
>> user applications only use the ioctl of v4l2 framework.
> 
> Ah, now I'm slowly understanding.  So, what you want is to have an
> interface to perform the batch conversion of a data stream from an
> input to an output?  And ALSA PCM interface doesn't fit fully for that
> purpose because the data handling is batched and it's not like a
> normal PCM streaming?
> 
> Basically the whole M2M arguments are rather subtle.  Those are
> implementation details that can be resolved in several different ways
> in the kernel side.  But the design of the operation is the crucial
> point.
> 
> Maybe we can consider implementing a similar feature in ALSA API, too.
> But it's too far-stretched for now.
> 
> So, if v4l2 interface provides the requested feature (the batched
> audio stream conversion), it's OK to ride on it.

The V4L2 M2M interface is simple: you open a video device and then you can
pass data to the hardware, it processes it and you get the processed data back.

The hardware just processes the data as fast as it can. Each time you open
the video device a new instance is created, and each instance can pass jobs
to the hardware.

Currently it is used for video scalers, deinterlacers, colorspace converters and
codecs, but in the end it is just data in, data out with some job scheduling (fifo)
towards the hardware. So supporting audio using the same core m2m framework wouldn't
be a big deal. We'd probably make a /dev/v4l-audio device for that.

It doesn't come for free: it is a new API, so besides adding support for it, it
also needs to be documented, we would need compliance tests, and very likely I
would want a new virtual driver for this (vim2m.c would be a good template).

Regards,

	Hans
Shengjiu Wang Aug. 30, 2023, 3:11 a.m. UTC | #21
On Fri, Aug 25, 2023 at 10:15 PM Hans Verkuil <hverkuil@xs4all.nl> wrote:
>
> On 25/08/2023 15:54, Takashi Iwai wrote:
> > On Fri, 25 Aug 2023 05:46:43 +0200,
> > Shengjiu Wang wrote:
> >>
> >> On Fri, Aug 25, 2023 at 4:21 AM Mark Brown <broonie@kernel.org> wrote:
> >>>
> >>> On Thu, Aug 24, 2023 at 07:03:09PM +0200, Takashi Iwai wrote:
> >>>> Shengjiu Wang wrote:
> >>>
> >>>>> But there are several issues:
> >>>>> 1. Need to create sound cards.  ASRC module support multi instances, then
> >>>>> need to create multi sound cards for each instance.
> >>>
> >>>> Hm, why can't it be multiple PCM instances instead?
> >>>
> >>> I'm having a hard time following this one too.
> >>>
> >>>>> 2. The ASRC is an entirety but with DPCM we need to separate input port and
> >>>>> output port to playback substream and capture stream. Synchronous between
> >>>>> playback substream and capture substream is a problem.
> >>>>> How to start them and stop them at the same time.
> >>>
> >>>> This could be done by enforcing the full duplex and linking the both
> >>>> PCM streams, I suppose.
> >>>
> >>>>> So shall we make the decision that we can go to the V4L2 solution?
> >>>
> >>>> Honestly speaking, I don't mind much whether it's implemented in V2L4
> >>>> or not -- at least for the kernel part, we can reorganize / refactor
> >>>> things internally.  But, the biggest remaining question to me is
> >>>> whether this user-space interface is the most suitable one.  Is it
> >>>> well defined, usable and maintained for the audio applications?  Or
> >>>> is it meant to be a stop-gap for a specific use case?
> >>>
> >>> I'm having a really hard time summoning much enthusiasm for using v4l
> >>> here, it feels like this is heading down the same bodge route as DPCM
> >>> but directly as ABI so even harder to fix properly.  That said all the
> >>> ALSA APIs are really intended to be used in real time and this sounds
> >>> like a non real time application?  I don't fully understand what the
> >>> actual use case is here.
> >>
> >> Thanks for your reply.
> >>
> >> This asrc memory to memory (memory ->asrc->memory) case is a non
> >> real time use case.
> >>
> >> User fills the input buffer to the asrc module,  after conversion, then asrc
> >> sends back the output buffer to user. So it is not a traditional ALSA playback
> >> and capture case. I think it is not good to create sound card for it,  it is
> >> not a sound card actually.
> >>
> >> It is a specific use case,  there is no reference in current kernel.
> >> v4l2 memory to memory is the closed implementation,  v4l2 current
> >> support video, image, radio, tuner, touch devices, so it is not
> >> complicated to add support for this specific audio case.
> >>
> >> Maybe you can go through these patches first.  Because we
> >> had implemented the "memory -> asrc ->i2s device-> codec"
> >> use case in ALSA.  Now the "memory->asrc->memory" needs
> >> to reuse the code in asrc driver, so the first 3 patches is for refining
> >> the code to make it can be shared by the "memory->asrc->memory"
> >> driver.
> >>
> >> The main change is in the v4l2 side, A /dev/vl42-audio will be created,
> >> user applications only use the ioctl of v4l2 framework.
> >
> > Ah, now I'm slowly understanding.  So, what you want is to have an
> > interface to perform the batch conversion of a data stream from an
> > input to an output?  And ALSA PCM interface doesn't fit fully for that
> > purpose because the data handling is batched and it's not like a
> > normal PCM streaming?
> >
> > Basically the whole M2M arguments are rather subtle.  Those are
> > implementation details that can be resolved in several different ways
> > in the kernel side.  But the design of the operation is the crucial
> > point.
> >
> > Maybe we can consider implementing a similar feature in ALSA API, too.
> > But it's too far-stretched for now.
> >
> > So, if v4l2 interface provides the requested feature (the batched
> > audio stream conversion), it's OK to ride on it.
>
> The V4L2 M2M interface is simple: you open a video device and then you can
> pass data to the hardware, it processes it and you get the processed data back.
>
> The hardware just processes the data as fast as it can. Each time you open
> the video device a new instance is created, and each instance can pass jobs
> to the hardware.
>
> Currently it is used for video scalers, deinterlacers, colorspace converters and
> codecs, but in the end it is just data in, data out with some job scheduling (fifo)
> towards the hardware. So supporting audio using the same core m2m framework wouldn't
> be a big deal. We'd probably make a /dev/v4l-audio device for that.
>
> It doesn't come for free: it is a new API, so besides adding support for it, it
> also needs to be documented, we would need compliance tests, and very likely I
> would want a new virtual driver for this (vim2m.c would be a good template).
>

Thanks all.

I will try to pass the compliance test.  Should the virtual driver be added now?

Best regards
Wang Shengiu