From patchwork Thu Feb 6 18:52:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2794 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DB90460946 for ; Thu, 6 Feb 2020 19:50:18 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id A4DA8FF804 for ; Thu, 6 Feb 2020 18:50:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 6 Feb 2020 19:52:41 +0100 Message-Id: <20200206185247.202233-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200206185247.202233-1-jacopo@jmondi.org> References: <20200206185247.202233-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 1/7] libcamera: properties: Define pixel array properties X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Feb 2020 18:50:19 -0000 Add definition of pixel array related properties. Signed-off-by: Jacopo Mondi --- src/libcamera/property_ids.yaml | 177 ++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml index c3070de9d9f8..709016904870 100644 --- a/src/libcamera/property_ids.yaml +++ b/src/libcamera/property_ids.yaml @@ -354,4 +354,181 @@ controls: | | | | +---------------+ + + - PixelArraySize: + type: float + compound: true + description: | + The physical sizes of the pixel array (width and height), in + millimeters. + + - PixelArrayBounds: + type: int32_t + compound: true + description: | + The camera sensor pixel array bounding rectangle vertical and + horizontal sizes. + + For image sensors with a rectangular pixel array the sizes described by + this property are the same as the PixelAreaSize property size. + + For image sensors with more complex pixel array displacements (such as + cross-shaped pixel arrays, non symmetrical pixel arrays etc) this + property represents the bounding rectangle in which all pixel array + dimensions are inscribed into. + + In example, the bounding rectangle sizes for image sensor with a + cross-shaped pixel array is described as + + + PixelArrayBound(0) = width + /-----------------/ + + (0,0)-> +----+------+----+ / + | |//////| | | + +----+//////+----+ | + |////////////////| | PixelArrayBound(1) = height + +----+//////+----+ | + | |//////| | | + +----+------+----+ / + | + -> Cross-shaped pixel area + + - PixelArrays: + type: int32_t + compound: true + description: | + The sensor pixel array rectangles, relative to the rectangle described + by the PixelArrayBounds property. + + This property describes an arbitrary number of (likely overlapping) + rectangles, representing the pixel array areas the sensor is composed + of. + + Each rectangle is defined by its displacement from pixel (0, 0) of + the bounding rectangle described by the PixelArrayBound property. + + For image sensors with a rectangular pixel array, a single rectangle + is required. For sensors with more complex pixel array displacements + multiple rectangles shall be specified, ordered from the tallest to the + shorter one. + + For each rectangle, this property reports the full pixel array size, + including non-active pixels, black level calibration pixels etc. + + In example, a simple sensor with a rectangular pixel array is described + as + + PixelArrayBound(0) = width + /-----------------/ + x1 x2 + (0,0)-> +-o------------o-+ / + y1 o +------------+ | | + | |////////////| | | + | |////////////| | | PixelArrayBound(1) = height + | |////////////| | | + y2 o +------------+ | | + +----------------+ / + + PixelArray = (x1, y1, (x2 - x1), (y2 - y1)) + + A more complex sensor, with a cross shaped pixel array displacement + is described with 2 rectangles, with the vertical rectangle + described first + + PixelArrayBound(0) = width + /-----------------/ + x1 x2 x3 x4 W + (0,0)-> +o---o------o---o+ / + | |//////| | | + y1 o+---+------+---+| | + ||///|//////|///|| | PixelArrayBound(1) = height + y2 o+---+------+---+| | + | |//////| | | + H +----+------+----+ / + + + PixelArray = ( (x2, 0, (x3 - x2), H), + (x1, y1, (x4 - x1), (y2 - y1)) + + - ActiveAreaSize: + type: int32_t + compound: true + description: | + The sensor active pixel area sizes, represented as rectangles + inscribed in the ones described by the PixelArrays property. + + One ActiveAreaSize rectangle per each rectangle described in the + PixelArrays property is required. As a consequence, the two properties + shall transport the same number of elements. + + The ActiveAreaSize rectangles represent the maximum image sizes the + sensor can produce. + + - BayerFilterArrangement: + type: int32_t + description: | + The pixel array color filter displacement. + + This property describes the arrangement and readout sequence of the + three RGB color components of the sensor's Bayer Color Filter Array + (CFA). + + Color filters are usually displaced in line-alternating fashion on the + sensor pixel array. In example, one line might be composed of Red-Green + while the successive is composed of Blue-Green color information. + + The value of this property represent the arrangement of color filters + in the top-left 2x2 pixel square. + + In example, for a sensor with the following color filter displacement + + (0, 0) (max-col) + +---+ +--------------...---+ + |B|G|<---|B|G|B|G|B|G|B|...B|G| + |G|R|<---|G|R|G|R|G|R|G|...G|R| + +---+ |B|G|B|G|B|G|B|...B|G| + ... .. + ... .. + |G|R|G|R|G|R|G|...G|R| + |B|G|B|G|B|G|B|...B|G| (max-lines) + +--------------...---+ + + The filer arrangement is represented by the BGGR value, which correspond + to the pixel readout sequence in line interleaved mode. + + enum: + - BayerFilterRGGB: + value: 0 + description: | + Color filter array displacement is Red-Green/Green-Blue + + - BayerFilterGRBG: + value: 1 + description: | + Color filter array displacement is Green-Red/Blue-Green + + - BayerFilterGBRG: + value: 2 + description: | + Color filter array displacement is Green-Blue/Red-Green + + - BayerFilterBGGR: + value: 3 + description: | + Color filter array displacement is Blue-Green/Green-Red + + - BayerFilterNonStandard: + value: 4 + description: | + The pixel array color filter does not use the standard Bayer RGB + color model + + - ISOSensitivityRange: + type: int32_t + compound: true + description: | + The range of supported ISO sensitivities, as documented by the + ISO 12232:2006 standard + ... From patchwork Thu Feb 6 18:52:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2795 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 419E760864 for ; Thu, 6 Feb 2020 19:50:19 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 0F664FF804 for ; Thu, 6 Feb 2020 18:50:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 6 Feb 2020 19:52:42 +0100 Message-Id: <20200206185247.202233-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200206185247.202233-1-jacopo@jmondi.org> References: <20200206185247.202233-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/7] libcamera: properties: Define 'lens' properties X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Feb 2020 18:50:19 -0000 Define properties that describe the optical characteristics of the image sensor. Signed-off-by: Jacopo Mondi --- src/libcamera/property_ids.yaml | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml index 709016904870..a296349f5227 100644 --- a/src/libcamera/property_ids.yaml +++ b/src/libcamera/property_ids.yaml @@ -531,4 +531,38 @@ controls: The range of supported ISO sensitivities, as documented by the ISO 12232:2006 standard + - LensApertures: + type: float + compound: true + description: | + The available lens apertures, expressed as f numbers (the ratio between + the lens focal distance and the diameter of the pupil aperture). + + If the camera module has a fixed aperture, the property transports a + single value. + + - LensFocalLength: + type: float + compound: true + description: | + The available lens focal lengths, expressed in millimeters. + + If the camera module supports multiple focal lengths this property + reports the focal lengths associated with each discrete step. For + camera modules with a single focal length, a single value should be + instead reported. + + - LensHyperfocalDistance: + type: float + compound: true + description: | + The hyperfocal distance of the camera module. The property is + particularly meaningful for modules with a single focal length. + + - LensMinimumFocusDistance: + type: float + description: | + The shortest distance in millimeters at which an object could be brought + into sharp focus. + ... From patchwork Thu Feb 6 18:52:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2796 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C941960864 for ; Thu, 6 Feb 2020 19:50:19 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 6F974FF804 for ; Thu, 6 Feb 2020 18:50:19 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 6 Feb 2020 19:52:43 +0100 Message-Id: <20200206185247.202233-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200206185247.202233-1-jacopo@jmondi.org> References: <20200206185247.202233-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 3/7] libcamera: camera_sensor: Introduce CameraSensorFactory X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Feb 2020 18:50:20 -0000 Introduce a factory to create CameraSensor derived classes instances by inspecting the sensor media entity name and provide a convenience macro to register specialized sensor handlers. Signed-off-by: Jacopo Mondi --- src/libcamera/camera_sensor.cpp | 134 ++++++++++++++++++ src/libcamera/include/camera_sensor.h | 39 ++++- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 +- src/libcamera/pipeline/vimc.cpp | 2 +- test/camera-sensor.cpp | 2 +- .../v4l2_videodevice_test.cpp | 2 +- 7 files changed, 177 insertions(+), 6 deletions(-) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 2219a4307436..fc8452b607a0 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include #include @@ -42,6 +44,18 @@ LOG_DEFINE_CATEGORY(CameraSensor); * devices as the needs arise. */ +/** + * \fn CameraSensor::entityName() + * \brief Retrieve the name of the entity which identifies the supported sensor + * + * Camera sensor handlers have to report with this function the name of the + * media entity which represents the camera sensor they support. The here + * reported name is then matched against the name of the MediaEntity provided + * at createSensor() time to identify the correct CameraSensorFactory. + * + * \return The name of the media entity that identifies the sensor + */ + /** * \brief Construct a CameraSensor * \param[in] entity The media entity backing the camera sensor @@ -366,4 +380,124 @@ std::string CameraSensor::logPrefix() const return "'" + subdev_->entity()->name() + "'"; } +/** + * \class CameraSensorFactory + * \brief Factory of camera sensor handlers + * + * The class provides to camera sensor handlers the ability to register + * themselves to the factory to allow the creation of their instances by + * matching the name of the media entity which represents the sensor. + * + * Camera sensor handlers use the REGISTER_CAMERA_SENSOR() macro to + * add themselves to the camera sensor factory. Users of the factory + * creates camera sensor handler instances by using the static + * CameraSensorFactory::createInstance() method, which returns a pointer + * to the opportune CameraSensor sub-class if any, or a newly created instance + * of the generic CameraSensor class. + */ + +LOG_DEFINE_CATEGORY(CameraSensorFactory); + +/** + * \typedef CameraSensorFactory::factoriesMap + * \brief An std::map of sensor handler factories + * + * The registered sensor handler factories are associated in a map with the + * names of the media entity that represent the sensor + */ + +/** + * \brief Register a camera sensor handler factory + * \param[in] name The name of the media entity representing the sensor + * + * Register a new camera sensor factory which creates sensor handler instances + * that support camera sensors represented by the media entity with \a name. + */ +CameraSensorFactory::CameraSensorFactory(const char *name) +{ + CameraSensorFactory::registerSensorFactory(name, this); +} + +/** + * \brief Retrieve the list of registered camera sensor factories + * + * The static factories map is defined inside the function to ensures it gets + * initialized on first use, without any dependency on link order. + * + * \return The static list of registered camera sensor factories + */ +CameraSensorFactory::factoriesMap &CameraSensorFactory::factories() +{ + static factoriesMap factories; + return factories; +} + +/** + * \brief Register a camera sensor handler factory + * \param[in] name The name of the media entity that represents the sensor + * \param[in] factory The factory instance to register + * + * The newly registered sensor handler \a factory is associated with \a name, + * when a new sensor handler is instantiated with createSensor() the name of + * the media entity is matched against the \a name registered here to + * retrieve the correct factory. + */ +void CameraSensorFactory::registerSensorFactory(const char *name, + CameraSensorFactory *factory) +{ + factoriesMap &map = CameraSensorFactory::factories(); + map[name] = factory; +} + +/** + * \brief Create and return a CameraSensor + * \param[in] entity The media entity that represents the camera sensor + * + * Create a new instance of an handler for the sensor represented by \a + * entity using one of the registered factories. If no specific handler is + * available for the sensor, or creating the handler fails, a newly created + * instance of the generic CameraSensor base class is returned. + * + * Ownership of the created camera sensor instance is passed to the caller + * which is reponsible for deleting the instance. + * FIXME: is it worth using a smart pointer here ? + * + * \return A newly created camera sensor handler instance + */ +CameraSensor *CameraSensorFactory::createSensor(const MediaEntity *entity) +{ + /* + * The entity name contains both the sensor name and the I2C bus ID. + * + * Remove the i2c bus part and use the sensor name only as key to + * search for on the sensor handlers map. + */ + const char *entityName = entity->name().c_str(); + const char *delim = strchrnul(entityName, ' '); + std::string sensorName(entityName, delim); + + auto it = CameraSensorFactory::factories().find(sensorName); + if (it == CameraSensorFactory::factories().end()) { + LOG(CameraSensorFactory, Info) + << "Unsupported sensor '" << entity->name() + << "': using generic sensor handler"; + return new CameraSensor(entity); + } + + LOG(CameraSensorFactory, Info) << "Create handler for '" + << entity->name() << "' sensor"; + + CameraSensorFactory *factory = it->second; + return factory->create(entity); +} + +/** + * \def REGISTER_CAMERA_SENSOR(handler) + * \brief Register a camera sensor handler to the sensor factory + * \param[in] handler The name of the sensor handler + * + * Register a camera sensor handler to the sensor factory to make it available + * to the factory users. + */ + } /* namespace libcamera */ diff --git a/src/libcamera/include/camera_sensor.h b/src/libcamera/include/camera_sensor.h index 99cff98128dc..2f4a0cc8ad3f 100644 --- a/src/libcamera/include/camera_sensor.h +++ b/src/libcamera/include/camera_sensor.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_CAMERA_SENSOR_H__ #define __LIBCAMERA_CAMERA_SENSOR_H__ +#include #include #include @@ -25,7 +26,8 @@ struct V4L2SubdeviceFormat; class CameraSensor : protected Loggable { public: - explicit CameraSensor(const MediaEntity *entity); + static const char *entityName(); + ~CameraSensor(); CameraSensor(const CameraSensor &) = delete; @@ -49,6 +51,8 @@ public: const ControlList &properties() const { return properties_; } protected: + friend class CameraSensorFactory; + explicit CameraSensor(const MediaEntity *entity); std::string logPrefix() const; private: @@ -61,6 +65,39 @@ private: ControlList properties_; }; +class CameraSensorFactory +{ +public: + using factoriesMap = std::map; + + CameraSensorFactory(const char *name); + virtual ~CameraSensorFactory() {} + + static CameraSensor *createSensor(const MediaEntity *entity = nullptr); + +private: + static factoriesMap &factories(); + static void registerSensorFactory(const char *name, + CameraSensorFactory *factory); + virtual CameraSensor *create(const MediaEntity *entity) = 0; + +}; + +#define REGISTER_CAMERA_SENSOR(handler) \ +class handler##CameraSensorFactory final : public CameraSensorFactory \ +{ \ +public: \ + handler##CameraSensorFactory() \ + : CameraSensorFactory(handler##CameraSensor::entityName()) {}\ + \ +private: \ + CameraSensor *create(const MediaEntity *entity) \ + { \ + return new handler##CameraSensor(entity); \ + } \ +}; \ +static handler##CameraSensorFactory global_##handler##CameraSensorFactory + } /* namespace libcamera */ #endif /* __LIBCAMERA_CAMERA_SENSOR_H__ */ diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 387bb070b505..21934e72eba7 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -1322,7 +1322,7 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index) MediaLink *link = links[0]; MediaEntity *sensorEntity = link->source()->entity(); - sensor_ = new CameraSensor(sensorEntity); + sensor_ = CameraSensorFactory::createSensor(sensorEntity); ret = sensor_->init(); if (ret) return ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 68f16f03a81e..f2f054596257 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -901,7 +901,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) data->controlInfo_ = std::move(ctrls); - data->sensor_ = new CameraSensor(sensor); + data->sensor_ = CameraSensorFactory::createSensor(sensor); ret = data->sensor_->init(); if (ret) return ret; diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index fd4df0b03c26..cfeec1aac751 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -403,7 +403,7 @@ int VimcCameraData::init(MediaDevice *media) return ret; /* Create and open the camera sensor, debayer, scaler and video device. */ - sensor_ = new CameraSensor(media->getEntityByName("Sensor B")); + sensor_ = CameraSensorFactory::createSensor(media->getEntityByName("Sensor B")); ret = sensor_->init(); if (ret) return ret; diff --git a/test/camera-sensor.cpp b/test/camera-sensor.cpp index 27c190fe7ace..24b83a45b656 100644 --- a/test/camera-sensor.cpp +++ b/test/camera-sensor.cpp @@ -50,7 +50,7 @@ protected: return TestFail; } - sensor_ = new CameraSensor(entity); + sensor_ = CameraSensorFactory::createSensor(entity); if (sensor_->init() < 0) { cerr << "Unable to initialise camera sensor" << endl; return TestFail; diff --git a/test/v4l2_videodevice/v4l2_videodevice_test.cpp b/test/v4l2_videodevice/v4l2_videodevice_test.cpp index 577da4cb601c..102a8b1b6c1c 100644 --- a/test/v4l2_videodevice/v4l2_videodevice_test.cpp +++ b/test/v4l2_videodevice/v4l2_videodevice_test.cpp @@ -61,7 +61,7 @@ int V4L2VideoDeviceTest::init() return TestFail; if (driver_ == "vimc") { - sensor_ = new CameraSensor(media_->getEntityByName("Sensor A")); + sensor_ = CameraSensorFactory::createSensor(media_->getEntityByName("Sensor A")); if (sensor_->init()) return TestFail; From patchwork Thu Feb 6 18:52:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2797 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4150B60965 for ; Thu, 6 Feb 2020 19:50:20 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 03C28FF804 for ; Thu, 6 Feb 2020 18:50:19 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 6 Feb 2020 19:52:44 +0100 Message-Id: <20200206185247.202233-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200206185247.202233-1-jacopo@jmondi.org> References: <20200206185247.202233-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 4/7] libcamera: sensor: Add OV5670 camera sensor X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Feb 2020 18:50:20 -0000 Add OV5670CameraSensor class to handle Omnivision OV5670 image sensor and register it to the camera sensor factory. Signed-off-by: Jacopo Mondi --- src/libcamera/camera_sensor.cpp | 1 + src/libcamera/meson.build | 1 + src/libcamera/sensor/meson.build | 3 +++ src/libcamera/sensor/ov5670.cpp | 43 ++++++++++++++++++++++++++++++++ src/libcamera/sensor/ov5670.h | 24 ++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 src/libcamera/sensor/meson.build create mode 100644 src/libcamera/sensor/ov5670.cpp create mode 100644 src/libcamera/sensor/ov5670.h diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index fc8452b607a0..06d10295a80e 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -6,6 +6,7 @@ */ #include "camera_sensor.h" +#include "sensor/ov5670.h" #include #include diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index ecc5b5fe4023..7dd7358b174e 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -58,6 +58,7 @@ includes = [ subdir('pipeline') subdir('proxy') +subdir('sensor') libudev = dependency('libudev', required : false) diff --git a/src/libcamera/sensor/meson.build b/src/libcamera/sensor/meson.build new file mode 100644 index 000000000000..7af70370cf5c --- /dev/null +++ b/src/libcamera/sensor/meson.build @@ -0,0 +1,3 @@ +libcamera_sources += files([ + 'ov5670.cpp', +]) diff --git a/src/libcamera/sensor/ov5670.cpp b/src/libcamera/sensor/ov5670.cpp new file mode 100644 index 000000000000..de6011875a2d --- /dev/null +++ b/src/libcamera/sensor/ov5670.cpp @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ov5670.cpp - OV5670 camera sensor + */ + +#include "ov5670.h" +#include "camera_sensor.h" + +/** + * \file ov5670.h + * \brief Omnivision OV5670 image sensor handler + */ + +namespace libcamera { + +/** + * \class OV5670CameraSensor + * \brief Camera sensor handler for Omnivision OV5670 image sensor + */ + +/** + * \brief Retrieve the name of the sensor entity supported by the handler + * \return The supported sensor entity name + */ +const char *OV5670CameraSensor::entityName() +{ + return "ov5670"; +} + +/** + * \brief Construct the ov5670 sensor handler + * \param[in] entity The media entity representing the sensor + */ +OV5670CameraSensor::OV5670CameraSensor(const MediaEntity *entity) + : CameraSensor(entity) +{ +} + +REGISTER_CAMERA_SENSOR(OV5670); + +}; /* namespace libcamera */ diff --git a/src/libcamera/sensor/ov5670.h b/src/libcamera/sensor/ov5670.h new file mode 100644 index 000000000000..4acf02a8b06b --- /dev/null +++ b/src/libcamera/sensor/ov5670.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2019, Google Inc. + * + * ov5670.h - OV5670 camera sensor + */ +#ifndef __LIBCAMERA_SENSOR_OV5670_H__ +#define __LIBCAMERA_SENSOR_OV5670_H__ + +#include "camera_sensor.h" + +namespace libcamera { + +class OV5670CameraSensor final : public CameraSensor +{ +public: + static const char *entityName(); + + OV5670CameraSensor(const MediaEntity *entity); +}; + +}; /* namespace libcamera */ + +#endif /* __LIBCAMERA_SENSOR_OV5670_H__ */ From patchwork Thu Feb 6 18:52:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2798 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 96B6660966 for ; Thu, 6 Feb 2020 19:50:20 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 6A790FF802 for ; Thu, 6 Feb 2020 18:50:20 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 6 Feb 2020 19:52:45 +0100 Message-Id: <20200206185247.202233-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200206185247.202233-1-jacopo@jmondi.org> References: <20200206185247.202233-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 5/7] libcamera: camera_sensor: Break out properties initialization X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Feb 2020 18:50:20 -0000 Refactor the CameraSensor properties initialization to a dedicated virtual function that derived classes could subclass to register sensor-specific properties values. While at it, move documentation of the properties() method to match the declaration order in the class definition. Signed-off-by: Jacopo Mondi --- src/libcamera/camera_sensor.cpp | 114 +++++++++++++++----------- src/libcamera/include/camera_sensor.h | 5 +- 2 files changed, 71 insertions(+), 48 deletions(-) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 06d10295a80e..08b2d2acdbfc 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -64,7 +64,7 @@ LOG_DEFINE_CATEGORY(CameraSensor); * Once constructed the instance must be initialized with init(). */ CameraSensor::CameraSensor(const MediaEntity *entity) - : entity_(entity), properties_(properties::properties) + : properties_(properties::properties), entity_(entity) { subdev_ = new V4L2Subdevice(entity); } @@ -106,45 +106,6 @@ int CameraSensor::init() if (ret < 0) return ret; - /* Retrieve and store the camera sensor properties. */ - const ControlInfoMap &controls = subdev_->controls(); - int32_t propertyValue; - - /* Camera Location: default is front location. */ - const auto &locationControl = controls.find(V4L2_CID_CAMERA_SENSOR_LOCATION); - if (locationControl != controls.end()) { - int32_t v4l2Location = - locationControl->second.def().get(); - - switch (v4l2Location) { - default: - LOG(CameraSensor, Warning) - << "Unsupported camera location " - << v4l2Location << ", setting to Front"; - /* Fall-through */ - case V4L2_LOCATION_FRONT: - propertyValue = properties::CameraLocationFront; - break; - case V4L2_LOCATION_BACK: - propertyValue = properties::CameraLocationBack; - break; - case V4L2_LOCATION_EXTERNAL: - propertyValue = properties::CameraLocationExternal; - break; - } - } else { - propertyValue = properties::CameraLocationFront; - } - properties_.set(properties::Location, propertyValue); - - /* Camera Rotation: default is 0 degrees. */ - const auto &rotationControl = controls.find(V4L2_CID_CAMERA_SENSOR_ROTATION); - if (rotationControl != controls.end()) - propertyValue = rotationControl->second.def().get(); - else - propertyValue = 0; - properties_.set(properties::Rotation, propertyValue); - /* Enumerate and cache media bus codes and sizes. */ const ImageFormats formats = subdev_->formats(0); if (formats.isEmpty()) { @@ -175,6 +136,62 @@ int CameraSensor::init() std::sort(mbusCodes_.begin(), mbusCodes_.end()); std::sort(sizes_.begin(), sizes_.end()); + return initProperties(subdev_->controls()); +} + +/** + * \brief Initialize the camera sensor properties + * \param[in] controlMap The map of control information provided by the sensor + * + * This method initializes the camera sensor properties, by inspecting the + * control information reported by the sensor media entity in \a controlMap. + * For each supported standard V4L2 control reported by the sensor, a libcamera + * property is created and registered in the list of properties supported by the + * sensor. + * + * Derived classes are free to override this method to register sensor specific + * properties as they like, by inspecting custom controls or by adding + * properties with pre-defined values, and eventually call this base class + * implementation to register standard ones. + * + * \return 0 on success, a negative error code otherwise + */ +int CameraSensor::initProperties(const ControlInfoMap &controlMap) +{ + int32_t propertyValue; + + /* Camera Location: default is front location. */ + const auto &locationControl = controlMap.find(V4L2_CID_CAMERA_SENSOR_LOCATION); + if (locationControl != controlMap.end()) { + int32_t v4l2Location = + locationControl->second.def().get(); + switch (v4l2Location) { + case V4L2_LOCATION_EXTERNAL: + propertyValue = properties::CameraLocationExternal; + break; + case V4L2_LOCATION_FRONT: + propertyValue = properties::CameraLocationFront; + break; + case V4L2_LOCATION_BACK: + propertyValue = properties::CameraLocationBack; + break; + default: + LOG(CameraSensor, Error) + << "Unsupported camera location: " << v4l2Location; + return -EINVAL; + } + } else { + propertyValue = properties::CameraLocationFront; + } + properties_.set(properties::Location, propertyValue); + + /* Camera Rotation: default is 0 degrees. */ + propertyValue = 0; + const auto &rotationControl = controlMap.find(V4L2_CID_CAMERA_SENSOR_ROTATION); + if (rotationControl != controlMap.end()) + propertyValue = rotationControl->second.def().get(); + properties_.set(properties::Rotation, propertyValue); + return 0; } @@ -340,12 +357,6 @@ int CameraSensor::getControls(ControlList *ctrls) return subdev_->getControls(ctrls); } -/** - * \fn CameraSensor::properties() - * \brief Retrieve the camera sensor properties - * \return The list of camera sensor properties - */ - /** * \brief Write controls to the sensor * \param[in] ctrls The list of controls to write @@ -376,6 +387,17 @@ int CameraSensor::setControls(ControlList *ctrls) return subdev_->setControls(ctrls); } +/** + * \fn CameraSensor::properties() + * \brief Retrieve the camera sensor properties + * \return The list of camera sensor properties + */ + +/** + * \var CameraSensor::properties_ + * \brief The list of camera sensor properties + */ + std::string CameraSensor::logPrefix() const { return "'" + subdev_->entity()->name() + "'"; diff --git a/src/libcamera/include/camera_sensor.h b/src/libcamera/include/camera_sensor.h index 2f4a0cc8ad3f..87d3516aaae7 100644 --- a/src/libcamera/include/camera_sensor.h +++ b/src/libcamera/include/camera_sensor.h @@ -34,6 +34,7 @@ public: CameraSensor &operator=(const CameraSensor &) = delete; int init(); + virtual int initProperties(const ControlInfoMap &controlMap); const MediaEntity *entity() const { return entity_; } const std::vector &mbusCodes() const { return mbusCodes_; } @@ -51,6 +52,8 @@ public: const ControlList &properties() const { return properties_; } protected: + ControlList properties_; + friend class CameraSensorFactory; explicit CameraSensor(const MediaEntity *entity); std::string logPrefix() const; @@ -61,8 +64,6 @@ private: std::vector mbusCodes_; std::vector sizes_; - - ControlList properties_; }; class CameraSensorFactory From patchwork Thu Feb 6 18:52:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2799 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E132360969 for ; Thu, 6 Feb 2020 19:50:20 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id B4ECAFF802 for ; Thu, 6 Feb 2020 18:50:20 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 6 Feb 2020 19:52:46 +0100 Message-Id: <20200206185247.202233-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200206185247.202233-1-jacopo@jmondi.org> References: <20200206185247.202233-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 6/7] libcamera: sensor: ov5670: Register pixel array properties X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Feb 2020 18:50:22 -0000 Implement sensor specific pixel array properties initialization for the OV5670 sensor driver by overriding CameraSensor::initProperties() method. Signed-off-by: Jacopo Mondi --- src/libcamera/sensor/ov5670.cpp | 41 +++++++++++++++++++++++++++++++++ src/libcamera/sensor/ov5670.h | 3 +++ 2 files changed, 44 insertions(+) diff --git a/src/libcamera/sensor/ov5670.cpp b/src/libcamera/sensor/ov5670.cpp index de6011875a2d..a49fcebb2d9d 100644 --- a/src/libcamera/sensor/ov5670.cpp +++ b/src/libcamera/sensor/ov5670.cpp @@ -6,6 +6,12 @@ */ #include "ov5670.h" + +#include + +#include +#include + #include "camera_sensor.h" /** @@ -38,6 +44,41 @@ OV5670CameraSensor::OV5670CameraSensor(const MediaEntity *entity) { } +/** + * \brief Initialize Camera properties with ov5670 specific values + * \param[in] controlMap The map of control information provided by the sensor + * \return 0 on success, a negative error code otherwise + */ +int OV5670CameraSensor::initProperties(const ControlInfoMap &controlMap) +{ + /* Pixel Array Properties. */ + std::array pixelArraySize = { 2.9f, 1.18f }; + properties_.set(properties::PixelArraySize, + Span{ pixelArraySize }); + + std::array pixelArrayBounds = { 2592, 1944 }; + properties_.set(properties::PixelArrayBounds, + Span{ pixelArrayBounds }); + + std::array pixelArrays = { 2592, 1944 }; + properties_.set(properties::PixelArrays, + Span{ pixelArrays }); + + std::array activeAreaSize = { 16, 6, 2560, 1920 }; + properties_.set(properties::ActiveAreaSize, + Span{ activeAreaSize }); + + int32_t bayerFilter = properties::BayerFilterGRBG; + properties_.set(properties::BayerFilterArrangement, bayerFilter); + + std::array isoSensitivities = { 50, 800 }; + properties_.set(properties::ISOSensitivityRange, + Span{ isoSensitivities }); + + return CameraSensor::initProperties(controlMap); +} + REGISTER_CAMERA_SENSOR(OV5670); }; /* namespace libcamera */ + diff --git a/src/libcamera/sensor/ov5670.h b/src/libcamera/sensor/ov5670.h index 4acf02a8b06b..a66bdb6ae276 100644 --- a/src/libcamera/sensor/ov5670.h +++ b/src/libcamera/sensor/ov5670.h @@ -11,12 +11,15 @@ namespace libcamera { +class ControlInfoMap; + class OV5670CameraSensor final : public CameraSensor { public: static const char *entityName(); OV5670CameraSensor(const MediaEntity *entity); + int initProperties(const ControlInfoMap &controlMap); }; }; /* namespace libcamera */ From patchwork Thu Feb 6 18:52:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 2800 Return-Path: Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 428046096F for ; Thu, 6 Feb 2020 19:50:21 +0100 (CET) X-Originating-IP: 93.34.114.233 Received: from uno.lan (93-34-114-233.ip49.fastwebnet.it [93.34.114.233]) (Authenticated sender: jacopo@jmondi.org) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 0FC46FF802 for ; Thu, 6 Feb 2020 18:50:20 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Thu, 6 Feb 2020 19:52:47 +0100 Message-Id: <20200206185247.202233-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200206185247.202233-1-jacopo@jmondi.org> References: <20200206185247.202233-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 7/7] DNI: libcamera: sensor: ov5670: Add lens properties X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Feb 2020 18:50:22 -0000 Register lens properties in the ov5670 sensor handler. This patch is not intended for merge as we know lens properties do no belong to the sensor handler, but I am including it anyhow to trigger discussions on where they would be more appropriately defined. Signed-off-by: Jacopo Mondi --- src/libcamera/sensor/ov5670.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libcamera/sensor/ov5670.cpp b/src/libcamera/sensor/ov5670.cpp index a49fcebb2d9d..1396e9fe94dc 100644 --- a/src/libcamera/sensor/ov5670.cpp +++ b/src/libcamera/sensor/ov5670.cpp @@ -75,6 +75,21 @@ int OV5670CameraSensor::initProperties(const ControlInfoMap &controlMap) properties_.set(properties::ISOSensitivityRange, Span{ isoSensitivities }); + /* Lens Properties. */ + std::array lensApertures = { 0.0f }; + properties_.set(properties::LensApertures, + Span{ lensApertures }); + + std::array lensFocalLengths = { 3.69f }; + properties_.set(properties::LensFocalLength, + Span{ lensFocalLengths }); + + std::array lensHyperfocalMinDistance = { 0.0f }; + properties_.set(properties::LensHyperfocalDistance, + Span{ lensHyperfocalMinDistance }); + + properties_.set(properties::LensMinimumFocusDistance, 3.69f); + return CameraSensor::initProperties(controlMap); }