@@ -245,6 +245,18 @@ protected:
void mapBuffers(Camera *camera, const BufferMap &buffers, unsigned int mask);
+ /* Platform-specific helpers used by survey() and createCamera(). */
+ virtual DeviceMatch frontendMatch() const = 0;
+ virtual DeviceMatch backendMatch() const = 0;
+ virtual const char *frontendLinkName() const = 0;
+ virtual bool platformSupported([[maybe_unused]] const MediaDevice *frontend,
+ [[maybe_unused]] const MediaDevice *backend) const
+ {
+ return true;
+ }
+ virtual std::unique_ptr<CameraData>
+ allocateCameraData(MediaDevice *frontend, MediaDevice *backend) = 0;
+
virtual int platformRegister(std::unique_ptr<CameraData> &cameraData,
std::shared_ptr<MediaDevice> unicam,
std::shared_ptr<MediaDevice> isp) = 0;
@@ -869,12 +869,81 @@ private:
return static_cast<PiSPCameraData *>(camera->_d());
}
+ DeviceMatch frontendMatch() const override
+ {
+ DeviceMatch cfe("rp1-cfe");
+ cfe.add("rp1-cfe-fe-image0");
+ cfe.add("rp1-cfe-fe-stats");
+ cfe.add("rp1-cfe-fe-config");
+ return cfe;
+ }
+
+ DeviceMatch backendMatch() const override
+ {
+ DeviceMatch isp("pispbe");
+ isp.add("pispbe-input");
+ isp.add("pispbe-config");
+ isp.add("pispbe-output0");
+ isp.add("pispbe-output1");
+ isp.add("pispbe-tdn_output");
+ isp.add("pispbe-tdn_input");
+ isp.add("pispbe-stitch_output");
+ isp.add("pispbe-stitch_input");
+ return isp;
+ }
+
+ const char *frontendLinkName() const override
+ {
+ return "csi2";
+ }
+
+ bool platformSupported(const MediaDevice *frontend,
+ const MediaDevice *backend) const override
+ {
+ const libpisp::PiSPVariant &variant =
+ libpisp::get_variant(frontend->hwRevision(),
+ backend->hwRevision());
+ return variant.NumFrontEnds() && variant.NumBackEnds();
+ }
+
+ std::unique_ptr<RPi::CameraData>
+ allocateCameraData(MediaDevice *frontend, MediaDevice *backend) override;
+
int allocateBuffers(Camera *camera) override;
int platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,
std::shared_ptr<MediaDevice> cfe,
std::shared_ptr<MediaDevice> isp) override;
};
+std::unique_ptr<RPi::CameraData>
+PipelineHandlerPiSP::allocateCameraData(MediaDevice *frontend, MediaDevice *backend)
+{
+ const libpisp::PiSPVariant &variant =
+ libpisp::get_variant(frontend->hwRevision(),
+ backend->hwRevision());
+ if (!variant.NumFrontEnds() || !variant.NumBackEnds()) {
+ LOG(RPI, Error) << "Unsupported PiSP variant";
+ return {};
+ }
+
+ std::unique_ptr<RPi::CameraData> cameraData =
+ std::make_unique<PiSPCameraData>(this, variant);
+ PiSPCameraData *pisp =
+ static_cast<PiSPCameraData *>(cameraData.get());
+
+ pisp->fe_ = SharedMemObject<FrontEnd>
+ ("pisp_frontend", true, pisp->pispVariant_);
+ pisp->be_ = SharedMemObject<BackEnd>
+ ("pisp_backend", BackEnd::Config({}), pisp->pispVariant_);
+
+ if (!pisp->fe_.fd().isValid() || !pisp->be_.fd().isValid()) {
+ LOG(RPI, Error) << "Failed to create ISP shared objects";
+ return {};
+ }
+
+ return cameraData;
+}
+
bool PipelineHandlerPiSP::match(DeviceEnumerator *enumerator)
{
constexpr unsigned int numCfeDevices = 2;
@@ -158,6 +158,28 @@ private:
return static_cast<Vc4CameraData *>(camera->_d());
}
+ DeviceMatch frontendMatch() const override
+ {
+ return DeviceMatch("unicam");
+ }
+
+ DeviceMatch backendMatch() const override
+ {
+ return DeviceMatch("bcm2835-isp");
+ }
+
+ const char *frontendLinkName() const override
+ {
+ return "unicam-image";
+ }
+
+ std::unique_ptr<RPi::CameraData>
+ allocateCameraData([[maybe_unused]] MediaDevice *frontend,
+ [[maybe_unused]] MediaDevice *backend) override
+ {
+ return std::make_unique<Vc4CameraData>(this);
+ }
+
int allocateBuffers(Camera *camera) override;
int platformRegister(std::unique_ptr<RPi::CameraData> &cameraData,
std::shared_ptr<MediaDevice> unicam,
The vc4 and pisp match() implementations differ only in the media devices they look for, the frontend link name, the camera data they allocate and, for pisp, a check of the PiSP variant. Expose these differences as platforms specific helpers in PipelineHandlerBase and implement them for both vc4 and pisp. In a subsequent commit, a generic survey() and createCamera() can be built on them. The existing match() implementations are left untouched. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> --- .../pipeline/rpi/common/pipeline_base.h | 12 ++++ src/libcamera/pipeline/rpi/pisp/pisp.cpp | 69 +++++++++++++++++++ src/libcamera/pipeline/rpi/vc4/vc4.cpp | 22 ++++++ 3 files changed, 103 insertions(+)