Message ID | 20250625084212.858487-4-naush@raspberrypi.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
Hi Naush, Thank you for the patch. On Wed, Jun 25, 2025 at 09:41:18AM +0100, Naushir Patuck wrote: > If an entity advertises streams support, and no routes are active, set > a default active route for Stream 0:[pad 0 -> pad 1]. This allows > serialiser/deserialiser devices to run without user setup in the default > case. > > Signed-off-by: Naushir Patuck <naush@raspberrypi.com> > --- > .../pipeline/rpi/common/pipeline_base.cpp | 33 ++++++++++++++++++- > 1 file changed, 32 insertions(+), 1 deletion(-) > > diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > index 219bd81cc63a..eafbf702ed0b 100644 > --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > @@ -107,7 +107,38 @@ int configureMediaDevices(std::vector<std::pair<std::unique_ptr<V4L2Subdevice>, > } > > /* > - * Next, enable the entity -> entity links, and setup the pad format. > + * Next, setup the stream routing if needed. By default this > + * sets up Stream 0:[pad 0 -> pad 1] route. Anything more > + * complicated must currently be setup and activated externally. > + * > + * If we find any active routes, we don't change anything. > + */ > + if (device->caps().hasStreams()) { > + V4L2Subdevice::Routing routing; > + > + ret = device->getRouting(&routing); > + if (ret) > + return ret; > + > + /* If we find an active route, don't do anything more. */ > + for (auto const &r : routing) { > + if (r.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) > + return 0; > + } > + > + /* > + * Set up a default Stream 0:[pad 0 -> pad 1] route if nothing > + * has already been set. > + */ > + routing = { { V4L2Subdevice::Stream{ 0, 0 }, > + V4L2Subdevice::Stream{ 1, 0 }, > + V4L2_SUBDEV_ROUTE_FL_ACTIVE } }; That's really shooting in the dark :-( We should model serializers and deserializers with dedicated objects, like we do with the CameraSensor class. > + > + ret = device->setRouting(&routing); > + } > + > + /* > + * Finally, enable the entity -> entity links, and setup the pad format. > * > * \todo Some bridge devices may chainge the media bus code, so we > * ought to read the source pad format and propagate it to the sink pad.
On Thu, 26 Jun 2025 at 13:45, Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote: > > Hi Naush, > > Thank you for the patch. > > On Wed, Jun 25, 2025 at 09:41:18AM +0100, Naushir Patuck wrote: > > If an entity advertises streams support, and no routes are active, set > > a default active route for Stream 0:[pad 0 -> pad 1]. This allows > > serialiser/deserialiser devices to run without user setup in the default > > case. > > > > Signed-off-by: Naushir Patuck <naush@raspberrypi.com> > > --- > > .../pipeline/rpi/common/pipeline_base.cpp | 33 ++++++++++++++++++- > > 1 file changed, 32 insertions(+), 1 deletion(-) > > > > diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > > index 219bd81cc63a..eafbf702ed0b 100644 > > --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > > +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > > @@ -107,7 +107,38 @@ int configureMediaDevices(std::vector<std::pair<std::unique_ptr<V4L2Subdevice>, > > } > > > > /* > > - * Next, enable the entity -> entity links, and setup the pad format. > > + * Next, setup the stream routing if needed. By default this > > + * sets up Stream 0:[pad 0 -> pad 1] route. Anything more > > + * complicated must currently be setup and activated externally. > > + * > > + * If we find any active routes, we don't change anything. > > + */ > > + if (device->caps().hasStreams()) { > > + V4L2Subdevice::Routing routing; > > + > > + ret = device->getRouting(&routing); > > + if (ret) > > + return ret; > > + > > + /* If we find an active route, don't do anything more. */ > > + for (auto const &r : routing) { > > + if (r.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) > > + return 0; > > + } > > + > > + /* > > + * Set up a default Stream 0:[pad 0 -> pad 1] route if nothing > > + * has already been set. > > + */ > > + routing = { { V4L2Subdevice::Stream{ 0, 0 }, > > + V4L2Subdevice::Stream{ 1, 0 }, > > + V4L2_SUBDEV_ROUTE_FL_ACTIVE } }; > > That's really shooting in the dark :-( > > We should model serializers and deserializers with dedicated objects, > like we do with the CameraSensor class. Sadly I agree, but how can we expose this to the user/application to configure for their needs? Naush > > > + > > + ret = device->setRouting(&routing); > > + } > > + > > + /* > > + * Finally, enable the entity -> entity links, and setup the pad format. > > * > > * \todo Some bridge devices may chainge the media bus code, so we > > * ought to read the source pad format and propagate it to the sink pad. > > -- > Regards, > > Laurent Pinchart
On Thu, Jun 26, 2025 at 01:52:51PM +0100, Naushir Patuck wrote: > On Thu, 26 Jun 2025 at 13:45, Laurent Pinchart > <laurent.pinchart@ideasonboard.com> wrote: > > > > Hi Naush, > > > > Thank you for the patch. > > > > On Wed, Jun 25, 2025 at 09:41:18AM +0100, Naushir Patuck wrote: > > > If an entity advertises streams support, and no routes are active, set > > > a default active route for Stream 0:[pad 0 -> pad 1]. This allows > > > serialiser/deserialiser devices to run without user setup in the default > > > case. > > > > > > Signed-off-by: Naushir Patuck <naush@raspberrypi.com> > > > --- > > > .../pipeline/rpi/common/pipeline_base.cpp | 33 ++++++++++++++++++- > > > 1 file changed, 32 insertions(+), 1 deletion(-) > > > > > > diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > > > index 219bd81cc63a..eafbf702ed0b 100644 > > > --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > > > +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp > > > @@ -107,7 +107,38 @@ int configureMediaDevices(std::vector<std::pair<std::unique_ptr<V4L2Subdevice>, > > > } > > > > > > /* > > > - * Next, enable the entity -> entity links, and setup the pad format. > > > + * Next, setup the stream routing if needed. By default this > > > + * sets up Stream 0:[pad 0 -> pad 1] route. Anything more > > > + * complicated must currently be setup and activated externally. > > > + * > > > + * If we find any active routes, we don't change anything. > > > + */ > > > + if (device->caps().hasStreams()) { > > > + V4L2Subdevice::Routing routing; > > > + > > > + ret = device->getRouting(&routing); > > > + if (ret) > > > + return ret; > > > + > > > + /* If we find an active route, don't do anything more. */ > > > + for (auto const &r : routing) { > > > + if (r.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) > > > + return 0; > > > + } > > > + > > > + /* > > > + * Set up a default Stream 0:[pad 0 -> pad 1] route if nothing > > > + * has already been set. > > > + */ > > > + routing = { { V4L2Subdevice::Stream{ 0, 0 }, > > > + V4L2Subdevice::Stream{ 1, 0 }, > > > + V4L2_SUBDEV_ROUTE_FL_ACTIVE } }; > > > > That's really shooting in the dark :-( > > > > We should model serializers and deserializers with dedicated objects, > > like we do with the CameraSensor class. > > Sadly I agree, but how can we expose this to the user/application to > configure for their needs? I don't think we need to, at least not yet (*). The main issue to solve in my opinion is that individual pipeline handlers should not have to manually handle serializers, deserializers and muxes. The part of the pipeline in front of the CSI-2 receiver should be handled by helpers classes shared by pipeline handlers. That will give us the ability to implement specialized classes for specific components, and applying a default configuration matching their needs. After that, we can work on exposing some control over that pipeline to applications. * I was going to write that I am for once limiting the amount of requested yak shaving, but looking at what folows the first sentence, I'm not so sure :-) > > > + > > > + ret = device->setRouting(&routing); > > > + } > > > + > > > + /* > > > + * Finally, enable the entity -> entity links, and setup the pad format. > > > * > > > * \todo Some bridge devices may chainge the media bus code, so we > > > * ought to read the source pad format and propagate it to the sink pad.
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 219bd81cc63a..eafbf702ed0b 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -107,7 +107,38 @@ int configureMediaDevices(std::vector<std::pair<std::unique_ptr<V4L2Subdevice>, } /* - * Next, enable the entity -> entity links, and setup the pad format. + * Next, setup the stream routing if needed. By default this + * sets up Stream 0:[pad 0 -> pad 1] route. Anything more + * complicated must currently be setup and activated externally. + * + * If we find any active routes, we don't change anything. + */ + if (device->caps().hasStreams()) { + V4L2Subdevice::Routing routing; + + ret = device->getRouting(&routing); + if (ret) + return ret; + + /* If we find an active route, don't do anything more. */ + for (auto const &r : routing) { + if (r.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) + return 0; + } + + /* + * Set up a default Stream 0:[pad 0 -> pad 1] route if nothing + * has already been set. + */ + routing = { { V4L2Subdevice::Stream{ 0, 0 }, + V4L2Subdevice::Stream{ 1, 0 }, + V4L2_SUBDEV_ROUTE_FL_ACTIVE } }; + + ret = device->setRouting(&routing); + } + + /* + * Finally, enable the entity -> entity links, and setup the pad format. * * \todo Some bridge devices may chainge the media bus code, so we * ought to read the source pad format and propagate it to the sink pad.
If an entity advertises streams support, and no routes are active, set a default active route for Stream 0:[pad 0 -> pad 1]. This allows serialiser/deserialiser devices to run without user setup in the default case. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> --- .../pipeline/rpi/common/pipeline_base.cpp | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-)