[RFC PATCH 0/8] v4l-utils: add v4l-audioX support
This patch series adds support for v4l-audioX M2M devices.
It is an initial version and it needs a bit more work. Mainly adding support for the new V4L2_CTRL_TYPE_FIXED_POINT, but that requires some more work in the driver patch series.
At least this series will get the basic support in place and adds a vim2m-audio test to the test-media regression test script.
Regards,
Hans
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl --- contrib/freebsd/include/linux/v4l2-controls.h | 9 ++++ contrib/freebsd/include/linux/videodev2.h | 42 +++++++++++++++++++ include/linux/media.h | 2 + include/linux/v4l2-controls.h | 9 ++++ include/linux/videodev2.h | 42 +++++++++++++++++++ utils/common/v4l2-pix-formats.h | 13 ++++++ 6 files changed, 117 insertions(+)
diff --git a/contrib/freebsd/include/linux/v4l2-controls.h b/contrib/freebsd/include/linux/v4l2-controls.h index cbf252bd..3934bb26 100644 --- a/contrib/freebsd/include/linux/v4l2-controls.h +++ b/contrib/freebsd/include/linux/v4l2-controls.h @@ -34,6 +34,7 @@ #define V4L2_CTRL_CLASS_DETECT 0x00a30000 /* Detection controls */ #define V4L2_CTRL_CLASS_CODEC_STATELESS 0x00a40000 /* Stateless codecs controls */ #define V4L2_CTRL_CLASS_COLORIMETRY 0x00a50000 /* Colorimetry controls */ +#define V4L2_CTRL_CLASS_M2M_AUDIO 0x00a60000 /* Audio M2M controls */
/* User-class control IDs */
@@ -3485,6 +3486,14 @@ struct v4l2_ctrl_av1_film_grain { __u8 reserved[4]; };
+#define V4L2_CID_M2M_AUDIO_CLASS_BASE (V4L2_CTRL_CLASS_M2M_AUDIO | 0x900) +#define V4L2_CID_M2M_AUDIO_CLASS (V4L2_CTRL_CLASS_M2M_AUDIO | 1) + +#define V4L2_CID_M2M_AUDIO_SOURCE_RATE (V4L2_CID_M2M_AUDIO_CLASS_BASE + 0) +#define V4L2_CID_M2M_AUDIO_DEST_RATE (V4L2_CID_M2M_AUDIO_CLASS_BASE + 1) +#define V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET (V4L2_CID_M2M_AUDIO_CLASS_BASE + 2) +#define V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET (V4L2_CID_M2M_AUDIO_CLASS_BASE + 3) + /* MPEG-compression definitions kept for backwards compatibility */ #define V4L2_CTRL_CLASS_MPEG V4L2_CTRL_CLASS_CODEC #define V4L2_CID_MPEG_CLASS V4L2_CID_CODEC_CLASS diff --git a/contrib/freebsd/include/linux/videodev2.h b/contrib/freebsd/include/linux/videodev2.h index 3bf0441e..8743381b 100644 --- a/contrib/freebsd/include/linux/videodev2.h +++ b/contrib/freebsd/include/linux/videodev2.h @@ -185,6 +185,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, }; @@ -201,6 +203,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)) @@ -480,6 +483,7 @@ struct v4l2_capability { #define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ #define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ #define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_AUDIO_M2M 0x00000008 /* audio memory to memory */ #define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ #define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ @@ -846,6 +850,29 @@ struct v4l2_pix_format { #define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 3A Parameters */ #define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') /* Rockchip ISP1 3A Statistics */
+/* + * Audio-data formats + * All these audio formats use a fourcc starting with 'AU' + * followed by the SNDRV_PCM_FORMAT_ value from asound.h. + */ +#define V4L2_AUDIO_FMT_S8 v4l2_fourcc('A', 'U', '0', '0') +#define V4L2_AUDIO_FMT_S16_LE v4l2_fourcc('A', 'U', '0', '2') +#define V4L2_AUDIO_FMT_U16_LE v4l2_fourcc('A', 'U', '0', '4') +#define V4L2_AUDIO_FMT_S24_LE v4l2_fourcc('A', 'U', '0', '6') +#define V4L2_AUDIO_FMT_U24_LE v4l2_fourcc('A', 'U', '0', '8') +#define V4L2_AUDIO_FMT_S32_LE v4l2_fourcc('A', 'U', '1', '0') +#define V4L2_AUDIO_FMT_U32_LE v4l2_fourcc('A', 'U', '1', '2') +#define V4L2_AUDIO_FMT_FLOAT_LE v4l2_fourcc('A', 'U', '1', '4') +#define V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE v4l2_fourcc('A', 'U', '1', '8') +#define V4L2_AUDIO_FMT_S24_3LE v4l2_fourcc('A', 'U', '3', '2') +#define V4L2_AUDIO_FMT_U24_3LE v4l2_fourcc('A', 'U', '3', '4') +#define V4L2_AUDIO_FMT_S20_3LE v4l2_fourcc('A', 'U', '3', '6') +#define V4L2_AUDIO_FMT_U20_3LE v4l2_fourcc('A', 'U', '3', '8') + +#define v4l2_fourcc_to_audfmt(fourcc) \ + (snd_pcm_format_t)(((((fourcc) >> 16) & 0xff) - '0') * 10 \ + + ((((fourcc) >> 24) & 0xff) - '0')) + /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
@@ -1854,6 +1881,7 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_STRING = 7, V4L2_CTRL_TYPE_BITMASK = 8, V4L2_CTRL_TYPE_INTEGER_MENU = 9, + V4L2_CTRL_TYPE_FIXED_POINT = 10,
/* Compound types are >= 0x0100 */ V4L2_CTRL_COMPOUND_TYPES = 0x0100, @@ -2396,6 +2424,18 @@ struct v4l2_meta_format { uint32_t buffersize; } __attribute__ ((packed));
+/** + * struct v4l2_audio_format - audio data format definition + * @audioformat: little endian four character code (fourcc) + * @channels: channel numbers + * @buffersize: maximum size in bytes required for data + */ +struct v4l2_audio_format { + uint32_t audioformat; + uint32_t channels; + uint32_t buffersize; +} __attribute__ ((packed)); + /** * struct v4l2_format - stream data format * @type: enum v4l2_buf_type; type of the data stream @@ -2404,6 +2444,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 @@ -2418,6 +2459,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 */ uint8_t raw_data[200]; /* user-defined */ } fmt; }; diff --git a/include/linux/media.h b/include/linux/media.h index b5a77bbf..9c91341e 100644 --- a/include/linux/media.h +++ b/include/linux/media.h @@ -125,6 +125,7 @@ struct media_device_info { #define MEDIA_ENT_F_PROC_VIDEO_ENCODER (MEDIA_ENT_F_BASE + 0x4007) #define MEDIA_ENT_F_PROC_VIDEO_DECODER (MEDIA_ENT_F_BASE + 0x4008) #define MEDIA_ENT_F_PROC_VIDEO_ISP (MEDIA_ENT_F_BASE + 0x4009) +#define MEDIA_ENT_F_PROC_AUDIO_RESAMPLER (MEDIA_ENT_F_BASE + 0x400a)
/* * Switch and bridge entity functions @@ -258,6 +259,7 @@ struct media_links_enum { #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) #define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5) +#define MEDIA_INTF_T_V4L_AUDIO (MEDIA_INTF_T_V4L_BASE + 6)
#define MEDIA_INTF_T_ALSA_BASE 0x00000300 #define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) diff --git a/include/linux/v4l2-controls.h b/include/linux/v4l2-controls.h index cbf252bd..3934bb26 100644 --- a/include/linux/v4l2-controls.h +++ b/include/linux/v4l2-controls.h @@ -34,6 +34,7 @@ #define V4L2_CTRL_CLASS_DETECT 0x00a30000 /* Detection controls */ #define V4L2_CTRL_CLASS_CODEC_STATELESS 0x00a40000 /* Stateless codecs controls */ #define V4L2_CTRL_CLASS_COLORIMETRY 0x00a50000 /* Colorimetry controls */ +#define V4L2_CTRL_CLASS_M2M_AUDIO 0x00a60000 /* Audio M2M controls */
/* User-class control IDs */
@@ -3485,6 +3486,14 @@ struct v4l2_ctrl_av1_film_grain { __u8 reserved[4]; };
+#define V4L2_CID_M2M_AUDIO_CLASS_BASE (V4L2_CTRL_CLASS_M2M_AUDIO | 0x900) +#define V4L2_CID_M2M_AUDIO_CLASS (V4L2_CTRL_CLASS_M2M_AUDIO | 1) + +#define V4L2_CID_M2M_AUDIO_SOURCE_RATE (V4L2_CID_M2M_AUDIO_CLASS_BASE + 0) +#define V4L2_CID_M2M_AUDIO_DEST_RATE (V4L2_CID_M2M_AUDIO_CLASS_BASE + 1) +#define V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET (V4L2_CID_M2M_AUDIO_CLASS_BASE + 2) +#define V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET (V4L2_CID_M2M_AUDIO_CLASS_BASE + 3) + /* MPEG-compression definitions kept for backwards compatibility */ #define V4L2_CTRL_CLASS_MPEG V4L2_CTRL_CLASS_CODEC #define V4L2_CID_MPEG_CLASS V4L2_CID_CODEC_CLASS diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 27680a39..6be8591e 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -151,6 +151,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, }; @@ -167,6 +169,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)) @@ -446,6 +449,7 @@ struct v4l2_capability { #define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ #define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ #define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_AUDIO_M2M 0x00000008 /* audio memory to memory */ #define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ #define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ @@ -812,6 +816,29 @@ struct v4l2_pix_format { #define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 3A Parameters */ #define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') /* Rockchip ISP1 3A Statistics */
+/* + * Audio-data formats + * All these audio formats use a fourcc starting with 'AU' + * followed by the SNDRV_PCM_FORMAT_ value from asound.h. + */ +#define V4L2_AUDIO_FMT_S8 v4l2_fourcc('A', 'U', '0', '0') +#define V4L2_AUDIO_FMT_S16_LE v4l2_fourcc('A', 'U', '0', '2') +#define V4L2_AUDIO_FMT_U16_LE v4l2_fourcc('A', 'U', '0', '4') +#define V4L2_AUDIO_FMT_S24_LE v4l2_fourcc('A', 'U', '0', '6') +#define V4L2_AUDIO_FMT_U24_LE v4l2_fourcc('A', 'U', '0', '8') +#define V4L2_AUDIO_FMT_S32_LE v4l2_fourcc('A', 'U', '1', '0') +#define V4L2_AUDIO_FMT_U32_LE v4l2_fourcc('A', 'U', '1', '2') +#define V4L2_AUDIO_FMT_FLOAT_LE v4l2_fourcc('A', 'U', '1', '4') +#define V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE v4l2_fourcc('A', 'U', '1', '8') +#define V4L2_AUDIO_FMT_S24_3LE v4l2_fourcc('A', 'U', '3', '2') +#define V4L2_AUDIO_FMT_U24_3LE v4l2_fourcc('A', 'U', '3', '4') +#define V4L2_AUDIO_FMT_S20_3LE v4l2_fourcc('A', 'U', '3', '6') +#define V4L2_AUDIO_FMT_U20_3LE v4l2_fourcc('A', 'U', '3', '8') + +#define v4l2_fourcc_to_audfmt(fourcc) \ + (snd_pcm_format_t)(((((fourcc) >> 16) & 0xff) - '0') * 10 \ + + ((((fourcc) >> 24) & 0xff) - '0')) + /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
@@ -1820,6 +1847,7 @@ enum v4l2_ctrl_type { V4L2_CTRL_TYPE_STRING = 7, V4L2_CTRL_TYPE_BITMASK = 8, V4L2_CTRL_TYPE_INTEGER_MENU = 9, + V4L2_CTRL_TYPE_FIXED_POINT = 10,
/* Compound types are >= 0x0100 */ V4L2_CTRL_COMPOUND_TYPES = 0x0100, @@ -2362,6 +2390,18 @@ struct v4l2_meta_format { __u32 buffersize; } __attribute__ ((packed));
+/** + * struct v4l2_audio_format - audio data format definition + * @audioformat: little endian four character code (fourcc) + * @channels: channel numbers + * @buffersize: maximum size in bytes required for data + */ +struct v4l2_audio_format { + __u32 audioformat; + __u32 channels; + __u32 buffersize; +} __attribute__ ((packed)); + /** * struct v4l2_format - stream data format * @type: enum v4l2_buf_type; type of the data stream @@ -2370,6 +2410,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 @@ -2384,6 +2425,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; }; diff --git a/utils/common/v4l2-pix-formats.h b/utils/common/v4l2-pix-formats.h index e8d2e441..db00cf65 100644 --- a/utils/common/v4l2-pix-formats.h +++ b/utils/common/v4l2-pix-formats.h @@ -192,6 +192,19 @@ case V4L2_PIX_FMT_Y210: return "10-bit YUYV Packed"; case V4L2_PIX_FMT_Y212: return "12-bit YUYV Packed"; case V4L2_PIX_FMT_Y216: return "16-bit YUYV Packed"; + case V4L2_AUDIO_FMT_S8: return "8-bit Signed"; + case V4L2_AUDIO_FMT_S16_LE: return "16-bit Signed LE"; + case V4L2_AUDIO_FMT_U16_LE: return "16-bit Unsigned LE"; + case V4L2_AUDIO_FMT_S24_LE: return "24(32)-bit Signed LE"; + case V4L2_AUDIO_FMT_U24_LE: return "24(32)-bit Unsigned LE"; + case V4L2_AUDIO_FMT_S32_LE: return "32-bit Signed LE"; + case V4L2_AUDIO_FMT_U32_LE: return "32-bit Unsigned LE"; + case V4L2_AUDIO_FMT_FLOAT_LE: return "32-bit Float LE"; + case V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE: return "32-bit IEC958 LE"; + case V4L2_AUDIO_FMT_S24_3LE: return "24(24)-bit Signed LE"; + case V4L2_AUDIO_FMT_U24_3LE: return "24(24)-bit Unsigned LE"; + case V4L2_AUDIO_FMT_S20_3LE: return "20(24)-bit Signed LE"; + case V4L2_AUDIO_FMT_U20_3LE: return "20(24)-bit Unsigned LE"; case V4L2_PIX_FMT_MJPEG: return "Motion-JPEG"; case V4L2_PIX_FMT_JPEG: return "JFIF JPEG"; case V4L2_PIX_FMT_DV: return "1394";
Add v4l-audio support to helper headers.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl --- utils/common/cv4l-helpers.h | 7 ++++++ utils/common/v4l-helpers.h | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+)
diff --git a/utils/common/cv4l-helpers.h b/utils/common/cv4l-helpers.h index 91a04146..235368ec 100644 --- a/utils/common/cv4l-helpers.h +++ b/utils/common/cv4l-helpers.h @@ -78,6 +78,13 @@ public: bool has_rds_out() const { return v4l_has_rds_out(this); } bool has_sdr_cap() const { return v4l_has_sdr_cap(this); } bool has_sdr_out() const { return v4l_has_sdr_out(this); } + bool has_touch() const { return v4l_has_touch(this); } + bool has_meta_cap() const { return v4l_has_meta_cap(this); } + bool has_meta_out() const { return v4l_has_meta_out(this); } + bool has_audio_cap() const { return v4l_has_audio_cap(this); } + bool has_audio_out() const { return v4l_has_audio_out(this); } + bool has_audio_m2m() const { return v4l_has_audio_m2m(this); } + bool has_m2m() const { return v4l_has_m2m(this); } bool has_hwseek() const { return v4l_has_hwseek(this); } bool has_rw() const { return v4l_has_rw(this); } bool has_streaming() const { return v4l_has_streaming(this); } diff --git a/utils/common/v4l-helpers.h b/utils/common/v4l-helpers.h index f8e96d58..a01b3e48 100644 --- a/utils/common/v4l-helpers.h +++ b/utils/common/v4l-helpers.h @@ -404,6 +404,26 @@ static inline bool v4l_has_touch(const struct v4l_fd *f) return v4l_g_caps(f) & V4L2_CAP_TOUCH; }
+static inline bool v4l_has_audio_cap(const struct v4l_fd *f) +{ + return v4l_g_caps(f) & V4L2_CAP_AUDIO_M2M; +} + +static inline bool v4l_has_audio_out(const struct v4l_fd *f) +{ + return v4l_g_caps(f) & V4L2_CAP_AUDIO_M2M; +} + +static inline bool v4l_has_audio_m2m(const struct v4l_fd *f) +{ + return v4l_g_caps(f) & V4L2_CAP_AUDIO_M2M; +} + +static inline bool v4l_has_m2m(const struct v4l_fd *f) +{ + return v4l_has_vid_m2m(f) || v4l_has_audio_m2m(f); +} + static inline bool v4l_has_hwseek(const struct v4l_fd *f) { return v4l_g_caps(f) & V4L2_CAP_HW_FREQ_SEEK; @@ -449,6 +469,10 @@ static inline __u32 v4l_determine_type(const struct v4l_fd *f) return V4L2_BUF_TYPE_META_CAPTURE; if (v4l_has_meta_out(f)) return V4L2_BUF_TYPE_META_OUTPUT; + if (v4l_has_audio_cap(f)) + return V4L2_BUF_TYPE_AUDIO_CAPTURE; + if (v4l_has_audio_out(f)) + return V4L2_BUF_TYPE_AUDIO_OUTPUT;
return 0; } @@ -701,6 +725,10 @@ static inline void v4l_format_s_pixelformat(struct v4l2_format *fmt, __u32 pixel case V4L2_BUF_TYPE_META_OUTPUT: fmt->fmt.meta.dataformat = pixelformat; break; + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + fmt->fmt.audio.audioformat = pixelformat; + break; } }
@@ -722,6 +750,9 @@ static inline __u32 v4l_format_g_pixelformat(const struct v4l2_format *fmt) case V4L2_BUF_TYPE_META_CAPTURE: case V4L2_BUF_TYPE_META_OUTPUT: return fmt->fmt.meta.dataformat; + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + return fmt->fmt.audio.audioformat; default: return 0; } @@ -1063,6 +1094,9 @@ v4l_format_g_sizeimage(const struct v4l2_format *fmt, unsigned plane) case V4L2_BUF_TYPE_META_CAPTURE: case V4L2_BUF_TYPE_META_OUTPUT: return plane ? 0 : fmt->fmt.meta.buffersize; + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + return plane ? 0 : fmt->fmt.audio.buffersize; default: return 0; } @@ -1187,12 +1221,22 @@ static inline bool v4l_type_is_meta(unsigned type) type == V4L2_BUF_TYPE_META_OUTPUT; }
+static inline bool v4l_type_is_audio(unsigned type) +{ + return type == V4L2_BUF_TYPE_AUDIO_CAPTURE || + type == V4L2_BUF_TYPE_AUDIO_OUTPUT; +} + static inline unsigned v4l_type_invert(unsigned type) { if (v4l_type_is_planar(type)) return v4l_type_is_output(type) ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + if (v4l_type_is_audio(type)) + return v4l_type_is_output(type) ? + V4L2_BUF_TYPE_AUDIO_CAPTURE : + V4L2_BUF_TYPE_AUDIO_OUTPUT; return v4l_type_is_output(type) ? V4L2_BUF_TYPE_VIDEO_CAPTURE : V4L2_BUF_TYPE_VIDEO_OUTPUT;
The media/v4l2-info sources now understand the new Audio types.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl --- utils/common/media-info.cpp | 3 +++ utils/common/media-info.h | 1 + utils/common/v4l2-info.cpp | 6 ++++++ 3 files changed, 10 insertions(+)
diff --git a/utils/common/media-info.cpp b/utils/common/media-info.cpp index 95e4c74f..060e8b64 100644 --- a/utils/common/media-info.cpp +++ b/utils/common/media-info.cpp @@ -44,6 +44,7 @@ static constexpr struct { { "swradio", MEDIA_TYPE_SDR }, { "v4l-subdev", MEDIA_TYPE_SUBDEV }, { "v4l-touch", MEDIA_TYPE_TOUCH }, + { "v4l-audio", MEDIA_TYPE_AUDIO }, { "media", MEDIA_TYPE_MEDIA }, { "frontend", MEDIA_TYPE_DVB_FRONTEND }, { "demux", MEDIA_TYPE_DVB_DEMUX }, @@ -280,6 +281,7 @@ static constexpr flag_def interface_types_def[] = { { MEDIA_INTF_T_V4L_SUBDEV, "V4L Sub-Device" }, { MEDIA_INTF_T_V4L_SWRADIO, "V4L Software Defined Radio" }, { MEDIA_INTF_T_V4L_TOUCH, "V4L Touch" }, + { MEDIA_INTF_T_V4L_AUDIO, "V4L Audio" },
{ MEDIA_INTF_T_ALSA_PCM_CAPTURE, "ALSA PCM Capture" }, { MEDIA_INTF_T_ALSA_PCM_PLAYBACK, "ALSA PCM Playback" }, @@ -335,6 +337,7 @@ static constexpr flag_def entity_functions_def[] = { { MEDIA_ENT_F_PROC_VIDEO_DECODER, "Video Decoder" }, { MEDIA_ENT_F_PROC_VIDEO_ENCODER, "Video Encoder" }, { MEDIA_ENT_F_PROC_VIDEO_ISP, "Image Signal Processor" }, + { MEDIA_ENT_F_PROC_AUDIO_RESAMPLER, "Audio Resampler" }, { MEDIA_ENT_F_VID_MUX, "Video Muxer" }, { MEDIA_ENT_F_VID_IF_BRIDGE, "Video Interface Bridge" }, { 0, nullptr } diff --git a/utils/common/media-info.h b/utils/common/media-info.h index a862b70b..578040b4 100644 --- a/utils/common/media-info.h +++ b/utils/common/media-info.h @@ -14,6 +14,7 @@ enum media_type { MEDIA_TYPE_RADIO, MEDIA_TYPE_SDR, MEDIA_TYPE_TOUCH, + MEDIA_TYPE_AUDIO, MEDIA_TYPE_SUBDEV, MEDIA_TYPE_DVB_FRONTEND, MEDIA_TYPE_DVB_DEMUX, diff --git a/utils/common/v4l2-info.cpp b/utils/common/v4l2-info.cpp index 4f8c2aa7..00de69ae 100644 --- a/utils/common/v4l2-info.cpp +++ b/utils/common/v4l2-info.cpp @@ -97,6 +97,8 @@ static std::string cap2s(unsigned cap) s += "\t\tExtended Pix Format\n"; if (cap & V4L2_CAP_DEVICE_CAPS) s += "\t\tDevice Capabilities\n"; + if (cap & V4L2_CAP_AUDIO_M2M) + s += "\t\tAudio Memory-to-Memory\n"; return s; }
@@ -191,6 +193,10 @@ std::string buftype2s(int type) return "Metadata Capture"; case V4L2_BUF_TYPE_META_OUTPUT: return "Metadata Output"; + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + return "Audio Capture"; + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + return "Audio Output"; case V4L2_BUF_TYPE_PRIVATE: return "Private"; default:
Detect v4l-audioX devices.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl --- utils/libmedia_dev/get_media_devices.c | 4 ++++ utils/libmedia_dev/get_media_devices.h | 1 + 2 files changed, 5 insertions(+)
diff --git a/utils/libmedia_dev/get_media_devices.c b/utils/libmedia_dev/get_media_devices.c index 21920867..51635acf 100644 --- a/utils/libmedia_dev/get_media_devices.c +++ b/utils/libmedia_dev/get_media_devices.c @@ -226,6 +226,8 @@ static int add_v4l_class(struct media_device_entry *md) md->type = MEDIA_V4L_RADIO; else if (strstr(md->node, "v4l-touch")) md->type = MEDIA_V4L_TOUCH; + else if (strstr(md->node, "v4l-audio")) + md->type = MEDIA_V4L_AUDIO; else if (strstr(md->node, "v4l-subdev")) md->type = MEDIA_V4L_SUBDEV;
@@ -379,6 +381,8 @@ const char *media_device_type(enum device_type type) return "swradio"; case MEDIA_V4L_TOUCH: return "v4l-touch"; + case MEDIA_V4L_AUDIO: + return "v4l-audio"; case MEDIA_V4L_SUBDEV: return "v4l subdevice";
diff --git a/utils/libmedia_dev/get_media_devices.h b/utils/libmedia_dev/get_media_devices.h index 1a62c54e..235a8c4a 100644 --- a/utils/libmedia_dev/get_media_devices.h +++ b/utils/libmedia_dev/get_media_devices.h @@ -37,6 +37,7 @@ enum device_type { MEDIA_V4L_RADIO, MEDIA_V4L_SWRADIO, MEDIA_V4L_TOUCH, + MEDIA_V4L_AUDIO, MEDIA_V4L_SUBDEV,
MEDIA_DVB_VIDEO = 100,
Detect the V4L2_CAP_AUDIO_M2M capability.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl --- utils/libv4l2util/v4l2_driver.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/utils/libv4l2util/v4l2_driver.c b/utils/libv4l2util/v4l2_driver.c index 6b6366fa..0c881b0c 100644 --- a/utils/libv4l2util/v4l2_driver.c +++ b/utils/libv4l2util/v4l2_driver.c @@ -164,6 +164,8 @@ static char *prt_caps(uint32_t caps) strcat (s,"META_OUTPUT "); if(V4L2_CAP_TOUCH & caps) strcat (s,"TOUCH "); + if(V4L2_CAP_AUDIO_M2M & caps) + strcat (s,"AUDIO_M2M "); if(V4L2_CAP_IO_MC & caps) strcat (s,"IO_MC ");
Add support for v4l-audioX devices.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl --- utils/v4l2-ctl/Android.mk | 3 +- utils/v4l2-ctl/meson.build | 1 + utils/v4l2-ctl/v4l2-ctl-audio.cpp | 131 ++++++++++++++++++++++++++ utils/v4l2-ctl/v4l2-ctl-common.cpp | 2 + utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 14 +-- utils/v4l2-ctl/v4l2-ctl.1.in | 4 + utils/v4l2-ctl/v4l2-ctl.cpp | 27 ++++++ utils/v4l2-ctl/v4l2-ctl.h | 18 ++++ 8 files changed, 193 insertions(+), 7 deletions(-) create mode 100644 utils/v4l2-ctl/v4l2-ctl-audio.cpp
diff --git a/utils/v4l2-ctl/Android.mk b/utils/v4l2-ctl/Android.mk index 3078c629..ecb8c5e1 100644 --- a/utils/v4l2-ctl/Android.mk +++ b/utils/v4l2-ctl/Android.mk @@ -22,6 +22,7 @@ LOCAL_SRC_FILES := \ v4l2-ctl-io.cpp v4l2-ctl-stds.cpp v4l2-ctl-vidcap.cpp v4l2-ctl-vidout.cpp \ v4l2-ctl-overlay.cpp v4l2-ctl-vbi.cpp v4l2-ctl-selection.cpp v4l2-ctl-misc.cpp \ v4l2-ctl-streaming.cpp v4l2-ctl-sdr.cpp v4l2-ctl-edid.cpp v4l2-ctl-modes.cpp \ - v4l2-ctl-meta.cpp v4l2-ctl-subdev.cpp v4l2-info.cpp media-info.cpp \ + v4l2-ctl-meta.cpp v4l2-ctl-audio.cpp v4l2-ctl-subdev.cpp \ + v4l2-info.cpp media-info.cpp \ v4l2-tpg-colors.c v4l2-tpg-core.c v4l-stream.c codec-fwht.c include $(BUILD_EXECUTABLE) diff --git a/utils/v4l2-ctl/meson.build b/utils/v4l2-ctl/meson.build index 3e366c6c..62c3c3ee 100644 --- a/utils/v4l2-ctl/meson.build +++ b/utils/v4l2-ctl/meson.build @@ -7,6 +7,7 @@ v4l2_ctl_sources = files( 'v4l2-ctl-edid.cpp', 'v4l2-ctl-io.cpp', 'v4l2-ctl-meta.cpp', + 'v4l2-ctl-audio.cpp', 'v4l2-ctl-misc.cpp', 'v4l2-ctl-modes.cpp', 'v4l2-ctl-overlay.cpp', diff --git a/utils/v4l2-ctl/v4l2-ctl-audio.cpp b/utils/v4l2-ctl/v4l2-ctl-audio.cpp new file mode 100644 index 00000000..23ff17ca --- /dev/null +++ b/utils/v4l2-ctl/v4l2-ctl-audio.cpp @@ -0,0 +1,131 @@ +#include <endian.h> + +#include "v4l2-ctl.h" + +static struct v4l2_format vfmt; /* set_format/get_format */ +static unsigned mbus_code; +static unsigned mbus_code_out; + +void audio_usage() +{ + printf("\nAudio Formats options:\n" + " --list-formats-audio [<mbus_code>] display supported audio capture formats.\n" + " <mbus_code> is an optional media bus code, if the device has\n" + " capability V4L2_CAP_IO_MC then only formats that support this\n" + " media bus code are listed [VIDIOC_ENUM_FMT]\n" + " --get-fmt-audio query the audio capture format [VIDIOC_G_FMT]\n" + " --set-fmt-audio <f> set the audio capture format [VIDIOC_S_FMT]\n" + " parameter is either the format index as reported by\n" + " --list-formats-audio, or the fourcc value as a string\n" + " --try-fmt-audio <f> try the audio capture format [VIDIOC_TRY_FMT]\n" + " parameter is either the format index as reported by\n" + " --list-formats-audio, or the fourcc value as a string\n" + " --list-formats-audio-out [<mbus_code>] display supported audio output formats.\n" + " <mbus_code> is an optional media bus code, if the device has\n" + " capability V4L2_CAP_IO_MC then only formats that support this\n" + " media bus code are listed [VIDIOC_ENUM_FMT]\n" + " --get-fmt-audio-out query the audio output format [VIDIOC_G_FMT]\n" + " --set-fmt-audio-out <f> set the audio output format [VIDIOC_S_FMT]\n" + " parameter is either the format index as reported by\n" + " --list-formats-audio-out, or the fourcc value as a string\n" + " --try-fmt-audio-out <f> try the audio output format [VIDIOC_TRY_FMT]\n" + " parameter is either the format index as reported by\n" + " --list-formats-audio-out, or the fourcc value as a string\n" + ); +} + +void audio_cmd(int ch, char *optarg) +{ + switch (ch) { + case OptSetAudioFormat: + case OptTryAudioFormat: + case OptSetAudioOutFormat: + case OptTryAudioOutFormat: + if (strlen(optarg) == 0) { + audio_usage(); + std::exit(EXIT_FAILURE); + } else if (strlen(optarg) == 4) { + vfmt.fmt.audio.audioformat = v4l2_fourcc(optarg[0], + optarg[1], optarg[2], optarg[3]); + } else { + vfmt.fmt.audio.audioformat = strtol(optarg, nullptr, 0); + } + break; + case OptListAudioFormats: + if (optarg) + mbus_code = strtoul(optarg, nullptr, 0); + break; + case OptListAudioOutFormats: + if (optarg) + mbus_code_out = strtoul(optarg, nullptr, 0); + break; + } +} + +static void __audio_set(cv4l_fd &_fd, bool set, bool _try, __u32 type) +{ + struct v4l2_format in_vfmt; + int fd = _fd.g_fd(); + int ret; + + if (!set && !_try) + return; + + in_vfmt.type = type; + in_vfmt.fmt.audio.audioformat = vfmt.fmt.audio.audioformat; + + if (in_vfmt.fmt.audio.audioformat < 256) { + struct v4l2_fmtdesc fmt = {}; + + fmt.index = in_vfmt.fmt.audio.audioformat; + fmt.type = in_vfmt.type; + + if (doioctl(fd, VIDIOC_ENUM_FMT, &fmt)) + fmt.pixelformat = 0; + + in_vfmt.fmt.audio.audioformat = fmt.pixelformat; + } + + if (set) + ret = doioctl(fd, VIDIOC_S_FMT, &in_vfmt); + else + ret = doioctl(fd, VIDIOC_TRY_FMT, &in_vfmt); + if (ret == 0 && (verbose || _try)) + printfmt(fd, in_vfmt); +} + +void audio_set(cv4l_fd &_fd) +{ + __audio_set(_fd, options[OptSetAudioFormat], options[OptTryAudioFormat], + V4L2_BUF_TYPE_AUDIO_CAPTURE); + __audio_set(_fd, options[OptSetAudioOutFormat], + options[OptTryAudioOutFormat], V4L2_BUF_TYPE_AUDIO_OUTPUT); +} + +static void __audio_get(cv4l_fd &fd, __u32 type) +{ + vfmt.type = type; + if (doioctl(fd.g_fd(), VIDIOC_G_FMT, &vfmt) == 0) + printfmt(fd.g_fd(), vfmt); +} + +void audio_get(cv4l_fd &fd) +{ + if (options[OptGetAudioFormat]) + __audio_get(fd, V4L2_BUF_TYPE_AUDIO_CAPTURE); + if (options[OptGetAudioOutFormat]) + __audio_get(fd, V4L2_BUF_TYPE_AUDIO_OUTPUT); +} + +void audio_list(cv4l_fd &fd) +{ + if (options[OptListAudioFormats]) { + printf("ioctl: VIDIOC_ENUM_FMT\n"); + print_video_formats(fd, V4L2_BUF_TYPE_AUDIO_CAPTURE, mbus_code); + } + + if (options[OptListAudioOutFormats]) { + printf("ioctl: VIDIOC_ENUM_FMT\n"); + print_video_formats(fd, V4L2_BUF_TYPE_AUDIO_OUTPUT, mbus_code_out); + } +} diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp index 0370708b..c089c332 100644 --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp @@ -79,6 +79,7 @@ void common_usage() " --help-all all options\n" " --help-io input/output options\n" " --help-meta metadata format options\n" + " --help-audio audio format options\n" " --help-misc miscellaneous options\n" " --help-overlay overlay format options\n" " --help-sdr SDR format options\n" @@ -123,6 +124,7 @@ static const char *prefixes[] = { "swradio", "v4l-subdev", "v4l-touch", + "v4l-audio", "media", nullptr }; diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp index 63522e87..18dd2c9b 100644 --- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp @@ -1857,7 +1857,8 @@ static void streaming_set_cap(cv4l_fd &fd, cv4l_fd &exp_fd) if (!(capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_META_CAPTURE | V4L2_CAP_SDR_CAPTURE | - V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE))) { + V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE | + V4L2_CAP_AUDIO_M2M))) { fprintf(stderr, "unsupported stream type\n"); return; } @@ -2155,7 +2156,7 @@ static FILE *open_input_file(cv4l_fd &fd, __u32 type)
static void streaming_set_out(cv4l_fd &fd, cv4l_fd &exp_fd) { - __u32 type = fd.has_vid_m2m() ? v4l_type_invert(fd.g_type()) : fd.g_type(); + __u32 type = fd.has_m2m() ? v4l_type_invert(fd.g_type()) : fd.g_type(); cv4l_queue q(type, out_memory); cv4l_queue exp_q(exp_fd.g_type(), V4L2_MEMORY_MMAP); int fd_flags = fcntl(fd.g_fd(), F_GETFL); @@ -2171,7 +2172,8 @@ static void streaming_set_out(cv4l_fd &fd, cv4l_fd &exp_fd) if (!(capabilities & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VBI_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_SDR_OUTPUT | V4L2_CAP_META_OUTPUT | - V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE))) { + V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE | + V4L2_CAP_AUDIO_M2M))) { fprintf(stderr, "unsupported stream type\n"); return; } @@ -2711,7 +2713,7 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd) fd.g_fmt(fmt[OUT], out.g_type()); fd.g_fmt(fmt[CAP], in.g_type());
- if (!fd.has_vid_m2m()) { + if (!fd.has_m2m()) { fprintf(stderr, "unsupported m2m stream type\n"); return; } @@ -2761,7 +2763,7 @@ static void streaming_set_cap2out(cv4l_fd &fd, cv4l_fd &out_fd) bool use_poll = options[OptStreamPoll]; bool use_dmabuf = options[OptStreamDmaBuf] || options[OptStreamOutDmaBuf]; bool use_userptr = options[OptStreamUser] && options[OptStreamOutUser]; - __u32 out_type = out_fd.has_vid_m2m() ? v4l_type_invert(out_fd.g_type()) : out_fd.g_type(); + __u32 out_type = out_fd.has_m2m() ? v4l_type_invert(out_fd.g_type()) : out_fd.g_type(); cv4l_queue in(fd.g_type(), memory); cv4l_queue out(out_type, out_memory); fps_timestamps fps_ts[2]; @@ -3000,7 +3002,7 @@ void streaming_list(cv4l_fd &fd, cv4l_fd &out_fd) list_buffers(fd, fd.g_type());
if (options[OptListBuffersOut]) - list_buffers(*p_out_fd, p_out_fd->has_vid_m2m() ? + list_buffers(*p_out_fd, p_out_fd->has_m2m() ? v4l_type_invert(p_out_fd->g_type()) : p_out_fd->g_type());
if (options[OptStreamBufCaps]) diff --git a/utils/v4l2-ctl/v4l2-ctl.1.in b/utils/v4l2-ctl/v4l2-ctl.1.in index 40817a82..82463244 100644 --- a/utils/v4l2-ctl/v4l2-ctl.1.in +++ b/utils/v4l2-ctl/v4l2-ctl.1.in @@ -32,6 +32,10 @@ wrapper library. \fB-h\fR, \fB--help\fR Prints the help message. .TP +\fB--help-audio\fR +Prints the help message for all options that get/set/list memory-to-memory audio +formats. +.TP \fB--help-io\fR Prints the help message for all options that get/set/list inputs and outputs, both video and audio. diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp index 4cd84f78..d3f96bef 100644 --- a/utils/v4l2-ctl/v4l2-ctl.cpp +++ b/utils/v4l2-ctl/v4l2-ctl.cpp @@ -76,6 +76,7 @@ static struct option long_options[] = { {"help-vbi", no_argument, nullptr, OptHelpVbi}, {"help-sdr", no_argument, nullptr, OptHelpSdr}, {"help-meta", no_argument, nullptr, OptHelpMeta}, + {"help-audio", no_argument, nullptr, OptHelpAudio}, {"help-subdev", no_argument, nullptr, OptHelpSubDev}, {"help-selection", no_argument, nullptr, OptHelpSelection}, {"help-misc", no_argument, nullptr, OptHelpMisc}, @@ -111,6 +112,8 @@ static struct option long_options[] = { {"list-formats-out-ext", optional_argument, nullptr, OptListOutFormatsExt}, {"list-formats-meta", optional_argument, nullptr, OptListMetaFormats}, {"list-formats-meta-out", optional_argument, nullptr, OptListMetaOutFormats}, + {"list-formats-audio", optional_argument, nullptr, OptListAudioFormats}, + {"list-formats-audio-out", optional_argument, nullptr, OptListAudioOutFormats}, {"list-subdev-mbus-codes", optional_argument, nullptr, OptListSubDevMBusCodes}, {"list-subdev-framesizes", required_argument, nullptr, OptListSubDevFrameSizes}, {"list-subdev-frameintervals", required_argument, nullptr, OptListSubDevFrameIntervals}, @@ -166,6 +169,12 @@ static struct option long_options[] = { {"get-fmt-meta-out", no_argument, nullptr, OptGetMetaOutFormat}, {"set-fmt-meta-out", required_argument, nullptr, OptSetMetaOutFormat}, {"try-fmt-meta-out", required_argument, nullptr, OptTryMetaOutFormat}, + {"get-fmt-audio", no_argument, nullptr, OptGetAudioFormat}, + {"set-fmt-audio", required_argument, nullptr, OptSetAudioFormat}, + {"try-fmt-audio", required_argument, nullptr, OptTryAudioFormat}, + {"get-fmt-audio-out", no_argument, nullptr, OptGetAudioOutFormat}, + {"set-fmt-audio-out", required_argument, nullptr, OptSetAudioOutFormat}, + {"try-fmt-audio-out", required_argument, nullptr, OptTryAudioOutFormat}, {"get-subdev-fmt", optional_argument, nullptr, OptGetSubDevFormat}, {"set-subdev-fmt", required_argument, nullptr, OptSetSubDevFormat}, {"try-subdev-fmt", required_argument, nullptr, OptTrySubDevFormat}, @@ -233,6 +242,8 @@ static struct option long_options[] = { {"list-buffers-sdr-out", no_argument, nullptr, OptListBuffersSdrOut}, {"list-buffers-meta", no_argument, nullptr, OptListBuffersMeta}, {"list-buffers-meta-out", no_argument, nullptr, OptListBuffersMetaOut}, + {"list-buffers-audio", no_argument, nullptr, OptListBuffersAudio}, + {"list-buffers-audio-out", no_argument, nullptr, OptListBuffersAudioOut}, {"stream-count", required_argument, nullptr, OptStreamCount}, {"stream-skip", required_argument, nullptr, OptStreamSkip}, {"stream-loop", no_argument, nullptr, OptStreamLoop}, @@ -287,6 +298,7 @@ static void usage_all() vbi_usage(); sdr_usage(); meta_usage(); + audio_usage(); subdev_usage(); selection_usage(); misc_usage(); @@ -523,6 +535,13 @@ void printfmt(int fd, const struct v4l2_format &vfmt) printfmtname(fd, vfmt.type, vfmt.fmt.meta.dataformat).c_str()); printf("\tBuffer Size : %u\n", vfmt.fmt.meta.buffersize); break; + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + printf("\tAudio Format : '%s'%s\n", fcc2s(vfmt.fmt.audio.audioformat).c_str(), + printfmtname(fd, vfmt.type, vfmt.fmt.audio.audioformat).c_str()); + printf("\tChannels : %u\n", vfmt.fmt.audio.channels); + printf("\tBuffer Size : %u\n", vfmt.fmt.audio.buffersize); + break; } }
@@ -1213,6 +1232,9 @@ int main(int argc, char **argv) case OptHelpMeta: meta_usage(); return 0; + case OptHelpAudio: + audio_usage(); + return 0; case OptHelpSubDev: subdev_usage(); return 0; @@ -1284,6 +1306,7 @@ int main(int argc, char **argv) vbi_cmd(ch, optarg); sdr_cmd(ch, optarg); meta_cmd(ch, optarg); + audio_cmd(ch, optarg); subdev_cmd(ch, optarg); selection_cmd(ch, optarg); misc_cmd(ch, optarg); @@ -1315,6 +1338,7 @@ int main(int argc, char **argv) case MEDIA_TYPE_RADIO: case MEDIA_TYPE_SDR: case MEDIA_TYPE_TOUCH: + case MEDIA_TYPE_AUDIO: case MEDIA_TYPE_SUBDEV: break; default: @@ -1480,6 +1504,7 @@ int main(int argc, char **argv) vbi_set(c_fd); sdr_set(c_fd); meta_set(c_fd); + audio_set(c_fd); subdev_set(c_fd); selection_set(c_fd); misc_set(c_fd); @@ -1497,6 +1522,7 @@ int main(int argc, char **argv) vbi_get(c_fd); sdr_get(c_fd); meta_get(c_fd); + audio_get(c_fd); subdev_get(c_fd); selection_get(c_fd); misc_get(c_fd); @@ -1513,6 +1539,7 @@ int main(int argc, char **argv) vbi_list(c_fd); sdr_list(c_fd); meta_list(c_fd); + audio_list(c_fd); subdev_list(c_fd); streaming_list(c_fd, c_out_fd);
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h index cc7f1184..b9e7c352 100644 --- a/utils/v4l2-ctl/v4l2-ctl.h +++ b/utils/v4l2-ctl/v4l2-ctl.h @@ -86,6 +86,8 @@ enum Option { OptGetSdrOutFormat, OptGetMetaFormat, OptGetMetaOutFormat, + OptGetAudioFormat, + OptGetAudioOutFormat, OptGetSubDevFormat, OptSetSlicedVbiOutFormat, OptSetOverlayFormat, @@ -95,6 +97,8 @@ enum Option { OptSetSdrOutFormat, OptSetMetaFormat, OptSetMetaOutFormat, + OptSetAudioFormat, + OptSetAudioOutFormat, OptSetSubDevFormat, OptTryVideoOutFormat, OptTrySlicedVbiOutFormat, @@ -107,6 +111,8 @@ enum Option { OptTrySdrOutFormat, OptTryMetaFormat, OptTryMetaOutFormat, + OptTryAudioFormat, + OptTryAudioOutFormat, OptTrySubDevFormat, OptAll, OptListStandards, @@ -122,6 +128,8 @@ enum Option { OptListOutFormatsExt, OptListMetaFormats, OptListMetaOutFormats, + OptListAudioFormats, + OptListAudioOutFormats, OptListSubDevMBusCodes, OptListSubDevFrameSizes, OptListSubDevFrameIntervals, @@ -210,6 +218,8 @@ enum Option { OptListBuffersSdrOut, OptListBuffersMeta, OptListBuffersMetaOut, + OptListBuffersAudio, + OptListBuffersAudioOut, OptStreamCount, OptStreamSkip, OptStreamLoop, @@ -255,6 +265,7 @@ enum Option { OptHelpVbi, OptHelpSdr, OptHelpMeta, + OptHelpAudio, OptHelpSubDev, OptHelpSelection, OptHelpMisc, @@ -418,6 +429,13 @@ void meta_list(cv4l_fd &fd); void print_meta_buffer(FILE *f, cv4l_buffer &buf, cv4l_fmt &fmt, cv4l_queue &q); void meta_fillbuffer(cv4l_buffer &buf, cv4l_fmt &fmt, cv4l_queue &q);
+// v4l2-ctl-audio.cpp +void audio_usage(void); +void audio_cmd(int ch, char *optarg); +void audio_set(cv4l_fd &fd); +void audio_get(cv4l_fd &fd); +void audio_list(cv4l_fd &fd); + // v4l2-ctl-subdev.cpp void subdev_usage(void); void subdev_cmd(int ch, char *optarg);
Support compliance testing of v4l-audioX devices.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl --- utils/v4l2-compliance/v4l2-compliance.1.in | 7 ++++++ utils/v4l2-compliance/v4l2-compliance.cpp | 16 +++++++++--- utils/v4l2-compliance/v4l2-compliance.h | 3 ++- utils/v4l2-compliance/v4l2-test-buffers.cpp | 10 +++++--- utils/v4l2-compliance/v4l2-test-formats.cpp | 28 +++++++++++++++++++++ utils/v4l2-compliance/v4l2-test-media.cpp | 1 + 6 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/utils/v4l2-compliance/v4l2-compliance.1.in b/utils/v4l2-compliance/v4l2-compliance.1.in index 89d7e482..f798da3a 100644 --- a/utils/v4l2-compliance/v4l2-compliance.1.in +++ b/utils/v4l2-compliance/v4l2-compliance.1.in @@ -81,6 +81,13 @@ Otherwise if \fB-z\fR was specified earlier, then \fI<dev>\fR is the entity name or interface ID (if prefixed with 0x) as found in the topology of the media device with the bus info string as specified by the \fB-z\fR option. .TP +\fB-A\fR, \fB--audio-device\fR \fI<dev>\fR +Use device \fI<dev>\fR as the audio memory-2-memory device. If \fI<dev>\fR is a number, +then /dev/v4l-audio\fI<dev>\fR is used. +Otherwise if \fB-z\fR was specified earlier, then \fI<dev>\fR is the entity name +or interface ID (if prefixed with 0x) as found in the topology of the media device +with the bus info string as specified by the \fB-z\fR option. +.TP \fB-u\fR, \fB--subdev-device\fR \fI<dev>\fR Use device \fI<dev>\fR as the v4l-subdevX device. If \fI<dev>\fR is a number, then /dev/v4l-subdev\fI<dev>\fR is used. Otherwise if \fB-z\fR was specified earlier, then \fI<dev>\fR is the entity name diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index 29475d6b..f751b01e 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -43,6 +43,7 @@ case is used to retrieve a setting. */ enum Option { OptStreamAllIO = 'a', + OptSetAudioDevice = 'A', OptStreamAllColorTest = 'c', OptColor = 'C', OptSetDevice = 'd', @@ -124,6 +125,7 @@ static struct option long_options[] = { {"subdev-device", required_argument, nullptr, OptSetSubDevDevice}, {"expbuf-device", required_argument, nullptr, OptSetExpBufDevice}, {"touch-device", required_argument, nullptr, OptSetTouchDevice}, + {"audio-device", required_argument, nullptr, OptSetAudioDevice}, {"media-device", required_argument, nullptr, OptSetMediaDevice}, {"media-device-only", required_argument, nullptr, OptSetMediaDeviceOnly}, {"media-bus-info", required_argument, nullptr, OptMediaBusInfo}, @@ -198,6 +200,10 @@ static void usage() printf(" Use device <dev> as the touch device.\n"); printf(" If <dev> starts with a digit, then /dev/v4l-touch<dev> is used.\n"); printf(" See the -d description of how <dev> is used in combination with -z.\n"); + printf(" -A, --audio-device <dev>\n"); + printf(" Use device <dev> as the audio M2M device.\n"); + printf(" If <dev> starts with a digit, then /dev/v4l-audio<dev> is used.\n"); + printf(" See the -d description of how <dev> is used in combination with -z.\n"); printf(" -u, --subdev-device <dev>\n"); printf(" Use device <dev> as the v4l-subdev device.\n"); printf(" If <dev> starts with a digit, then /dev/v4l-subdev<dev> is used.\n"); @@ -639,7 +645,7 @@ static int testCap(struct node *node) V4L2_CAP_SDR_OUTPUT | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_MODULATOR | V4L2_CAP_META_OUTPUT; const __u32 overlay_caps = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_OVERLAY; - const __u32 m2m_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE; + const __u32 m2m_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_AUDIO_M2M; const __u32 io_caps = V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; const __u32 mplane_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE; @@ -982,6 +988,7 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_ node.is_radio = type == MEDIA_TYPE_RADIO; node.is_sdr = type == MEDIA_TYPE_SDR; node.is_touch = type == MEDIA_TYPE_TOUCH; + node.is_audio = type == MEDIA_TYPE_AUDIO;
if (node.is_v4l2()) { doioctl(&node, VIDIOC_QUERYCAP, &vcap); @@ -1034,13 +1041,13 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_ V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_RDS_CAPTURE | V4L2_CAP_SDR_CAPTURE | - V4L2_CAP_META_CAPTURE)) + V4L2_CAP_META_CAPTURE | V4L2_CAP_AUDIO_M2M)) node.can_capture = true; if (node.g_caps() & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_RDS_OUTPUT | V4L2_CAP_SDR_OUTPUT | - V4L2_CAP_META_OUTPUT)) + V4L2_CAP_META_OUTPUT | V4L2_CAP_AUDIO_M2M)) node.can_output = true; if (node.g_caps() & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE)) @@ -1693,6 +1700,9 @@ int main(int argc, char **argv) case OptSetTouchDevice: device = make_devname(optarg, "v4l-touch", media_bus_info); break; + case OptSetAudioDevice: + device = make_devname(optarg, "v4l-audio", media_bus_info); + break; case OptSetSubDevDevice: device = make_devname(optarg, "v4l-subdev", media_bus_info); break; diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index 7e3860c8..1e83fba3 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -102,7 +102,7 @@ using frmsizes_count_map = std::map<__u32, unsigned>;
struct base_node;
-#define V4L2_BUF_TYPE_LAST V4L2_BUF_TYPE_META_OUTPUT +#define V4L2_BUF_TYPE_LAST V4L2_BUF_TYPE_AUDIO_OUTPUT
struct base_node { bool is_video; @@ -111,6 +111,7 @@ struct base_node { bool is_sdr; bool is_meta; bool is_touch; + bool is_audio; bool is_m2m; bool is_io_mc; bool is_planar; diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp index 6d592c9b..d5c8d17c 100644 --- a/utils/v4l2-compliance/v4l2-test-buffers.cpp +++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp @@ -235,12 +235,14 @@ public: if (v4l_type_is_output(g_type())) fill_output_buf(fill_bytesused); err = node->qbuf(*this); - if (err == 0 && - v4l_type_is_video(g_type()) && v4l_type_is_output(g_type())) { - fail_on_test(g_field() == V4L2_FIELD_ANY); + if (err) + return err; + if (v4l_type_is_output(g_type())) { + if (v4l_type_is_video(g_type())) + fail_on_test(g_field() == V4L2_FIELD_ANY); buffer_info[g_timestamp()] = buf; } - return err; + return 0; } int qbuf(node *node, const cv4l_queue &q) { diff --git a/utils/v4l2-compliance/v4l2-test-formats.cpp b/utils/v4l2-compliance/v4l2-test-formats.cpp index 8a16613c..adec678a 100644 --- a/utils/v4l2-compliance/v4l2-test-formats.cpp +++ b/utils/v4l2-compliance/v4l2-test-formats.cpp @@ -43,6 +43,8 @@ static constexpr __u32 buftype2cap[] = { V4L2_CAP_SDR_OUTPUT, V4L2_CAP_META_CAPTURE, V4L2_CAP_META_OUTPUT, + V4L2_CAP_AUDIO_M2M, + V4L2_CAP_AUDIO_M2M, };
static int testEnumFrameIntervals(struct node *node, __u32 pixfmt, @@ -330,6 +332,8 @@ int testEnumFormats(struct node *node) case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: case V4L2_BUF_TYPE_SDR_CAPTURE: case V4L2_BUF_TYPE_SDR_OUTPUT: + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: if (ret && (node->g_caps() & buftype2cap[type])) return fail("%s cap set, but no %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); @@ -447,6 +451,7 @@ static int testFormatsType(struct node *node, int ret, unsigned type, struct v4 struct v4l2_sliced_vbi_format &sliced = fmt.fmt.sliced; struct v4l2_sdr_format &sdr = fmt.fmt.sdr; struct v4l2_meta_format &meta = fmt.fmt.meta; + struct v4l2_audio_format &audio = fmt.fmt.audio; unsigned min_data_samples; unsigned min_sampling_rate; v4l2_std_id std; @@ -591,6 +596,13 @@ static int testFormatsType(struct node *node, int ret, unsigned type, struct v4 meta.dataformat, fcc2s(meta.dataformat).c_str(), type); fail_on_test(meta.buffersize == 0); break; + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + if (map.find(audio.audioformat) == map.end()) + return fail("audioformat %08x (%s) for buftype %d not reported by ENUM_FMT\n", + audio.audioformat, fcc2s(audio.audioformat).c_str(), type); + fail_on_test(audio.buffersize == 0); + break; case V4L2_BUF_TYPE_PRIVATE: break; } @@ -626,6 +638,8 @@ int testGetFormats(struct node *node) case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: case V4L2_BUF_TYPE_SDR_CAPTURE: case V4L2_BUF_TYPE_SDR_OUTPUT: + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: if (ret && (node->g_caps() & buftype2cap[type])) return fail("%s cap set, but no %s formats defined\n", buftype2s(type).c_str(), buftype2s(type).c_str()); @@ -703,6 +717,9 @@ static bool matchFormats(const struct v4l2_format &f1, const struct v4l2_format case V4L2_BUF_TYPE_META_CAPTURE: case V4L2_BUF_TYPE_META_OUTPUT: return !memcmp(&f1.fmt.meta, &f2.fmt.meta, sizeof(f1.fmt.meta)); + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + return !memcmp(&f1.fmt.audio, &f2.fmt.audio, sizeof(f1.fmt.audio));
} return false; @@ -782,6 +799,10 @@ int testTryFormats(struct node *node) case V4L2_BUF_TYPE_META_OUTPUT: pixelformat = fmt.fmt.meta.dataformat; break; + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + pixelformat = fmt.fmt.audio.audioformat; + break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: pixelformat = fmt.fmt.pix_mp.pixelformat; @@ -860,6 +881,9 @@ static int testM2MFormats(struct node *node) fail_on_test(node->g_fmt(fmt_out, out_type)); fail_on_test(node->g_fmt(fmt_cap, cap_type));
+ if (node->has_audio_m2m()) + return 0; + /* * JPEG codec have fixed colorspace, so these tests * are different compared to other m2m devices. @@ -1132,6 +1156,10 @@ int testSetFormats(struct node *node) case V4L2_BUF_TYPE_META_OUTPUT: pixelformat = fmt_set.fmt.meta.dataformat; break; + case V4L2_BUF_TYPE_AUDIO_CAPTURE: + case V4L2_BUF_TYPE_AUDIO_OUTPUT: + pixelformat = fmt_set.fmt.audio.audioformat; + break; case V4L2_BUF_TYPE_SDR_CAPTURE: case V4L2_BUF_TYPE_SDR_OUTPUT: pixelformat = fmt_set.fmt.sdr.pixelformat; diff --git a/utils/v4l2-compliance/v4l2-test-media.cpp b/utils/v4l2-compliance/v4l2-test-media.cpp index 52ab7fb8..ee1d03e0 100644 --- a/utils/v4l2-compliance/v4l2-test-media.cpp +++ b/utils/v4l2-compliance/v4l2-test-media.cpp @@ -573,6 +573,7 @@ void walkTopology(struct node &node, struct node &expbuf_node, case MEDIA_TYPE_RADIO: case MEDIA_TYPE_SDR: case MEDIA_TYPE_TOUCH: + case MEDIA_TYPE_AUDIO: case MEDIA_TYPE_SUBDEV: break; default:
Run v4l2-compliance for the vim2m-audio driver.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl --- contrib/test/test-media | 88 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-)
diff --git a/contrib/test/test-media b/contrib/test/test-media index afe20760..1186f02f 100755 --- a/contrib/test/test-media +++ b/contrib/test/test-media @@ -7,6 +7,7 @@ vidtv=0 vivid=0 vim2m=0 +vim2m_audio=0 vimc=0 vicodec=0 cec=0 @@ -53,13 +54,14 @@ if [ -z "$1" ]; then echo Test Targets: echo "vivid: test the vivid driver" echo "vim2m: test the vim2m driver" + echo "vim2m-audio: test the vim2m-audio driver" echo "vimc: test the vimc driver" echo "vicodec: test the vicodec driver" echo "vidtv: test the vidtv driver" echo "cec: adds the vivid CEC compliance tests, except for the CEC standby/wakeup tests." echo "cec-pwr: adds the vivid CEC compliance tests, including the CEC standby/wakeup tests." - echo "all: equals 'vivid vim2m vimc vicodec vidtv cec cec-pwr'" - echo "mc: equals 'vivid vim2m vimc vicodec vidtv'" + echo "all: equals 'vivid vim2m vim2m-audio vimc vicodec vidtv cec cec-pwr'" + echo "mc: equals 'vivid vim2m vim2m-audio vimc vicodec vidtv'" exit 0 fi
@@ -116,6 +118,7 @@ while [ ! -z "$1" ]; do vidtv=1 vivid=1 vim2m=1 + vim2m_audio=1 vimc=1 vicodec=1 cec=1 @@ -124,6 +127,7 @@ while [ ! -z "$1" ]; do mc) vivid=1 vim2m=1 + vim2m_audio=1 vimc=1 vicodec=1 vidtv=1 @@ -137,6 +141,9 @@ while [ ! -z "$1" ]; do vim2m) vim2m=1 ;; + vim2m-audio) + vim2m_audio=1 + ;; vimc) vimc=1 ;; @@ -421,6 +428,83 @@ if [ $vim2m -eq 1 -a $setup -eq 0 ]; then echo fi
+ +if [ $vim2m_audio -eq 1 ]; then + rmmod vim2m-audio 2&>/dev/null + modprobe vim2m-audio + sleep $modprobe_time + dmesg -n notice + + if ! $v4l2_ctl -z platform:vim2m-audio ; then + echo "FAIL: the vim2m-audio module failed to load" | tee -a $tmp + echo "Grand Total for vim2m-audio: Succeeded: 0, Failed: 1, Warnings: 0" | tee -a $tmp + echo "Final Summary: 1, Succeeded: 0, Failed: 1, Warnings: 0" + rmmod vivid + exit 0 + fi +fi + +if [ $vim2m_audio -eq 1 -a $setup -eq 0 ]; then + echo + echo vim2m-audio compliance tests | tee /dev/kmsg + echo + date + stdbuf -oL $v4l2_compliance -m platform:vim2m-audio -z platform:vivid-002 -e vivid-002-vid-cap -s10 -P -a 2>&1 | tee -a $tmp + echo + echo + echo + echo + echo + echo + echo + echo + echo + echo unbind vim2m-audio | tee /dev/kmsg + echo + echo -n vim2m-audio.0 >/sys/bus/platform/drivers/vim2m-audio/unbind + sleep $unbind_time + echo + echo rebind vim2m-audio | tee /dev/kmsg + echo + echo -n vim2m-audio.0 >/sys/bus/platform/drivers/vim2m-audio/bind + sleep 1 + echo + echo second unbind vim2m-audio | tee /dev/kmsg + echo + for i in `$v4l2_ctl -z platform:vim2m-audio --list-devices`; do + let "t = 1 + $RANDOM / 4096" + echo $i: sleep ${t}s + sleep $t <$i & + done + sleep 1 + echo + echo -n vim2m-audio.0 >/sys/bus/platform/drivers/vim2m-audio/unbind + sleep $reunbind_time + echo + echo rmmod vim2m-audio | tee /dev/kmsg + echo + rmmod vim2m-audio + sleep $rmmod_time + if [ $kmemleak -eq 1 ]; then + echo + echo kmemleak results for vim2m-audio: + echo + echo scan >/sys/kernel/debug/kmemleak + cat /sys/kernel/debug/kmemleak + echo + echo end of kmemleak results + echo clear >/sys/kernel/debug/kmemleak + fi + echo + echo + echo + echo + echo + echo + echo + echo +fi + if [ $vimc -eq 1 ]; then rmmod vimc 2&>/dev/null modprobe vimc
participants (1)
-
Hans Verkuil