Message ID | 20230210115546.199809-2-tomi.valkeinen@ideasonboard.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | v4l-utils: support multiplexed streams | expand |
Hi, On 10/02/2023 13:55, Tomi Valkeinen wrote: > 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" Laurent noticed that the above option, and a few others, break backward compatibility. If no one has other suggestions, I'll additionally add back the old option format. In other words, if the parameter is a number, it's a pad. Otherwise we look for pad=<pad>,stream=<stream> style option. Well, another alternative would be to use an "extended" pad format instead. I.e. for each <pad> in the old style, we'd accept something like <pad[/stream]>. E.g. "--list-subdev-framesizes pad=<pad[/stream]>,code=<code>" Opinions? Tomi
On 2/13/23 10:49, Tomi Valkeinen wrote: > Hi, > > On 10/02/2023 13:55, Tomi Valkeinen wrote: >> 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" > > Laurent noticed that the above option, and a few others, break backward > compatibility. > > If no one has other suggestions, I'll additionally add back the old > option format. In other words, if the parameter is a number, it's a pad. > Otherwise we look for pad=<pad>,stream=<stream> style option. That will work. Only mention the new arguments in the usage text, though. And add a comment in the code why you check if the arg is just a number. > > Well, another alternative would be to use an "extended" pad format > instead. I.e. for each <pad> in the old style, we'd accept something > like <pad[/stream]>. E.g. "--list-subdev-framesizes > pad=<pad[/stream]>,code=<code>" No, that's inconsistent with the argument style of v4l2-ctl. Note that I am not terribly concerned about backwards compatibility here, especially w.r.t. the subdev options. So if it turns out to be too much work to support the old option format, then I'm OK with breaking the compatibility. Regards, Hans > > Opinions? > > Tomi >
On Mon, Feb 13, 2023 at 11:49:26AM +0200, Tomi Valkeinen wrote: > Hi, > > On 10/02/2023 13:55, Tomi Valkeinen wrote: > > 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" > > Laurent noticed that the above option, and a few others, break backward > compatibility. > > If no one has other suggestions, I'll additionally add back the old > option format. In other words, if the parameter is a number, it's a pad. > Otherwise we look for pad=<pad>,stream=<stream> style option. > > Well, another alternative would be to use an "extended" pad format > instead. I.e. for each <pad> in the old style, we'd accept something > like <pad[/stream]>. E.g. "--list-subdev-framesizes > pad=<pad[/stream]>,code=<code>" > > Opinions? I'd go for pad=<pad>,stream=<stream>. For options that just take a numerical value, <pad>/<stream> is fine, but pad=<pad>/<stream> is confusing.
On Mon, Feb 13, 2023 at 11:00:14AM +0100, Hans Verkuil wrote: > On 2/13/23 10:49, Tomi Valkeinen wrote: > > Hi, > > > > On 10/02/2023 13:55, Tomi Valkeinen wrote: > >> 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" > > > > Laurent noticed that the above option, and a few others, break backward > > compatibility. > > > > If no one has other suggestions, I'll additionally add back the old > > option format. In other words, if the parameter is a number, it's a pad. > > Otherwise we look for pad=<pad>,stream=<stream> style option. > > That will work. Only mention the new arguments in the usage text, though. > > And add a comment in the code why you check if the arg is just a number. > > > > > Well, another alternative would be to use an "extended" pad format > > instead. I.e. for each <pad> in the old style, we'd accept something > > like <pad[/stream]>. E.g. "--list-subdev-framesizes > > pad=<pad[/stream]>,code=<code>" > > No, that's inconsistent with the argument style of v4l2-ctl. > > Note that I am not terribly concerned about backwards compatibility here, > especially w.r.t. the subdev options. So if it turns out to be too much > work to support the old option format, then I'm OK with breaking the > compatibility. I'm fine with this too. > > Opinions?
Hi Hans, Tomi, On Mon, Feb 13, 2023 at 11:00:14AM +0100, Hans Verkuil wrote: > On 2/13/23 10:49, Tomi Valkeinen wrote: > > Hi, > > > > On 10/02/2023 13:55, Tomi Valkeinen wrote: > >> 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" > > > > Laurent noticed that the above option, and a few others, break backward > > compatibility. > > > > If no one has other suggestions, I'll additionally add back the old > > option format. In other words, if the parameter is a number, it's a pad. > > Otherwise we look for pad=<pad>,stream=<stream> style option. > > That will work. Only mention the new arguments in the usage text, though. > > And add a comment in the code why you check if the arg is just a number. This would be my preference, too.
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,
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(-)