diff mbox series

[master/scarthgap,1/2] v4l-utils: Drop old recipe for v1.24.1

Message ID 20240618121743.2698489-1-j-luthra@ti.com
State Accepted
Delegated to: Ryan Eatmon
Headers show
Series [master/scarthgap,1/2] v4l-utils: Drop old recipe for v1.24.1 | expand

Commit Message

Jai Luthra June 18, 2024, 12:17 p.m. UTC
In scarthgap/master meta-oe recipe for v4l-utils has moved to v1.26
which has support for latest routing and media graph APIs.

So we can now drop support for v1.24.1 and custom routing patches from
the meta-arago layer.

Signed-off-by: Jai Luthra <j-luthra@ti.com>
---
 ...-Don-t-install-libmediactl-and-libv4.patch |   43 -
 ...-add-support-for-RGBIr-bayer-formats.patch |   61 -
 ...-ctl-Add-routing-and-streams-support.patch |  618 ----------
 ...l-add-support-for-routes-and-streams.patch | 1021 -----------------
 ...02-original-patch-mediactl-pkgconfig.patch |   21 -
 ...iginal-patch-export-mediactl-headers.patch |   24 -
 ...nce-add-routing-and-streams-multiple.patch |  459 --------
 .../v4l-utils/0004-Do-not-use-getsubopt.patch |   59 -
 .../v4l-utils/v4l-utils_1.24.1.bb             |   84 --
 9 files changed, 2390 deletions(-)
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-v4l2-ctl-Add-routing-and-streams-support.patch
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-media-ctl-add-support-for-routes-and-streams.patch
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-original-patch-mediactl-pkgconfig.patch
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-original-patch-export-mediactl-headers.patch
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0004-Do-not-use-getsubopt.patch
 delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils_1.24.1.bb

Comments

Chirag Shilwant June 18, 2024, 12:33 p.m. UTC | #1
On 18/06/24 17:47, Jai Luthra wrote:
> In scarthgap/master meta-oe recipe for v4l-utils has moved to v1.26
> which has support for latest routing and media graph APIs.
>
> So we can now drop support for v1.24.1 and custom routing patches from
> the meta-arago layer.
>
> Signed-off-by: Jai Luthra <j-luthra@ti.com>

Acked-by: Chirag Shilwant <c-shilwant@ti.com>

> ---
>   ...-Don-t-install-libmediactl-and-libv4.patch |   43 -
>   ...-add-support-for-RGBIr-bayer-formats.patch |   61 -
>   ...-ctl-Add-routing-and-streams-support.patch |  618 ----------
>   ...l-add-support-for-routes-and-streams.patch | 1021 -----------------
>   ...02-original-patch-mediactl-pkgconfig.patch |   21 -
>   ...iginal-patch-export-mediactl-headers.patch |   24 -
>   ...nce-add-routing-and-streams-multiple.patch |  459 --------
>   .../v4l-utils/0004-Do-not-use-getsubopt.patch |   59 -
>   .../v4l-utils/v4l-utils_1.24.1.bb             |   84 --
>   9 files changed, 2390 deletions(-)
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-v4l2-ctl-Add-routing-and-streams-support.patch
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-media-ctl-add-support-for-routes-and-streams.patch
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-original-patch-mediactl-pkgconfig.patch
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-original-patch-export-mediactl-headers.patch
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0004-Do-not-use-getsubopt.patch
>   delete mode 100644 meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils_1.24.1.bb
>
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch
> deleted file mode 100644
> index 7305e471..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch
> +++ /dev/null
> @@ -1,43 +0,0 @@
> -From 0d5c0e9a75eca43667b0e29155b635e50622b66a Mon Sep 17 00:00:00 2001
> -From: Khem Raj <raj.khem@gmail.com>
> -Date: Fri, 27 Feb 2015 21:55:36 +0000
> -Subject: [PATCH] Revert "media-ctl: Don't install libmediactl and
> -
> - libv4l2subdev"
> -
> -This reverts commit 0911dce53b08b0df3066be2c75f67e8a314d8729.
> -
> -Signed-off-by: Khem Raj <raj.khem@gmail.com>
> -
> -Conflicts:
> -	utils/media-ctl/Makefile.am
> -
> ----
> - utils/media-ctl/Makefile.am | 10 +++-------
> - 1 file changed, 3 insertions(+), 7 deletions(-)
> -
> -diff --git a/utils/media-ctl/Makefile.am b/utils/media-ctl/Makefile.am
> -index c48c8d6..e255e16 100644
> ---- a/utils/media-ctl/Makefile.am
> -+++ b/utils/media-ctl/Makefile.am
> -@@ -1,8 +1,7 @@
> --noinst_LTLIBRARIES = libmediactl.la libv4l2subdev.la
> --
> -+lib_LTLIBRARIES = libmediactl.la libv4l2subdev.la
> - libmediactl_la_SOURCES = libmediactl.c mediactl-priv.h
> --libmediactl_la_CFLAGS = -static $(LIBUDEV_CFLAGS)
> --libmediactl_la_LDFLAGS = -static $(LIBUDEV_LIBS)
> -+libmediactl_la_CFLAGS = $(LIBUDEV_CFLAGS)
> -+libmediactl_la_LDFLAGS = $(LIBUDEV_LIBS)
> -
> - media-bus-format-names.h: ../../include/linux/media-bus-format.h
> -	$(AM_V_GEN) sed -e '/#define MEDIA_BUS_FMT/ ! d; s/.*FMT_//; /FIXED/ d; s/\t.*//; s/.*/{ \"&\", MEDIA_BUS_FMT_& },/;' \
> -@@ -18,9 +17,6 @@ CLEANFILES = $(BUILT_SOURCES)
> - nodist_libv4l2subdev_la_SOURCES = $(BUILT_SOURCES)
> - libv4l2subdev_la_SOURCES = libv4l2subdev.c
> - libv4l2subdev_la_LIBADD = libmediactl.la
> --libv4l2subdev_la_CFLAGS = -static
> --libv4l2subdev_la_LDFLAGS = -static
> --
> - mediactl_includedir=$(includedir)/mediactl
> - noinst_HEADERS = mediactl.h v4l2subdev.h
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch
> deleted file mode 100644
> index 1dff0637..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch
> +++ /dev/null
> @@ -1,61 +0,0 @@
> -From 26e2a60d29456a9cc6acb16ea19039414808bc5e Mon Sep 17 00:00:00 2001
> -From: Jai Luthra <j-luthra@ti.com>
> -Date: Tue, 5 Jul 2022 16:23:39 +0530
> -Subject: [PATCH] media-ctl: add support for RGBIr bayer formats
> -
> -Signed-off-by: Jai Luthra <j-luthra@ti.com>
> ----
> - include/linux/media-bus-format.h | 10 +++++++++-
> - include/linux/videodev2.h        |  9 +++++++++
> - 2 files changed, 18 insertions(+), 1 deletion(-)
> -
> -diff --git a/include/linux/media-bus-format.h b/include/linux/media-bus-format.h
> -index ca9a24c8..cbdf3798 100644
> ---- a/include/linux/media-bus-format.h
> -+++ b/include/linux/media-bus-format.h
> -@@ -117,7 +117,7 @@
> - #define MEDIA_BUS_FMT_YUV16_1X48		0x202a
> - #define MEDIA_BUS_FMT_UYYVYY16_0_5X48		0x202b
> -
> --/* Bayer - next is	0x3021 */
> -+/* Bayer - next is	0x3029 */
> - #define MEDIA_BUS_FMT_SBGGR8_1X8		0x3001
> - #define MEDIA_BUS_FMT_SGBRG8_1X8		0x3013
> - #define MEDIA_BUS_FMT_SGRBG8_1X8		0x3002
> -@@ -150,6 +150,14 @@
> - #define MEDIA_BUS_FMT_SGBRG16_1X16		0x301e
> - #define MEDIA_BUS_FMT_SGRBG16_1X16		0x301f
> - #define MEDIA_BUS_FMT_SRGGB16_1X16		0x3020
> -+#define MEDIA_BUS_FMT_SRGGI10_1X10		0x3021
> -+#define MEDIA_BUS_FMT_SGRIG10_1X10		0x3022
> -+#define MEDIA_BUS_FMT_SBGGI10_1X10		0x3023
> -+#define MEDIA_BUS_FMT_SGBIG10_1X10		0x3024
> -+#define MEDIA_BUS_FMT_SGIRG10_1X10		0x3025
> -+#define MEDIA_BUS_FMT_SIGGR10_1X10		0x3026
> -+#define MEDIA_BUS_FMT_SGIBG10_1X10		0x3027
> -+#define MEDIA_BUS_FMT_SIGGB10_1X10		0x3028
> -
> - /* JPEG compressed formats - next is	0x4002 */
> - #define MEDIA_BUS_FMT_JPEG_1X8			0x4001
> -diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> -index 5eb96692..093104ab 100644
> ---- a/include/linux/videodev2.h
> -+++ b/include/linux/videodev2.h
> -@@ -682,6 +682,15 @@ struct v4l2_pix_format {
> - #define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16  GBGB.. RGRG.. */
> - #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') /* 16  GRGR.. BGBG.. */
> - #define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') /* 16  RGRG.. GBGB.. */
> -+	/* 10bit raw bayer with IR (4x4) */
> -+#define V4L2_PIX_FMT_SRGGI10 v4l2_fourcc('R', 'G', 'I', '0') /* 10 RGBG.. GIrGIr.. */
> -+#define V4L2_PIX_FMT_SGRIG10 v4l2_fourcc('G', 'R', 'I', '0') /* 10 GRGB.. IrGIrG.. */
> -+#define V4L2_PIX_FMT_SBGGI10 v4l2_fourcc('B', 'G', 'I', '0') /* 10 BGRG.. GIrGIr.. */
> -+#define V4L2_PIX_FMT_SGBIG10 v4l2_fourcc('G', 'B', 'I', '0') /* 10 GBGR.. IrGIrG.. */
> -+#define V4L2_PIX_FMT_SGIRG10 v4l2_fourcc('G', 'I', 'R', '0') /* 10 GIrGIr.. RGBG.. */
> -+#define V4L2_PIX_FMT_SIGGR10 v4l2_fourcc('I', 'G', 'R', '0') /* 10 IrGIrG.. GRGB.. */
> -+#define V4L2_PIX_FMT_SGIBG10 v4l2_fourcc('G', 'I', 'B', '0') /* 10 GIrGIr.. BGRG.. */
> -+#define V4L2_PIX_FMT_SIGGB10 v4l2_fourcc('I', 'G', 'B', '0') /* 10 IrGIrG.. GBGR.. */
> -
> - /* HSV formats */
> - #define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3')
> ---
> -2.40.0
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-v4l2-ctl-Add-routing-and-streams-support.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-v4l2-ctl-Add-routing-and-streams-support.patch
> deleted file mode 100644
> index 9fd19edc..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-v4l2-ctl-Add-routing-and-streams-support.patch
> +++ /dev/null
> @@ -1,618 +0,0 @@
> -From 3b57a10f899403acd877683ca0247f2a9eba8850 Mon Sep 17 00:00:00 2001
> -From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> -Date: Fri, 10 Feb 2023 13:55:44 +0200
> -Subject: [PATCH 1/3] v4l2-ctl: Add routing and streams support
> -MIME-Version: 1.0
> -Content-Type: text/plain; charset=UTF-8
> -Content-Transfer-Encoding: 8bit
> -
> -Add support to get and set subdev routes and to get and set
> -configurations per stream.
> -
> -Based on work from Jacopo Mondi <jacopo@jmondi.org> and
> -Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>.
> -
> -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ----
> - utils/v4l2-ctl/v4l2-ctl-subdev.cpp | 288 +++++++++++++++++++++++++----
> - utils/v4l2-ctl/v4l2-ctl.cpp        |   2 +
> - utils/v4l2-ctl/v4l2-ctl.h          |   2 +
> - 3 files changed, 259 insertions(+), 33 deletions(-)
> -
> -diff --git a/utils/v4l2-ctl/v4l2-ctl-subdev.cpp b/utils/v4l2-ctl/v4l2-ctl-subdev.cpp
> -index 33cc1342..81236451 100644
> ---- a/utils/v4l2-ctl/v4l2-ctl-subdev.cpp
> -+++ b/utils/v4l2-ctl/v4l2-ctl-subdev.cpp
> -@@ -1,5 +1,13 @@
> - #include "v4l2-ctl.h"
> -
> -+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
> -+
> -+/*
> -+ * The max value comes from a check in the kernel source code
> -+ * drivers/media/v4l2-core/v4l2-ioctl.c check_array_args()
> -+ */
> -+#define NUM_ROUTES_MAX 256
> -+
> - struct mbus_name {
> -	const char *name;
> -	__u32 code;
> -@@ -19,45 +27,57 @@ static const struct mbus_name mbus_names[] = {
> - #define SelectionFlags 		(1L<<4)
> -
> - static __u32 list_mbus_codes_pad;
> -+static __u32 list_mbus_codes_stream = 0;
> - static __u32 get_fmt_pad;
> -+static __u32 get_fmt_stream = 0;
> - static __u32 get_sel_pad;
> -+static __u32 get_sel_stream = 0;
> - static __u32 get_fps_pad;
> -+static __u32 get_fps_stream = 0;
> - static int get_sel_target = -1;
> - static unsigned int set_selection;
> - static struct v4l2_subdev_selection vsel;
> - static unsigned int set_fmt;
> - static __u32 set_fmt_pad;
> -+static __u32 set_fmt_stream = 0;
> - static struct v4l2_mbus_framefmt ffmt;
> - static struct v4l2_subdev_frame_size_enum frmsize;
> - static struct v4l2_subdev_frame_interval_enum frmival;
> - static __u32 set_fps_pad;
> -+static __u32 set_fps_stream = 0;
> - static double set_fps;
> -+static struct v4l2_subdev_routing routing;
> -+static struct v4l2_subdev_route routes[NUM_ROUTES_MAX];
> -
> - void subdev_usage()
> - {
> -	printf("\nSub-Device options:\n"
> --	       "  --list-subdev-mbus-codes <pad>\n"
> -+	       "  --list-subdev-mbus-codes pad=<pad>,stream=<stream>\n"
> -	       "                      display supported mediabus codes for this pad (0 is default)\n"
> -	       "                      [VIDIOC_SUBDEV_ENUM_MBUS_CODE]\n"
> --	       "  --list-subdev-framesizes pad=<pad>,code=<code>\n"
> -+	       "  --list-subdev-framesizes pad=<pad>,stream=<stream>,code=<code>\n"
> -	       "                     list supported framesizes for this pad and code\n"
> -	       "                     [VIDIOC_SUBDEV_ENUM_FRAME_SIZE]\n"
> -	       "                     <code> is the value of the mediabus code\n"
> --	       "  --list-subdev-frameintervals pad=<pad>,width=<w>,height=<h>,code=<code>\n"
> -+	       "  --list-subdev-frameintervals pad=<pad>,stream=<stream>,width=<w>,height=<h>,code=<code>\n"
> -	       "                     list supported frame intervals for this pad and code and\n"
> -	       "                     the given width and height [VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL]\n"
> -	       "                     <code> is the value of the mediabus code\n"
> --	       "  --get-subdev-fmt [<pad>]\n"
> --	       "     		     query the frame format for the given pad [VIDIOC_SUBDEV_G_FMT]\n"
> --	       "  --get-subdev-selection pad=<pad>,target=<target>\n"
> -+	       "  --get-subdev-fmt pad=<pad>,stream=<stream>\n"
> -+	       "     		     query the frame format for the given pad and optional stream [VIDIOC_SUBDEV_G_FMT]\n"
> -+	       "		     <pad> the pad to get the format from\n"
> -+	       "		     <stream> the stream to get the format from (0 if not specified)\n"
> -+	       "  --get-subdev-selection pad=<pad>,stream=<stream>,target=<target>\n"
> -	       "                     query the frame selection rectangle [VIDIOC_SUBDEV_G_SELECTION]\n"
> -	       "                     See --set-subdev-selection command for the valid <target> values.\n"
> --	       "  --get-subdev-fps [<pad>]\n"
> -+	       "  --get-subdev-fps pad=<pad>,stream=<stream>\n"
> -	       "                     query the frame rate [VIDIOC_SUBDEV_G_FRAME_INTERVAL]\n"
> -	       "  --set-subdev-fmt   (for testing only, otherwise use media-ctl)\n"
> --	       "  --try-subdev-fmt pad=<pad>,width=<w>,height=<h>,code=<code>,field=<f>,colorspace=<c>,\n"
> -+	       "  --try-subdev-fmt pad=<pad>,stream=<stream>,width=<w>,height=<h>,code=<code>,field=<f>,colorspace=<c>,\n"
> -	       "                   xfer=<xf>,ycbcr=<y>,hsv=<hsv>,quantization=<q>\n"
> --	       "                     set the frame format [VIDIOC_SUBDEV_S_FMT]\n"
> -+	       "                     set the frame format for the given pad and optional stream [VIDIOC_SUBDEV_S_FMT]\n"
> -+	       "                     <pad> the pad to get the format from\n"
> -+	       "                     <stream> the stream to get the format from (0 if not specified)\n"
> -	       "                     <code> is the value of the mediabus code\n"
> -	       "                     <f> can be one of the following field layouts:\n"
> -	       "                       any, none, top, bottom, interlaced, seq_tb, seq_bt,\n"
> -@@ -74,14 +94,30 @@ void subdev_usage()
> -	       "                     <q> can be one of the following quantization methods:\n"
> -	       "                       default, full-range, lim-range\n"
> -	       "  --set-subdev-selection (for testing only, otherwise use media-ctl)\n"
> --	       "  --try-subdev-selection pad=<pad>,target=<target>,flags=<flags>,\n"
> -+	       "  --try-subdev-selection pad=<pad>,stream=<stream>,target=<target>,flags=<flags>,\n"
> -	       "                         top=<x>,left=<y>,width=<w>,height=<h>\n"
> -	       "                     set the video capture selection rectangle [VIDIOC_SUBDEV_S_SELECTION]\n"
> -	       "                     target=crop|crop_bounds|crop_default|compose|compose_bounds|\n"
> -	       "                            compose_default|compose_padded|native_size\n"
> -	       "                     flags=le|ge|keep-config\n"
> --	       "  --set-subdev-fps pad=<pad>,fps=<fps> (for testing only, otherwise use media-ctl)\n"
> -+	       "  --set-subdev-fps pad=<pad>,stream=<stream>,fps=<fps> (for testing only, otherwise use media-ctl)\n"
> -	       "                     set the frame rate [VIDIOC_SUBDEV_S_FRAME_INTERVAL]\n"
> -+	       "  --get-routing      Print the route topology\n"
> -+	       "  --set-routing <routes>\n"
> -+	       "                     Comma-separated list of route descriptors to setup\n"
> -+	       "\n"
> -+	       "Routes are defined as\n"
> -+	       "	routes		= route { ',' route } ;\n"
> -+	       "	route		= sink '->' source '[' flags ']' ;\n"
> -+	       "	sink		= sink-pad '/' sink-stream ;\n"
> -+	       "	source		= source-pad '/' source-stream ;\n"
> -+	       "\n"
> -+	       "where\n"
> -+	       "	sink-pad	= Pad numeric identifier for sink\n"
> -+	       "	sink-stream	= Stream numeric identifier for sink\n"
> -+	       "	source-pad	= Pad numeric identifier for source\n"
> -+	       "	source-stream	= Stream numeric identifier for source\n"
> -+	       "	flags		= Route flags (0: inactive, 1: active)\n"
> -	       );
> - }
> -
> -@@ -91,14 +127,33 @@ void subdev_cmd(int ch, char *optarg)
> -
> -	switch (ch) {
> -	case OptListSubDevMBusCodes:
> --		if (optarg)
> --			list_mbus_codes_pad = strtoul(optarg, nullptr, 0);
> -+		subs = optarg;
> -+		while (subs && *subs != '\0') {
> -+			static constexpr const char *subopts[] = {
> -+				"pad",
> -+				"stream",
> -+				nullptr
> -+			};
> -+
> -+			switch (parse_subopt(&subs, subopts, &value)) {
> -+			case 0:
> -+				list_mbus_codes_pad = strtoul(value, nullptr, 0);
> -+				break;
> -+			case 1:
> -+				list_mbus_codes_stream = strtoul(value, nullptr, 0);
> -+				break;
> -+			default:
> -+				subdev_usage();
> -+				std::exit(EXIT_FAILURE);
> -+			}
> -+		}
> -		break;
> -	case OptListSubDevFrameSizes:
> -		subs = optarg;
> -		while (*subs != '\0') {
> -			static constexpr const char *subopts[] = {
> -				"pad",
> -+				"stream",
> -				"code",
> -				nullptr
> -			};
> -@@ -108,6 +163,9 @@ void subdev_cmd(int ch, char *optarg)
> -				frmsize.pad = strtoul(value, nullptr, 0);
> -				break;
> -			case 1:
> -+				frmsize.stream = strtoul(value, nullptr, 0);
> -+				break;
> -+			case 2:
> -				frmsize.code = strtoul(value, nullptr, 0);
> -				break;
> -			default:
> -@@ -121,6 +179,7 @@ void subdev_cmd(int ch, char *optarg)
> -		while (*subs != '\0') {
> -			static constexpr const char *subopts[] = {
> -				"pad",
> -+				"stream",
> -				"code",
> -				"width",
> -				"height",
> -@@ -132,12 +191,15 @@ void subdev_cmd(int ch, char *optarg)
> -				frmival.pad = strtoul(value, nullptr, 0);
> -				break;
> -			case 1:
> --				frmival.code = strtoul(value, nullptr, 0);
> -+				frmival.stream = strtoul(value, nullptr, 0);
> -				break;
> -			case 2:
> --				frmival.width = strtoul(value, nullptr, 0);
> -+				frmival.code = strtoul(value, nullptr, 0);
> -				break;
> -			case 3:
> -+				frmival.width = strtoul(value, nullptr, 0);
> -+				break;
> -+			case 4:
> -				frmival.height = strtoul(value, nullptr, 0);
> -				break;
> -			default:
> -@@ -147,14 +209,33 @@ void subdev_cmd(int ch, char *optarg)
> -		}
> -		break;
> -	case OptGetSubDevFormat:
> --		if (optarg)
> --			get_fmt_pad = strtoul(optarg, nullptr, 0);
> -+		subs = optarg;
> -+		while (subs && *subs != '\0') {
> -+			static constexpr const char *subopts[] = {
> -+				"pad",
> -+				"stream",
> -+				nullptr
> -+			};
> -+
> -+			switch (parse_subopt(&subs, subopts, &value)) {
> -+			case 0:
> -+				get_fmt_pad = strtoul(value, nullptr, 0);
> -+				break;
> -+			case 1:
> -+				get_fmt_stream = strtoul(value, nullptr, 0);
> -+				break;
> -+			default:
> -+				subdev_usage();
> -+				std::exit(EXIT_FAILURE);
> -+			}
> -+		}
> -		break;
> -	case OptGetSubDevSelection:
> -		subs = optarg;
> -		while (*subs != '\0') {
> -			static constexpr const char *subopts[] = {
> -				"pad",
> -+				"stream",
> -				"target",
> -				nullptr
> -			};
> -@@ -165,6 +246,9 @@ void subdev_cmd(int ch, char *optarg)
> -				get_sel_pad = strtoul(value, nullptr, 0);
> -				break;
> -			case 1:
> -+				get_sel_stream = strtoul(value, nullptr, 0);
> -+				break;
> -+			case 2:
> -				if (parse_selection_target(value, target)) {
> -					fprintf(stderr, "Unknown selection target\n");
> -					subdev_usage();
> -@@ -179,8 +263,26 @@ void subdev_cmd(int ch, char *optarg)
> -		}
> -		break;
> -	case OptGetSubDevFPS:
> --		if (optarg)
> --			get_fps_pad = strtoul(optarg, nullptr, 0);
> -+		subs = optarg;
> -+		while (subs && *subs != '\0') {
> -+			static constexpr const char *subopts[] = {
> -+				"pad",
> -+				"stream",
> -+				nullptr
> -+			};
> -+
> -+			switch (parse_subopt(&subs, subopts, &value)) {
> -+			case 0:
> -+				get_fps_pad = strtoul(value, nullptr, 0);
> -+				break;
> -+			case 1:
> -+				get_fps_stream = strtoul(value, nullptr, 0);
> -+				break;
> -+			default:
> -+				subdev_usage();
> -+				std::exit(EXIT_FAILURE);
> -+			}
> -+		}
> -		break;
> -	case OptSetSubDevFormat:
> -	case OptTrySubDevFormat:
> -@@ -198,6 +300,7 @@ void subdev_cmd(int ch, char *optarg)
> -				"quantization",
> -				"xfer",
> -				"pad",
> -+				"stream",
> -				nullptr
> -			};
> -
> -@@ -244,6 +347,9 @@ void subdev_cmd(int ch, char *optarg)
> -			case 9:
> -				set_fmt_pad = strtoul(value, nullptr, 0);
> -				break;
> -+			case 10:
> -+				set_fmt_stream = strtoul(value, nullptr, 0);
> -+				break;
> -			default:
> -				fprintf(stderr, "Unknown option\n");
> -				subdev_usage();
> -@@ -264,6 +370,7 @@ void subdev_cmd(int ch, char *optarg)
> -				"width",
> -				"height",
> -				"pad",
> -+				"stream",
> -				nullptr
> -			};
> -
> -@@ -298,6 +405,9 @@ void subdev_cmd(int ch, char *optarg)
> -			case 6:
> -				vsel.pad = strtoul(value, nullptr, 0);
> -				break;
> -+			case 7:
> -+				vsel.stream = strtoul(value, nullptr, 0);
> -+				break;
> -			default:
> -				fprintf(stderr, "Unknown option\n");
> -				subdev_usage();
> -@@ -311,6 +421,7 @@ void subdev_cmd(int ch, char *optarg)
> -		while (*subs != '\0') {
> -			static constexpr const char *subopts[] = {
> -				"pad",
> -+				"stream",
> -				"fps",
> -				nullptr
> -			};
> -@@ -320,6 +431,9 @@ void subdev_cmd(int ch, char *optarg)
> -				set_fps_pad = strtoul(value, nullptr, 0);
> -				break;
> -			case 1:
> -+				set_fps_stream = strtoul(value, nullptr, 0);
> -+				break;
> -+			case 2:
> -				set_fps = strtod(value, nullptr);
> -				break;
> -			default:
> -@@ -329,6 +443,47 @@ void subdev_cmd(int ch, char *optarg)
> -			}
> -		}
> -		break;
> -+	case OptSetRouting: {
> -+		struct v4l2_subdev_route *r;
> -+		char *end, *ref, *tok;
> -+		unsigned int flags;
> -+
> -+		memset(&routing, 0, sizeof(routing));
> -+		memset(routes, 0, sizeof(routes[0]) * NUM_ROUTES_MAX);
> -+		routing.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> -+		routing.num_routes = 0;
> -+		routing.routes = (__u64)routes;
> -+
> -+		if (!optarg)
> -+			break;
> -+
> -+		r = (v4l2_subdev_route *)routing.routes;
> -+		ref = end = strdup(optarg);
> -+		while ((tok = strsep(&end, ",")) != NULL) {
> -+			if (sscanf(tok, "%u/%u -> %u/%u [%u]",
> -+				   &r->sink_pad, &r->sink_stream,
> -+				   &r->source_pad, &r->source_stream,
> -+				   &flags) != 5) {
> -+				free(ref);
> -+				fprintf(stderr, "Invalid route information specified\n");
> -+				subdev_usage();
> -+				std::exit(EXIT_FAILURE);
> -+			}
> -+
> -+			if (flags & ~(V4L2_SUBDEV_ROUTE_FL_ACTIVE)) {
> -+				fprintf(stderr, "Invalid route flags specified: %#x\n", flags);
> -+				subdev_usage();
> -+				std::exit(EXIT_FAILURE);
> -+			}
> -+
> -+			r->flags = flags;
> -+
> -+			r++;
> -+			routing.num_routes++;
> -+		}
> -+		free(ref);
> -+		break;
> -+	}
> -	default:
> -		break;
> -	}
> -@@ -394,6 +549,7 @@ void subdev_set(cv4l_fd &_fd)
> -
> -		memset(&fmt, 0, sizeof(fmt));
> -		fmt.pad = set_fmt_pad;
> -+		fmt.stream = set_fmt_stream;
> -		fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> -
> -		if (doioctl(fd, VIDIOC_SUBDEV_G_FMT, &fmt) == 0) {
> -@@ -430,7 +586,7 @@ void subdev_set(cv4l_fd &_fd)
> -			else
> -				fmt.which = V4L2_SUBDEV_FORMAT_TRY;
> -
> --			printf("ioctl: VIDIOC_SUBDEV_S_FMT (pad=%u)\n", fmt.pad);
> -+			printf("ioctl: VIDIOC_SUBDEV_S_FMT (pad=%u,stream=%u)\n", fmt.pad, fmt.stream);
> -			ret = doioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt);
> -			if (ret == 0 && (verbose || !options[OptSetSubDevFormat]))
> -				print_framefmt(fmt.format);
> -@@ -441,6 +597,7 @@ void subdev_set(cv4l_fd &_fd)
> -
> -		memset(&sel, 0, sizeof(sel));
> -		sel.pad = vsel.pad;
> -+		sel.stream = vsel.stream;
> -		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> -		sel.target = vsel.target;
> -
> -@@ -461,7 +618,7 @@ void subdev_set(cv4l_fd &_fd)
> -			else
> -				sel.which = V4L2_SUBDEV_FORMAT_TRY;
> -
> --			printf("ioctl: VIDIOC_SUBDEV_S_SELECTION (pad=%u)\n", sel.pad);
> -+			printf("ioctl: VIDIOC_SUBDEV_S_SELECTION (pad=%u,stream=%u)\n", sel.pad, sel.stream);
> -			int ret = doioctl(fd, VIDIOC_SUBDEV_S_SELECTION, &sel);
> -			if (ret == 0 && (verbose || !options[OptSetSubDevSelection]))
> -				print_subdev_selection(sel);
> -@@ -472,6 +629,7 @@ void subdev_set(cv4l_fd &_fd)
> -
> -		memset(&fival, 0, sizeof(fival));
> -		fival.pad = set_fps_pad;
> -+		fival.stream = set_fps_stream;
> -
> -		if (set_fps <= 0) {
> -			fprintf(stderr, "invalid fps %f\n", set_fps);
> -@@ -482,7 +640,7 @@ void subdev_set(cv4l_fd &_fd)
> -		fival.interval.denominator = static_cast<uint32_t>(set_fps * fival.interval.numerator);
> -		printf("Note: --set-subdev-fps is only for testing.\n"
> -		       "Normally media-ctl is used to configure the video pipeline.\n");
> --		printf("ioctl: VIDIOC_SUBDEV_S_FRAME_INTERVAL (pad=%u)\n", fival.pad);
> -+		printf("ioctl: VIDIOC_SUBDEV_S_FRAME_INTERVAL (pad=%u,stream=%u)\n", fival.pad, fival.stream);
> -		if (doioctl(fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &fival) == 0) {
> -			if (!fival.interval.denominator || !fival.interval.numerator)
> -				printf("\tFrames per second: invalid (%d/%d)\n",
> -@@ -493,6 +651,55 @@ void subdev_set(cv4l_fd &_fd)
> -					fival.interval.denominator, fival.interval.numerator);
> -		}
> -	}
> -+	if (options[OptSetRouting]) {
> -+		if (doioctl(fd, VIDIOC_SUBDEV_S_ROUTING, &routing) == 0)
> -+			printf("Routing set\n");
> -+	}
> -+}
> -+
> -+struct flag_name {
> -+	__u32 flag;
> -+	const char *name;
> -+};
> -+
> -+static void print_flags(const struct flag_name *flag_names, unsigned int num_entries, __u32 flags)
> -+{
> -+	bool first = true;
> -+	unsigned int i;
> -+
> -+	for (i = 0; i < num_entries; i++) {
> -+		if (!(flags & flag_names[i].flag))
> -+			continue;
> -+		if (!first)
> -+			printf(",");
> -+		printf("%s", flag_names[i].name);
> -+		flags &= ~flag_names[i].flag;
> -+		first = false;
> -+	}
> -+
> -+	if (flags) {
> -+		if (!first)
> -+			printf(",");
> -+		printf("0x%x", flags);
> -+	}
> -+}
> -+
> -+static void print_routes(const struct v4l2_subdev_routing *r)
> -+{
> -+	unsigned int i;
> -+	struct v4l2_subdev_route *routes = (struct v4l2_subdev_route *)r->routes;
> -+
> -+	static const struct flag_name route_flags[] = {
> -+		{ V4L2_SUBDEV_ROUTE_FL_ACTIVE, "ACTIVE" },
> -+	};
> -+
> -+	for (i = 0; i < r->num_routes; i++) {
> -+		printf("%d/%d -> %d/%d [",
> -+		       routes[i].sink_pad, routes[i].sink_stream,
> -+		       routes[i].source_pad, routes[i].source_stream);
> -+		print_flags(route_flags, ARRAY_SIZE(route_flags), routes[i].flags);
> -+		printf("]\n");
> -+	}
> - }
> -
> - void subdev_get(cv4l_fd &_fd)
> -@@ -505,8 +712,9 @@ void subdev_get(cv4l_fd &_fd)
> -		memset(&fmt, 0, sizeof(fmt));
> -		fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> -		fmt.pad = get_fmt_pad;
> -+		fmt.stream = get_fmt_stream;
> -
> --		printf("ioctl: VIDIOC_SUBDEV_G_FMT (pad=%u)\n", fmt.pad);
> -+		printf("ioctl: VIDIOC_SUBDEV_G_FMT (pad=%u, stream=%u)\n", fmt.pad, fmt.stream);
> -		if (doioctl(fd, VIDIOC_SUBDEV_G_FMT, &fmt) == 0)
> -			print_framefmt(fmt.format);
> -	}
> -@@ -518,8 +726,9 @@ void subdev_get(cv4l_fd &_fd)
> -		memset(&sel, 0, sizeof(sel));
> -		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> -		sel.pad = get_sel_pad;
> -+		sel.stream = get_sel_stream;
> -
> --		printf("ioctl: VIDIOC_SUBDEV_G_SELECTION (pad=%u)\n", sel.pad);
> -+		printf("ioctl: VIDIOC_SUBDEV_G_SELECTION (pad=%u,stream=%u)\n", sel.pad, sel.stream);
> -		if (options[OptAll] || get_sel_target == -1) {
> -			while (valid_seltarget_at_idx(idx)) {
> -				sel.target = seltarget_at_idx(idx);
> -@@ -538,8 +747,9 @@ void subdev_get(cv4l_fd &_fd)
> -
> -		memset(&fival, 0, sizeof(fival));
> -		fival.pad = get_fps_pad;
> -+		fival.stream = get_fps_stream;
> -
> --		printf("ioctl: VIDIOC_SUBDEV_G_FRAME_INTERVAL (pad=%u)\n", fival.pad);
> -+		printf("ioctl: VIDIOC_SUBDEV_G_FRAME_INTERVAL (pad=%u,stream=%u)\n", fival.pad, fival.stream);
> -		if (doioctl(fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &fival) == 0) {
> -			if (!fival.interval.denominator || !fival.interval.numerator)
> -				printf("\tFrames per second: invalid (%d/%d)\n",
> -@@ -550,6 +760,17 @@ void subdev_get(cv4l_fd &_fd)
> -					fival.interval.denominator, fival.interval.numerator);
> -		}
> -	}
> -+
> -+	if (options[OptGetRouting]) {
> -+		memset(&routing, 0, sizeof(routing));
> -+		memset(routes, 0, sizeof(routes[0]) * NUM_ROUTES_MAX);
> -+		routing.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> -+		routing.num_routes = NUM_ROUTES_MAX;
> -+		routing.routes = (__u64)routes;
> -+
> -+		if (doioctl(fd, VIDIOC_SUBDEV_G_ROUTING, &routing) == 0)
> -+			print_routes(&routing);
> -+	}
> - }
> -
> - static void print_mbus_code(__u32 code)
> -@@ -566,11 +787,12 @@ static void print_mbus_code(__u32 code)
> -		printf("\t0x%04x", code);
> - }
> -
> --static void print_mbus_codes(int fd, __u32 pad)
> -+static void print_mbus_codes(int fd, __u32 pad, __u32 stream)
> - {
> -	struct v4l2_subdev_mbus_code_enum mbus_code = {};
> -
> -	mbus_code.pad = pad;
> -+	mbus_code.stream = stream;
> -	mbus_code.which = V4L2_SUBDEV_FORMAT_TRY;
> -
> -	for (;;) {
> -@@ -623,13 +845,13 @@ void subdev_list(cv4l_fd &_fd)
> -	int fd = _fd.g_fd();
> -
> -	if (options[OptListSubDevMBusCodes]) {
> --		printf("ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=%u)\n",
> --		       list_mbus_codes_pad);
> --		print_mbus_codes(fd, list_mbus_codes_pad);
> -+		printf("ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=%u,stream=%u)\n",
> -+		       list_mbus_codes_pad, list_mbus_codes_stream);
> -+		print_mbus_codes(fd, list_mbus_codes_pad, list_mbus_codes_stream);
> -	}
> -	if (options[OptListSubDevFrameSizes]) {
> --		printf("ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE (pad=%u)\n",
> --		       frmsize.pad);
> -+		printf("ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE (pad=%u,stream=%u)\n",
> -+		       frmsize.pad, frmsize.stream);
> -		frmsize.index = 0;
> -		frmsize.which = V4L2_SUBDEV_FORMAT_TRY;
> -		while (test_ioctl(fd, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &frmsize) >= 0) {
> -@@ -638,8 +860,8 @@ void subdev_list(cv4l_fd &_fd)
> -		}
> -	}
> -	if (options[OptListSubDevFrameIntervals]) {
> --		printf("ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=%u)\n",
> --		       frmival.pad);
> -+		printf("ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=%u,stream=%u)\n",
> -+		       frmival.pad, frmival.stream);
> -		frmival.index = 0;
> -		frmival.which = V4L2_SUBDEV_FORMAT_TRY;
> -		while (test_ioctl(fd, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, &frmival) >= 0) {
> -diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
> -index 8585278f..1cfb50f7 100644
> ---- a/utils/v4l2-ctl/v4l2-ctl.cpp
> -+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
> -@@ -64,6 +64,8 @@ static struct option long_options[] = {
> -	{"get-fmt-video-out", no_argument, nullptr, OptGetVideoOutFormat},
> -	{"set-fmt-video-out", required_argument, nullptr, OptSetVideoOutFormat},
> -	{"try-fmt-video-out", required_argument, nullptr, OptTryVideoOutFormat},
> -+	{"set-routing", required_argument, 0, OptSetRouting},
> -+	{"get-routing", no_argument, 0, OptGetRouting},
> -	{"help", no_argument, nullptr, OptHelp},
> -	{"help-tuner", no_argument, nullptr, OptHelpTuner},
> -	{"help-io", no_argument, nullptr, OptHelpIO},
> -diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
> -index 70a80ade..51a68b92 100644
> ---- a/utils/v4l2-ctl/v4l2-ctl.h
> -+++ b/utils/v4l2-ctl/v4l2-ctl.h
> -@@ -197,6 +197,8 @@ enum Option {
> -	OptInfoEdid,
> -	OptShowEdid,
> -	OptFixEdidChecksums,
> -+	OptSetRouting,
> -+	OptGetRouting,
> -	OptFreqSeek,
> -	OptEncoderCmd,
> -	OptTryEncoderCmd,
> ---
> -2.40.0
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-media-ctl-add-support-for-routes-and-streams.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-media-ctl-add-support-for-routes-and-streams.patch
> deleted file mode 100644
> index 79864f01..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-media-ctl-add-support-for-routes-and-streams.patch
> +++ /dev/null
> @@ -1,1021 +0,0 @@
> -From 868c176e0de433777d5eed3e6d6d8dc03b9145a6 Mon Sep 17 00:00:00 2001
> -From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> -Date: Fri, 10 Feb 2023 13:55:45 +0200
> -Subject: [PATCH 2/3] media-ctl: add support for routes and streams
> -
> -Add support to get and set subdev routes and to get and set
> -configurations per stream.
> -
> -Based on work from Sakari Ailus <sakari.ailus@linux.intel.com>.
> -
> -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ----
> - utils/media-ctl/libmediactl.c   |  41 +++++
> - utils/media-ctl/libv4l2subdev.c | 283 ++++++++++++++++++++++++++++----
> - utils/media-ctl/media-ctl.c     | 121 ++++++++++++--
> - utils/media-ctl/mediactl.h      |  16 ++
> - utils/media-ctl/options.c       |  15 +-
> - utils/media-ctl/options.h       |   1 +
> - utils/media-ctl/v4l2subdev.h    |  58 ++++++-
> - 7 files changed, 478 insertions(+), 57 deletions(-)
> -
> -diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
> -index 1fd6525b..537365d0 100644
> ---- a/utils/media-ctl/libmediactl.c
> -+++ b/utils/media-ctl/libmediactl.c
> -@@ -876,6 +876,47 @@ struct media_pad *media_parse_pad(struct media_device *media,
> -	return &entity->pads[pad];
> - }
> -
> -+struct media_pad *media_parse_pad_stream(struct media_device *media,
> -+					 const char *p, unsigned int *stream,
> -+					 char **endp)
> -+{
> -+	struct media_pad *pad;
> -+	const char *orig_p = p;
> -+	char *ep;
> -+
> -+	pad = media_parse_pad(media, p, &ep);
> -+	if (pad == NULL)
> -+		return NULL;
> -+
> -+	p = ep;
> -+
> -+	if (*p == '/') {
> -+		unsigned int s;
> -+
> -+		p++;
> -+
> -+		s = strtoul(p, &ep, 10);
> -+
> -+		if (ep == p) {
> -+			printf("Unable to parse stream: '%s'\n", orig_p);
> -+			if (endp)
> -+				*endp = (char*)p;
> -+			return NULL;
> -+		}
> -+
> -+		*stream = s;
> -+
> -+		p++;
> -+	} else {
> -+		*stream = 0;
> -+	}
> -+
> -+	if (endp)
> -+		*endp = (char*)p;
> -+
> -+	return pad;
> -+}
> -+
> - struct media_link *media_parse_link(struct media_device *media,
> -				    const char *p, char **endp)
> - {
> -diff --git a/utils/media-ctl/libv4l2subdev.c b/utils/media-ctl/libv4l2subdev.c
> -index 63bb3d75..d203e5b4 100644
> ---- a/utils/media-ctl/libv4l2subdev.c
> -+++ b/utils/media-ctl/libv4l2subdev.c
> -@@ -64,7 +64,7 @@ void v4l2_subdev_close(struct media_entity *entity)
> - }
> -
> - int v4l2_subdev_get_format(struct media_entity *entity,
> --	struct v4l2_mbus_framefmt *format, unsigned int pad,
> -+	struct v4l2_mbus_framefmt *format, unsigned int pad, unsigned int stream,
> -	enum v4l2_subdev_format_whence which)
> - {
> -	struct v4l2_subdev_format fmt;
> -@@ -76,6 +76,7 @@ int v4l2_subdev_get_format(struct media_entity *entity,
> -
> -	memset(&fmt, 0, sizeof(fmt));
> -	fmt.pad = pad;
> -+	fmt.stream = stream;
> -	fmt.which = which;
> -
> -	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_FMT, &fmt);
> -@@ -88,6 +89,7 @@ int v4l2_subdev_get_format(struct media_entity *entity,
> -
> - int v4l2_subdev_set_format(struct media_entity *entity,
> -	struct v4l2_mbus_framefmt *format, unsigned int pad,
> -+	unsigned int stream,
> -	enum v4l2_subdev_format_whence which)
> - {
> -	struct v4l2_subdev_format fmt;
> -@@ -99,6 +101,7 @@ int v4l2_subdev_set_format(struct media_entity *entity,
> -
> -	memset(&fmt, 0, sizeof(fmt));
> -	fmt.pad = pad;
> -+	fmt.stream = stream;
> -	fmt.which = which;
> -	fmt.format = *format;
> -
> -@@ -111,8 +114,8 @@ int v4l2_subdev_set_format(struct media_entity *entity,
> - }
> -
> - int v4l2_subdev_get_selection(struct media_entity *entity,
> --	struct v4l2_rect *rect, unsigned int pad, unsigned int target,
> --	enum v4l2_subdev_format_whence which)
> -+	struct v4l2_rect *rect, unsigned int pad, unsigned int stream,
> -+	unsigned int target, enum v4l2_subdev_format_whence which)
> - {
> -	union {
> -		struct v4l2_subdev_selection sel;
> -@@ -150,8 +153,8 @@ int v4l2_subdev_get_selection(struct media_entity *entity,
> - }
> -
> - int v4l2_subdev_set_selection(struct media_entity *entity,
> --	struct v4l2_rect *rect, unsigned int pad, unsigned int target,
> --	enum v4l2_subdev_format_whence which)
> -+	struct v4l2_rect *rect, unsigned int pad, unsigned int stream,
> -+	unsigned int target, enum v4l2_subdev_format_whence which)
> - {
> -	union {
> -		struct v4l2_subdev_selection sel;
> -@@ -165,6 +168,7 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
> -
> -	memset(&u.sel, 0, sizeof(u.sel));
> -	u.sel.pad = pad;
> -+	u.sel.stream = stream;
> -	u.sel.target = target;
> -	u.sel.which = which;
> -	u.sel.r = *rect;
> -@@ -179,6 +183,7 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
> -
> -	memset(&u.crop, 0, sizeof(u.crop));
> -	u.crop.pad = pad;
> -+	u.crop.stream = stream;
> -	u.crop.which = which;
> -	u.crop.rect = *rect;
> -
> -@@ -190,6 +195,69 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
> -	return 0;
> - }
> -
> -+int v4l2_subdev_set_routing(struct media_entity *entity,
> -+			    struct v4l2_subdev_route *routes,
> -+			    unsigned int num_routes)
> -+{
> -+	struct v4l2_subdev_routing routing = {
> -+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
> -+		.routes = (uintptr_t)routes,
> -+		.num_routes = num_routes,
> -+	};
> -+	int ret;
> -+
> -+	ret = v4l2_subdev_open(entity);
> -+	if (ret < 0)
> -+		return ret;
> -+
> -+	ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_ROUTING, &routing);
> -+	if (ret == -1)
> -+		return -errno;
> -+
> -+	return 0;
> -+}
> -+
> -+int v4l2_subdev_get_routing(struct media_entity *entity,
> -+			    struct v4l2_subdev_route **routes,
> -+			    unsigned int *num_routes)
> -+{
> -+	struct v4l2_subdev_routing routing = { 0 };
> -+	struct v4l2_subdev_route *r;
> -+	int ret;
> -+
> -+	ret = v4l2_subdev_open(entity);
> -+	if (ret < 0)
> -+		return ret;
> -+
> -+	routing.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> -+
> -+	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_ROUTING, &routing);
> -+	if (ret == -1 && errno != ENOSPC)
> -+		return -errno;
> -+
> -+	if (!routing.num_routes) {
> -+		*routes = NULL;
> -+		*num_routes = 0;
> -+		return 0;
> -+	}
> -+
> -+	r = calloc(routing.num_routes, sizeof(*r));
> -+	if (!r)
> -+		return -ENOMEM;
> -+
> -+	routing.routes = (uintptr_t)r;
> -+	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_ROUTING, &routing);
> -+	if (ret) {
> -+		free(r);
> -+		return ret;
> -+	}
> -+
> -+	*num_routes = routing.num_routes;
> -+	*routes = r;
> -+
> -+	return 0;
> -+}
> -+
> - int v4l2_subdev_get_dv_timings_caps(struct media_entity *entity,
> -	struct v4l2_dv_timings_cap *caps)
> - {
> -@@ -264,7 +332,7 @@ int v4l2_subdev_set_dv_timings(struct media_entity *entity,
> -
> - int v4l2_subdev_get_frame_interval(struct media_entity *entity,
> -				   struct v4l2_fract *interval,
> --				   unsigned int pad)
> -+				   unsigned int pad, unsigned int stream)
> - {
> -	struct v4l2_subdev_frame_interval ival;
> -	int ret;
> -@@ -275,6 +343,7 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
> -
> -	memset(&ival, 0, sizeof(ival));
> -	ival.pad = pad;
> -+	ival.stream = stream;
> -
> -	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &ival);
> -	if (ret < 0)
> -@@ -286,7 +355,7 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
> -
> - int v4l2_subdev_set_frame_interval(struct media_entity *entity,
> -				   struct v4l2_fract *interval,
> --				   unsigned int pad)
> -+				   unsigned int pad, unsigned int stream)
> - {
> -	struct v4l2_subdev_frame_interval ival;
> -	int ret;
> -@@ -297,6 +366,7 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
> -
> -	memset(&ival, 0, sizeof(ival));
> -	ival.pad = pad;
> -+	ival.stream = stream;
> -	ival.interval = *interval;
> -
> -	ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &ival);
> -@@ -307,6 +377,155 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
> -	return 0;
> - }
> -
> -+static int v4l2_subdev_parse_setup_route(struct media_device *media,
> -+					 struct v4l2_subdev_route *r,
> -+					 const char *p, char **endp)
> -+{
> -+	char *end;
> -+
> -+	/* sink pad/stream */
> -+
> -+	r->sink_pad = strtoul(p, &end, 10);
> -+
> -+	if (*end != '/') {
> -+		media_dbg(media, "Expected '/'\n");
> -+		return -EINVAL;
> -+	}
> -+
> -+	p = end + 1;
> -+
> -+	r->sink_stream = strtoul(p, &end, 10);
> -+
> -+	for (; isspace(*end); ++end);
> -+
> -+	if (end[0] != '-' || end[1] != '>') {
> -+		media_dbg(media, "Expected '->'\n");
> -+		return -EINVAL;
> -+	}
> -+	p = end + 2;
> -+
> -+	/* source pad/stream */
> -+
> -+	r->source_pad = strtoul(p, &end, 10);
> -+
> -+	if (*end != '/') {
> -+		media_dbg(media, "Expected '/'\n");
> -+		return -EINVAL;
> -+	}
> -+
> -+	p = end + 1;
> -+
> -+	r->source_stream = strtoul(p, &end, 10);
> -+
> -+	/* flags */
> -+
> -+	for (; isspace(*end); ++end);
> -+
> -+	if (*end != '[') {
> -+		media_dbg(media, "Expected '['\n");
> -+		return -EINVAL;
> -+	}
> -+
> -+	for (end++; isspace(*end); ++end);
> -+
> -+	p = end;
> -+
> -+	r->flags = strtoul(p, &end, 0);
> -+
> -+	if (r->flags & ~(V4L2_SUBDEV_ROUTE_FL_ACTIVE)) {
> -+		media_dbg(media, "Bad route flags %#x\n", r->flags);
> -+		return -EINVAL;
> -+	}
> -+
> -+	for (; isspace(*end); ++end);
> -+
> -+	if (*end != ']') {
> -+		media_dbg(media, "Expected ']'\n");
> -+		return -EINVAL;
> -+	}
> -+	end++;
> -+
> -+	*endp = end;
> -+
> -+	return 0;
> -+}
> -+
> -+int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p)
> -+{
> -+	struct media_entity *entity;
> -+	struct v4l2_subdev_route *routes;
> -+	unsigned int num_routes;
> -+	char *end;
> -+	int ret;
> -+	int i;
> -+
> -+	entity = media_parse_entity(media, p, &end);
> -+	if (!entity)
> -+		return -EINVAL;
> -+
> -+	p = end;
> -+
> -+	if (*p != '[') {
> -+		media_dbg(media, "Expected '['\n");
> -+		return -EINVAL;
> -+	}
> -+
> -+	p++;
> -+
> -+	routes = calloc(256, sizeof(routes[0]));
> -+	if (!routes)
> -+		return -ENOMEM;
> -+
> -+	num_routes = 0;
> -+
> -+	while (*p != 0) {
> -+		struct v4l2_subdev_route *r = &routes[num_routes];
> -+
> -+		ret = v4l2_subdev_parse_setup_route(media, r, p, &end);
> -+		if (ret)
> -+			goto out;
> -+
> -+		p = end;
> -+
> -+		num_routes++;
> -+
> -+		if (*p == ',') {
> -+			p++;
> -+			continue;
> -+		}
> -+
> -+		break;
> -+	}
> -+
> -+	if (*p != ']') {
> -+		media_dbg(media, "Expected ']'\n");
> -+		ret = -EINVAL;
> -+		goto out;
> -+	}
> -+
> -+	for (i = 0; i < num_routes; ++i) {
> -+		struct v4l2_subdev_route *r = &routes[i];
> -+
> -+		media_dbg(entity->media,
> -+			  "Setting up route %s : %u/%u -> %u/%u, flags 0x%8.8x\n",
> -+			  entity->info.name,
> -+			  r->sink_pad, r->sink_stream,
> -+			  r->source_pad, r->source_stream,
> -+			  r->flags);
> -+	}
> -+
> -+	ret = v4l2_subdev_set_routing(entity, routes, num_routes);
> -+	if (ret) {
> -+		printf("VIDIOC_SUBDEV_S_ROUTING failed: %d\n", ret);
> -+		goto out;
> -+	}
> -+
> -+out:
> -+	free(routes);
> -+
> -+	return ret;
> -+}
> -+
> - static int v4l2_subdev_parse_format(struct media_device *media,
> -				    struct v4l2_mbus_framefmt *format,
> -				    const char *p, char **endp)
> -@@ -442,7 +661,8 @@ static bool strhazit(const char *str, const char **p)
> - }
> -
> - static struct media_pad *v4l2_subdev_parse_pad_format(
> --	struct media_device *media, struct v4l2_mbus_framefmt *format,
> -+	struct media_device *media, unsigned int *stream,
> -+	struct v4l2_mbus_framefmt *format,
> -	struct v4l2_rect *crop, struct v4l2_rect *compose,
> -	struct v4l2_fract *interval, const char *p, char **endp)
> - {
> -@@ -453,7 +673,7 @@ static struct media_pad *v4l2_subdev_parse_pad_format(
> -
> -	for (; isspace(*p); ++p);
> -
> --	pad = media_parse_pad(media, p, &end);
> -+	pad = media_parse_pad_stream(media, p, stream, &end);
> -	if (pad == NULL) {
> -		*endp = end;
> -		return NULL;
> -@@ -675,6 +895,7 @@ static struct media_pad *v4l2_subdev_parse_pad_format(
> - }
> -
> - static int set_format(struct media_pad *pad,
> -+		      unsigned int stream,
> -		      struct v4l2_mbus_framefmt *format)
> - {
> -	int ret;
> -@@ -683,12 +904,12 @@ static int set_format(struct media_pad *pad,
> -		return 0;
> -
> -	media_dbg(pad->entity->media,
> --		  "Setting up format %s %ux%u on pad %s/%u\n",
> -+		  "Setting up format %s %ux%u on pad %s/%u/%u\n",
> -		  v4l2_subdev_pixelcode_to_string(format->code),
> -		  format->width, format->height,
> --		  pad->entity->info.name, pad->index);
> -+		  pad->entity->info.name, pad->index, stream);
> -
> --	ret = v4l2_subdev_set_format(pad->entity, format, pad->index,
> -+	ret = v4l2_subdev_set_format(pad->entity, format, pad->index, stream,
> -				     V4L2_SUBDEV_FORMAT_ACTIVE);
> -	if (ret < 0) {
> -		media_dbg(pad->entity->media,
> -@@ -705,8 +926,8 @@ static int set_format(struct media_pad *pad,
> -	return 0;
> - }
> -
> --static int set_selection(struct media_pad *pad, unsigned int target,
> --			 struct v4l2_rect *rect)
> -+static int set_selection(struct media_pad *pad, unsigned int stream,
> -+			 unsigned int target, struct v4l2_rect *rect)
> - {
> -	int ret;
> -
> -@@ -714,11 +935,11 @@ static int set_selection(struct media_pad *pad, unsigned int target,
> -		return 0;
> -
> -	media_dbg(pad->entity->media,
> --		  "Setting up selection target %u rectangle (%u,%u)/%ux%u on pad %s/%u\n",
> -+		  "Setting up selection target %u rectangle (%u,%u)/%ux%u on pad %s/%u/%u\n",
> -		  target, rect->left, rect->top, rect->width, rect->height,
> --		  pad->entity->info.name, pad->index);
> -+		  pad->entity->info.name, pad->index, stream);
> -
> --	ret = v4l2_subdev_set_selection(pad->entity, rect, pad->index,
> -+	ret = v4l2_subdev_set_selection(pad->entity, rect, pad->index, stream,
> -					target, V4L2_SUBDEV_FORMAT_ACTIVE);
> -	if (ret < 0) {
> -		media_dbg(pad->entity->media,
> -@@ -734,7 +955,7 @@ static int set_selection(struct media_pad *pad, unsigned int target,
> -	return 0;
> - }
> -
> --static int set_frame_interval(struct media_pad *pad,
> -+static int set_frame_interval(struct media_pad *pad, unsigned int stream,
> -			      struct v4l2_fract *interval)
> - {
> -	int ret;
> -@@ -743,11 +964,12 @@ static int set_frame_interval(struct media_pad *pad,
> -		return 0;
> -
> -	media_dbg(pad->entity->media,
> --		  "Setting up frame interval %u/%u on pad %s/%u\n",
> -+		  "Setting up frame interval %u/%u on pad %s/%u/%u\n",
> -		  interval->numerator, interval->denominator,
> --		  pad->entity->info.name, pad->index);
> -+		  pad->entity->info.name, pad->index, stream);
> -
> --	ret = v4l2_subdev_set_frame_interval(pad->entity, interval, pad->index);
> -+	ret = v4l2_subdev_set_frame_interval(pad->entity, interval, pad->index,
> -+					     stream);
> -	if (ret < 0) {
> -		media_dbg(pad->entity->media,
> -			  "Unable to set frame interval: %s (%d)",
> -@@ -770,11 +992,13 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
> -	struct v4l2_rect crop = { -1, -1, -1, -1 };
> -	struct v4l2_rect compose = crop;
> -	struct v4l2_fract interval = { 0, 0 };
> -+	unsigned int stream;
> -	unsigned int i;
> -	char *end;
> -	int ret;
> -
> --	pad = v4l2_subdev_parse_pad_format(media, &format, &crop, &compose,
> -+	pad = v4l2_subdev_parse_pad_format(media, &stream,
> -+					   &format, &crop, &compose,
> -					   &interval, p, &end);
> -	if (pad == NULL) {
> -		media_print_streampos(media, p, end);
> -@@ -783,30 +1007,29 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
> -	}
> -
> -	if (pad->flags & MEDIA_PAD_FL_SINK) {
> --		ret = set_format(pad, &format);
> -+		ret = set_format(pad, stream, &format);
> -		if (ret < 0)
> -			return ret;
> -	}
> -
> --	ret = set_selection(pad, V4L2_SEL_TGT_CROP, &crop);
> -+	ret = set_selection(pad, stream, V4L2_SEL_TGT_CROP, &crop);
> -	if (ret < 0)
> -		return ret;
> -
> --	ret = set_selection(pad, V4L2_SEL_TGT_COMPOSE, &compose);
> -+	ret = set_selection(pad, stream, V4L2_SEL_TGT_COMPOSE, &compose);
> -	if (ret < 0)
> -		return ret;
> -
> -	if (pad->flags & MEDIA_PAD_FL_SOURCE) {
> --		ret = set_format(pad, &format);
> -+		ret = set_format(pad, stream, &format);
> -		if (ret < 0)
> -			return ret;
> -	}
> -
> --	ret = set_frame_interval(pad, &interval);
> -+	ret = set_frame_interval(pad, stream, &interval);
> -	if (ret < 0)
> -		return ret;
> -
> --
> -	/* If the pad is an output pad, automatically set the same format and
> -	 * frame interval on the remote subdev input pads, if any.
> -	 */
> -@@ -821,9 +1044,9 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
> -			if (link->source == pad &&
> -			    link->sink->entity->info.type == MEDIA_ENT_T_V4L2_SUBDEV) {
> -				remote_format = format;
> --				set_format(link->sink, &remote_format);
> -+				set_format(link->sink, stream, &remote_format);
> -
> --				ret = set_frame_interval(link->sink, &interval);
> -+				ret = set_frame_interval(link->sink, stream, &interval);
> -				if (ret < 0 && ret != -EINVAL && ret != -ENOTTY)
> -					return ret;
> -			}
> -diff --git a/utils/media-ctl/media-ctl.c b/utils/media-ctl/media-ctl.c
> -index 84ee7a83..831136a0 100644
> ---- a/utils/media-ctl/media-ctl.c
> -+++ b/utils/media-ctl/media-ctl.c
> -@@ -28,6 +28,7 @@
> - #include <errno.h>
> - #include <fcntl.h>
> - #include <stdbool.h>
> -+#include <stdint.h>
> - #include <stdio.h>
> - #include <stdlib.h>
> - #include <string.h>
> -@@ -75,23 +76,43 @@ static void print_flags(const struct flag_name *flag_names, unsigned int num_ent
> -	}
> - }
> -
> -+static void v4l2_subdev_print_routes(struct media_entity *entity,
> -+				     struct v4l2_subdev_route *routes,
> -+				     unsigned int num_routes)
> -+{
> -+	unsigned int i;
> -+
> -+	for (i = 0; i < num_routes; i++) {
> -+		const struct v4l2_subdev_route *r = &routes[i];
> -+
> -+		if (i == 0)
> -+			printf("\troutes:\n");
> -+
> -+		printf("\t\t%u/%u -> %u/%u [%s]\n",
> -+		       r->sink_pad, r->sink_stream,
> -+		       r->source_pad, r->source_stream,
> -+		       r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE ? "ACTIVE" : "INACTIVE");
> -+	}
> -+}
> -+
> - static void v4l2_subdev_print_format(struct media_entity *entity,
> --	unsigned int pad, enum v4l2_subdev_format_whence which)
> -+	unsigned int pad, unsigned int stream,
> -+	enum v4l2_subdev_format_whence which)
> - {
> -	struct v4l2_mbus_framefmt format;
> -	struct v4l2_fract interval = { 0, 0 };
> -	struct v4l2_rect rect;
> -	int ret;
> -
> --	ret = v4l2_subdev_get_format(entity, &format, pad, which);
> -+	ret = v4l2_subdev_get_format(entity, &format, pad, stream, which);
> -	if (ret != 0)
> -		return;
> -
> --	ret = v4l2_subdev_get_frame_interval(entity, &interval, pad);
> -+	ret = v4l2_subdev_get_frame_interval(entity, &interval, pad, stream);
> -	if (ret != 0 && ret != -ENOTTY && ret != -EINVAL)
> -		return;
> -
> --	printf("\t\t[fmt:%s/%ux%u",
> -+	printf("\t\t[stream:%u fmt:%s/%ux%u", stream,
> -	       v4l2_subdev_pixelcode_to_string(format.code),
> -	       format.width, format.height);
> -
> -@@ -118,28 +139,28 @@ static void v4l2_subdev_print_format(struct media_entity *entity,
> -			       v4l2_subdev_quantization_to_string(format.quantization));
> -	}
> -
> --	ret = v4l2_subdev_get_selection(entity, &rect, pad,
> -+	ret = v4l2_subdev_get_selection(entity, &rect, pad, stream,
> -					V4L2_SEL_TGT_CROP_BOUNDS,
> -					which);
> -	if (ret == 0)
> -		printf("\n\t\t crop.bounds:(%u,%u)/%ux%u", rect.left, rect.top,
> -		       rect.width, rect.height);
> -
> --	ret = v4l2_subdev_get_selection(entity, &rect, pad,
> -+	ret = v4l2_subdev_get_selection(entity, &rect, pad, stream,
> -					V4L2_SEL_TGT_CROP,
> -					which);
> -	if (ret == 0)
> -		printf("\n\t\t crop:(%u,%u)/%ux%u", rect.left, rect.top,
> -		       rect.width, rect.height);
> -
> --	ret = v4l2_subdev_get_selection(entity, &rect, pad,
> -+	ret = v4l2_subdev_get_selection(entity, &rect, pad, stream,
> -					V4L2_SEL_TGT_COMPOSE_BOUNDS,
> -					which);
> -	if (ret == 0)
> -		printf("\n\t\t compose.bounds:(%u,%u)/%ux%u",
> -		       rect.left, rect.top, rect.width, rect.height);
> -
> --	ret = v4l2_subdev_get_selection(entity, &rect, pad,
> -+	ret = v4l2_subdev_get_selection(entity, &rect, pad, stream,
> -					V4L2_SEL_TGT_COMPOSE,
> -					which);
> -	if (ret == 0)
> -@@ -455,16 +476,58 @@ static void media_print_topology_dot(struct media_device *media)
> - }
> -
> - static void media_print_pad_text(struct media_entity *entity,
> --				 const struct media_pad *pad)
> -+				 const struct media_pad *pad,
> -+				 struct v4l2_subdev_route *routes,
> -+				 unsigned int num_routes)
> - {
> -+	unsigned int i;
> -+	uint64_t printed_streams_mask;
> -+
> -	if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV)
> -		return;
> -
> --	v4l2_subdev_print_format(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
> --	v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
> -+	if (!routes) {
> -+		v4l2_subdev_print_format(entity, pad->index, 0, V4L2_SUBDEV_FORMAT_ACTIVE);
> -+		v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
> -+
> -+		if (pad->flags & MEDIA_PAD_FL_SOURCE)
> -+			v4l2_subdev_print_subdev_dv(entity);
> -+
> -+		return;
> -+	}
> -+
> -+	printed_streams_mask = 0;
> -+
> -+	for (i = 0; i < num_routes; ++i) {
> -+		const struct v4l2_subdev_route *r = &routes[i];
> -+		unsigned int stream;
> -
> --	if (pad->flags & MEDIA_PAD_FL_SOURCE)
> --		v4l2_subdev_print_subdev_dv(entity);
> -+		if (!(r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
> -+			continue;
> -+
> -+		if (pad->flags & MEDIA_PAD_FL_SINK) {
> -+			if (r->sink_pad != pad->index)
> -+				continue;
> -+
> -+			stream = r->sink_stream;
> -+		} else {
> -+			if (r->source_pad != pad->index)
> -+				continue;
> -+
> -+			stream = r->source_stream;
> -+		}
> -+
> -+		if (printed_streams_mask & (1 << stream))
> -+			continue;
> -+
> -+		v4l2_subdev_print_format(entity, pad->index, stream, V4L2_SUBDEV_FORMAT_ACTIVE);
> -+		v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
> -+
> -+		if (pad->flags & MEDIA_PAD_FL_SOURCE)
> -+			v4l2_subdev_print_subdev_dv(entity);
> -+
> -+		printed_streams_mask |= (1 << stream);
> -+	}
> - }
> -
> - static void media_print_topology_text_entity(struct media_device *media,
> -@@ -480,11 +543,17 @@ static void media_print_topology_text_entity(struct media_device *media,
> -	unsigned int num_links = media_entity_get_links_count(entity);
> -	unsigned int j, k;
> -	unsigned int padding;
> -+	struct v4l2_subdev_route *routes = NULL;
> -+	unsigned int num_routes = 0;
> -+
> -+	if (media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV)
> -+		v4l2_subdev_get_routing(entity, &routes, &num_routes);
> -
> -	padding = printf("- entity %u: ", info->id);
> --	printf("%s (%u pad%s, %u link%s)\n", info->name,
> -+	printf("%s (%u pad%s, %u link%s, %u route%s)\n", info->name,
> -	       info->pads, info->pads > 1 ? "s" : "",
> --	       num_links, num_links > 1 ? "s" : "");
> -+	       num_links, num_links > 1 ? "s" : "",
> -+	       num_routes, num_routes > 1 ? "s" : "");
> -	printf("%*ctype %s subtype %s flags %x\n", padding, ' ',
> -	       media_entity_type_to_string(info->type),
> -	       media_entity_subtype_to_string(info->type),
> -@@ -492,12 +561,15 @@ static void media_print_topology_text_entity(struct media_device *media,
> -	if (devname)
> -		printf("%*cdevice node name %s\n", padding, ' ', devname);
> -
> -+	if (media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV)
> -+		v4l2_subdev_print_routes(entity, routes, num_routes);
> -+
> -	for (j = 0; j < info->pads; j++) {
> -		const struct media_pad *pad = media_entity_get_pad(entity, j);
> -
> -		printf("\tpad%u: %s\n", j, media_pad_type_to_string(pad->flags));
> -
> --		media_print_pad_text(entity, pad);
> -+		media_print_pad_text(entity, pad, routes, num_routes);
> -
> -		for (k = 0; k < num_links; k++) {
> -			const struct media_link *link = media_entity_get_link(entity, k);
> -@@ -521,6 +593,8 @@ static void media_print_topology_text_entity(struct media_device *media,
> -		}
> -	}
> -	printf("\n");
> -+
> -+	free(routes);
> - }
> -
> - static void media_print_topology_text(struct media_device *media)
> -@@ -594,14 +668,16 @@ int main(int argc, char **argv)
> -
> -	if (media_opts.fmt_pad) {
> -		struct media_pad *pad;
> -+		unsigned int stream;
> -+		char *p;
> -
> --		pad = media_parse_pad(media, media_opts.fmt_pad, NULL);
> -+		pad = media_parse_pad_stream(media, media_opts.fmt_pad, &stream, &p);
> -		if (pad == NULL) {
> -			printf("Pad '%s' not found\n", media_opts.fmt_pad);
> -			goto out;
> -		}
> -
> --		v4l2_subdev_print_format(pad->entity, pad->index,
> -+		v4l2_subdev_print_format(pad->entity, pad->index, stream,
> -					 V4L2_SUBDEV_FORMAT_ACTIVE);
> -	}
> -
> -@@ -685,6 +761,15 @@ int main(int argc, char **argv)
> -		}
> -	}
> -
> -+	if (media_opts.routes) {
> -+		ret = v4l2_subdev_parse_setup_routes(media, media_opts.routes);
> -+		if (ret) {
> -+			printf("Unable to setup routes: %s (%d)\n",
> -+			       strerror(-ret), -ret);
> -+			goto out;
> -+		}
> -+	}
> -+
> -	if (media_opts.interactive) {
> -		while (1) {
> -			char buffer[32];
> -diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
> -index af360518..c0fc2962 100644
> ---- a/utils/media-ctl/mediactl.h
> -+++ b/utils/media-ctl/mediactl.h
> -@@ -394,6 +394,22 @@ struct media_entity *media_parse_entity(struct media_device *media,
> - struct media_pad *media_parse_pad(struct media_device *media,
> -				  const char *p, char **endp);
> -
> -+/**
> -+ * @brief Parse string to a pad and stream on the media device.
> -+ * @param media - media device.
> -+ * @param p - input string
> -+ * @param stream - pointer to uint where the stream number is stored
> -+ * @param endp - pointer to string where parsing ended
> -+ *
> -+ * Parse NULL terminated string describing a pad and stream and return its struct
> -+ * media_pad instance and the stream number.
> -+ *
> -+ * @return Pointer to struct media_pad on success, NULL on failure.
> -+ */
> -+struct media_pad *media_parse_pad_stream(struct media_device *media,
> -+					 const char *p, unsigned int *stream,
> -+					 char **endp);
> -+
> - /**
> -  * @brief Parse string to a link on the media device.
> -  * @param media - media device.
> -diff --git a/utils/media-ctl/options.c b/utils/media-ctl/options.c
> -index 6d30d3dc..58ddec3c 100644
> ---- a/utils/media-ctl/options.c
> -+++ b/utils/media-ctl/options.c
> -@@ -63,6 +63,7 @@ static void usage(const char *argv0)
> -	printf("    --get-v4l2 pad	Print the active format on a given pad\n");
> -	printf("    --get-dv pad        Print detected and current DV timings on a given pad\n");
> -	printf("    --set-dv pad	Configure DV timings on a given pad\n");
> -+	printf("-R, --set-routes routes Configure routes on a given subdev entity\n");
> -	printf("-h, --help		Show verbose help and exit\n");
> -	printf("-i, --interactive	Modify links interactively\n");
> -	printf("-l, --links links	Comma-separated list of link descriptors to setup\n");
> -@@ -78,7 +79,7 @@ static void usage(const char *argv0)
> -	printf("Links and formats are defined as\n");
> -	printf("\tlinks           = link { ',' link } ;\n");
> -	printf("\tlink            = pad '->' pad '[' flags ']' ;\n");
> --	printf("\tpad             = entity ':' pad-number ;\n");
> -+	printf("\tpad             = entity ':' pad-number { '/' stream-number } ;\n");
> -	printf("\tentity          = entity-number | ( '\"' entity-name '\"' ) ;\n");
> -	printf("\n");
> -	printf("\tv4l2            = pad '[' v4l2-properties ']' ;\n");
> -@@ -95,11 +96,16 @@ static void usage(const char *argv0)
> -	printf("\trectangle       = '(' left ',' top, ')' '/' size ;\n");
> -	printf("\tsize            = width 'x' height ;\n");
> -	printf("\n");
> -+	printf("\troutes          = entity '[' route { ',' route } ']' ;\n");
> -+	printf("\troute           = pad-number '/' stream-number '->' pad-number '/' stream-number '[' route-flags ']' ;\n");
> -+	printf("\n");
> -	printf("where the fields are\n");
> -	printf("\tentity-number   Entity numeric identifier\n");
> -	printf("\tentity-name     Entity name (string) \n");
> -	printf("\tpad-number      Pad numeric identifier\n");
> -+	printf("\tstream-number   Stream numeric identifier\n");
> -	printf("\tflags           Link flags (0: inactive, 1: active)\n");
> -+	printf("\troute-flags     Route flags (bitmask of route flags: active - 0x1, immutable - 0x2, source - 0x4)\n");
> -	printf("\tfcc             Format FourCC\n");
> -	printf("\twidth           Image width in pixels\n");
> -	printf("\theight          Image height in pixels\n");
> -@@ -152,6 +158,7 @@ static struct option opts[] = {
> -	{"get-v4l2", 1, 0, OPT_GET_FORMAT},
> -	{"get-dv", 1, 0, OPT_GET_DV},
> -	{"set-dv", 1, 0, OPT_SET_DV},
> -+	{"set-routes", 1, 0, 'R'},
> -	{"help", 0, 0, 'h'},
> -	{"interactive", 0, 0, 'i'},
> -	{"links", 1, 0, 'l'},
> -@@ -237,7 +244,7 @@ int parse_cmdline(int argc, char **argv)
> -	}
> -
> -	/* parse options */
> --	while ((opt = getopt_long(argc, argv, "d:e:f:hil:prvV:",
> -+	while ((opt = getopt_long(argc, argv, "d:e:f:hil:prvV:R:",
> -				  opts, NULL)) != -1) {
> -		switch (opt) {
> -		case 'd':
> -@@ -283,6 +290,10 @@ int parse_cmdline(int argc, char **argv)
> -			media_opts.verbose = 1;
> -			break;
> -
> -+		case 'R':
> -+			media_opts.routes = optarg;
> -+			break;
> -+
> -		case OPT_PRINT_DOT:
> -			media_opts.print_dot = 1;
> -			break;
> -diff --git a/utils/media-ctl/options.h b/utils/media-ctl/options.h
> -index b1751f56..8796f1b6 100644
> ---- a/utils/media-ctl/options.h
> -+++ b/utils/media-ctl/options.h
> -@@ -38,6 +38,7 @@ struct media_options
> -	const char *fmt_pad;
> -	const char *get_dv_pad;
> -	const char *dv_pad;
> -+	const char *routes;
> - };
> -
> - extern struct media_options media_opts;
> -diff --git a/utils/media-ctl/v4l2subdev.h b/utils/media-ctl/v4l2subdev.h
> -index a1813911..a8a6e7ad 100644
> ---- a/utils/media-ctl/v4l2subdev.h
> -+++ b/utils/media-ctl/v4l2subdev.h
> -@@ -64,7 +64,7 @@ void v4l2_subdev_close(struct media_entity *entity);
> -  * @return 0 on success, or a negative error code on failure.
> -  */
> - int v4l2_subdev_get_format(struct media_entity *entity,
> --	struct v4l2_mbus_framefmt *format, unsigned int pad,
> -+	struct v4l2_mbus_framefmt *format, unsigned int pad, unsigned int stream,
> -	enum v4l2_subdev_format_whence which);
> -
> - /**
> -@@ -86,6 +86,7 @@ int v4l2_subdev_get_format(struct media_entity *entity,
> -  */
> - int v4l2_subdev_set_format(struct media_entity *entity,
> -	struct v4l2_mbus_framefmt *format, unsigned int pad,
> -+	unsigned int stream,
> -	enum v4l2_subdev_format_whence which);
> -
> - /**
> -@@ -107,8 +108,8 @@ int v4l2_subdev_set_format(struct media_entity *entity,
> -  * @return 0 on success, or a negative error code on failure.
> -  */
> - int v4l2_subdev_get_selection(struct media_entity *entity,
> --	struct v4l2_rect *rect, unsigned int pad, unsigned int target,
> --	enum v4l2_subdev_format_whence which);
> -+	struct v4l2_rect *rect, unsigned int pad, unsigned int stream,
> -+	unsigned int target, enum v4l2_subdev_format_whence which);
> -
> - /**
> -  * @brief Set a selection rectangle on a pad.
> -@@ -129,8 +130,40 @@ int v4l2_subdev_get_selection(struct media_entity *entity,
> -  * @return 0 on success, or a negative error code on failure.
> -  */
> - int v4l2_subdev_set_selection(struct media_entity *entity,
> --	struct v4l2_rect *rect, unsigned int pad, unsigned int target,
> --	enum v4l2_subdev_format_whence which);
> -+	struct v4l2_rect *rect, unsigned int pad, unsigned int stream,
> -+	unsigned int target, enum v4l2_subdev_format_whence which);
> -+
> -+/**
> -+ * @brief Get the routing table of a subdev media entity.
> -+ * @param entity - subdev-device media entity.
> -+ * @param routes - routes of the subdev.
> -+ * @param num_routes - number of routes.
> -+ *
> -+ * Get the routes of @a entity and return them in an allocated array in @a routes
> -+ * and the number of routes in @a num_routes.
> -+ *
> -+ * The caller is responsible for freeing the routes array after use.
> -+ *
> -+ * @return 0 on success, or a negative error code on failure.
> -+ */
> -+int v4l2_subdev_get_routing(struct media_entity *entity,
> -+			    struct v4l2_subdev_route **routes,
> -+			    unsigned int *num_routes);
> -+
> -+/**
> -+ * @brief Set the routing table of a subdev media entity.
> -+ * @param entity - subdev-device media entity.
> -+ * @param routes - routes of the subdev.
> -+ * @param num_routes - number of routes.
> -+ *
> -+ * Set the routes of @a entity. The routes are given in @a routes with the
> -+ * length of @a num_routes.
> -+ *
> -+ * @return 0 on success, or a negative error code on failure.
> -+ */
> -+int v4l2_subdev_set_routing(struct media_entity *entity,
> -+			    struct v4l2_subdev_route *route,
> -+			    unsigned int num_routes);
> -
> - /**
> -  * @brief Query the digital video capabilities of a pad.
> -@@ -200,7 +233,7 @@ int v4l2_subdev_set_dv_timings(struct media_entity *entity,
> -  */
> -
> - int v4l2_subdev_get_frame_interval(struct media_entity *entity,
> --	struct v4l2_fract *interval, unsigned int pad);
> -+	struct v4l2_fract *interval, unsigned int pad, unsigned int stream);
> -
> - /**
> -  * @brief Set the frame interval on a sub-device.
> -@@ -217,7 +250,7 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
> -  * @return 0 on success, or a negative error code on failure.
> -  */
> - int v4l2_subdev_set_frame_interval(struct media_entity *entity,
> --	struct v4l2_fract *interval, unsigned int pad);
> -+	struct v4l2_fract *interval, unsigned int pad, unsigned int stream);
> -
> - /**
> -  * @brief Parse a string and apply format, crop and frame interval settings.
> -@@ -235,6 +268,17 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
> -  */
> - int v4l2_subdev_parse_setup_formats(struct media_device *media, const char *p);
> -
> -+/**
> -+ * @brief Parse a string and apply route settings.
> -+ * @param media - media device.
> -+ * @param p - input string
> -+ *
> -+ * Parse string @a p and apply route settings to a subdev.
> -+ *
> -+ * @return 0 on success, or a negative error code on failure.
> -+ */
> -+int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p);
> -+
> - /**
> -  * @brief Convert media bus pixel code to string.
> -  * @param code - input string
> ---
> -2.40.0
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-original-patch-mediactl-pkgconfig.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-original-patch-mediactl-pkgconfig.patch
> deleted file mode 100644
> index 6ad9f2c1..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-original-patch-mediactl-pkgconfig.patch
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -From 320b8378ee30eb5e0fe83a8b397f822f2f88a4c1 Mon Sep 17 00:00:00 2001
> -From: Khem Raj <raj.khem@gmail.com>
> -Date: Sun, 1 Mar 2015 22:25:07 +0000
> -Subject: [PATCH] %% original patch: mediactl-pkgconfig.patch
> -
> ----
> - utils/media-ctl/Makefile.am | 1 +
> - 1 file changed, 1 insertion(+)
> -
> -diff --git a/utils/media-ctl/Makefile.am b/utils/media-ctl/Makefile.am
> -index e255e16..ff7b417 100644
> ---- a/utils/media-ctl/Makefile.am
> -+++ b/utils/media-ctl/Makefile.am
> -@@ -20,6 +20,7 @@ libv4l2subdev_la_LIBADD = libmediactl.la
> - mediactl_includedir=$(includedir)/mediactl
> - noinst_HEADERS = mediactl.h v4l2subdev.h
> -
> -+pkgconfig_DATA = libmediactl.pc
> - bin_PROGRAMS = media-ctl
> - media_ctl_SOURCES = media-ctl.c options.c options.h tools.h
> - media_ctl_LDADD = libmediactl.la libv4l2subdev.la
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-original-patch-export-mediactl-headers.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-original-patch-export-mediactl-headers.patch
> deleted file mode 100644
> index 5562d2c1..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-original-patch-export-mediactl-headers.patch
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -From f7109d6b2fcb291824d795071c04a492d9fbc45b Mon Sep 17 00:00:00 2001
> -From: Khem Raj <raj.khem@gmail.com>
> -Date: Sun, 1 Mar 2015 22:25:07 +0000
> -Subject: [PATCH] %% original patch: export-mediactl-headers.patch
> -
> ----
> - utils/media-ctl/Makefile.am | 4 ++--
> - 1 file changed, 2 insertions(+), 2 deletions(-)
> -
> -diff --git a/utils/media-ctl/Makefile.am b/utils/media-ctl/Makefile.am
> -index ff7b417..6ce656f 100644
> ---- a/utils/media-ctl/Makefile.am
> -+++ b/utils/media-ctl/Makefile.am
> -@@ -17,8 +17,8 @@ CLEANFILES = $(BUILT_SOURCES)
> - nodist_libv4l2subdev_la_SOURCES = $(BUILT_SOURCES)
> - libv4l2subdev_la_SOURCES = libv4l2subdev.c
> - libv4l2subdev_la_LIBADD = libmediactl.la
> --mediactl_includedir=$(includedir)/mediactl
> --noinst_HEADERS = mediactl.h v4l2subdev.h
> -+otherincludedir = $(includedir)/mediactl
> -+otherinclude_HEADERS = mediactl.h v4l2subdev.h
> -
> - pkgconfig_DATA = libmediactl.pc
> - bin_PROGRAMS = media-ctl
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch
> deleted file mode 100644
> index aeb97e09..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch
> +++ /dev/null
> @@ -1,459 +0,0 @@
> -From 2866c81d2597f47ed976928bc9c27942bbf095f0 Mon Sep 17 00:00:00 2001
> -From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> -Date: Fri, 10 Feb 2023 13:55:46 +0200
> -Subject: [PATCH 3/3] v4l2-ctl/compliance: add routing and streams multiplexed
> - streams
> -
> -Add basic support for routing and streams.
> -
> -Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
> ----
> - utils/v4l2-compliance/v4l2-compliance.cpp   | 120 ++++++++++++++++----
> - utils/v4l2-compliance/v4l2-compliance.h     |   8 +-
> - utils/v4l2-compliance/v4l2-test-subdevs.cpp |  43 ++++++-
> - 3 files changed, 137 insertions(+), 34 deletions(-)
> -
> -diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp
> -index 8aebae2e..63b5fbbb 100644
> ---- a/utils/v4l2-compliance/v4l2-compliance.cpp
> -+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
> -@@ -1224,6 +1224,10 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
> -	if (node.is_subdev()) {
> -		bool has_source = false;
> -		bool has_sink = false;
> -+		struct v4l2_subdev_routing sd_routing[2] = {};
> -+		struct v4l2_subdev_route sd_routes[2][256] = {};
> -+		bool has_routes = !!(subdevcap.capabilities & V4L2_SUBDEV_CAP_STREAMS);
> -+		int ret;
> -
> -		node.frame_interval_pad = -1;
> -		node.enum_frame_interval_pad = -1;
> -@@ -1235,6 +1239,22 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
> -		}
> -		node.is_passthrough_subdev = has_source && has_sink;
> -
> -+		if (has_routes) {
> -+			for (unsigned which = V4L2_SUBDEV_FORMAT_TRY;
> -+				which <= V4L2_SUBDEV_FORMAT_ACTIVE; which++) {
> -+
> -+				sd_routing[which].which = which;
> -+				sd_routing[which].routes = (__u64)sd_routes[which];
> -+				sd_routing[which].num_routes = 256;
> -+
> -+				ret = doioctl(&node, VIDIOC_SUBDEV_G_ROUTING, &sd_routing[which]);
> -+				if (ret) {
> -+					fail("VIDIOC_SUBDEV_G_ROUTING: failed to get routing\n");
> -+					sd_routing[which].num_routes = 0;
> -+				}
> -+			}
> -+		}
> -+
> -		for (unsigned pad = 0; pad < node.entity.pads; pad++) {
> -			printf("Sub-Device ioctls (%s Pad %u):\n",
> -			       (node.pads[pad].flags & MEDIA_PAD_FL_SINK) ?
> -@@ -1244,32 +1264,82 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
> -			node.has_subdev_enum_fival = 0;
> -			for (unsigned which = V4L2_SUBDEV_FORMAT_TRY;
> -			     which <= V4L2_SUBDEV_FORMAT_ACTIVE; which++) {
> --				printf("\ttest %s VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: %s\n",
> --				       which ? "Active" : "Try",
> --				       ok(testSubDevEnum(&node, which, pad)));
> --				printf("\ttest %s VIDIOC_SUBDEV_G/S_FMT: %s\n",
> --				       which ? "Active" : "Try",
> --				       ok(testSubDevFormat(&node, which, pad)));
> --				printf("\ttest %s VIDIOC_SUBDEV_G/S_SELECTION/CROP: %s\n",
> --				       which ? "Active" : "Try",
> --				       ok(testSubDevSelection(&node, which, pad)));
> --				if (which)
> --					printf("\ttest VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: %s\n",
> --					       ok(testSubDevFrameInterval(&node, pad)));
> -+				struct v4l2_subdev_routing dummy_routing;
> -+				struct v4l2_subdev_route dummy_routes[1];
> -+
> -+				const struct v4l2_subdev_routing *routing;
> -+				const struct v4l2_subdev_route *routes;
> -+
> -+				if (has_routes) {
> -+					routing = &sd_routing[which];
> -+					routes = sd_routes[which];
> -+				} else {
> -+					dummy_routing.num_routes = 1;
> -+					dummy_routing.routes = (__u64)&dummy_routes;
> -+					dummy_routes[0].source_pad = pad;
> -+					dummy_routes[0].source_stream = 0;
> -+					dummy_routes[0].sink_pad = pad;
> -+					dummy_routes[0].sink_stream = 0;
> -+					dummy_routes[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
> -+
> -+					routing = &dummy_routing;
> -+					routes = dummy_routes;
> -+				}
> -+
> -+				for (unsigned i = 0; i < routing->num_routes; ++i) {
> -+					const struct v4l2_subdev_route *r = &routes[i];
> -+					unsigned stream;
> -+
> -+					if (!(r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
> -+						continue;
> -+
> -+					if ((node.pads[pad].flags & MEDIA_PAD_FL_SINK) &&
> -+					    (r->sink_pad == pad))
> -+						stream = r->sink_stream;
> -+					else if ((node.pads[pad].flags & MEDIA_PAD_FL_SOURCE) &&
> -+					    (r->source_pad == pad))
> -+						stream = r->source_stream;
> -+					else
> -+						continue;
> -+
> -+					printf("\t%s Stream %u\n",which ? "Active" : "Try",
> -+					       stream);
> -+
> -+					printf("\ttest %s VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: %s\n",
> -+					       which ? "Active" : "Try",
> -+					       ok(testSubDevEnum(&node, which, pad, stream)));
> -+					printf("\ttest %s VIDIOC_SUBDEV_G/S_FMT: %s\n",
> -+					       which ? "Active" : "Try",
> -+					       ok(testSubDevFormat(&node, which, pad, stream)));
> -+					printf("\ttest %s VIDIOC_SUBDEV_G/S_SELECTION/CROP: %s\n",
> -+					       which ? "Active" : "Try",
> -+					       ok(testSubDevSelection(&node, which, pad, stream)));
> -+					if (which)
> -+						printf("\ttest VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: %s\n",
> -+						       ok(testSubDevFrameInterval(&node, pad, stream)));
> -+				}
> -+			}
> -+
> -+			/*
> -+			 * These tests do not make sense for subdevs with multiplexed streams,
> -+			 * as the try & active cases may have different routing and thus different
> -+			 * behavior.
> -+			 */
> -+			if (!has_routes) {
> -+				if (node.has_subdev_enum_code && node.has_subdev_enum_code < 3)
> -+					fail("VIDIOC_SUBDEV_ENUM_MBUS_CODE: try/active mismatch\n");
> -+				if (node.has_subdev_enum_fsize && node.has_subdev_enum_fsize < 3)
> -+					fail("VIDIOC_SUBDEV_ENUM_FRAME_SIZE: try/active mismatch\n");
> -+				if (node.has_subdev_enum_fival && node.has_subdev_enum_fival < 3)
> -+					fail("VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: try/active mismatch\n");
> -+				if (node.has_subdev_fmt && node.has_subdev_fmt < 3)
> -+					fail("VIDIOC_SUBDEV_G/S_FMT: try/active mismatch\n");
> -+				if (node.has_subdev_selection && node.has_subdev_selection < 3)
> -+					fail("VIDIOC_SUBDEV_G/S_SELECTION: try/active mismatch\n");
> -+				if (node.has_subdev_selection &&
> -+				    node.has_subdev_selection != node.has_subdev_fmt)
> -+					fail("VIDIOC_SUBDEV_G/S_SELECTION: fmt/selection mismatch\n");
> -			}
> --			if (node.has_subdev_enum_code && node.has_subdev_enum_code < 3)
> --				fail("VIDIOC_SUBDEV_ENUM_MBUS_CODE: try/active mismatch\n");
> --			if (node.has_subdev_enum_fsize && node.has_subdev_enum_fsize < 3)
> --				fail("VIDIOC_SUBDEV_ENUM_FRAME_SIZE: try/active mismatch\n");
> --			if (node.has_subdev_enum_fival && node.has_subdev_enum_fival < 3)
> --				fail("VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: try/active mismatch\n");
> --			if (node.has_subdev_fmt && node.has_subdev_fmt < 3)
> --				fail("VIDIOC_SUBDEV_G/S_FMT: try/active mismatch\n");
> --			if (node.has_subdev_selection && node.has_subdev_selection < 3)
> --				fail("VIDIOC_SUBDEV_G/S_SELECTION: try/active mismatch\n");
> --			if (node.has_subdev_selection &&
> --			    node.has_subdev_selection != node.has_subdev_fmt)
> --				fail("VIDIOC_SUBDEV_G/S_SELECTION: fmt/selection mismatch\n");
> -			printf("\n");
> -		}
> -	}
> -diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h
> -index e574c06c..67b3521e 100644
> ---- a/utils/v4l2-compliance/v4l2-compliance.h
> -+++ b/utils/v4l2-compliance/v4l2-compliance.h
> -@@ -373,10 +373,10 @@ int testDecoder(struct node *node);
> -
> - // SubDev ioctl tests
> - int testSubDevCap(struct node *node);
> --int testSubDevEnum(struct node *node, unsigned which, unsigned pad);
> --int testSubDevFormat(struct node *node, unsigned which, unsigned pad);
> --int testSubDevSelection(struct node *node, unsigned which, unsigned pad);
> --int testSubDevFrameInterval(struct node *node, unsigned pad);
> -+int testSubDevEnum(struct node *node, unsigned which, unsigned pad, unsigned stream);
> -+int testSubDevFormat(struct node *node, unsigned which, unsigned pad, unsigned stream);
> -+int testSubDevSelection(struct node *node, unsigned which, unsigned pad, unsigned stream);
> -+int testSubDevFrameInterval(struct node *node, unsigned pad, unsigned stream);
> -
> - // Buffer ioctl tests
> - int testReqBufs(struct node *node);
> -diff --git a/utils/v4l2-compliance/v4l2-test-subdevs.cpp b/utils/v4l2-compliance/v4l2-test-subdevs.cpp
> -index f3d85771..07192bda 100644
> ---- a/utils/v4l2-compliance/v4l2-test-subdevs.cpp
> -+++ b/utils/v4l2-compliance/v4l2-test-subdevs.cpp
> -@@ -25,7 +25,7 @@
> -
> - #include "v4l2-compliance.h"
> -
> --#define VALID_SUBDEV_CAPS (V4L2_SUBDEV_CAP_RO_SUBDEV)
> -+#define VALID_SUBDEV_CAPS (V4L2_SUBDEV_CAP_RO_SUBDEV | V4L2_SUBDEV_CAP_STREAMS)
> -
> - int testSubDevCap(struct node *node)
> - {
> -@@ -54,6 +54,7 @@ static int testSubDevEnumFrameInterval(struct node *node, unsigned which,
> -	memset(&fie, 0, sizeof(fie));
> -	fie.which = which;
> -	fie.pad = pad;
> -+	fie.stream = 0;
> -	fie.code = code;
> -	fie.width = width;
> -	fie.height = height;
> -@@ -83,6 +84,7 @@ static int testSubDevEnumFrameInterval(struct node *node, unsigned which,
> -	memset(&fie, 0xff, sizeof(fie));
> -	fie.which = which;
> -	fie.pad = pad;
> -+	fie.stream = 0;
> -	fie.code = code;
> -	fie.width = width;
> -	fie.height = height;
> -@@ -128,6 +130,7 @@ static int testSubDevEnumFrameSize(struct node *node, unsigned which,
> -	memset(&fse, 0, sizeof(fse));
> -	fse.which = which;
> -	fse.pad = pad;
> -+	fse.stream = 0;
> -	fse.code = code;
> -	ret = doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &fse);
> -	node->has_subdev_enum_fsize |= (ret != ENOTTY) << which;
> -@@ -137,6 +140,7 @@ static int testSubDevEnumFrameSize(struct node *node, unsigned which,
> -		memset(&fie, 0, sizeof(fie));
> -		fie.which = which;
> -		fie.pad = pad;
> -+		fie.stream = 0;
> -		fie.code = code;
> -		fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, &fie) != ENOTTY);
> -		return ret;
> -@@ -152,6 +156,7 @@ static int testSubDevEnumFrameSize(struct node *node, unsigned which,
> -	memset(&fse, 0xff, sizeof(fse));
> -	fse.which = which;
> -	fse.pad = pad;
> -+	fse.stream = 0;
> -	fse.code = code;
> -	fse.index = 0;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &fse));
> -@@ -195,7 +200,7 @@ static int testSubDevEnumFrameSize(struct node *node, unsigned which,
> -	return 0;
> - }
> -
> --int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
> -+int testSubDevEnum(struct node *node, unsigned which, unsigned pad, unsigned stream)
> - {
> -	struct v4l2_subdev_mbus_code_enum mbus_core_enum;
> -	unsigned num_codes;
> -@@ -204,6 +209,7 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
> -	memset(&mbus_core_enum, 0, sizeof(mbus_core_enum));
> -	mbus_core_enum.which = which;
> -	mbus_core_enum.pad = pad;
> -+	mbus_core_enum.stream = stream;
> -	ret = doioctl(node, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbus_core_enum);
> -	node->has_subdev_enum_code |= (ret != ENOTTY) << which;
> -	if (ret == ENOTTY) {
> -@@ -214,8 +220,10 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
> -		memset(&fie, 0, sizeof(fie));
> -		fse.which = which;
> -		fse.pad = pad;
> -+		fse.stream = stream;
> -		fie.which = which;
> -		fie.pad = pad;
> -+		fie.stream = stream;
> -		fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &fse) != ENOTTY);
> -		fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, &fie) != ENOTTY);
> -		return ret;
> -@@ -226,16 +234,19 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
> -	mbus_core_enum.index = ~0;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbus_core_enum) != EINVAL);
> -	mbus_core_enum.pad = node->entity.pads;
> -+	mbus_core_enum.stream = stream;
> -	mbus_core_enum.index = 0;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbus_core_enum) != EINVAL);
> -	memset(&mbus_core_enum, 0xff, sizeof(mbus_core_enum));
> -	mbus_core_enum.which = which;
> -	mbus_core_enum.pad = pad;
> -+	mbus_core_enum.stream = stream;
> -	mbus_core_enum.index = 0;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbus_core_enum));
> -	fail_on_test(check_0(mbus_core_enum.reserved, sizeof(mbus_core_enum.reserved)));
> -	fail_on_test(mbus_core_enum.code == ~0U);
> -	fail_on_test(mbus_core_enum.pad != pad);
> -+	fail_on_test(mbus_core_enum.stream != stream);
> -	fail_on_test(mbus_core_enum.index);
> -	fail_on_test(mbus_core_enum.which != which);
> -	do {
> -@@ -252,6 +263,7 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
> -		fail_on_test(!mbus_core_enum.code);
> -		fail_on_test(mbus_core_enum.which != which);
> -		fail_on_test(mbus_core_enum.pad != pad);
> -+		fail_on_test(mbus_core_enum.stream != stream);
> -		fail_on_test(mbus_core_enum.index != i);
> -
> -		ret = testSubDevEnumFrameSize(node, which, pad, mbus_core_enum.code);
> -@@ -260,7 +272,7 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
> -	return 0;
> - }
> -
> --int testSubDevFrameInterval(struct node *node, unsigned pad)
> -+int testSubDevFrameInterval(struct node *node, unsigned pad, unsigned stream)
> - {
> -	struct v4l2_subdev_frame_interval fival;
> -	struct v4l2_fract ival;
> -@@ -268,6 +280,7 @@ int testSubDevFrameInterval(struct node *node, unsigned pad)
> -
> -	memset(&fival, 0xff, sizeof(fival));
> -	fival.pad = pad;
> -+	fival.stream = stream;
> -	ret = doioctl(node, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &fival);
> -	if (ret == ENOTTY) {
> -		fail_on_test(node->enum_frame_interval_pad >= 0);
> -@@ -279,6 +292,7 @@ int testSubDevFrameInterval(struct node *node, unsigned pad)
> -	node->frame_interval_pad = pad;
> -	fail_on_test(check_0(fival.reserved, sizeof(fival.reserved)));
> -	fail_on_test(fival.pad != pad);
> -+	fail_on_test(fival.stream != stream);
> -	fail_on_test(!fival.interval.numerator);
> -	fail_on_test(!fival.interval.denominator);
> -	fail_on_test(fival.interval.numerator == ~0U || fival.interval.denominator == ~0U);
> -@@ -290,20 +304,25 @@ int testSubDevFrameInterval(struct node *node, unsigned pad)
> -	}
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &fival));
> -	fail_on_test(fival.pad != pad);
> -+	fail_on_test(fival.stream != stream);
> -	fail_on_test(ival.numerator != fival.interval.numerator);
> -	fail_on_test(ival.denominator != fival.interval.denominator);
> -	fail_on_test(check_0(fival.reserved, sizeof(fival.reserved)));
> -	memset(&fival, 0, sizeof(fival));
> -	fival.pad = pad;
> -+	fival.stream = stream;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &fival));
> -	fail_on_test(fival.pad != pad);
> -+	fail_on_test(fival.stream != stream);
> -	fail_on_test(ival.numerator != fival.interval.numerator);
> -	fail_on_test(ival.denominator != fival.interval.denominator);
> -
> -	fival.pad = node->entity.pads;
> -+	fival.stream = stream;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &fival) != EINVAL);
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &fival) != EINVAL);
> -	fival.pad = pad;
> -+	fival.stream = stream;
> -	fival.interval = ival;
> -	fival.interval.numerator = 0;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &fival));
> -@@ -340,7 +359,7 @@ static int checkMBusFrameFmt(struct node *node, struct v4l2_mbus_framefmt &fmt)
> -	return 0;
> - }
> -
> --int testSubDevFormat(struct node *node, unsigned which, unsigned pad)
> -+int testSubDevFormat(struct node *node, unsigned which, unsigned pad, unsigned stream)
> - {
> -	struct v4l2_subdev_format fmt;
> -	struct v4l2_subdev_format s_fmt;
> -@@ -349,6 +368,7 @@ int testSubDevFormat(struct node *node, unsigned which, unsigned pad)
> -	memset(&fmt, 0, sizeof(fmt));
> -	fmt.which = which;
> -	fmt.pad = pad;
> -+	fmt.stream = stream;
> -	ret = doioctl(node, VIDIOC_SUBDEV_G_FMT, &fmt);
> -	node->has_subdev_fmt |= (ret != ENOTTY) << which;
> -	if (ret == ENOTTY) {
> -@@ -359,14 +379,17 @@ int testSubDevFormat(struct node *node, unsigned which, unsigned pad)
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FMT, &fmt) != EINVAL);
> -	fmt.which = 0;
> -	fmt.pad = node->entity.pads;
> -+	fmt.stream = stream;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FMT, &fmt) != EINVAL);
> -	memset(&fmt, 0xff, sizeof(fmt));
> -	fmt.which = which;
> -	fmt.pad = pad;
> -+	fmt.stream = stream;
> -	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FMT, &fmt));
> -	fail_on_test(check_0(fmt.reserved, sizeof(fmt.reserved)));
> -	fail_on_test(fmt.which != which);
> -	fail_on_test(fmt.pad != pad);
> -+	fail_on_test(fmt.stream != stream);
> -	fail_on_test(checkMBusFrameFmt(node, fmt.format));
> -	s_fmt = fmt;
> -	memset(s_fmt.reserved, 0xff, sizeof(s_fmt.reserved));
> -@@ -379,6 +402,7 @@ int testSubDevFormat(struct node *node, unsigned which, unsigned pad)
> -	fail_on_test(ret && ret != ENOTTY);
> -	fail_on_test(s_fmt.which != which);
> -	fail_on_test(s_fmt.pad != pad);
> -+	fail_on_test(s_fmt.stream != stream);
> -	if (ret) {
> -		warn("VIDIOC_SUBDEV_G_FMT is supported but not VIDIOC_SUBDEV_S_FMT\n");
> -		return 0;
> -@@ -423,7 +447,7 @@ static target_info targets[] = {
> -	{ ~0U },
> - };
> -
> --int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
> -+int testSubDevSelection(struct node *node, unsigned which, unsigned pad, unsigned stream)
> - {
> -	struct v4l2_subdev_selection sel;
> -	struct v4l2_subdev_selection s_sel;
> -@@ -435,10 +459,12 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
> -	targets[V4L2_SEL_TGT_NATIVE_SIZE].readonly = is_sink;
> -	memset(&crop, 0, sizeof(crop));
> -	crop.pad = pad;
> -+	crop.stream = stream;
> -	crop.which = which;
> -	memset(&sel, 0, sizeof(sel));
> -	sel.which = which;
> -	sel.pad = pad;
> -+	sel.stream = stream;
> -	sel.target = V4L2_SEL_TGT_CROP;
> -	ret = doioctl(node, VIDIOC_SUBDEV_G_SELECTION, &sel);
> -	node->has_subdev_selection |= (ret != ENOTTY) << which;
> -@@ -451,6 +477,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
> -	fail_on_test(check_0(crop.reserved, sizeof(crop.reserved)));
> -	fail_on_test(crop.which != which);
> -	fail_on_test(crop.pad != pad);
> -+	fail_on_test(crop.stream != stream);
> -	fail_on_test(memcmp(&crop.rect, &sel.r, sizeof(sel.r)));
> -
> -	for (unsigned tgt = 0; targets[tgt].target != ~0U; tgt++) {
> -@@ -458,6 +485,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
> -		memset(&sel, 0xff, sizeof(sel));
> -		sel.which = which;
> -		sel.pad = pad;
> -+		sel.stream = stream;
> -		sel.target = tgt;
> -		ret = doioctl(node, VIDIOC_SUBDEV_G_SELECTION, &sel);
> -		targets[tgt].found = !ret;
> -@@ -469,6 +497,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
> -		fail_on_test(check_0(sel.reserved, sizeof(sel.reserved)));
> -		fail_on_test(sel.which != which);
> -		fail_on_test(sel.pad != pad);
> -+		fail_on_test(sel.stream != stream);
> -		fail_on_test(sel.target != tgt);
> -		fail_on_test(!sel.r.width);
> -		fail_on_test(sel.r.width == ~0U);
> -@@ -480,9 +509,11 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
> -		fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_SELECTION, &sel) != EINVAL);
> -		sel.which = 0;
> -		sel.pad = node->entity.pads;
> -+		sel.stream = stream;
> -		fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_SELECTION, &sel) != EINVAL);
> -		sel.which = which;
> -		sel.pad = pad;
> -+		sel.stream = stream;
> -		s_sel = sel;
> -		memset(s_sel.reserved, 0xff, sizeof(s_sel.reserved));
> -		ret = doioctl(node, VIDIOC_SUBDEV_S_SELECTION, &s_sel);
> -@@ -496,6 +527,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
> -				fail_on_test(check_0(crop.reserved, sizeof(crop.reserved)));
> -				fail_on_test(crop.which != which);
> -				fail_on_test(crop.pad != pad);
> -+				fail_on_test(crop.stream != stream);
> -				fail_on_test(memcmp(&crop.rect, &sel.r, sizeof(sel.r)));
> -			}
> -		}
> -@@ -504,6 +536,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
> -		fail_on_test(!ret && targets[tgt].readonly);
> -		fail_on_test(s_sel.which != which);
> -		fail_on_test(s_sel.pad != pad);
> -+		fail_on_test(s_sel.stream != stream);
> -		if (ret && !targets[tgt].readonly && tgt != V4L2_SEL_TGT_NATIVE_SIZE)
> -			warn("VIDIOC_SUBDEV_G_SELECTION is supported for target %u but not VIDIOC_SUBDEV_S_SELECTION\n", tgt);
> -		if (ret)
> ---
> -2.40.0
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0004-Do-not-use-getsubopt.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0004-Do-not-use-getsubopt.patch
> deleted file mode 100644
> index f67d48e9..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0004-Do-not-use-getsubopt.patch
> +++ /dev/null
> @@ -1,59 +0,0 @@
> -From 6e7e52de7afe29597016952a7317faf9c3ea3268 Mon Sep 17 00:00:00 2001
> -From: Khem Raj <raj.khem@gmail.com>
> -Date: Sat, 30 Nov 2019 18:50:34 -0800
> -Subject: [PATCH] Do not use getsubopt
> -
> -POSIX says that behavior when subopts list is empty is undefined.
> -musl libs will set value to NULL which leads to crash.
> -
> -Simply avoid getsubopt, since we cannot rely on it.
> -
> -Imported from Alpine Linux
> -
> -Upstream-Status: Pending
> -
> -Signed-off-by: Khem Raj <raj.khem@gmail.com>
> -
> -Adapt patch to 1.23.0.
> -
> -(v4l-utils rev fd544473800d02e90bc289434cc44e5aa8fadd0f).
> -
> -%% original patch: 0007-Do-not-use-getsubopt.patch
> -
> -Signed-off-by: Daniel Gomez <daniel@qtec.com>
> ----
> - utils/v4l2-ctl/v4l2-ctl-common.cpp | 18 ++++++++++--------
> - 1 file changed, 10 insertions(+), 8 deletions(-)
> -
> -diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp
> -index d77f7104..838c297d 100644
> ---- a/utils/v4l2-ctl/v4l2-ctl-common.cpp
> -+++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp
> -@@ -994,15 +994,17 @@ static bool parse_subset(char *optarg)
> -
> - static bool parse_next_subopt(char **subs, char **value)
> - {
> --	static char *const subopts[] = {
> --	    nullptr
> --	};
> --	int opt = v4l_getsubopt(subs, subopts, value);
> -+	char *p = *subs;
> -+	*value = *subs;
> -
> --	if (opt < 0 || *value)
> --		return false;
> --	fprintf(stderr, "Missing suboption value\n");
> --	return true;
> -+	while (*p && *p != ',')
> -+		p++;
> -+
> -+	if (*p)
> -+		*p++ = '\0';
> -+
> -+	*subs = p;
> -+	return false;
> - }
> -
> - void common_cmd(const std::string &media_bus_info, int ch, char *optarg)
> ---
> -2.35.1
> diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils_1.24.1.bb b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils_1.24.1.bb
> deleted file mode 100644
> index a2ebb0ea..00000000
> --- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils_1.24.1.bb
> +++ /dev/null
> @@ -1,84 +0,0 @@
> -SUMMARY = "v4l2 and IR applications"
> -LICENSE = "GPL-2.0-only & LGPL-2.1-only"
> -LIC_FILES_CHKSUM = "file://COPYING;md5=48da9957849056017dc568bbc43d8975 \
> -                    file://COPYING.libv4l;md5=d749e86a105281d7a44c2328acebc4b0"
> -PROVIDES = "libv4l media-ctl"
> -
> -DEPENDS = "jpeg \
> -           ${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'virtual/libx11', '', d)} \
> -           ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)} \
> -           ${@bb.utils.contains('DISTRO_FEATURES', 'alsa', 'alsa-lib', '', d)} \
> -           ${@bb.utils.contains_any('PACKAGECONFIG', 'qv4l2 qvidcap', 'qtbase qtbase-native', '', d)}"
> -
> -DEPENDS:append:libc-musl = " argp-standalone"
> -DEPENDS:append:class-target = " udev"
> -LDFLAGS:append = " -pthread"
> -# v4l2 explicitly sets _FILE_OFFSET_BITS=32 to get access to
> -# both 32 and 64 bit file APIs.  But it does not handle the time side?
> -# Needs further investigation
> -GLIBC_64BIT_TIME_FLAGS = ""
> -
> -inherit autotools gettext pkgconfig
> -
> -PACKAGECONFIG ??= "media-ctl"
> -PACKAGECONFIG[media-ctl] = "--enable-v4l-utils,--disable-v4l-utils,,"
> -PACKAGECONFIG[qv4l2] = ",--disable-qv4l2"
> -PACKAGECONFIG[qvidcap] = ",--disable-qvidcap"
> -
> -SRC_URI = "\
> -    http://linuxtv.org/downloads/v4l-utils/v4l-utils-${PV}.tar.bz2 \
> -    file://0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch \
> -    file://0002-original-patch-mediactl-pkgconfig.patch \
> -    file://0003-original-patch-export-mediactl-headers.patch \
> -    file://0004-Do-not-use-getsubopt.patch \
> -    file://0001-v4l2-ctl-Add-routing-and-streams-support.patch \
> -    file://0002-media-ctl-add-support-for-routes-and-streams.patch \
> -    file://0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch \
> -    file://0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch \
> -"
> -
> -SRC_URI[md5sum] = "8ba9c73c4319b6afab5fa4358edc43de"
> -SRC_URI[sha256sum] = "cbb7fe8a6307f5ce533a05cded70bb93c3ba06395ab9b6d007eb53b75d805f5b"
> -
> -EXTRA_OECONF = "--enable-shared --with-udevdir=${base_libdir}/udev \
> -                --disable-v4l2-compliance-32 --disable-v4l2-ctl-32"
> -
> -VIRTUAL-RUNTIME_ir-keytable-keymaps ?= "rc-keymaps"
> -
> -PACKAGES =+ "media-ctl ir-keytable rc-keymaps libv4l libv4l-dev qv4l2 qvidcap"
> -
> -RPROVIDES:${PN}-dbg += "libv4l-dbg"
> -
> -FILES:media-ctl = "${bindir}/media-ctl ${libdir}/libmediactl.so.*"
> -FILES:qv4l2 = "\
> -    ${bindir}/qv4l2 \
> -    ${datadir}/applications/qv4l2.desktop \
> -    ${datadir}/icons/hicolor/*/apps/qv4l2.* \
> -"
> -FILES:qvidcap = "\
> -    ${bindir}/qvidcap \
> -    ${datadir}/applications/qvidcap.desktop \
> -    ${datadir}/icons/hicolor/*/apps/qvidcap.* \
> -"
> -
> -FILES:ir-keytable = "${bindir}/ir-keytable ${base_libdir}/udev/rules.d/*-infrared.rules"
> -RDEPENDS:ir-keytable += "${VIRTUAL-RUNTIME_ir-keytable-keymaps}"
> -RDEPENDS:qv4l2 += "\
> -    ${@bb.utils.contains('PACKAGECONFIG', 'qv4l2', 'qtbase', '', d)}"
> -RDEPENDS:qvidcap += "\
> -    ${@bb.utils.contains('PACKAGECONFIG', 'qvidcap', 'qtbase', '', d)}"
> -
> -FILES:rc-keymaps = "${sysconfdir}/rc* ${base_libdir}/udev/rc*"
> -
> -FILES:${PN} = "${bindir} ${sbindir}"
> -
> -FILES:libv4l += "${libdir}/libv4l*${SOLIBS} ${libdir}/libv4l/*.so ${libdir}/libv4l/plugins/*.so \
> -                 ${libdir}/libdvbv5*${SOLIBS} \
> -                 ${libdir}/libv4l/*-decomp"
> -
> -FILES:libv4l-dev += "${includedir} ${libdir}/pkgconfig \
> -                     ${libdir}/libv4l*${SOLIBSDEV} ${libdir}/*.la \
> -                     ${libdir}/v4l*${SOLIBSDEV} ${libdir}/libv4l/*.la ${libdir}/libv4l/plugins/*.la"
> -
> -PARALLEL_MAKE:class-native = ""
> -BBCLASSEXTEND = "native"
diff mbox series

Patch

diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch
deleted file mode 100644
index 7305e471..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch
+++ /dev/null
@@ -1,43 +0,0 @@ 
-From 0d5c0e9a75eca43667b0e29155b635e50622b66a Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Fri, 27 Feb 2015 21:55:36 +0000
-Subject: [PATCH] Revert "media-ctl: Don't install libmediactl and
-
- libv4l2subdev"
-
-This reverts commit 0911dce53b08b0df3066be2c75f67e8a314d8729.
-
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
-
-Conflicts:
-	utils/media-ctl/Makefile.am
-
----
- utils/media-ctl/Makefile.am | 10 +++-------
- 1 file changed, 3 insertions(+), 7 deletions(-)
-
-diff --git a/utils/media-ctl/Makefile.am b/utils/media-ctl/Makefile.am
-index c48c8d6..e255e16 100644
---- a/utils/media-ctl/Makefile.am
-+++ b/utils/media-ctl/Makefile.am
-@@ -1,8 +1,7 @@
--noinst_LTLIBRARIES = libmediactl.la libv4l2subdev.la
--
-+lib_LTLIBRARIES = libmediactl.la libv4l2subdev.la
- libmediactl_la_SOURCES = libmediactl.c mediactl-priv.h
--libmediactl_la_CFLAGS = -static $(LIBUDEV_CFLAGS)
--libmediactl_la_LDFLAGS = -static $(LIBUDEV_LIBS)
-+libmediactl_la_CFLAGS = $(LIBUDEV_CFLAGS)
-+libmediactl_la_LDFLAGS = $(LIBUDEV_LIBS)
-
- media-bus-format-names.h: ../../include/linux/media-bus-format.h
-	$(AM_V_GEN) sed -e '/#define MEDIA_BUS_FMT/ ! d; s/.*FMT_//; /FIXED/ d; s/\t.*//; s/.*/{ \"&\", MEDIA_BUS_FMT_& },/;' \
-@@ -18,9 +17,6 @@ CLEANFILES = $(BUILT_SOURCES)
- nodist_libv4l2subdev_la_SOURCES = $(BUILT_SOURCES)
- libv4l2subdev_la_SOURCES = libv4l2subdev.c
- libv4l2subdev_la_LIBADD = libmediactl.la
--libv4l2subdev_la_CFLAGS = -static
--libv4l2subdev_la_LDFLAGS = -static
--
- mediactl_includedir=$(includedir)/mediactl
- noinst_HEADERS = mediactl.h v4l2subdev.h
diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch
deleted file mode 100644
index 1dff0637..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch
+++ /dev/null
@@ -1,61 +0,0 @@ 
-From 26e2a60d29456a9cc6acb16ea19039414808bc5e Mon Sep 17 00:00:00 2001
-From: Jai Luthra <j-luthra@ti.com>
-Date: Tue, 5 Jul 2022 16:23:39 +0530
-Subject: [PATCH] media-ctl: add support for RGBIr bayer formats
-
-Signed-off-by: Jai Luthra <j-luthra@ti.com>
----
- include/linux/media-bus-format.h | 10 +++++++++-
- include/linux/videodev2.h        |  9 +++++++++
- 2 files changed, 18 insertions(+), 1 deletion(-)
-
-diff --git a/include/linux/media-bus-format.h b/include/linux/media-bus-format.h
-index ca9a24c8..cbdf3798 100644
---- a/include/linux/media-bus-format.h
-+++ b/include/linux/media-bus-format.h
-@@ -117,7 +117,7 @@
- #define MEDIA_BUS_FMT_YUV16_1X48		0x202a
- #define MEDIA_BUS_FMT_UYYVYY16_0_5X48		0x202b
-
--/* Bayer - next is	0x3021 */
-+/* Bayer - next is	0x3029 */
- #define MEDIA_BUS_FMT_SBGGR8_1X8		0x3001
- #define MEDIA_BUS_FMT_SGBRG8_1X8		0x3013
- #define MEDIA_BUS_FMT_SGRBG8_1X8		0x3002
-@@ -150,6 +150,14 @@
- #define MEDIA_BUS_FMT_SGBRG16_1X16		0x301e
- #define MEDIA_BUS_FMT_SGRBG16_1X16		0x301f
- #define MEDIA_BUS_FMT_SRGGB16_1X16		0x3020
-+#define MEDIA_BUS_FMT_SRGGI10_1X10		0x3021
-+#define MEDIA_BUS_FMT_SGRIG10_1X10		0x3022
-+#define MEDIA_BUS_FMT_SBGGI10_1X10		0x3023
-+#define MEDIA_BUS_FMT_SGBIG10_1X10		0x3024
-+#define MEDIA_BUS_FMT_SGIRG10_1X10		0x3025
-+#define MEDIA_BUS_FMT_SIGGR10_1X10		0x3026
-+#define MEDIA_BUS_FMT_SGIBG10_1X10		0x3027
-+#define MEDIA_BUS_FMT_SIGGB10_1X10		0x3028
-
- /* JPEG compressed formats - next is	0x4002 */
- #define MEDIA_BUS_FMT_JPEG_1X8			0x4001
-diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
-index 5eb96692..093104ab 100644
---- a/include/linux/videodev2.h
-+++ b/include/linux/videodev2.h
-@@ -682,6 +682,15 @@ struct v4l2_pix_format {
- #define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') /* 16  GBGB.. RGRG.. */
- #define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') /* 16  GRGR.. BGBG.. */
- #define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') /* 16  RGRG.. GBGB.. */
-+	/* 10bit raw bayer with IR (4x4) */
-+#define V4L2_PIX_FMT_SRGGI10 v4l2_fourcc('R', 'G', 'I', '0') /* 10 RGBG.. GIrGIr.. */
-+#define V4L2_PIX_FMT_SGRIG10 v4l2_fourcc('G', 'R', 'I', '0') /* 10 GRGB.. IrGIrG.. */
-+#define V4L2_PIX_FMT_SBGGI10 v4l2_fourcc('B', 'G', 'I', '0') /* 10 BGRG.. GIrGIr.. */
-+#define V4L2_PIX_FMT_SGBIG10 v4l2_fourcc('G', 'B', 'I', '0') /* 10 GBGR.. IrGIrG.. */
-+#define V4L2_PIX_FMT_SGIRG10 v4l2_fourcc('G', 'I', 'R', '0') /* 10 GIrGIr.. RGBG.. */
-+#define V4L2_PIX_FMT_SIGGR10 v4l2_fourcc('I', 'G', 'R', '0') /* 10 IrGIrG.. GRGB.. */
-+#define V4L2_PIX_FMT_SGIBG10 v4l2_fourcc('G', 'I', 'B', '0') /* 10 GIrGIr.. BGRG.. */
-+#define V4L2_PIX_FMT_SIGGB10 v4l2_fourcc('I', 'G', 'B', '0') /* 10 IrGIrG.. GBGR.. */
-
- /* HSV formats */
- #define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3')
---
-2.40.0
diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-v4l2-ctl-Add-routing-and-streams-support.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-v4l2-ctl-Add-routing-and-streams-support.patch
deleted file mode 100644
index 9fd19edc..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0001-v4l2-ctl-Add-routing-and-streams-support.patch
+++ /dev/null
@@ -1,618 +0,0 @@ 
-From 3b57a10f899403acd877683ca0247f2a9eba8850 Mon Sep 17 00:00:00 2001
-From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
-Date: Fri, 10 Feb 2023 13:55:44 +0200
-Subject: [PATCH 1/3] v4l2-ctl: Add routing and streams support
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Add support to get and set subdev routes and to get and set
-configurations per stream.
-
-Based on work from Jacopo Mondi <jacopo@jmondi.org> and
-Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>.
-
-Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
----
- utils/v4l2-ctl/v4l2-ctl-subdev.cpp | 288 +++++++++++++++++++++++++----
- utils/v4l2-ctl/v4l2-ctl.cpp        |   2 +
- utils/v4l2-ctl/v4l2-ctl.h          |   2 +
- 3 files changed, 259 insertions(+), 33 deletions(-)
-
-diff --git a/utils/v4l2-ctl/v4l2-ctl-subdev.cpp b/utils/v4l2-ctl/v4l2-ctl-subdev.cpp
-index 33cc1342..81236451 100644
---- a/utils/v4l2-ctl/v4l2-ctl-subdev.cpp
-+++ b/utils/v4l2-ctl/v4l2-ctl-subdev.cpp
-@@ -1,5 +1,13 @@
- #include "v4l2-ctl.h"
-
-+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
-+
-+/*
-+ * The max value comes from a check in the kernel source code
-+ * drivers/media/v4l2-core/v4l2-ioctl.c check_array_args()
-+ */
-+#define NUM_ROUTES_MAX 256
-+
- struct mbus_name {
-	const char *name;
-	__u32 code;
-@@ -19,45 +27,57 @@ static const struct mbus_name mbus_names[] = {
- #define SelectionFlags 		(1L<<4)
-
- static __u32 list_mbus_codes_pad;
-+static __u32 list_mbus_codes_stream = 0;
- static __u32 get_fmt_pad;
-+static __u32 get_fmt_stream = 0;
- static __u32 get_sel_pad;
-+static __u32 get_sel_stream = 0;
- static __u32 get_fps_pad;
-+static __u32 get_fps_stream = 0;
- static int get_sel_target = -1;
- static unsigned int set_selection;
- static struct v4l2_subdev_selection vsel;
- static unsigned int set_fmt;
- static __u32 set_fmt_pad;
-+static __u32 set_fmt_stream = 0;
- static struct v4l2_mbus_framefmt ffmt;
- static struct v4l2_subdev_frame_size_enum frmsize;
- static struct v4l2_subdev_frame_interval_enum frmival;
- static __u32 set_fps_pad;
-+static __u32 set_fps_stream = 0;
- static double set_fps;
-+static struct v4l2_subdev_routing routing;
-+static struct v4l2_subdev_route routes[NUM_ROUTES_MAX];
-
- void subdev_usage()
- {
-	printf("\nSub-Device options:\n"
--	       "  --list-subdev-mbus-codes <pad>\n"
-+	       "  --list-subdev-mbus-codes pad=<pad>,stream=<stream>\n"
-	       "                      display supported mediabus codes for this pad (0 is default)\n"
-	       "                      [VIDIOC_SUBDEV_ENUM_MBUS_CODE]\n"
--	       "  --list-subdev-framesizes pad=<pad>,code=<code>\n"
-+	       "  --list-subdev-framesizes pad=<pad>,stream=<stream>,code=<code>\n"
-	       "                     list supported framesizes for this pad and code\n"
-	       "                     [VIDIOC_SUBDEV_ENUM_FRAME_SIZE]\n"
-	       "                     <code> is the value of the mediabus code\n"
--	       "  --list-subdev-frameintervals pad=<pad>,width=<w>,height=<h>,code=<code>\n"
-+	       "  --list-subdev-frameintervals pad=<pad>,stream=<stream>,width=<w>,height=<h>,code=<code>\n"
-	       "                     list supported frame intervals for this pad and code and\n"
-	       "                     the given width and height [VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL]\n"
-	       "                     <code> is the value of the mediabus code\n"
--	       "  --get-subdev-fmt [<pad>]\n"
--	       "     		     query the frame format for the given pad [VIDIOC_SUBDEV_G_FMT]\n"
--	       "  --get-subdev-selection pad=<pad>,target=<target>\n"
-+	       "  --get-subdev-fmt pad=<pad>,stream=<stream>\n"
-+	       "     		     query the frame format for the given pad and optional stream [VIDIOC_SUBDEV_G_FMT]\n"
-+	       "		     <pad> the pad to get the format from\n"
-+	       "		     <stream> the stream to get the format from (0 if not specified)\n"
-+	       "  --get-subdev-selection pad=<pad>,stream=<stream>,target=<target>\n"
-	       "                     query the frame selection rectangle [VIDIOC_SUBDEV_G_SELECTION]\n"
-	       "                     See --set-subdev-selection command for the valid <target> values.\n"
--	       "  --get-subdev-fps [<pad>]\n"
-+	       "  --get-subdev-fps pad=<pad>,stream=<stream>\n"
-	       "                     query the frame rate [VIDIOC_SUBDEV_G_FRAME_INTERVAL]\n"
-	       "  --set-subdev-fmt   (for testing only, otherwise use media-ctl)\n"
--	       "  --try-subdev-fmt pad=<pad>,width=<w>,height=<h>,code=<code>,field=<f>,colorspace=<c>,\n"
-+	       "  --try-subdev-fmt pad=<pad>,stream=<stream>,width=<w>,height=<h>,code=<code>,field=<f>,colorspace=<c>,\n"
-	       "                   xfer=<xf>,ycbcr=<y>,hsv=<hsv>,quantization=<q>\n"
--	       "                     set the frame format [VIDIOC_SUBDEV_S_FMT]\n"
-+	       "                     set the frame format for the given pad and optional stream [VIDIOC_SUBDEV_S_FMT]\n"
-+	       "                     <pad> the pad to get the format from\n"
-+	       "                     <stream> the stream to get the format from (0 if not specified)\n"
-	       "                     <code> is the value of the mediabus code\n"
-	       "                     <f> can be one of the following field layouts:\n"
-	       "                       any, none, top, bottom, interlaced, seq_tb, seq_bt,\n"
-@@ -74,14 +94,30 @@ void subdev_usage()
-	       "                     <q> can be one of the following quantization methods:\n"
-	       "                       default, full-range, lim-range\n"
-	       "  --set-subdev-selection (for testing only, otherwise use media-ctl)\n"
--	       "  --try-subdev-selection pad=<pad>,target=<target>,flags=<flags>,\n"
-+	       "  --try-subdev-selection pad=<pad>,stream=<stream>,target=<target>,flags=<flags>,\n"
-	       "                         top=<x>,left=<y>,width=<w>,height=<h>\n"
-	       "                     set the video capture selection rectangle [VIDIOC_SUBDEV_S_SELECTION]\n"
-	       "                     target=crop|crop_bounds|crop_default|compose|compose_bounds|\n"
-	       "                            compose_default|compose_padded|native_size\n"
-	       "                     flags=le|ge|keep-config\n"
--	       "  --set-subdev-fps pad=<pad>,fps=<fps> (for testing only, otherwise use media-ctl)\n"
-+	       "  --set-subdev-fps pad=<pad>,stream=<stream>,fps=<fps> (for testing only, otherwise use media-ctl)\n"
-	       "                     set the frame rate [VIDIOC_SUBDEV_S_FRAME_INTERVAL]\n"
-+	       "  --get-routing      Print the route topology\n"
-+	       "  --set-routing <routes>\n"
-+	       "                     Comma-separated list of route descriptors to setup\n"
-+	       "\n"
-+	       "Routes are defined as\n"
-+	       "	routes		= route { ',' route } ;\n"
-+	       "	route		= sink '->' source '[' flags ']' ;\n"
-+	       "	sink		= sink-pad '/' sink-stream ;\n"
-+	       "	source		= source-pad '/' source-stream ;\n"
-+	       "\n"
-+	       "where\n"
-+	       "	sink-pad	= Pad numeric identifier for sink\n"
-+	       "	sink-stream	= Stream numeric identifier for sink\n"
-+	       "	source-pad	= Pad numeric identifier for source\n"
-+	       "	source-stream	= Stream numeric identifier for source\n"
-+	       "	flags		= Route flags (0: inactive, 1: active)\n"
-	       );
- }
-
-@@ -91,14 +127,33 @@ void subdev_cmd(int ch, char *optarg)
-
-	switch (ch) {
-	case OptListSubDevMBusCodes:
--		if (optarg)
--			list_mbus_codes_pad = strtoul(optarg, nullptr, 0);
-+		subs = optarg;
-+		while (subs && *subs != '\0') {
-+			static constexpr const char *subopts[] = {
-+				"pad",
-+				"stream",
-+				nullptr
-+			};
-+
-+			switch (parse_subopt(&subs, subopts, &value)) {
-+			case 0:
-+				list_mbus_codes_pad = strtoul(value, nullptr, 0);
-+				break;
-+			case 1:
-+				list_mbus_codes_stream = strtoul(value, nullptr, 0);
-+				break;
-+			default:
-+				subdev_usage();
-+				std::exit(EXIT_FAILURE);
-+			}
-+		}
-		break;
-	case OptListSubDevFrameSizes:
-		subs = optarg;
-		while (*subs != '\0') {
-			static constexpr const char *subopts[] = {
-				"pad",
-+				"stream",
-				"code",
-				nullptr
-			};
-@@ -108,6 +163,9 @@ void subdev_cmd(int ch, char *optarg)
-				frmsize.pad = strtoul(value, nullptr, 0);
-				break;
-			case 1:
-+				frmsize.stream = strtoul(value, nullptr, 0);
-+				break;
-+			case 2:
-				frmsize.code = strtoul(value, nullptr, 0);
-				break;
-			default:
-@@ -121,6 +179,7 @@ void subdev_cmd(int ch, char *optarg)
-		while (*subs != '\0') {
-			static constexpr const char *subopts[] = {
-				"pad",
-+				"stream",
-				"code",
-				"width",
-				"height",
-@@ -132,12 +191,15 @@ void subdev_cmd(int ch, char *optarg)
-				frmival.pad = strtoul(value, nullptr, 0);
-				break;
-			case 1:
--				frmival.code = strtoul(value, nullptr, 0);
-+				frmival.stream = strtoul(value, nullptr, 0);
-				break;
-			case 2:
--				frmival.width = strtoul(value, nullptr, 0);
-+				frmival.code = strtoul(value, nullptr, 0);
-				break;
-			case 3:
-+				frmival.width = strtoul(value, nullptr, 0);
-+				break;
-+			case 4:
-				frmival.height = strtoul(value, nullptr, 0);
-				break;
-			default:
-@@ -147,14 +209,33 @@ void subdev_cmd(int ch, char *optarg)
-		}
-		break;
-	case OptGetSubDevFormat:
--		if (optarg)
--			get_fmt_pad = strtoul(optarg, nullptr, 0);
-+		subs = optarg;
-+		while (subs && *subs != '\0') {
-+			static constexpr const char *subopts[] = {
-+				"pad",
-+				"stream",
-+				nullptr
-+			};
-+
-+			switch (parse_subopt(&subs, subopts, &value)) {
-+			case 0:
-+				get_fmt_pad = strtoul(value, nullptr, 0);
-+				break;
-+			case 1:
-+				get_fmt_stream = strtoul(value, nullptr, 0);
-+				break;
-+			default:
-+				subdev_usage();
-+				std::exit(EXIT_FAILURE);
-+			}
-+		}
-		break;
-	case OptGetSubDevSelection:
-		subs = optarg;
-		while (*subs != '\0') {
-			static constexpr const char *subopts[] = {
-				"pad",
-+				"stream",
-				"target",
-				nullptr
-			};
-@@ -165,6 +246,9 @@ void subdev_cmd(int ch, char *optarg)
-				get_sel_pad = strtoul(value, nullptr, 0);
-				break;
-			case 1:
-+				get_sel_stream = strtoul(value, nullptr, 0);
-+				break;
-+			case 2:
-				if (parse_selection_target(value, target)) {
-					fprintf(stderr, "Unknown selection target\n");
-					subdev_usage();
-@@ -179,8 +263,26 @@ void subdev_cmd(int ch, char *optarg)
-		}
-		break;
-	case OptGetSubDevFPS:
--		if (optarg)
--			get_fps_pad = strtoul(optarg, nullptr, 0);
-+		subs = optarg;
-+		while (subs && *subs != '\0') {
-+			static constexpr const char *subopts[] = {
-+				"pad",
-+				"stream",
-+				nullptr
-+			};
-+
-+			switch (parse_subopt(&subs, subopts, &value)) {
-+			case 0:
-+				get_fps_pad = strtoul(value, nullptr, 0);
-+				break;
-+			case 1:
-+				get_fps_stream = strtoul(value, nullptr, 0);
-+				break;
-+			default:
-+				subdev_usage();
-+				std::exit(EXIT_FAILURE);
-+			}
-+		}
-		break;
-	case OptSetSubDevFormat:
-	case OptTrySubDevFormat:
-@@ -198,6 +300,7 @@ void subdev_cmd(int ch, char *optarg)
-				"quantization",
-				"xfer",
-				"pad",
-+				"stream",
-				nullptr
-			};
-
-@@ -244,6 +347,9 @@ void subdev_cmd(int ch, char *optarg)
-			case 9:
-				set_fmt_pad = strtoul(value, nullptr, 0);
-				break;
-+			case 10:
-+				set_fmt_stream = strtoul(value, nullptr, 0);
-+				break;
-			default:
-				fprintf(stderr, "Unknown option\n");
-				subdev_usage();
-@@ -264,6 +370,7 @@ void subdev_cmd(int ch, char *optarg)
-				"width",
-				"height",
-				"pad",
-+				"stream",
-				nullptr
-			};
-
-@@ -298,6 +405,9 @@ void subdev_cmd(int ch, char *optarg)
-			case 6:
-				vsel.pad = strtoul(value, nullptr, 0);
-				break;
-+			case 7:
-+				vsel.stream = strtoul(value, nullptr, 0);
-+				break;
-			default:
-				fprintf(stderr, "Unknown option\n");
-				subdev_usage();
-@@ -311,6 +421,7 @@ void subdev_cmd(int ch, char *optarg)
-		while (*subs != '\0') {
-			static constexpr const char *subopts[] = {
-				"pad",
-+				"stream",
-				"fps",
-				nullptr
-			};
-@@ -320,6 +431,9 @@ void subdev_cmd(int ch, char *optarg)
-				set_fps_pad = strtoul(value, nullptr, 0);
-				break;
-			case 1:
-+				set_fps_stream = strtoul(value, nullptr, 0);
-+				break;
-+			case 2:
-				set_fps = strtod(value, nullptr);
-				break;
-			default:
-@@ -329,6 +443,47 @@ void subdev_cmd(int ch, char *optarg)
-			}
-		}
-		break;
-+	case OptSetRouting: {
-+		struct v4l2_subdev_route *r;
-+		char *end, *ref, *tok;
-+		unsigned int flags;
-+
-+		memset(&routing, 0, sizeof(routing));
-+		memset(routes, 0, sizeof(routes[0]) * NUM_ROUTES_MAX);
-+		routing.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-+		routing.num_routes = 0;
-+		routing.routes = (__u64)routes;
-+
-+		if (!optarg)
-+			break;
-+
-+		r = (v4l2_subdev_route *)routing.routes;
-+		ref = end = strdup(optarg);
-+		while ((tok = strsep(&end, ",")) != NULL) {
-+			if (sscanf(tok, "%u/%u -> %u/%u [%u]",
-+				   &r->sink_pad, &r->sink_stream,
-+				   &r->source_pad, &r->source_stream,
-+				   &flags) != 5) {
-+				free(ref);
-+				fprintf(stderr, "Invalid route information specified\n");
-+				subdev_usage();
-+				std::exit(EXIT_FAILURE);
-+			}
-+
-+			if (flags & ~(V4L2_SUBDEV_ROUTE_FL_ACTIVE)) {
-+				fprintf(stderr, "Invalid route flags specified: %#x\n", flags);
-+				subdev_usage();
-+				std::exit(EXIT_FAILURE);
-+			}
-+
-+			r->flags = flags;
-+
-+			r++;
-+			routing.num_routes++;
-+		}
-+		free(ref);
-+		break;
-+	}
-	default:
-		break;
-	}
-@@ -394,6 +549,7 @@ void subdev_set(cv4l_fd &_fd)
-
-		memset(&fmt, 0, sizeof(fmt));
-		fmt.pad = set_fmt_pad;
-+		fmt.stream = set_fmt_stream;
-		fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-
-		if (doioctl(fd, VIDIOC_SUBDEV_G_FMT, &fmt) == 0) {
-@@ -430,7 +586,7 @@ void subdev_set(cv4l_fd &_fd)
-			else
-				fmt.which = V4L2_SUBDEV_FORMAT_TRY;
-
--			printf("ioctl: VIDIOC_SUBDEV_S_FMT (pad=%u)\n", fmt.pad);
-+			printf("ioctl: VIDIOC_SUBDEV_S_FMT (pad=%u,stream=%u)\n", fmt.pad, fmt.stream);
-			ret = doioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt);
-			if (ret == 0 && (verbose || !options[OptSetSubDevFormat]))
-				print_framefmt(fmt.format);
-@@ -441,6 +597,7 @@ void subdev_set(cv4l_fd &_fd)
-
-		memset(&sel, 0, sizeof(sel));
-		sel.pad = vsel.pad;
-+		sel.stream = vsel.stream;
-		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-		sel.target = vsel.target;
-
-@@ -461,7 +618,7 @@ void subdev_set(cv4l_fd &_fd)
-			else
-				sel.which = V4L2_SUBDEV_FORMAT_TRY;
-
--			printf("ioctl: VIDIOC_SUBDEV_S_SELECTION (pad=%u)\n", sel.pad);
-+			printf("ioctl: VIDIOC_SUBDEV_S_SELECTION (pad=%u,stream=%u)\n", sel.pad, sel.stream);
-			int ret = doioctl(fd, VIDIOC_SUBDEV_S_SELECTION, &sel);
-			if (ret == 0 && (verbose || !options[OptSetSubDevSelection]))
-				print_subdev_selection(sel);
-@@ -472,6 +629,7 @@ void subdev_set(cv4l_fd &_fd)
-
-		memset(&fival, 0, sizeof(fival));
-		fival.pad = set_fps_pad;
-+		fival.stream = set_fps_stream;
-
-		if (set_fps <= 0) {
-			fprintf(stderr, "invalid fps %f\n", set_fps);
-@@ -482,7 +640,7 @@ void subdev_set(cv4l_fd &_fd)
-		fival.interval.denominator = static_cast<uint32_t>(set_fps * fival.interval.numerator);
-		printf("Note: --set-subdev-fps is only for testing.\n"
-		       "Normally media-ctl is used to configure the video pipeline.\n");
--		printf("ioctl: VIDIOC_SUBDEV_S_FRAME_INTERVAL (pad=%u)\n", fival.pad);
-+		printf("ioctl: VIDIOC_SUBDEV_S_FRAME_INTERVAL (pad=%u,stream=%u)\n", fival.pad, fival.stream);
-		if (doioctl(fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &fival) == 0) {
-			if (!fival.interval.denominator || !fival.interval.numerator)
-				printf("\tFrames per second: invalid (%d/%d)\n",
-@@ -493,6 +651,55 @@ void subdev_set(cv4l_fd &_fd)
-					fival.interval.denominator, fival.interval.numerator);
-		}
-	}
-+	if (options[OptSetRouting]) {
-+		if (doioctl(fd, VIDIOC_SUBDEV_S_ROUTING, &routing) == 0)
-+			printf("Routing set\n");
-+	}
-+}
-+
-+struct flag_name {
-+	__u32 flag;
-+	const char *name;
-+};
-+
-+static void print_flags(const struct flag_name *flag_names, unsigned int num_entries, __u32 flags)
-+{
-+	bool first = true;
-+	unsigned int i;
-+
-+	for (i = 0; i < num_entries; i++) {
-+		if (!(flags & flag_names[i].flag))
-+			continue;
-+		if (!first)
-+			printf(",");
-+		printf("%s", flag_names[i].name);
-+		flags &= ~flag_names[i].flag;
-+		first = false;
-+	}
-+
-+	if (flags) {
-+		if (!first)
-+			printf(",");
-+		printf("0x%x", flags);
-+	}
-+}
-+
-+static void print_routes(const struct v4l2_subdev_routing *r)
-+{
-+	unsigned int i;
-+	struct v4l2_subdev_route *routes = (struct v4l2_subdev_route *)r->routes;
-+
-+	static const struct flag_name route_flags[] = {
-+		{ V4L2_SUBDEV_ROUTE_FL_ACTIVE, "ACTIVE" },
-+	};
-+
-+	for (i = 0; i < r->num_routes; i++) {
-+		printf("%d/%d -> %d/%d [",
-+		       routes[i].sink_pad, routes[i].sink_stream,
-+		       routes[i].source_pad, routes[i].source_stream);
-+		print_flags(route_flags, ARRAY_SIZE(route_flags), routes[i].flags);
-+		printf("]\n");
-+	}
- }
-
- void subdev_get(cv4l_fd &_fd)
-@@ -505,8 +712,9 @@ void subdev_get(cv4l_fd &_fd)
-		memset(&fmt, 0, sizeof(fmt));
-		fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-		fmt.pad = get_fmt_pad;
-+		fmt.stream = get_fmt_stream;
-
--		printf("ioctl: VIDIOC_SUBDEV_G_FMT (pad=%u)\n", fmt.pad);
-+		printf("ioctl: VIDIOC_SUBDEV_G_FMT (pad=%u, stream=%u)\n", fmt.pad, fmt.stream);
-		if (doioctl(fd, VIDIOC_SUBDEV_G_FMT, &fmt) == 0)
-			print_framefmt(fmt.format);
-	}
-@@ -518,8 +726,9 @@ void subdev_get(cv4l_fd &_fd)
-		memset(&sel, 0, sizeof(sel));
-		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-		sel.pad = get_sel_pad;
-+		sel.stream = get_sel_stream;
-
--		printf("ioctl: VIDIOC_SUBDEV_G_SELECTION (pad=%u)\n", sel.pad);
-+		printf("ioctl: VIDIOC_SUBDEV_G_SELECTION (pad=%u,stream=%u)\n", sel.pad, sel.stream);
-		if (options[OptAll] || get_sel_target == -1) {
-			while (valid_seltarget_at_idx(idx)) {
-				sel.target = seltarget_at_idx(idx);
-@@ -538,8 +747,9 @@ void subdev_get(cv4l_fd &_fd)
-
-		memset(&fival, 0, sizeof(fival));
-		fival.pad = get_fps_pad;
-+		fival.stream = get_fps_stream;
-
--		printf("ioctl: VIDIOC_SUBDEV_G_FRAME_INTERVAL (pad=%u)\n", fival.pad);
-+		printf("ioctl: VIDIOC_SUBDEV_G_FRAME_INTERVAL (pad=%u,stream=%u)\n", fival.pad, fival.stream);
-		if (doioctl(fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &fival) == 0) {
-			if (!fival.interval.denominator || !fival.interval.numerator)
-				printf("\tFrames per second: invalid (%d/%d)\n",
-@@ -550,6 +760,17 @@ void subdev_get(cv4l_fd &_fd)
-					fival.interval.denominator, fival.interval.numerator);
-		}
-	}
-+
-+	if (options[OptGetRouting]) {
-+		memset(&routing, 0, sizeof(routing));
-+		memset(routes, 0, sizeof(routes[0]) * NUM_ROUTES_MAX);
-+		routing.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-+		routing.num_routes = NUM_ROUTES_MAX;
-+		routing.routes = (__u64)routes;
-+
-+		if (doioctl(fd, VIDIOC_SUBDEV_G_ROUTING, &routing) == 0)
-+			print_routes(&routing);
-+	}
- }
-
- static void print_mbus_code(__u32 code)
-@@ -566,11 +787,12 @@ static void print_mbus_code(__u32 code)
-		printf("\t0x%04x", code);
- }
-
--static void print_mbus_codes(int fd, __u32 pad)
-+static void print_mbus_codes(int fd, __u32 pad, __u32 stream)
- {
-	struct v4l2_subdev_mbus_code_enum mbus_code = {};
-
-	mbus_code.pad = pad;
-+	mbus_code.stream = stream;
-	mbus_code.which = V4L2_SUBDEV_FORMAT_TRY;
-
-	for (;;) {
-@@ -623,13 +845,13 @@ void subdev_list(cv4l_fd &_fd)
-	int fd = _fd.g_fd();
-
-	if (options[OptListSubDevMBusCodes]) {
--		printf("ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=%u)\n",
--		       list_mbus_codes_pad);
--		print_mbus_codes(fd, list_mbus_codes_pad);
-+		printf("ioctl: VIDIOC_SUBDEV_ENUM_MBUS_CODE (pad=%u,stream=%u)\n",
-+		       list_mbus_codes_pad, list_mbus_codes_stream);
-+		print_mbus_codes(fd, list_mbus_codes_pad, list_mbus_codes_stream);
-	}
-	if (options[OptListSubDevFrameSizes]) {
--		printf("ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE (pad=%u)\n",
--		       frmsize.pad);
-+		printf("ioctl: VIDIOC_SUBDEV_ENUM_FRAME_SIZE (pad=%u,stream=%u)\n",
-+		       frmsize.pad, frmsize.stream);
-		frmsize.index = 0;
-		frmsize.which = V4L2_SUBDEV_FORMAT_TRY;
-		while (test_ioctl(fd, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &frmsize) >= 0) {
-@@ -638,8 +860,8 @@ void subdev_list(cv4l_fd &_fd)
-		}
-	}
-	if (options[OptListSubDevFrameIntervals]) {
--		printf("ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=%u)\n",
--		       frmival.pad);
-+		printf("ioctl: VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL (pad=%u,stream=%u)\n",
-+		       frmival.pad, frmival.stream);
-		frmival.index = 0;
-		frmival.which = V4L2_SUBDEV_FORMAT_TRY;
-		while (test_ioctl(fd, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, &frmival) >= 0) {
-diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
-index 8585278f..1cfb50f7 100644
---- a/utils/v4l2-ctl/v4l2-ctl.cpp
-+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
-@@ -64,6 +64,8 @@ static struct option long_options[] = {
-	{"get-fmt-video-out", no_argument, nullptr, OptGetVideoOutFormat},
-	{"set-fmt-video-out", required_argument, nullptr, OptSetVideoOutFormat},
-	{"try-fmt-video-out", required_argument, nullptr, OptTryVideoOutFormat},
-+	{"set-routing", required_argument, 0, OptSetRouting},
-+	{"get-routing", no_argument, 0, OptGetRouting},
-	{"help", no_argument, nullptr, OptHelp},
-	{"help-tuner", no_argument, nullptr, OptHelpTuner},
-	{"help-io", no_argument, nullptr, OptHelpIO},
-diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
-index 70a80ade..51a68b92 100644
---- a/utils/v4l2-ctl/v4l2-ctl.h
-+++ b/utils/v4l2-ctl/v4l2-ctl.h
-@@ -197,6 +197,8 @@ enum Option {
-	OptInfoEdid,
-	OptShowEdid,
-	OptFixEdidChecksums,
-+	OptSetRouting,
-+	OptGetRouting,
-	OptFreqSeek,
-	OptEncoderCmd,
-	OptTryEncoderCmd,
---
-2.40.0
diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-media-ctl-add-support-for-routes-and-streams.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-media-ctl-add-support-for-routes-and-streams.patch
deleted file mode 100644
index 79864f01..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-media-ctl-add-support-for-routes-and-streams.patch
+++ /dev/null
@@ -1,1021 +0,0 @@ 
-From 868c176e0de433777d5eed3e6d6d8dc03b9145a6 Mon Sep 17 00:00:00 2001
-From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
-Date: Fri, 10 Feb 2023 13:55:45 +0200
-Subject: [PATCH 2/3] media-ctl: add support for routes and streams
-
-Add support to get and set subdev routes and to get and set
-configurations per stream.
-
-Based on work from Sakari Ailus <sakari.ailus@linux.intel.com>.
-
-Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
----
- utils/media-ctl/libmediactl.c   |  41 +++++
- utils/media-ctl/libv4l2subdev.c | 283 ++++++++++++++++++++++++++++----
- utils/media-ctl/media-ctl.c     | 121 ++++++++++++--
- utils/media-ctl/mediactl.h      |  16 ++
- utils/media-ctl/options.c       |  15 +-
- utils/media-ctl/options.h       |   1 +
- utils/media-ctl/v4l2subdev.h    |  58 ++++++-
- 7 files changed, 478 insertions(+), 57 deletions(-)
-
-diff --git a/utils/media-ctl/libmediactl.c b/utils/media-ctl/libmediactl.c
-index 1fd6525b..537365d0 100644
---- a/utils/media-ctl/libmediactl.c
-+++ b/utils/media-ctl/libmediactl.c
-@@ -876,6 +876,47 @@ struct media_pad *media_parse_pad(struct media_device *media,
-	return &entity->pads[pad];
- }
-
-+struct media_pad *media_parse_pad_stream(struct media_device *media,
-+					 const char *p, unsigned int *stream,
-+					 char **endp)
-+{
-+	struct media_pad *pad;
-+	const char *orig_p = p;
-+	char *ep;
-+
-+	pad = media_parse_pad(media, p, &ep);
-+	if (pad == NULL)
-+		return NULL;
-+
-+	p = ep;
-+
-+	if (*p == '/') {
-+		unsigned int s;
-+
-+		p++;
-+
-+		s = strtoul(p, &ep, 10);
-+
-+		if (ep == p) {
-+			printf("Unable to parse stream: '%s'\n", orig_p);
-+			if (endp)
-+				*endp = (char*)p;
-+			return NULL;
-+		}
-+
-+		*stream = s;
-+
-+		p++;
-+	} else {
-+		*stream = 0;
-+	}
-+
-+	if (endp)
-+		*endp = (char*)p;
-+
-+	return pad;
-+}
-+
- struct media_link *media_parse_link(struct media_device *media,
-				    const char *p, char **endp)
- {
-diff --git a/utils/media-ctl/libv4l2subdev.c b/utils/media-ctl/libv4l2subdev.c
-index 63bb3d75..d203e5b4 100644
---- a/utils/media-ctl/libv4l2subdev.c
-+++ b/utils/media-ctl/libv4l2subdev.c
-@@ -64,7 +64,7 @@ void v4l2_subdev_close(struct media_entity *entity)
- }
-
- int v4l2_subdev_get_format(struct media_entity *entity,
--	struct v4l2_mbus_framefmt *format, unsigned int pad,
-+	struct v4l2_mbus_framefmt *format, unsigned int pad, unsigned int stream,
-	enum v4l2_subdev_format_whence which)
- {
-	struct v4l2_subdev_format fmt;
-@@ -76,6 +76,7 @@ int v4l2_subdev_get_format(struct media_entity *entity,
-
-	memset(&fmt, 0, sizeof(fmt));
-	fmt.pad = pad;
-+	fmt.stream = stream;
-	fmt.which = which;
-
-	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_FMT, &fmt);
-@@ -88,6 +89,7 @@ int v4l2_subdev_get_format(struct media_entity *entity,
-
- int v4l2_subdev_set_format(struct media_entity *entity,
-	struct v4l2_mbus_framefmt *format, unsigned int pad,
-+	unsigned int stream,
-	enum v4l2_subdev_format_whence which)
- {
-	struct v4l2_subdev_format fmt;
-@@ -99,6 +101,7 @@ int v4l2_subdev_set_format(struct media_entity *entity,
-
-	memset(&fmt, 0, sizeof(fmt));
-	fmt.pad = pad;
-+	fmt.stream = stream;
-	fmt.which = which;
-	fmt.format = *format;
-
-@@ -111,8 +114,8 @@ int v4l2_subdev_set_format(struct media_entity *entity,
- }
-
- int v4l2_subdev_get_selection(struct media_entity *entity,
--	struct v4l2_rect *rect, unsigned int pad, unsigned int target,
--	enum v4l2_subdev_format_whence which)
-+	struct v4l2_rect *rect, unsigned int pad, unsigned int stream,
-+	unsigned int target, enum v4l2_subdev_format_whence which)
- {
-	union {
-		struct v4l2_subdev_selection sel;
-@@ -150,8 +153,8 @@ int v4l2_subdev_get_selection(struct media_entity *entity,
- }
-
- int v4l2_subdev_set_selection(struct media_entity *entity,
--	struct v4l2_rect *rect, unsigned int pad, unsigned int target,
--	enum v4l2_subdev_format_whence which)
-+	struct v4l2_rect *rect, unsigned int pad, unsigned int stream,
-+	unsigned int target, enum v4l2_subdev_format_whence which)
- {
-	union {
-		struct v4l2_subdev_selection sel;
-@@ -165,6 +168,7 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
-
-	memset(&u.sel, 0, sizeof(u.sel));
-	u.sel.pad = pad;
-+	u.sel.stream = stream;
-	u.sel.target = target;
-	u.sel.which = which;
-	u.sel.r = *rect;
-@@ -179,6 +183,7 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
-
-	memset(&u.crop, 0, sizeof(u.crop));
-	u.crop.pad = pad;
-+	u.crop.stream = stream;
-	u.crop.which = which;
-	u.crop.rect = *rect;
-
-@@ -190,6 +195,69 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
-	return 0;
- }
-
-+int v4l2_subdev_set_routing(struct media_entity *entity,
-+			    struct v4l2_subdev_route *routes,
-+			    unsigned int num_routes)
-+{
-+	struct v4l2_subdev_routing routing = {
-+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
-+		.routes = (uintptr_t)routes,
-+		.num_routes = num_routes,
-+	};
-+	int ret;
-+
-+	ret = v4l2_subdev_open(entity);
-+	if (ret < 0)
-+		return ret;
-+
-+	ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_ROUTING, &routing);
-+	if (ret == -1)
-+		return -errno;
-+
-+	return 0;
-+}
-+
-+int v4l2_subdev_get_routing(struct media_entity *entity,
-+			    struct v4l2_subdev_route **routes,
-+			    unsigned int *num_routes)
-+{
-+	struct v4l2_subdev_routing routing = { 0 };
-+	struct v4l2_subdev_route *r;
-+	int ret;
-+
-+	ret = v4l2_subdev_open(entity);
-+	if (ret < 0)
-+		return ret;
-+
-+	routing.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-+
-+	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_ROUTING, &routing);
-+	if (ret == -1 && errno != ENOSPC)
-+		return -errno;
-+
-+	if (!routing.num_routes) {
-+		*routes = NULL;
-+		*num_routes = 0;
-+		return 0;
-+	}
-+
-+	r = calloc(routing.num_routes, sizeof(*r));
-+	if (!r)
-+		return -ENOMEM;
-+
-+	routing.routes = (uintptr_t)r;
-+	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_ROUTING, &routing);
-+	if (ret) {
-+		free(r);
-+		return ret;
-+	}
-+
-+	*num_routes = routing.num_routes;
-+	*routes = r;
-+
-+	return 0;
-+}
-+
- int v4l2_subdev_get_dv_timings_caps(struct media_entity *entity,
-	struct v4l2_dv_timings_cap *caps)
- {
-@@ -264,7 +332,7 @@ int v4l2_subdev_set_dv_timings(struct media_entity *entity,
-
- int v4l2_subdev_get_frame_interval(struct media_entity *entity,
-				   struct v4l2_fract *interval,
--				   unsigned int pad)
-+				   unsigned int pad, unsigned int stream)
- {
-	struct v4l2_subdev_frame_interval ival;
-	int ret;
-@@ -275,6 +343,7 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
-
-	memset(&ival, 0, sizeof(ival));
-	ival.pad = pad;
-+	ival.stream = stream;
-
-	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &ival);
-	if (ret < 0)
-@@ -286,7 +355,7 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
-
- int v4l2_subdev_set_frame_interval(struct media_entity *entity,
-				   struct v4l2_fract *interval,
--				   unsigned int pad)
-+				   unsigned int pad, unsigned int stream)
- {
-	struct v4l2_subdev_frame_interval ival;
-	int ret;
-@@ -297,6 +366,7 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
-
-	memset(&ival, 0, sizeof(ival));
-	ival.pad = pad;
-+	ival.stream = stream;
-	ival.interval = *interval;
-
-	ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &ival);
-@@ -307,6 +377,155 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
-	return 0;
- }
-
-+static int v4l2_subdev_parse_setup_route(struct media_device *media,
-+					 struct v4l2_subdev_route *r,
-+					 const char *p, char **endp)
-+{
-+	char *end;
-+
-+	/* sink pad/stream */
-+
-+	r->sink_pad = strtoul(p, &end, 10);
-+
-+	if (*end != '/') {
-+		media_dbg(media, "Expected '/'\n");
-+		return -EINVAL;
-+	}
-+
-+	p = end + 1;
-+
-+	r->sink_stream = strtoul(p, &end, 10);
-+
-+	for (; isspace(*end); ++end);
-+
-+	if (end[0] != '-' || end[1] != '>') {
-+		media_dbg(media, "Expected '->'\n");
-+		return -EINVAL;
-+	}
-+	p = end + 2;
-+
-+	/* source pad/stream */
-+
-+	r->source_pad = strtoul(p, &end, 10);
-+
-+	if (*end != '/') {
-+		media_dbg(media, "Expected '/'\n");
-+		return -EINVAL;
-+	}
-+
-+	p = end + 1;
-+
-+	r->source_stream = strtoul(p, &end, 10);
-+
-+	/* flags */
-+
-+	for (; isspace(*end); ++end);
-+
-+	if (*end != '[') {
-+		media_dbg(media, "Expected '['\n");
-+		return -EINVAL;
-+	}
-+
-+	for (end++; isspace(*end); ++end);
-+
-+	p = end;
-+
-+	r->flags = strtoul(p, &end, 0);
-+
-+	if (r->flags & ~(V4L2_SUBDEV_ROUTE_FL_ACTIVE)) {
-+		media_dbg(media, "Bad route flags %#x\n", r->flags);
-+		return -EINVAL;
-+	}
-+
-+	for (; isspace(*end); ++end);
-+
-+	if (*end != ']') {
-+		media_dbg(media, "Expected ']'\n");
-+		return -EINVAL;
-+	}
-+	end++;
-+
-+	*endp = end;
-+
-+	return 0;
-+}
-+
-+int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p)
-+{
-+	struct media_entity *entity;
-+	struct v4l2_subdev_route *routes;
-+	unsigned int num_routes;
-+	char *end;
-+	int ret;
-+	int i;
-+
-+	entity = media_parse_entity(media, p, &end);
-+	if (!entity)
-+		return -EINVAL;
-+
-+	p = end;
-+
-+	if (*p != '[') {
-+		media_dbg(media, "Expected '['\n");
-+		return -EINVAL;
-+	}
-+
-+	p++;
-+
-+	routes = calloc(256, sizeof(routes[0]));
-+	if (!routes)
-+		return -ENOMEM;
-+
-+	num_routes = 0;
-+
-+	while (*p != 0) {
-+		struct v4l2_subdev_route *r = &routes[num_routes];
-+
-+		ret = v4l2_subdev_parse_setup_route(media, r, p, &end);
-+		if (ret)
-+			goto out;
-+
-+		p = end;
-+
-+		num_routes++;
-+
-+		if (*p == ',') {
-+			p++;
-+			continue;
-+		}
-+
-+		break;
-+	}
-+
-+	if (*p != ']') {
-+		media_dbg(media, "Expected ']'\n");
-+		ret = -EINVAL;
-+		goto out;
-+	}
-+
-+	for (i = 0; i < num_routes; ++i) {
-+		struct v4l2_subdev_route *r = &routes[i];
-+
-+		media_dbg(entity->media,
-+			  "Setting up route %s : %u/%u -> %u/%u, flags 0x%8.8x\n",
-+			  entity->info.name,
-+			  r->sink_pad, r->sink_stream,
-+			  r->source_pad, r->source_stream,
-+			  r->flags);
-+	}
-+
-+	ret = v4l2_subdev_set_routing(entity, routes, num_routes);
-+	if (ret) {
-+		printf("VIDIOC_SUBDEV_S_ROUTING failed: %d\n", ret);
-+		goto out;
-+	}
-+
-+out:
-+	free(routes);
-+
-+	return ret;
-+}
-+
- static int v4l2_subdev_parse_format(struct media_device *media,
-				    struct v4l2_mbus_framefmt *format,
-				    const char *p, char **endp)
-@@ -442,7 +661,8 @@ static bool strhazit(const char *str, const char **p)
- }
-
- static struct media_pad *v4l2_subdev_parse_pad_format(
--	struct media_device *media, struct v4l2_mbus_framefmt *format,
-+	struct media_device *media, unsigned int *stream,
-+	struct v4l2_mbus_framefmt *format,
-	struct v4l2_rect *crop, struct v4l2_rect *compose,
-	struct v4l2_fract *interval, const char *p, char **endp)
- {
-@@ -453,7 +673,7 @@ static struct media_pad *v4l2_subdev_parse_pad_format(
-
-	for (; isspace(*p); ++p);
-
--	pad = media_parse_pad(media, p, &end);
-+	pad = media_parse_pad_stream(media, p, stream, &end);
-	if (pad == NULL) {
-		*endp = end;
-		return NULL;
-@@ -675,6 +895,7 @@ static struct media_pad *v4l2_subdev_parse_pad_format(
- }
-
- static int set_format(struct media_pad *pad,
-+		      unsigned int stream,
-		      struct v4l2_mbus_framefmt *format)
- {
-	int ret;
-@@ -683,12 +904,12 @@ static int set_format(struct media_pad *pad,
-		return 0;
-
-	media_dbg(pad->entity->media,
--		  "Setting up format %s %ux%u on pad %s/%u\n",
-+		  "Setting up format %s %ux%u on pad %s/%u/%u\n",
-		  v4l2_subdev_pixelcode_to_string(format->code),
-		  format->width, format->height,
--		  pad->entity->info.name, pad->index);
-+		  pad->entity->info.name, pad->index, stream);
-
--	ret = v4l2_subdev_set_format(pad->entity, format, pad->index,
-+	ret = v4l2_subdev_set_format(pad->entity, format, pad->index, stream,
-				     V4L2_SUBDEV_FORMAT_ACTIVE);
-	if (ret < 0) {
-		media_dbg(pad->entity->media,
-@@ -705,8 +926,8 @@ static int set_format(struct media_pad *pad,
-	return 0;
- }
-
--static int set_selection(struct media_pad *pad, unsigned int target,
--			 struct v4l2_rect *rect)
-+static int set_selection(struct media_pad *pad, unsigned int stream,
-+			 unsigned int target, struct v4l2_rect *rect)
- {
-	int ret;
-
-@@ -714,11 +935,11 @@ static int set_selection(struct media_pad *pad, unsigned int target,
-		return 0;
-
-	media_dbg(pad->entity->media,
--		  "Setting up selection target %u rectangle (%u,%u)/%ux%u on pad %s/%u\n",
-+		  "Setting up selection target %u rectangle (%u,%u)/%ux%u on pad %s/%u/%u\n",
-		  target, rect->left, rect->top, rect->width, rect->height,
--		  pad->entity->info.name, pad->index);
-+		  pad->entity->info.name, pad->index, stream);
-
--	ret = v4l2_subdev_set_selection(pad->entity, rect, pad->index,
-+	ret = v4l2_subdev_set_selection(pad->entity, rect, pad->index, stream,
-					target, V4L2_SUBDEV_FORMAT_ACTIVE);
-	if (ret < 0) {
-		media_dbg(pad->entity->media,
-@@ -734,7 +955,7 @@ static int set_selection(struct media_pad *pad, unsigned int target,
-	return 0;
- }
-
--static int set_frame_interval(struct media_pad *pad,
-+static int set_frame_interval(struct media_pad *pad, unsigned int stream,
-			      struct v4l2_fract *interval)
- {
-	int ret;
-@@ -743,11 +964,12 @@ static int set_frame_interval(struct media_pad *pad,
-		return 0;
-
-	media_dbg(pad->entity->media,
--		  "Setting up frame interval %u/%u on pad %s/%u\n",
-+		  "Setting up frame interval %u/%u on pad %s/%u/%u\n",
-		  interval->numerator, interval->denominator,
--		  pad->entity->info.name, pad->index);
-+		  pad->entity->info.name, pad->index, stream);
-
--	ret = v4l2_subdev_set_frame_interval(pad->entity, interval, pad->index);
-+	ret = v4l2_subdev_set_frame_interval(pad->entity, interval, pad->index,
-+					     stream);
-	if (ret < 0) {
-		media_dbg(pad->entity->media,
-			  "Unable to set frame interval: %s (%d)",
-@@ -770,11 +992,13 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
-	struct v4l2_rect crop = { -1, -1, -1, -1 };
-	struct v4l2_rect compose = crop;
-	struct v4l2_fract interval = { 0, 0 };
-+	unsigned int stream;
-	unsigned int i;
-	char *end;
-	int ret;
-
--	pad = v4l2_subdev_parse_pad_format(media, &format, &crop, &compose,
-+	pad = v4l2_subdev_parse_pad_format(media, &stream,
-+					   &format, &crop, &compose,
-					   &interval, p, &end);
-	if (pad == NULL) {
-		media_print_streampos(media, p, end);
-@@ -783,30 +1007,29 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
-	}
-
-	if (pad->flags & MEDIA_PAD_FL_SINK) {
--		ret = set_format(pad, &format);
-+		ret = set_format(pad, stream, &format);
-		if (ret < 0)
-			return ret;
-	}
-
--	ret = set_selection(pad, V4L2_SEL_TGT_CROP, &crop);
-+	ret = set_selection(pad, stream, V4L2_SEL_TGT_CROP, &crop);
-	if (ret < 0)
-		return ret;
-
--	ret = set_selection(pad, V4L2_SEL_TGT_COMPOSE, &compose);
-+	ret = set_selection(pad, stream, V4L2_SEL_TGT_COMPOSE, &compose);
-	if (ret < 0)
-		return ret;
-
-	if (pad->flags & MEDIA_PAD_FL_SOURCE) {
--		ret = set_format(pad, &format);
-+		ret = set_format(pad, stream, &format);
-		if (ret < 0)
-			return ret;
-	}
-
--	ret = set_frame_interval(pad, &interval);
-+	ret = set_frame_interval(pad, stream, &interval);
-	if (ret < 0)
-		return ret;
-
--
-	/* If the pad is an output pad, automatically set the same format and
-	 * frame interval on the remote subdev input pads, if any.
-	 */
-@@ -821,9 +1044,9 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
-			if (link->source == pad &&
-			    link->sink->entity->info.type == MEDIA_ENT_T_V4L2_SUBDEV) {
-				remote_format = format;
--				set_format(link->sink, &remote_format);
-+				set_format(link->sink, stream, &remote_format);
-
--				ret = set_frame_interval(link->sink, &interval);
-+				ret = set_frame_interval(link->sink, stream, &interval);
-				if (ret < 0 && ret != -EINVAL && ret != -ENOTTY)
-					return ret;
-			}
-diff --git a/utils/media-ctl/media-ctl.c b/utils/media-ctl/media-ctl.c
-index 84ee7a83..831136a0 100644
---- a/utils/media-ctl/media-ctl.c
-+++ b/utils/media-ctl/media-ctl.c
-@@ -28,6 +28,7 @@
- #include <errno.h>
- #include <fcntl.h>
- #include <stdbool.h>
-+#include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-@@ -75,23 +76,43 @@ static void print_flags(const struct flag_name *flag_names, unsigned int num_ent
-	}
- }
-
-+static void v4l2_subdev_print_routes(struct media_entity *entity,
-+				     struct v4l2_subdev_route *routes,
-+				     unsigned int num_routes)
-+{
-+	unsigned int i;
-+
-+	for (i = 0; i < num_routes; i++) {
-+		const struct v4l2_subdev_route *r = &routes[i];
-+
-+		if (i == 0)
-+			printf("\troutes:\n");
-+
-+		printf("\t\t%u/%u -> %u/%u [%s]\n",
-+		       r->sink_pad, r->sink_stream,
-+		       r->source_pad, r->source_stream,
-+		       r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE ? "ACTIVE" : "INACTIVE");
-+	}
-+}
-+
- static void v4l2_subdev_print_format(struct media_entity *entity,
--	unsigned int pad, enum v4l2_subdev_format_whence which)
-+	unsigned int pad, unsigned int stream,
-+	enum v4l2_subdev_format_whence which)
- {
-	struct v4l2_mbus_framefmt format;
-	struct v4l2_fract interval = { 0, 0 };
-	struct v4l2_rect rect;
-	int ret;
-
--	ret = v4l2_subdev_get_format(entity, &format, pad, which);
-+	ret = v4l2_subdev_get_format(entity, &format, pad, stream, which);
-	if (ret != 0)
-		return;
-
--	ret = v4l2_subdev_get_frame_interval(entity, &interval, pad);
-+	ret = v4l2_subdev_get_frame_interval(entity, &interval, pad, stream);
-	if (ret != 0 && ret != -ENOTTY && ret != -EINVAL)
-		return;
-
--	printf("\t\t[fmt:%s/%ux%u",
-+	printf("\t\t[stream:%u fmt:%s/%ux%u", stream,
-	       v4l2_subdev_pixelcode_to_string(format.code),
-	       format.width, format.height);
-
-@@ -118,28 +139,28 @@ static void v4l2_subdev_print_format(struct media_entity *entity,
-			       v4l2_subdev_quantization_to_string(format.quantization));
-	}
-
--	ret = v4l2_subdev_get_selection(entity, &rect, pad,
-+	ret = v4l2_subdev_get_selection(entity, &rect, pad, stream,
-					V4L2_SEL_TGT_CROP_BOUNDS,
-					which);
-	if (ret == 0)
-		printf("\n\t\t crop.bounds:(%u,%u)/%ux%u", rect.left, rect.top,
-		       rect.width, rect.height);
-
--	ret = v4l2_subdev_get_selection(entity, &rect, pad,
-+	ret = v4l2_subdev_get_selection(entity, &rect, pad, stream,
-					V4L2_SEL_TGT_CROP,
-					which);
-	if (ret == 0)
-		printf("\n\t\t crop:(%u,%u)/%ux%u", rect.left, rect.top,
-		       rect.width, rect.height);
-
--	ret = v4l2_subdev_get_selection(entity, &rect, pad,
-+	ret = v4l2_subdev_get_selection(entity, &rect, pad, stream,
-					V4L2_SEL_TGT_COMPOSE_BOUNDS,
-					which);
-	if (ret == 0)
-		printf("\n\t\t compose.bounds:(%u,%u)/%ux%u",
-		       rect.left, rect.top, rect.width, rect.height);
-
--	ret = v4l2_subdev_get_selection(entity, &rect, pad,
-+	ret = v4l2_subdev_get_selection(entity, &rect, pad, stream,
-					V4L2_SEL_TGT_COMPOSE,
-					which);
-	if (ret == 0)
-@@ -455,16 +476,58 @@ static void media_print_topology_dot(struct media_device *media)
- }
-
- static void media_print_pad_text(struct media_entity *entity,
--				 const struct media_pad *pad)
-+				 const struct media_pad *pad,
-+				 struct v4l2_subdev_route *routes,
-+				 unsigned int num_routes)
- {
-+	unsigned int i;
-+	uint64_t printed_streams_mask;
-+
-	if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV)
-		return;
-
--	v4l2_subdev_print_format(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
--	v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
-+	if (!routes) {
-+		v4l2_subdev_print_format(entity, pad->index, 0, V4L2_SUBDEV_FORMAT_ACTIVE);
-+		v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
-+
-+		if (pad->flags & MEDIA_PAD_FL_SOURCE)
-+			v4l2_subdev_print_subdev_dv(entity);
-+
-+		return;
-+	}
-+
-+	printed_streams_mask = 0;
-+
-+	for (i = 0; i < num_routes; ++i) {
-+		const struct v4l2_subdev_route *r = &routes[i];
-+		unsigned int stream;
-
--	if (pad->flags & MEDIA_PAD_FL_SOURCE)
--		v4l2_subdev_print_subdev_dv(entity);
-+		if (!(r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
-+			continue;
-+
-+		if (pad->flags & MEDIA_PAD_FL_SINK) {
-+			if (r->sink_pad != pad->index)
-+				continue;
-+
-+			stream = r->sink_stream;
-+		} else {
-+			if (r->source_pad != pad->index)
-+				continue;
-+
-+			stream = r->source_stream;
-+		}
-+
-+		if (printed_streams_mask & (1 << stream))
-+			continue;
-+
-+		v4l2_subdev_print_format(entity, pad->index, stream, V4L2_SUBDEV_FORMAT_ACTIVE);
-+		v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE);
-+
-+		if (pad->flags & MEDIA_PAD_FL_SOURCE)
-+			v4l2_subdev_print_subdev_dv(entity);
-+
-+		printed_streams_mask |= (1 << stream);
-+	}
- }
-
- static void media_print_topology_text_entity(struct media_device *media,
-@@ -480,11 +543,17 @@ static void media_print_topology_text_entity(struct media_device *media,
-	unsigned int num_links = media_entity_get_links_count(entity);
-	unsigned int j, k;
-	unsigned int padding;
-+	struct v4l2_subdev_route *routes = NULL;
-+	unsigned int num_routes = 0;
-+
-+	if (media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV)
-+		v4l2_subdev_get_routing(entity, &routes, &num_routes);
-
-	padding = printf("- entity %u: ", info->id);
--	printf("%s (%u pad%s, %u link%s)\n", info->name,
-+	printf("%s (%u pad%s, %u link%s, %u route%s)\n", info->name,
-	       info->pads, info->pads > 1 ? "s" : "",
--	       num_links, num_links > 1 ? "s" : "");
-+	       num_links, num_links > 1 ? "s" : "",
-+	       num_routes, num_routes > 1 ? "s" : "");
-	printf("%*ctype %s subtype %s flags %x\n", padding, ' ',
-	       media_entity_type_to_string(info->type),
-	       media_entity_subtype_to_string(info->type),
-@@ -492,12 +561,15 @@ static void media_print_topology_text_entity(struct media_device *media,
-	if (devname)
-		printf("%*cdevice node name %s\n", padding, ' ', devname);
-
-+	if (media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV)
-+		v4l2_subdev_print_routes(entity, routes, num_routes);
-+
-	for (j = 0; j < info->pads; j++) {
-		const struct media_pad *pad = media_entity_get_pad(entity, j);
-
-		printf("\tpad%u: %s\n", j, media_pad_type_to_string(pad->flags));
-
--		media_print_pad_text(entity, pad);
-+		media_print_pad_text(entity, pad, routes, num_routes);
-
-		for (k = 0; k < num_links; k++) {
-			const struct media_link *link = media_entity_get_link(entity, k);
-@@ -521,6 +593,8 @@ static void media_print_topology_text_entity(struct media_device *media,
-		}
-	}
-	printf("\n");
-+
-+	free(routes);
- }
-
- static void media_print_topology_text(struct media_device *media)
-@@ -594,14 +668,16 @@ int main(int argc, char **argv)
-
-	if (media_opts.fmt_pad) {
-		struct media_pad *pad;
-+		unsigned int stream;
-+		char *p;
-
--		pad = media_parse_pad(media, media_opts.fmt_pad, NULL);
-+		pad = media_parse_pad_stream(media, media_opts.fmt_pad, &stream, &p);
-		if (pad == NULL) {
-			printf("Pad '%s' not found\n", media_opts.fmt_pad);
-			goto out;
-		}
-
--		v4l2_subdev_print_format(pad->entity, pad->index,
-+		v4l2_subdev_print_format(pad->entity, pad->index, stream,
-					 V4L2_SUBDEV_FORMAT_ACTIVE);
-	}
-
-@@ -685,6 +761,15 @@ int main(int argc, char **argv)
-		}
-	}
-
-+	if (media_opts.routes) {
-+		ret = v4l2_subdev_parse_setup_routes(media, media_opts.routes);
-+		if (ret) {
-+			printf("Unable to setup routes: %s (%d)\n",
-+			       strerror(-ret), -ret);
-+			goto out;
-+		}
-+	}
-+
-	if (media_opts.interactive) {
-		while (1) {
-			char buffer[32];
-diff --git a/utils/media-ctl/mediactl.h b/utils/media-ctl/mediactl.h
-index af360518..c0fc2962 100644
---- a/utils/media-ctl/mediactl.h
-+++ b/utils/media-ctl/mediactl.h
-@@ -394,6 +394,22 @@ struct media_entity *media_parse_entity(struct media_device *media,
- struct media_pad *media_parse_pad(struct media_device *media,
-				  const char *p, char **endp);
-
-+/**
-+ * @brief Parse string to a pad and stream on the media device.
-+ * @param media - media device.
-+ * @param p - input string
-+ * @param stream - pointer to uint where the stream number is stored
-+ * @param endp - pointer to string where parsing ended
-+ *
-+ * Parse NULL terminated string describing a pad and stream and return its struct
-+ * media_pad instance and the stream number.
-+ *
-+ * @return Pointer to struct media_pad on success, NULL on failure.
-+ */
-+struct media_pad *media_parse_pad_stream(struct media_device *media,
-+					 const char *p, unsigned int *stream,
-+					 char **endp);
-+
- /**
-  * @brief Parse string to a link on the media device.
-  * @param media - media device.
-diff --git a/utils/media-ctl/options.c b/utils/media-ctl/options.c
-index 6d30d3dc..58ddec3c 100644
---- a/utils/media-ctl/options.c
-+++ b/utils/media-ctl/options.c
-@@ -63,6 +63,7 @@ static void usage(const char *argv0)
-	printf("    --get-v4l2 pad	Print the active format on a given pad\n");
-	printf("    --get-dv pad        Print detected and current DV timings on a given pad\n");
-	printf("    --set-dv pad	Configure DV timings on a given pad\n");
-+	printf("-R, --set-routes routes Configure routes on a given subdev entity\n");
-	printf("-h, --help		Show verbose help and exit\n");
-	printf("-i, --interactive	Modify links interactively\n");
-	printf("-l, --links links	Comma-separated list of link descriptors to setup\n");
-@@ -78,7 +79,7 @@ static void usage(const char *argv0)
-	printf("Links and formats are defined as\n");
-	printf("\tlinks           = link { ',' link } ;\n");
-	printf("\tlink            = pad '->' pad '[' flags ']' ;\n");
--	printf("\tpad             = entity ':' pad-number ;\n");
-+	printf("\tpad             = entity ':' pad-number { '/' stream-number } ;\n");
-	printf("\tentity          = entity-number | ( '\"' entity-name '\"' ) ;\n");
-	printf("\n");
-	printf("\tv4l2            = pad '[' v4l2-properties ']' ;\n");
-@@ -95,11 +96,16 @@ static void usage(const char *argv0)
-	printf("\trectangle       = '(' left ',' top, ')' '/' size ;\n");
-	printf("\tsize            = width 'x' height ;\n");
-	printf("\n");
-+	printf("\troutes          = entity '[' route { ',' route } ']' ;\n");
-+	printf("\troute           = pad-number '/' stream-number '->' pad-number '/' stream-number '[' route-flags ']' ;\n");
-+	printf("\n");
-	printf("where the fields are\n");
-	printf("\tentity-number   Entity numeric identifier\n");
-	printf("\tentity-name     Entity name (string) \n");
-	printf("\tpad-number      Pad numeric identifier\n");
-+	printf("\tstream-number   Stream numeric identifier\n");
-	printf("\tflags           Link flags (0: inactive, 1: active)\n");
-+	printf("\troute-flags     Route flags (bitmask of route flags: active - 0x1, immutable - 0x2, source - 0x4)\n");
-	printf("\tfcc             Format FourCC\n");
-	printf("\twidth           Image width in pixels\n");
-	printf("\theight          Image height in pixels\n");
-@@ -152,6 +158,7 @@ static struct option opts[] = {
-	{"get-v4l2", 1, 0, OPT_GET_FORMAT},
-	{"get-dv", 1, 0, OPT_GET_DV},
-	{"set-dv", 1, 0, OPT_SET_DV},
-+	{"set-routes", 1, 0, 'R'},
-	{"help", 0, 0, 'h'},
-	{"interactive", 0, 0, 'i'},
-	{"links", 1, 0, 'l'},
-@@ -237,7 +244,7 @@ int parse_cmdline(int argc, char **argv)
-	}
-
-	/* parse options */
--	while ((opt = getopt_long(argc, argv, "d:e:f:hil:prvV:",
-+	while ((opt = getopt_long(argc, argv, "d:e:f:hil:prvV:R:",
-				  opts, NULL)) != -1) {
-		switch (opt) {
-		case 'd':
-@@ -283,6 +290,10 @@ int parse_cmdline(int argc, char **argv)
-			media_opts.verbose = 1;
-			break;
-
-+		case 'R':
-+			media_opts.routes = optarg;
-+			break;
-+
-		case OPT_PRINT_DOT:
-			media_opts.print_dot = 1;
-			break;
-diff --git a/utils/media-ctl/options.h b/utils/media-ctl/options.h
-index b1751f56..8796f1b6 100644
---- a/utils/media-ctl/options.h
-+++ b/utils/media-ctl/options.h
-@@ -38,6 +38,7 @@ struct media_options
-	const char *fmt_pad;
-	const char *get_dv_pad;
-	const char *dv_pad;
-+	const char *routes;
- };
-
- extern struct media_options media_opts;
-diff --git a/utils/media-ctl/v4l2subdev.h b/utils/media-ctl/v4l2subdev.h
-index a1813911..a8a6e7ad 100644
---- a/utils/media-ctl/v4l2subdev.h
-+++ b/utils/media-ctl/v4l2subdev.h
-@@ -64,7 +64,7 @@ void v4l2_subdev_close(struct media_entity *entity);
-  * @return 0 on success, or a negative error code on failure.
-  */
- int v4l2_subdev_get_format(struct media_entity *entity,
--	struct v4l2_mbus_framefmt *format, unsigned int pad,
-+	struct v4l2_mbus_framefmt *format, unsigned int pad, unsigned int stream,
-	enum v4l2_subdev_format_whence which);
-
- /**
-@@ -86,6 +86,7 @@ int v4l2_subdev_get_format(struct media_entity *entity,
-  */
- int v4l2_subdev_set_format(struct media_entity *entity,
-	struct v4l2_mbus_framefmt *format, unsigned int pad,
-+	unsigned int stream,
-	enum v4l2_subdev_format_whence which);
-
- /**
-@@ -107,8 +108,8 @@ int v4l2_subdev_set_format(struct media_entity *entity,
-  * @return 0 on success, or a negative error code on failure.
-  */
- int v4l2_subdev_get_selection(struct media_entity *entity,
--	struct v4l2_rect *rect, unsigned int pad, unsigned int target,
--	enum v4l2_subdev_format_whence which);
-+	struct v4l2_rect *rect, unsigned int pad, unsigned int stream,
-+	unsigned int target, enum v4l2_subdev_format_whence which);
-
- /**
-  * @brief Set a selection rectangle on a pad.
-@@ -129,8 +130,40 @@ int v4l2_subdev_get_selection(struct media_entity *entity,
-  * @return 0 on success, or a negative error code on failure.
-  */
- int v4l2_subdev_set_selection(struct media_entity *entity,
--	struct v4l2_rect *rect, unsigned int pad, unsigned int target,
--	enum v4l2_subdev_format_whence which);
-+	struct v4l2_rect *rect, unsigned int pad, unsigned int stream,
-+	unsigned int target, enum v4l2_subdev_format_whence which);
-+
-+/**
-+ * @brief Get the routing table of a subdev media entity.
-+ * @param entity - subdev-device media entity.
-+ * @param routes - routes of the subdev.
-+ * @param num_routes - number of routes.
-+ *
-+ * Get the routes of @a entity and return them in an allocated array in @a routes
-+ * and the number of routes in @a num_routes.
-+ *
-+ * The caller is responsible for freeing the routes array after use.
-+ *
-+ * @return 0 on success, or a negative error code on failure.
-+ */
-+int v4l2_subdev_get_routing(struct media_entity *entity,
-+			    struct v4l2_subdev_route **routes,
-+			    unsigned int *num_routes);
-+
-+/**
-+ * @brief Set the routing table of a subdev media entity.
-+ * @param entity - subdev-device media entity.
-+ * @param routes - routes of the subdev.
-+ * @param num_routes - number of routes.
-+ *
-+ * Set the routes of @a entity. The routes are given in @a routes with the
-+ * length of @a num_routes.
-+ *
-+ * @return 0 on success, or a negative error code on failure.
-+ */
-+int v4l2_subdev_set_routing(struct media_entity *entity,
-+			    struct v4l2_subdev_route *route,
-+			    unsigned int num_routes);
-
- /**
-  * @brief Query the digital video capabilities of a pad.
-@@ -200,7 +233,7 @@ int v4l2_subdev_set_dv_timings(struct media_entity *entity,
-  */
-
- int v4l2_subdev_get_frame_interval(struct media_entity *entity,
--	struct v4l2_fract *interval, unsigned int pad);
-+	struct v4l2_fract *interval, unsigned int pad, unsigned int stream);
-
- /**
-  * @brief Set the frame interval on a sub-device.
-@@ -217,7 +250,7 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
-  * @return 0 on success, or a negative error code on failure.
-  */
- int v4l2_subdev_set_frame_interval(struct media_entity *entity,
--	struct v4l2_fract *interval, unsigned int pad);
-+	struct v4l2_fract *interval, unsigned int pad, unsigned int stream);
-
- /**
-  * @brief Parse a string and apply format, crop and frame interval settings.
-@@ -235,6 +268,17 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
-  */
- int v4l2_subdev_parse_setup_formats(struct media_device *media, const char *p);
-
-+/**
-+ * @brief Parse a string and apply route settings.
-+ * @param media - media device.
-+ * @param p - input string
-+ *
-+ * Parse string @a p and apply route settings to a subdev.
-+ *
-+ * @return 0 on success, or a negative error code on failure.
-+ */
-+int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p);
-+
- /**
-  * @brief Convert media bus pixel code to string.
-  * @param code - input string
---
-2.40.0
diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-original-patch-mediactl-pkgconfig.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-original-patch-mediactl-pkgconfig.patch
deleted file mode 100644
index 6ad9f2c1..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0002-original-patch-mediactl-pkgconfig.patch
+++ /dev/null
@@ -1,21 +0,0 @@ 
-From 320b8378ee30eb5e0fe83a8b397f822f2f88a4c1 Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Sun, 1 Mar 2015 22:25:07 +0000
-Subject: [PATCH] %% original patch: mediactl-pkgconfig.patch
-
----
- utils/media-ctl/Makefile.am | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/utils/media-ctl/Makefile.am b/utils/media-ctl/Makefile.am
-index e255e16..ff7b417 100644
---- a/utils/media-ctl/Makefile.am
-+++ b/utils/media-ctl/Makefile.am
-@@ -20,6 +20,7 @@ libv4l2subdev_la_LIBADD = libmediactl.la
- mediactl_includedir=$(includedir)/mediactl
- noinst_HEADERS = mediactl.h v4l2subdev.h
-
-+pkgconfig_DATA = libmediactl.pc
- bin_PROGRAMS = media-ctl
- media_ctl_SOURCES = media-ctl.c options.c options.h tools.h
- media_ctl_LDADD = libmediactl.la libv4l2subdev.la
diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-original-patch-export-mediactl-headers.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-original-patch-export-mediactl-headers.patch
deleted file mode 100644
index 5562d2c1..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-original-patch-export-mediactl-headers.patch
+++ /dev/null
@@ -1,24 +0,0 @@ 
-From f7109d6b2fcb291824d795071c04a492d9fbc45b Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Sun, 1 Mar 2015 22:25:07 +0000
-Subject: [PATCH] %% original patch: export-mediactl-headers.patch
-
----
- utils/media-ctl/Makefile.am | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/utils/media-ctl/Makefile.am b/utils/media-ctl/Makefile.am
-index ff7b417..6ce656f 100644
---- a/utils/media-ctl/Makefile.am
-+++ b/utils/media-ctl/Makefile.am
-@@ -17,8 +17,8 @@ CLEANFILES = $(BUILT_SOURCES)
- nodist_libv4l2subdev_la_SOURCES = $(BUILT_SOURCES)
- libv4l2subdev_la_SOURCES = libv4l2subdev.c
- libv4l2subdev_la_LIBADD = libmediactl.la
--mediactl_includedir=$(includedir)/mediactl
--noinst_HEADERS = mediactl.h v4l2subdev.h
-+otherincludedir = $(includedir)/mediactl
-+otherinclude_HEADERS = mediactl.h v4l2subdev.h
-
- pkgconfig_DATA = libmediactl.pc
- bin_PROGRAMS = media-ctl
diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch
deleted file mode 100644
index aeb97e09..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch
+++ /dev/null
@@ -1,459 +0,0 @@ 
-From 2866c81d2597f47ed976928bc9c27942bbf095f0 Mon Sep 17 00:00:00 2001
-From: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
-Date: Fri, 10 Feb 2023 13:55:46 +0200
-Subject: [PATCH 3/3] v4l2-ctl/compliance: add routing and streams multiplexed
- streams
-
-Add basic support for routing and streams.
-
-Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
----
- utils/v4l2-compliance/v4l2-compliance.cpp   | 120 ++++++++++++++++----
- utils/v4l2-compliance/v4l2-compliance.h     |   8 +-
- utils/v4l2-compliance/v4l2-test-subdevs.cpp |  43 ++++++-
- 3 files changed, 137 insertions(+), 34 deletions(-)
-
-diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp
-index 8aebae2e..63b5fbbb 100644
---- a/utils/v4l2-compliance/v4l2-compliance.cpp
-+++ b/utils/v4l2-compliance/v4l2-compliance.cpp
-@@ -1224,6 +1224,10 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
-	if (node.is_subdev()) {
-		bool has_source = false;
-		bool has_sink = false;
-+		struct v4l2_subdev_routing sd_routing[2] = {};
-+		struct v4l2_subdev_route sd_routes[2][256] = {};
-+		bool has_routes = !!(subdevcap.capabilities & V4L2_SUBDEV_CAP_STREAMS);
-+		int ret;
-
-		node.frame_interval_pad = -1;
-		node.enum_frame_interval_pad = -1;
-@@ -1235,6 +1239,22 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
-		}
-		node.is_passthrough_subdev = has_source && has_sink;
-
-+		if (has_routes) {
-+			for (unsigned which = V4L2_SUBDEV_FORMAT_TRY;
-+				which <= V4L2_SUBDEV_FORMAT_ACTIVE; which++) {
-+
-+				sd_routing[which].which = which;
-+				sd_routing[which].routes = (__u64)sd_routes[which];
-+				sd_routing[which].num_routes = 256;
-+
-+				ret = doioctl(&node, VIDIOC_SUBDEV_G_ROUTING, &sd_routing[which]);
-+				if (ret) {
-+					fail("VIDIOC_SUBDEV_G_ROUTING: failed to get routing\n");
-+					sd_routing[which].num_routes = 0;
-+				}
-+			}
-+		}
-+
-		for (unsigned pad = 0; pad < node.entity.pads; pad++) {
-			printf("Sub-Device ioctls (%s Pad %u):\n",
-			       (node.pads[pad].flags & MEDIA_PAD_FL_SINK) ?
-@@ -1244,32 +1264,82 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_
-			node.has_subdev_enum_fival = 0;
-			for (unsigned which = V4L2_SUBDEV_FORMAT_TRY;
-			     which <= V4L2_SUBDEV_FORMAT_ACTIVE; which++) {
--				printf("\ttest %s VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: %s\n",
--				       which ? "Active" : "Try",
--				       ok(testSubDevEnum(&node, which, pad)));
--				printf("\ttest %s VIDIOC_SUBDEV_G/S_FMT: %s\n",
--				       which ? "Active" : "Try",
--				       ok(testSubDevFormat(&node, which, pad)));
--				printf("\ttest %s VIDIOC_SUBDEV_G/S_SELECTION/CROP: %s\n",
--				       which ? "Active" : "Try",
--				       ok(testSubDevSelection(&node, which, pad)));
--				if (which)
--					printf("\ttest VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: %s\n",
--					       ok(testSubDevFrameInterval(&node, pad)));
-+				struct v4l2_subdev_routing dummy_routing;
-+				struct v4l2_subdev_route dummy_routes[1];
-+
-+				const struct v4l2_subdev_routing *routing;
-+				const struct v4l2_subdev_route *routes;
-+
-+				if (has_routes) {
-+					routing = &sd_routing[which];
-+					routes = sd_routes[which];
-+				} else {
-+					dummy_routing.num_routes = 1;
-+					dummy_routing.routes = (__u64)&dummy_routes;
-+					dummy_routes[0].source_pad = pad;
-+					dummy_routes[0].source_stream = 0;
-+					dummy_routes[0].sink_pad = pad;
-+					dummy_routes[0].sink_stream = 0;
-+					dummy_routes[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE;
-+
-+					routing = &dummy_routing;
-+					routes = dummy_routes;
-+				}
-+
-+				for (unsigned i = 0; i < routing->num_routes; ++i) {
-+					const struct v4l2_subdev_route *r = &routes[i];
-+					unsigned stream;
-+
-+					if (!(r->flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
-+						continue;
-+
-+					if ((node.pads[pad].flags & MEDIA_PAD_FL_SINK) &&
-+					    (r->sink_pad == pad))
-+						stream = r->sink_stream;
-+					else if ((node.pads[pad].flags & MEDIA_PAD_FL_SOURCE) &&
-+					    (r->source_pad == pad))
-+						stream = r->source_stream;
-+					else
-+						continue;
-+
-+					printf("\t%s Stream %u\n",which ? "Active" : "Try",
-+					       stream);
-+
-+					printf("\ttest %s VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: %s\n",
-+					       which ? "Active" : "Try",
-+					       ok(testSubDevEnum(&node, which, pad, stream)));
-+					printf("\ttest %s VIDIOC_SUBDEV_G/S_FMT: %s\n",
-+					       which ? "Active" : "Try",
-+					       ok(testSubDevFormat(&node, which, pad, stream)));
-+					printf("\ttest %s VIDIOC_SUBDEV_G/S_SELECTION/CROP: %s\n",
-+					       which ? "Active" : "Try",
-+					       ok(testSubDevSelection(&node, which, pad, stream)));
-+					if (which)
-+						printf("\ttest VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: %s\n",
-+						       ok(testSubDevFrameInterval(&node, pad, stream)));
-+				}
-+			}
-+
-+			/*
-+			 * These tests do not make sense for subdevs with multiplexed streams,
-+			 * as the try & active cases may have different routing and thus different
-+			 * behavior.
-+			 */
-+			if (!has_routes) {
-+				if (node.has_subdev_enum_code && node.has_subdev_enum_code < 3)
-+					fail("VIDIOC_SUBDEV_ENUM_MBUS_CODE: try/active mismatch\n");
-+				if (node.has_subdev_enum_fsize && node.has_subdev_enum_fsize < 3)
-+					fail("VIDIOC_SUBDEV_ENUM_FRAME_SIZE: try/active mismatch\n");
-+				if (node.has_subdev_enum_fival && node.has_subdev_enum_fival < 3)
-+					fail("VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: try/active mismatch\n");
-+				if (node.has_subdev_fmt && node.has_subdev_fmt < 3)
-+					fail("VIDIOC_SUBDEV_G/S_FMT: try/active mismatch\n");
-+				if (node.has_subdev_selection && node.has_subdev_selection < 3)
-+					fail("VIDIOC_SUBDEV_G/S_SELECTION: try/active mismatch\n");
-+				if (node.has_subdev_selection &&
-+				    node.has_subdev_selection != node.has_subdev_fmt)
-+					fail("VIDIOC_SUBDEV_G/S_SELECTION: fmt/selection mismatch\n");
-			}
--			if (node.has_subdev_enum_code && node.has_subdev_enum_code < 3)
--				fail("VIDIOC_SUBDEV_ENUM_MBUS_CODE: try/active mismatch\n");
--			if (node.has_subdev_enum_fsize && node.has_subdev_enum_fsize < 3)
--				fail("VIDIOC_SUBDEV_ENUM_FRAME_SIZE: try/active mismatch\n");
--			if (node.has_subdev_enum_fival && node.has_subdev_enum_fival < 3)
--				fail("VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: try/active mismatch\n");
--			if (node.has_subdev_fmt && node.has_subdev_fmt < 3)
--				fail("VIDIOC_SUBDEV_G/S_FMT: try/active mismatch\n");
--			if (node.has_subdev_selection && node.has_subdev_selection < 3)
--				fail("VIDIOC_SUBDEV_G/S_SELECTION: try/active mismatch\n");
--			if (node.has_subdev_selection &&
--			    node.has_subdev_selection != node.has_subdev_fmt)
--				fail("VIDIOC_SUBDEV_G/S_SELECTION: fmt/selection mismatch\n");
-			printf("\n");
-		}
-	}
-diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h
-index e574c06c..67b3521e 100644
---- a/utils/v4l2-compliance/v4l2-compliance.h
-+++ b/utils/v4l2-compliance/v4l2-compliance.h
-@@ -373,10 +373,10 @@ int testDecoder(struct node *node);
-
- // SubDev ioctl tests
- int testSubDevCap(struct node *node);
--int testSubDevEnum(struct node *node, unsigned which, unsigned pad);
--int testSubDevFormat(struct node *node, unsigned which, unsigned pad);
--int testSubDevSelection(struct node *node, unsigned which, unsigned pad);
--int testSubDevFrameInterval(struct node *node, unsigned pad);
-+int testSubDevEnum(struct node *node, unsigned which, unsigned pad, unsigned stream);
-+int testSubDevFormat(struct node *node, unsigned which, unsigned pad, unsigned stream);
-+int testSubDevSelection(struct node *node, unsigned which, unsigned pad, unsigned stream);
-+int testSubDevFrameInterval(struct node *node, unsigned pad, unsigned stream);
-
- // Buffer ioctl tests
- int testReqBufs(struct node *node);
-diff --git a/utils/v4l2-compliance/v4l2-test-subdevs.cpp b/utils/v4l2-compliance/v4l2-test-subdevs.cpp
-index f3d85771..07192bda 100644
---- a/utils/v4l2-compliance/v4l2-test-subdevs.cpp
-+++ b/utils/v4l2-compliance/v4l2-test-subdevs.cpp
-@@ -25,7 +25,7 @@
-
- #include "v4l2-compliance.h"
-
--#define VALID_SUBDEV_CAPS (V4L2_SUBDEV_CAP_RO_SUBDEV)
-+#define VALID_SUBDEV_CAPS (V4L2_SUBDEV_CAP_RO_SUBDEV | V4L2_SUBDEV_CAP_STREAMS)
-
- int testSubDevCap(struct node *node)
- {
-@@ -54,6 +54,7 @@ static int testSubDevEnumFrameInterval(struct node *node, unsigned which,
-	memset(&fie, 0, sizeof(fie));
-	fie.which = which;
-	fie.pad = pad;
-+	fie.stream = 0;
-	fie.code = code;
-	fie.width = width;
-	fie.height = height;
-@@ -83,6 +84,7 @@ static int testSubDevEnumFrameInterval(struct node *node, unsigned which,
-	memset(&fie, 0xff, sizeof(fie));
-	fie.which = which;
-	fie.pad = pad;
-+	fie.stream = 0;
-	fie.code = code;
-	fie.width = width;
-	fie.height = height;
-@@ -128,6 +130,7 @@ static int testSubDevEnumFrameSize(struct node *node, unsigned which,
-	memset(&fse, 0, sizeof(fse));
-	fse.which = which;
-	fse.pad = pad;
-+	fse.stream = 0;
-	fse.code = code;
-	ret = doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &fse);
-	node->has_subdev_enum_fsize |= (ret != ENOTTY) << which;
-@@ -137,6 +140,7 @@ static int testSubDevEnumFrameSize(struct node *node, unsigned which,
-		memset(&fie, 0, sizeof(fie));
-		fie.which = which;
-		fie.pad = pad;
-+		fie.stream = 0;
-		fie.code = code;
-		fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, &fie) != ENOTTY);
-		return ret;
-@@ -152,6 +156,7 @@ static int testSubDevEnumFrameSize(struct node *node, unsigned which,
-	memset(&fse, 0xff, sizeof(fse));
-	fse.which = which;
-	fse.pad = pad;
-+	fse.stream = 0;
-	fse.code = code;
-	fse.index = 0;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &fse));
-@@ -195,7 +200,7 @@ static int testSubDevEnumFrameSize(struct node *node, unsigned which,
-	return 0;
- }
-
--int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
-+int testSubDevEnum(struct node *node, unsigned which, unsigned pad, unsigned stream)
- {
-	struct v4l2_subdev_mbus_code_enum mbus_core_enum;
-	unsigned num_codes;
-@@ -204,6 +209,7 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
-	memset(&mbus_core_enum, 0, sizeof(mbus_core_enum));
-	mbus_core_enum.which = which;
-	mbus_core_enum.pad = pad;
-+	mbus_core_enum.stream = stream;
-	ret = doioctl(node, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbus_core_enum);
-	node->has_subdev_enum_code |= (ret != ENOTTY) << which;
-	if (ret == ENOTTY) {
-@@ -214,8 +220,10 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
-		memset(&fie, 0, sizeof(fie));
-		fse.which = which;
-		fse.pad = pad;
-+		fse.stream = stream;
-		fie.which = which;
-		fie.pad = pad;
-+		fie.stream = stream;
-		fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &fse) != ENOTTY);
-		fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, &fie) != ENOTTY);
-		return ret;
-@@ -226,16 +234,19 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
-	mbus_core_enum.index = ~0;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbus_core_enum) != EINVAL);
-	mbus_core_enum.pad = node->entity.pads;
-+	mbus_core_enum.stream = stream;
-	mbus_core_enum.index = 0;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbus_core_enum) != EINVAL);
-	memset(&mbus_core_enum, 0xff, sizeof(mbus_core_enum));
-	mbus_core_enum.which = which;
-	mbus_core_enum.pad = pad;
-+	mbus_core_enum.stream = stream;
-	mbus_core_enum.index = 0;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &mbus_core_enum));
-	fail_on_test(check_0(mbus_core_enum.reserved, sizeof(mbus_core_enum.reserved)));
-	fail_on_test(mbus_core_enum.code == ~0U);
-	fail_on_test(mbus_core_enum.pad != pad);
-+	fail_on_test(mbus_core_enum.stream != stream);
-	fail_on_test(mbus_core_enum.index);
-	fail_on_test(mbus_core_enum.which != which);
-	do {
-@@ -252,6 +263,7 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
-		fail_on_test(!mbus_core_enum.code);
-		fail_on_test(mbus_core_enum.which != which);
-		fail_on_test(mbus_core_enum.pad != pad);
-+		fail_on_test(mbus_core_enum.stream != stream);
-		fail_on_test(mbus_core_enum.index != i);
-
-		ret = testSubDevEnumFrameSize(node, which, pad, mbus_core_enum.code);
-@@ -260,7 +272,7 @@ int testSubDevEnum(struct node *node, unsigned which, unsigned pad)
-	return 0;
- }
-
--int testSubDevFrameInterval(struct node *node, unsigned pad)
-+int testSubDevFrameInterval(struct node *node, unsigned pad, unsigned stream)
- {
-	struct v4l2_subdev_frame_interval fival;
-	struct v4l2_fract ival;
-@@ -268,6 +280,7 @@ int testSubDevFrameInterval(struct node *node, unsigned pad)
-
-	memset(&fival, 0xff, sizeof(fival));
-	fival.pad = pad;
-+	fival.stream = stream;
-	ret = doioctl(node, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &fival);
-	if (ret == ENOTTY) {
-		fail_on_test(node->enum_frame_interval_pad >= 0);
-@@ -279,6 +292,7 @@ int testSubDevFrameInterval(struct node *node, unsigned pad)
-	node->frame_interval_pad = pad;
-	fail_on_test(check_0(fival.reserved, sizeof(fival.reserved)));
-	fail_on_test(fival.pad != pad);
-+	fail_on_test(fival.stream != stream);
-	fail_on_test(!fival.interval.numerator);
-	fail_on_test(!fival.interval.denominator);
-	fail_on_test(fival.interval.numerator == ~0U || fival.interval.denominator == ~0U);
-@@ -290,20 +304,25 @@ int testSubDevFrameInterval(struct node *node, unsigned pad)
-	}
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &fival));
-	fail_on_test(fival.pad != pad);
-+	fail_on_test(fival.stream != stream);
-	fail_on_test(ival.numerator != fival.interval.numerator);
-	fail_on_test(ival.denominator != fival.interval.denominator);
-	fail_on_test(check_0(fival.reserved, sizeof(fival.reserved)));
-	memset(&fival, 0, sizeof(fival));
-	fival.pad = pad;
-+	fival.stream = stream;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &fival));
-	fail_on_test(fival.pad != pad);
-+	fail_on_test(fival.stream != stream);
-	fail_on_test(ival.numerator != fival.interval.numerator);
-	fail_on_test(ival.denominator != fival.interval.denominator);
-
-	fival.pad = node->entity.pads;
-+	fival.stream = stream;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &fival) != EINVAL);
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &fival) != EINVAL);
-	fival.pad = pad;
-+	fival.stream = stream;
-	fival.interval = ival;
-	fival.interval.numerator = 0;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &fival));
-@@ -340,7 +359,7 @@ static int checkMBusFrameFmt(struct node *node, struct v4l2_mbus_framefmt &fmt)
-	return 0;
- }
-
--int testSubDevFormat(struct node *node, unsigned which, unsigned pad)
-+int testSubDevFormat(struct node *node, unsigned which, unsigned pad, unsigned stream)
- {
-	struct v4l2_subdev_format fmt;
-	struct v4l2_subdev_format s_fmt;
-@@ -349,6 +368,7 @@ int testSubDevFormat(struct node *node, unsigned which, unsigned pad)
-	memset(&fmt, 0, sizeof(fmt));
-	fmt.which = which;
-	fmt.pad = pad;
-+	fmt.stream = stream;
-	ret = doioctl(node, VIDIOC_SUBDEV_G_FMT, &fmt);
-	node->has_subdev_fmt |= (ret != ENOTTY) << which;
-	if (ret == ENOTTY) {
-@@ -359,14 +379,17 @@ int testSubDevFormat(struct node *node, unsigned which, unsigned pad)
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FMT, &fmt) != EINVAL);
-	fmt.which = 0;
-	fmt.pad = node->entity.pads;
-+	fmt.stream = stream;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FMT, &fmt) != EINVAL);
-	memset(&fmt, 0xff, sizeof(fmt));
-	fmt.which = which;
-	fmt.pad = pad;
-+	fmt.stream = stream;
-	fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_FMT, &fmt));
-	fail_on_test(check_0(fmt.reserved, sizeof(fmt.reserved)));
-	fail_on_test(fmt.which != which);
-	fail_on_test(fmt.pad != pad);
-+	fail_on_test(fmt.stream != stream);
-	fail_on_test(checkMBusFrameFmt(node, fmt.format));
-	s_fmt = fmt;
-	memset(s_fmt.reserved, 0xff, sizeof(s_fmt.reserved));
-@@ -379,6 +402,7 @@ int testSubDevFormat(struct node *node, unsigned which, unsigned pad)
-	fail_on_test(ret && ret != ENOTTY);
-	fail_on_test(s_fmt.which != which);
-	fail_on_test(s_fmt.pad != pad);
-+	fail_on_test(s_fmt.stream != stream);
-	if (ret) {
-		warn("VIDIOC_SUBDEV_G_FMT is supported but not VIDIOC_SUBDEV_S_FMT\n");
-		return 0;
-@@ -423,7 +447,7 @@ static target_info targets[] = {
-	{ ~0U },
- };
-
--int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
-+int testSubDevSelection(struct node *node, unsigned which, unsigned pad, unsigned stream)
- {
-	struct v4l2_subdev_selection sel;
-	struct v4l2_subdev_selection s_sel;
-@@ -435,10 +459,12 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
-	targets[V4L2_SEL_TGT_NATIVE_SIZE].readonly = is_sink;
-	memset(&crop, 0, sizeof(crop));
-	crop.pad = pad;
-+	crop.stream = stream;
-	crop.which = which;
-	memset(&sel, 0, sizeof(sel));
-	sel.which = which;
-	sel.pad = pad;
-+	sel.stream = stream;
-	sel.target = V4L2_SEL_TGT_CROP;
-	ret = doioctl(node, VIDIOC_SUBDEV_G_SELECTION, &sel);
-	node->has_subdev_selection |= (ret != ENOTTY) << which;
-@@ -451,6 +477,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
-	fail_on_test(check_0(crop.reserved, sizeof(crop.reserved)));
-	fail_on_test(crop.which != which);
-	fail_on_test(crop.pad != pad);
-+	fail_on_test(crop.stream != stream);
-	fail_on_test(memcmp(&crop.rect, &sel.r, sizeof(sel.r)));
-
-	for (unsigned tgt = 0; targets[tgt].target != ~0U; tgt++) {
-@@ -458,6 +485,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
-		memset(&sel, 0xff, sizeof(sel));
-		sel.which = which;
-		sel.pad = pad;
-+		sel.stream = stream;
-		sel.target = tgt;
-		ret = doioctl(node, VIDIOC_SUBDEV_G_SELECTION, &sel);
-		targets[tgt].found = !ret;
-@@ -469,6 +497,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
-		fail_on_test(check_0(sel.reserved, sizeof(sel.reserved)));
-		fail_on_test(sel.which != which);
-		fail_on_test(sel.pad != pad);
-+		fail_on_test(sel.stream != stream);
-		fail_on_test(sel.target != tgt);
-		fail_on_test(!sel.r.width);
-		fail_on_test(sel.r.width == ~0U);
-@@ -480,9 +509,11 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
-		fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_SELECTION, &sel) != EINVAL);
-		sel.which = 0;
-		sel.pad = node->entity.pads;
-+		sel.stream = stream;
-		fail_on_test(doioctl(node, VIDIOC_SUBDEV_G_SELECTION, &sel) != EINVAL);
-		sel.which = which;
-		sel.pad = pad;
-+		sel.stream = stream;
-		s_sel = sel;
-		memset(s_sel.reserved, 0xff, sizeof(s_sel.reserved));
-		ret = doioctl(node, VIDIOC_SUBDEV_S_SELECTION, &s_sel);
-@@ -496,6 +527,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
-				fail_on_test(check_0(crop.reserved, sizeof(crop.reserved)));
-				fail_on_test(crop.which != which);
-				fail_on_test(crop.pad != pad);
-+				fail_on_test(crop.stream != stream);
-				fail_on_test(memcmp(&crop.rect, &sel.r, sizeof(sel.r)));
-			}
-		}
-@@ -504,6 +536,7 @@ int testSubDevSelection(struct node *node, unsigned which, unsigned pad)
-		fail_on_test(!ret && targets[tgt].readonly);
-		fail_on_test(s_sel.which != which);
-		fail_on_test(s_sel.pad != pad);
-+		fail_on_test(s_sel.stream != stream);
-		if (ret && !targets[tgt].readonly && tgt != V4L2_SEL_TGT_NATIVE_SIZE)
-			warn("VIDIOC_SUBDEV_G_SELECTION is supported for target %u but not VIDIOC_SUBDEV_S_SELECTION\n", tgt);
-		if (ret)
---
-2.40.0
diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0004-Do-not-use-getsubopt.patch b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0004-Do-not-use-getsubopt.patch
deleted file mode 100644
index f67d48e9..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils/0004-Do-not-use-getsubopt.patch
+++ /dev/null
@@ -1,59 +0,0 @@ 
-From 6e7e52de7afe29597016952a7317faf9c3ea3268 Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Sat, 30 Nov 2019 18:50:34 -0800
-Subject: [PATCH] Do not use getsubopt
-
-POSIX says that behavior when subopts list is empty is undefined.
-musl libs will set value to NULL which leads to crash.
-
-Simply avoid getsubopt, since we cannot rely on it.
-
-Imported from Alpine Linux
-
-Upstream-Status: Pending
-
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
-
-Adapt patch to 1.23.0.
-
-(v4l-utils rev fd544473800d02e90bc289434cc44e5aa8fadd0f).
-
-%% original patch: 0007-Do-not-use-getsubopt.patch
-
-Signed-off-by: Daniel Gomez <daniel@qtec.com>
----
- utils/v4l2-ctl/v4l2-ctl-common.cpp | 18 ++++++++++--------
- 1 file changed, 10 insertions(+), 8 deletions(-)
-
-diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp
-index d77f7104..838c297d 100644
---- a/utils/v4l2-ctl/v4l2-ctl-common.cpp
-+++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp
-@@ -994,15 +994,17 @@ static bool parse_subset(char *optarg)
-
- static bool parse_next_subopt(char **subs, char **value)
- {
--	static char *const subopts[] = {
--	    nullptr
--	};
--	int opt = v4l_getsubopt(subs, subopts, value);
-+	char *p = *subs;
-+	*value = *subs;
-
--	if (opt < 0 || *value)
--		return false;
--	fprintf(stderr, "Missing suboption value\n");
--	return true;
-+	while (*p && *p != ',')
-+		p++;
-+
-+	if (*p)
-+		*p++ = '\0';
-+
-+	*subs = p;
-+	return false;
- }
-
- void common_cmd(const std::string &media_bus_info, int ch, char *optarg)
---
-2.35.1
diff --git a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils_1.24.1.bb b/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils_1.24.1.bb
deleted file mode 100644
index a2ebb0ea..00000000
--- a/meta-arago-extras/recipes-multimedia/v4l-utils/v4l-utils_1.24.1.bb
+++ /dev/null
@@ -1,84 +0,0 @@ 
-SUMMARY = "v4l2 and IR applications"
-LICENSE = "GPL-2.0-only & LGPL-2.1-only"
-LIC_FILES_CHKSUM = "file://COPYING;md5=48da9957849056017dc568bbc43d8975 \
-                    file://COPYING.libv4l;md5=d749e86a105281d7a44c2328acebc4b0"
-PROVIDES = "libv4l media-ctl"
-
-DEPENDS = "jpeg \
-           ${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'virtual/libx11', '', d)} \
-           ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd', '', d)} \
-           ${@bb.utils.contains('DISTRO_FEATURES', 'alsa', 'alsa-lib', '', d)} \
-           ${@bb.utils.contains_any('PACKAGECONFIG', 'qv4l2 qvidcap', 'qtbase qtbase-native', '', d)}"
-
-DEPENDS:append:libc-musl = " argp-standalone"
-DEPENDS:append:class-target = " udev"
-LDFLAGS:append = " -pthread"
-# v4l2 explicitly sets _FILE_OFFSET_BITS=32 to get access to
-# both 32 and 64 bit file APIs.  But it does not handle the time side?
-# Needs further investigation
-GLIBC_64BIT_TIME_FLAGS = ""
-
-inherit autotools gettext pkgconfig
-
-PACKAGECONFIG ??= "media-ctl"
-PACKAGECONFIG[media-ctl] = "--enable-v4l-utils,--disable-v4l-utils,,"
-PACKAGECONFIG[qv4l2] = ",--disable-qv4l2"
-PACKAGECONFIG[qvidcap] = ",--disable-qvidcap"
-
-SRC_URI = "\
-    http://linuxtv.org/downloads/v4l-utils/v4l-utils-${PV}.tar.bz2 \
-    file://0001-Revert-media-ctl-Don-t-install-libmediactl-and-libv4.patch \
-    file://0002-original-patch-mediactl-pkgconfig.patch \
-    file://0003-original-patch-export-mediactl-headers.patch \
-    file://0004-Do-not-use-getsubopt.patch \
-    file://0001-v4l2-ctl-Add-routing-and-streams-support.patch \
-    file://0002-media-ctl-add-support-for-routes-and-streams.patch \
-    file://0003-v4l2-ctl-compliance-add-routing-and-streams-multiple.patch \
-    file://0001-media-ctl-add-support-for-RGBIr-bayer-formats.patch \
-"
-
-SRC_URI[md5sum] = "8ba9c73c4319b6afab5fa4358edc43de"
-SRC_URI[sha256sum] = "cbb7fe8a6307f5ce533a05cded70bb93c3ba06395ab9b6d007eb53b75d805f5b"
-
-EXTRA_OECONF = "--enable-shared --with-udevdir=${base_libdir}/udev \
-                --disable-v4l2-compliance-32 --disable-v4l2-ctl-32"
-
-VIRTUAL-RUNTIME_ir-keytable-keymaps ?= "rc-keymaps"
-
-PACKAGES =+ "media-ctl ir-keytable rc-keymaps libv4l libv4l-dev qv4l2 qvidcap"
-
-RPROVIDES:${PN}-dbg += "libv4l-dbg"
-
-FILES:media-ctl = "${bindir}/media-ctl ${libdir}/libmediactl.so.*"
-FILES:qv4l2 = "\
-    ${bindir}/qv4l2 \
-    ${datadir}/applications/qv4l2.desktop \
-    ${datadir}/icons/hicolor/*/apps/qv4l2.* \
-"
-FILES:qvidcap = "\
-    ${bindir}/qvidcap \
-    ${datadir}/applications/qvidcap.desktop \
-    ${datadir}/icons/hicolor/*/apps/qvidcap.* \
-"
-
-FILES:ir-keytable = "${bindir}/ir-keytable ${base_libdir}/udev/rules.d/*-infrared.rules"
-RDEPENDS:ir-keytable += "${VIRTUAL-RUNTIME_ir-keytable-keymaps}"
-RDEPENDS:qv4l2 += "\
-    ${@bb.utils.contains('PACKAGECONFIG', 'qv4l2', 'qtbase', '', d)}"
-RDEPENDS:qvidcap += "\
-    ${@bb.utils.contains('PACKAGECONFIG', 'qvidcap', 'qtbase', '', d)}"
-
-FILES:rc-keymaps = "${sysconfdir}/rc* ${base_libdir}/udev/rc*"
-
-FILES:${PN} = "${bindir} ${sbindir}"
-
-FILES:libv4l += "${libdir}/libv4l*${SOLIBS} ${libdir}/libv4l/*.so ${libdir}/libv4l/plugins/*.so \
-                 ${libdir}/libdvbv5*${SOLIBS} \
-                 ${libdir}/libv4l/*-decomp"
-
-FILES:libv4l-dev += "${includedir} ${libdir}/pkgconfig \
-                     ${libdir}/libv4l*${SOLIBSDEV} ${libdir}/*.la \
-                     ${libdir}/v4l*${SOLIBSDEV} ${libdir}/libv4l/*.la ${libdir}/libv4l/plugins/*.la"
-
-PARALLEL_MAKE:class-native = ""
-BBCLASSEXTEND = "native"