[{"id":21714,"web_url":"https://patchwork.libcamera.org/comment/21714/","msgid":"<CAEmqJPpNHHg+xPDjyPFtGF6Uya6o1oO_q4+QceqstE18uP8guQ@mail.gmail.com>","date":"2021-12-09T15:17:36","subject":"Re: [libcamera-devel] [PATCH v3 2/2] pipeline: raspberrypi: Add\n\tsupport for Video Mux and Bridge devices","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"On Thu, 9 Dec 2021 at 13:32, Naushir Patuck <naush@raspberrypi.com> wrote:\n\n> This change will allow the pipeline handler to enumerate and control Video\n> Mux or Bridge devices that may be attached between sensors and a particular\n> Unicam instance. Cascaded mux or bridge devices are also handled.\n>\n> A new member function enumerateVideoDevices(), called from\n> registerCamera(), is\n> used to identify and open all mux and bridge subdevices present in the\n> sensor -> Unicam link.\n>\n> Relevent links are enabled/disabled and pad formats correctly set in\n> configure()\n> before the camera is started.\n>\n> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  .../pipeline/raspberrypi/raspberrypi.cpp      | 119 ++++++++++++++++++\n>  1 file changed, 119 insertions(+)\n>\n> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> index 2a2fb5273eb8..49dbefd8637c 100644\n> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> @@ -12,6 +12,7 @@\n>  #include <mutex>\n>  #include <queue>\n>  #include <unordered_set>\n> +#include <utility>\n>\n>  #include <libcamera/base/shared_fd.h>\n>  #include <libcamera/base/utils.h>\n> @@ -220,6 +221,11 @@ public:\n>         std::vector<RPi::Stream *> streams_;\n>         /* Stores the ids of the buffers mapped in the IPA. */\n>         std::unordered_set<unsigned int> ipaBuffers_;\n> +       /*\n> +        * Stores a cascade of Video Mux or Bridge devices between the\n> sensor and\n> +        * Unicam together with media link across the entities.\n> +        */\n> +       std::vector<std::pair<std::unique_ptr<V4L2Subdevice>, MediaLink\n> *>> bridgeDevices_;\n>\n>         /* DMAHEAP allocation helper. */\n>         RPi::DmaHeap dmaHeap_;\n> @@ -311,6 +317,7 @@ private:\n>         }\n>\n>         int registerCamera(MediaDevice *unicam, MediaDevice *isp,\n> MediaEntity *sensorEntity);\n> +       void enumerateVideoDevices(RPiCameraData *data, MediaLink *link);\n>         int queueAllBuffers(Camera *camera);\n>         int prepareBuffers(Camera *camera);\n>         void freeBuffers(Camera *camera);\n> @@ -868,6 +875,33 @@ int PipelineHandlerRPi::configure(Camera *camera,\n> CameraConfiguration *config)\n>          */\n>         data->properties_.set(properties::ScalerCropMaximum,\n> data->sensorInfo_.analogCrop);\n>\n> +       /* Setup the Video Mux/Bridge entities. */\n> +       for (auto &[device, link] : data->bridgeDevices_) {\n> +               /* Start by disabling all the sink pad links on the\n> devices in the cascade. */\n> +               for (const MediaPad *p : device->entity()->pads()) {\n> +                       if (!(p->flags() & MEDIA_PAD_FL_SINK))\n> +                               continue;\n> +\n> +                       for (MediaLink *l : p->links())\n> +                               l->setEnabled(false);\n> +               }\n> +\n> +               /* Next, enable the entity -> entity links, and setup the\n> pad format. */\n> +               link->setEnabled(true);\n> +               const MediaPad *srcPad = link->sink();\n> +               ret = device->setFormat(srcPad->index(), &sensorFormat);\n> +               if (ret) {\n> +                       LOG(RPI, Error) << \"Failed to set format on \" <<\n> device->entity()->name()\n> +                                       << \" pad \" << srcPad->index()\n> +                                       << \" with format  \" <<\n> format.toString()\n> +                                       << \": \" << ret;\n> +                       return ret;\n> +               }\n> +\n> +               LOG(RPI, Info) << \"Configured media link on device \" <<\n> device->entity()->name()\n> +                              << \" on pad \" << srcPad->index();\n> +       }\n> +\n>         return ret;\n>  }\n>\n> @@ -1098,6 +1132,13 @@ int PipelineHandlerRPi::registerCamera(MediaDevice\n> *unicam, MediaDevice *isp, Me\n>         if (data->sensor_->init())\n>                 return -EINVAL;\n>\n> +       /*\n> +        * Enumerate all the Video Mux/Bridge devices across the sensor ->\n> unicam\n> +        * link. There may be a cascade of devices in this link!\n> +        */\n> +       MediaLink *link = sensorEntity->getPadByIndex(0)->links()[0];\n> +       enumerateVideoDevices(data.get(), link);\n> +\n>         data->sensorFormats_ = populateSensorFormats(data->sensor_);\n>\n>         ipa::RPi::SensorConfig sensorConfig;\n> @@ -1224,6 +1265,84 @@ int PipelineHandlerRPi::registerCamera(MediaDevice\n> *unicam, MediaDevice *isp, Me\n>         return 0;\n>  }\n>\n> +/*\n> + * enumerateVideoDevices() iterates over the Media Controller topology,\n> starting\n> + * at the sensor and finishing at Unicam. For each sensor, RPiCameraData\n> stores\n> + * a unique list of any intermediate video mux or bridge devices\n> connected in a\n> + * cascade, together with the entity to entity link.\n> + *\n> + * Entity pad configuration and link enabling happens at the end of\n> configure().\n> + * We first disables all pad links on each entity device in the chain,\n> and then\n> + * selectively enabling the specific links to link sensor to Unicam\n> across all\n> + * intermediate muxes and bridges.\n> + *\n> + * In the cascaded topology below, if Sensor1 is used, the Mux2 -> Mux1\n> link\n> + * will be disabled, and Sensor1 -> Mux1 -> Unicam links enabled.\n> Alternatively,\n> + * if Sensor3 is used, the Sensor2 -> Mux2 and Sensor1 -> Mux1 links are\n> disabled,\n> + * and Sensor3 -> Mux2 -> Mux1 -> Unicam links are enabled. All other\n> links will\n> + * remain unchanged.\n> + *\n> + *  +----------+\n> + *  |  Unicam  |\n> + *  +-----^----+\n> + *        |\n> + *    +---+---+\n> + *    |  Mux1 <-------+\n> + *    +--^----+       |\n> + *       |            |\n> + * +-----+---+    +---+---+\n> + * | Sensor1 |    |  Mux2 |<--+\n> + * +---------+    +-^-----+   |\n> + *                  |         |\n> + *          +-------+-+   +---+-----+\n> + *          | Sensor2 |   | Sensor3 |\n> + *          +---------+   +---------+\n> + */\n> +void PipelineHandlerRPi::enumerateVideoDevices(RPiCameraData *data,\n> MediaLink *link)\n> +{\n> +       const MediaPad *sinkPad = link->sink();\n> +       const MediaEntity *entity = sinkPad->entity();\n> +       bool unicamFound = false;\n> +\n> +       /* We only deal with Video Mux and Bridge devices in cascade. */\n> +       if (entity->function() != MEDIA_ENT_F_VID_MUX &&\n> +           entity->function() != MEDIA_ENT_F_VID_IF_BRIDGE)\n> +               return;\n>\n\nI wonder if I should have a test here to ensure that the entity should only\never have one source pad? If not, return without traversing down this\ncascade.  Or are Video Mux and Bridge devices guaranteed to have\nonly one source pad?\n\n\n> +\n> +       LOG(RPI, Info) << \"Found video mux device \" << entity->name()\n> +                      << \" linked to sink pad \" << sinkPad->index();\n> +\n> +\n>  data->bridgeDevices_.emplace_back(std::make_unique<V4L2Subdevice>(entity),\n> link);\n> +       data->bridgeDevices_.back().first->open();\n> +\n> +       for (const MediaPad *pad : entity->pads()) {\n> +               /*\n> +                * Iterate through all the sink pads down the cascade to\n> find any\n> +                * other Video Mux and Bridge devices.\n> +                */\n> +               if (!(pad->flags() & MEDIA_PAD_FL_SOURCE))\n> +                       continue;\n> +\n> +               for (MediaLink *l : pad->links()) {\n> +                       enumerateVideoDevices(data, l);\n> +                       if (l->sink()->entity()->name() == \"unicam-image\")\n> +                               unicamFound = true;\n> +               }\n> +       }\n> +\n> +       /* This identifies the end of our entity enumeration recursion. */\n> +       if (link->source()->entity()->function() ==\n> MEDIA_ENT_F_CAM_SENSOR) {\n> +               /*\n> +               * If Unicam is not at the end of this cascade, we cannot\n> configure\n> +               * this topology automatically, so remove all entity\n> references.\n> +               */\n> +               if (!unicamFound) {\n> +                       LOG(RPI, Warning) << \"Cannot automatically\n> configure this MC topology!\";\n> +                       data->bridgeDevices_.clear();\n> +               }\n> +       }\n> +}\n> +\n>  int PipelineHandlerRPi::queueAllBuffers(Camera *camera)\n>  {\n>         RPiCameraData *data = cameraData(camera);\n> --\n> 2.25.1\n>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0023DBF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  9 Dec 2021 15:17:56 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 32DCF6087A;\n\tThu,  9 Dec 2021 16:17:56 +0100 (CET)","from mail-lj1-x22a.google.com (mail-lj1-x22a.google.com\n\t[IPv6:2a00:1450:4864:20::22a])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C45C4607DE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  9 Dec 2021 16:17:53 +0100 (CET)","by mail-lj1-x22a.google.com with SMTP id bn20so9480872ljb.8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 09 Dec 2021 07:17:53 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"HH28QTyu\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=qzlDBAgFqhwIdI+96UQsru1i+LImqJjY72nuV3wZLxo=;\n\tb=HH28QTyufTILJ+ZeNoyXJyH+TwZc9ETN+C7W1QuX9VXW2GYnibT3S+8WNpJVr+jyYM\n\t4ChPCZiCMGzyHqDAygyFKrLTNn3QRaLyCGKuo3g6+Ax/FVEdx+YtZypUI9upVpBwuikA\n\tzIzomtSzVHvDR6H/cK7Cp4lyXoFEdF11FhXplevYhGFuug7ZACkQ4Wy65Ordt5MS5FL1\n\tVb8yuMHgvcU12MhFvoHPKtK3owCf43RB6UWm5sPcJZWlBUPzMjZQzQVHwhSYvPlxgCgf\n\tCHjpXsJfxMP/Hr0UUxPjEiFpjoPt35iiYgISPfgd8gXLqwLLv8vkXhkpWlrBvjKFyJzT\n\tSQKw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=qzlDBAgFqhwIdI+96UQsru1i+LImqJjY72nuV3wZLxo=;\n\tb=emUZSA1i1TD1+/mbuawbeuaqskTKD/fSWsmW6BP+GPaj+6HyIlkSsDPVUYJJ/UKkVv\n\t8ZXVaY0/14K47qbg5PeO36n6HuKPABhF2UkC4FN8G7iOp5yzgyoG3jLH2k02RGVJnXjp\n\timas+1hztUwG/eL9OllQ/pVG+SDSXwvwQ7k2VYh23gPlv/QRfTVZJusYUDXng3k8UuhW\n\tNxUwvLuTyQcq6rU9c8SeYWNukRbCzylnaDCWpDGS5zTW4x6PD8tYPaL/S1R3NYt983wm\n\tuIzxuxG8sel1bG4zzVm/flTfnYBInO+G/OkLHLwAK+dx1nZyAO+Bx+HvfR/jDJrHZm/t\n\tDeNQ==","X-Gm-Message-State":"AOAM532AMWkJ75d4Dpj3ozLewn+KeWr9cE20uvXCH1rw/v66viRY+Foj\n\tq19HGvRF3ls0mQzVPIMP+sF+2xKEiTB1msYF09fTn6ACZ2mUXQ==","X-Google-Smtp-Source":"ABdhPJzZYtauzBNfcS73Jo5s7Vrc/Lh/T5+5tYGXaZIux4ZslQSNtv95Lnc6izDY4Ku78/81kSa1jeqRhIacXaIWxx8=","X-Received":"by 2002:a2e:908b:: with SMTP id\n\tl11mr7148939ljg.208.1639063072508; \n\tThu, 09 Dec 2021 07:17:52 -0800 (PST)","MIME-Version":"1.0","References":"<20211209133252.2234668-1-naush@raspberrypi.com>\n\t<20211209133252.2234668-3-naush@raspberrypi.com>","In-Reply-To":"<20211209133252.2234668-3-naush@raspberrypi.com>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Thu, 9 Dec 2021 15:17:36 +0000","Message-ID":"<CAEmqJPpNHHg+xPDjyPFtGF6Uya6o1oO_q4+QceqstE18uP8guQ@mail.gmail.com>","To":"libcamera devel <libcamera-devel@lists.libcamera.org>","Content-Type":"multipart/alternative; boundary=\"00000000000033c35205d2b81c35\"","Subject":"Re: [libcamera-devel] [PATCH v3 2/2] pipeline: raspberrypi: Add\n\tsupport for Video Mux and Bridge devices","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":21755,"web_url":"https://patchwork.libcamera.org/comment/21755/","msgid":"<163914821512.2066819.14318384464991701631@Monstersaurus>","date":"2021-12-10T14:56:55","subject":"Re: [libcamera-devel] [PATCH v3 2/2] pipeline: raspberrypi: Add\n\tsupport for Video Mux and Bridge devices","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Naushir Patuck (2021-12-09 15:17:36)\n> On Thu, 9 Dec 2021 at 13:32, Naushir Patuck <naush@raspberrypi.com> wrote:\n> \n> > This change will allow the pipeline handler to enumerate and control Video\n> > Mux or Bridge devices that may be attached between sensors and a particular\n> > Unicam instance. Cascaded mux or bridge devices are also handled.\n> >\n> > A new member function enumerateVideoDevices(), called from\n> > registerCamera(), is\n> > used to identify and open all mux and bridge subdevices present in the\n> > sensor -> Unicam link.\n> >\n> > Relevent links are enabled/disabled and pad formats correctly set in\n> > configure()\n> > before the camera is started.\n> >\n> > Signed-off-by: Naushir Patuck <naush@raspberrypi.com>\n> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > ---\n> >  .../pipeline/raspberrypi/raspberrypi.cpp      | 119 ++++++++++++++++++\n> >  1 file changed, 119 insertions(+)\n> >\n> > diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> > b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> > index 2a2fb5273eb8..49dbefd8637c 100644\n> > --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> > +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> > @@ -12,6 +12,7 @@\n> >  #include <mutex>\n> >  #include <queue>\n> >  #include <unordered_set>\n> > +#include <utility>\n> >\n> >  #include <libcamera/base/shared_fd.h>\n> >  #include <libcamera/base/utils.h>\n> > @@ -220,6 +221,11 @@ public:\n> >         std::vector<RPi::Stream *> streams_;\n> >         /* Stores the ids of the buffers mapped in the IPA. */\n> >         std::unordered_set<unsigned int> ipaBuffers_;\n> > +       /*\n> > +        * Stores a cascade of Video Mux or Bridge devices between the\n> > sensor and\n> > +        * Unicam together with media link across the entities.\n> > +        */\n> > +       std::vector<std::pair<std::unique_ptr<V4L2Subdevice>, MediaLink\n> > *>> bridgeDevices_;\n> >\n> >         /* DMAHEAP allocation helper. */\n> >         RPi::DmaHeap dmaHeap_;\n> > @@ -311,6 +317,7 @@ private:\n> >         }\n> >\n> >         int registerCamera(MediaDevice *unicam, MediaDevice *isp,\n> > MediaEntity *sensorEntity);\n> > +       void enumerateVideoDevices(RPiCameraData *data, MediaLink *link);\n> >         int queueAllBuffers(Camera *camera);\n> >         int prepareBuffers(Camera *camera);\n> >         void freeBuffers(Camera *camera);\n> > @@ -868,6 +875,33 @@ int PipelineHandlerRPi::configure(Camera *camera,\n> > CameraConfiguration *config)\n> >          */\n> >         data->properties_.set(properties::ScalerCropMaximum,\n> > data->sensorInfo_.analogCrop);\n> >\n> > +       /* Setup the Video Mux/Bridge entities. */\n> > +       for (auto &[device, link] : data->bridgeDevices_) {\n> > +               /* Start by disabling all the sink pad links on the\n> > devices in the cascade. */\n> > +               for (const MediaPad *p : device->entity()->pads()) {\n> > +                       if (!(p->flags() & MEDIA_PAD_FL_SINK))\n> > +                               continue;\n> > +\n> > +                       for (MediaLink *l : p->links())\n> > +                               l->setEnabled(false);\n> > +               }\n> > +\n> > +               /* Next, enable the entity -> entity links, and setup the\n> > pad format. */\n> > +               link->setEnabled(true);\n> > +               const MediaPad *srcPad = link->sink();\n> > +               ret = device->setFormat(srcPad->index(), &sensorFormat);\n> > +               if (ret) {\n> > +                       LOG(RPI, Error) << \"Failed to set format on \" <<\n> > device->entity()->name()\n> > +                                       << \" pad \" << srcPad->index()\n> > +                                       << \" with format  \" <<\n> > format.toString()\n> > +                                       << \": \" << ret;\n> > +                       return ret;\n> > +               }\n> > +\n> > +               LOG(RPI, Info) << \"Configured media link on device \" <<\n> > device->entity()->name()\n> > +                              << \" on pad \" << srcPad->index();\n> > +       }\n> > +\n> >         return ret;\n> >  }\n> >\n> > @@ -1098,6 +1132,13 @@ int PipelineHandlerRPi::registerCamera(MediaDevice\n> > *unicam, MediaDevice *isp, Me\n> >         if (data->sensor_->init())\n> >                 return -EINVAL;\n> >\n> > +       /*\n> > +        * Enumerate all the Video Mux/Bridge devices across the sensor ->\n> > unicam\n> > +        * link. There may be a cascade of devices in this link!\n> > +        */\n> > +       MediaLink *link = sensorEntity->getPadByIndex(0)->links()[0];\n> > +       enumerateVideoDevices(data.get(), link);\n> > +\n> >         data->sensorFormats_ = populateSensorFormats(data->sensor_);\n> >\n> >         ipa::RPi::SensorConfig sensorConfig;\n> > @@ -1224,6 +1265,84 @@ int PipelineHandlerRPi::registerCamera(MediaDevice\n> > *unicam, MediaDevice *isp, Me\n> >         return 0;\n> >  }\n> >\n> > +/*\n> > + * enumerateVideoDevices() iterates over the Media Controller topology,\n> > starting\n> > + * at the sensor and finishing at Unicam. For each sensor, RPiCameraData\n> > stores\n> > + * a unique list of any intermediate video mux or bridge devices\n> > connected in a\n> > + * cascade, together with the entity to entity link.\n> > + *\n> > + * Entity pad configuration and link enabling happens at the end of\n> > configure().\n> > + * We first disables all pad links on each entity device in the chain,\n> > and then\n> > + * selectively enabling the specific links to link sensor to Unicam\n> > across all\n> > + * intermediate muxes and bridges.\n> > + *\n> > + * In the cascaded topology below, if Sensor1 is used, the Mux2 -> Mux1\n> > link\n> > + * will be disabled, and Sensor1 -> Mux1 -> Unicam links enabled.\n> > Alternatively,\n> > + * if Sensor3 is used, the Sensor2 -> Mux2 and Sensor1 -> Mux1 links are\n> > disabled,\n> > + * and Sensor3 -> Mux2 -> Mux1 -> Unicam links are enabled. All other\n> > links will\n> > + * remain unchanged.\n> > + *\n> > + *  +----------+\n> > + *  |  Unicam  |\n> > + *  +-----^----+\n> > + *        |\n> > + *    +---+---+\n> > + *    |  Mux1 <-------+\n> > + *    +--^----+       |\n> > + *       |            |\n> > + * +-----+---+    +---+---+\n> > + * | Sensor1 |    |  Mux2 |<--+\n> > + * +---------+    +-^-----+   |\n> > + *                  |         |\n> > + *          +-------+-+   +---+-----+\n> > + *          | Sensor2 |   | Sensor3 |\n> > + *          +---------+   +---------+\n> > + */\n> > +void PipelineHandlerRPi::enumerateVideoDevices(RPiCameraData *data,\n> > MediaLink *link)\n> > +{\n> > +       const MediaPad *sinkPad = link->sink();\n> > +       const MediaEntity *entity = sinkPad->entity();\n> > +       bool unicamFound = false;\n> > +\n> > +       /* We only deal with Video Mux and Bridge devices in cascade. */\n> > +       if (entity->function() != MEDIA_ENT_F_VID_MUX &&\n> > +           entity->function() != MEDIA_ENT_F_VID_IF_BRIDGE)\n> > +               return;\n> >\n> \n> I wonder if I should have a test here to ensure that the entity should only\n> ever have one source pad? If not, return without traversing down this\n> cascade.  Or are Video Mux and Bridge devices guaranteed to have\n> only one source pad?\n\nI don't think it's essential at this stage, as it's not particularly\nsupported but ... <looks down at diagram of hardware in front of him>\nI could imagine a video mux that acts as a crossbar being defined\nsometime...\n\nI suspect as a sanity check to validate that it only parses devices it\ncan handle, a check with a warning print would help any future developer\nthat might decide to try to implement something a bit more complex...\n\n--\nKieran\n\n> > +\n> > +       LOG(RPI, Info) << \"Found video mux device \" << entity->name()\n> > +                      << \" linked to sink pad \" << sinkPad->index();\n> > +\n> > +\n> >  data->bridgeDevices_.emplace_back(std::make_unique<V4L2Subdevice>(entity),\n> > link);\n> > +       data->bridgeDevices_.back().first->open();\n> > +\n> > +       for (const MediaPad *pad : entity->pads()) {\n> > +               /*\n> > +                * Iterate through all the sink pads down the cascade to\n> > find any\n> > +                * other Video Mux and Bridge devices.\n> > +                */\n> > +               if (!(pad->flags() & MEDIA_PAD_FL_SOURCE))\n> > +                       continue;\n> > +\n> > +               for (MediaLink *l : pad->links()) {\n> > +                       enumerateVideoDevices(data, l);\n> > +                       if (l->sink()->entity()->name() == \"unicam-image\")\n> > +                               unicamFound = true;\n> > +               }\n> > +       }\n> > +\n> > +       /* This identifies the end of our entity enumeration recursion. */\n> > +       if (link->source()->entity()->function() ==\n> > MEDIA_ENT_F_CAM_SENSOR) {\n> > +               /*\n> > +               * If Unicam is not at the end of this cascade, we cannot\n> > configure\n> > +               * this topology automatically, so remove all entity\n> > references.\n> > +               */\n> > +               if (!unicamFound) {\n> > +                       LOG(RPI, Warning) << \"Cannot automatically\n> > configure this MC topology!\";\n> > +                       data->bridgeDevices_.clear();\n> > +               }\n> > +       }\n> > +}\n> > +\n> >  int PipelineHandlerRPi::queueAllBuffers(Camera *camera)\n> >  {\n> >         RPiCameraData *data = cameraData(camera);\n> > --\n> > 2.25.1\n> >\n> >","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 85395BDB13\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 10 Dec 2021 14:57:00 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B162A60897;\n\tFri, 10 Dec 2021 15:56:59 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B19B66087E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Dec 2021 15:56:57 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 418B2F84;\n\tFri, 10 Dec 2021 15:56:57 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"bj9icVct\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1639148217;\n\tbh=l24henjzVHg1UuC4ENYIimvDAPvHIHj2ZvIozn8/mCE=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=bj9icVctBKRsnJmyfT3mQC6aygxyoREmvtiscMeUlI0AwSWcMt7nBy8VIpuYDvxtu\n\tee7DTuEx6Lc5ePEbJbD4CKOx2YknNBnB+3ZnntojqsGdavy+kNxhYC8dp1fCUmjwQW\n\t2hmFMH9JbLJy3bIG1bCrz9OnvzQHFjk0Hf1nCT0M=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<CAEmqJPpNHHg+xPDjyPFtGF6Uya6o1oO_q4+QceqstE18uP8guQ@mail.gmail.com>","References":"<20211209133252.2234668-1-naush@raspberrypi.com>\n\t<20211209133252.2234668-3-naush@raspberrypi.com>\n\t<CAEmqJPpNHHg+xPDjyPFtGF6Uya6o1oO_q4+QceqstE18uP8guQ@mail.gmail.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"Naushir Patuck <naush@raspberrypi.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","Date":"Fri, 10 Dec 2021 14:56:55 +0000","Message-ID":"<163914821512.2066819.14318384464991701631@Monstersaurus>","User-Agent":"alot/0.10","Subject":"Re: [libcamera-devel] [PATCH v3 2/2] pipeline: raspberrypi: Add\n\tsupport for Video Mux and Bridge devices","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]