[libcamera-devel,RFCv2,2/2] libcamera: camera_sensor: Add method to get sensor info

Message ID 20200327113152.348570-3-jacopo@jmondi.org
State Accepted
Headers show
Series
  • Define CameraSensorInfo
Related show

Commit Message

Jacopo Mondi March 27, 2020, 11:31 a.m. UTC
Add method to retrieve the CameraSensorInfo to the CameraSensor class.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/libcamera/camera_sensor.cpp       | 127 ++++++++++++++++++++++++++
 src/libcamera/include/camera_sensor.h |   1 +
 2 files changed, 128 insertions(+)

Comments

Niklas Söderlund April 7, 2020, 11:29 p.m. UTC | #1
Hi Jacopo,

Thanks for your work.

On 2020-03-27 12:31:52 +0100, Jacopo Mondi wrote:
> Add method to retrieve the CameraSensorInfo to the CameraSensor class.
> 
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> ---
>  src/libcamera/camera_sensor.cpp       | 127 ++++++++++++++++++++++++++
>  src/libcamera/include/camera_sensor.h |   1 +
>  2 files changed, 128 insertions(+)
> 
> diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
> index df1d82d29f74..23204b05d062 100644
> --- a/src/libcamera/camera_sensor.cpp
> +++ b/src/libcamera/camera_sensor.cpp
> @@ -11,10 +11,13 @@
>  #include <float.h>
>  #include <iomanip>
>  #include <limits.h>
> +#include <map>
>  #include <math.h>
>  #include <memory>
>  #include <string.h>
>  
> +#include <linux/v4l2-mediabus.h>
> +
>  #include <libcamera/property_ids.h>
>  
>  #include "formats.h"
> @@ -30,6 +33,101 @@ namespace libcamera {
>  
>  LOG_DEFINE_CATEGORY(CameraSensor);
>  
> +namespace {
> +
> +const std::map<uint32_t, uint8_t> mbusToBppMap = {
> +	{ V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE, 16 },
> +	{ V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, 16 },
> +	{ V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, 16 },
> +	{ V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, 16 },
> +	{ V4L2_MBUS_FMT_BGR565_2X8_BE, 16 },
> +	{ V4L2_MBUS_FMT_BGR565_2X8_LE, 16 },
> +	{ V4L2_MBUS_FMT_RGB565_2X8_BE, 16 },
> +	{ V4L2_MBUS_FMT_RGB565_2X8_LE, 16 },
> +	{ V4L2_MBUS_FMT_RGB666_1X18, 18 },
> +	{ V4L2_MBUS_FMT_RGB888_1X24, 24 },
> +	{ V4L2_MBUS_FMT_RGB888_2X12_BE, 24 },
> +	{ V4L2_MBUS_FMT_RGB888_2X12_LE, 24 },
> +	{ V4L2_MBUS_FMT_ARGB8888_1X32, 32 },
> +	{ V4L2_MBUS_FMT_Y8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_UV8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_UYVY8_1_5X8, 40 },
> +	{ V4L2_MBUS_FMT_VYUY8_1_5X8, 40 },
> +	{ V4L2_MBUS_FMT_YUYV8_1_5X8, 40 },
> +	{ V4L2_MBUS_FMT_YVYU8_1_5X8, 40 },
> +	{ V4L2_MBUS_FMT_UYVY8_2X8, 16 },
> +	{ V4L2_MBUS_FMT_VYUY8_2X8, 16 },
> +	{ V4L2_MBUS_FMT_YUYV8_2X8, 16 },
> +	{ V4L2_MBUS_FMT_YVYU8_2X8, 16 },
> +	{ V4L2_MBUS_FMT_Y10_1X10, 10 },
> +	{ V4L2_MBUS_FMT_UYVY10_2X10, 20 },
> +	{ V4L2_MBUS_FMT_VYUY10_2X10, 20 },
> +	{ V4L2_MBUS_FMT_YUYV10_2X10, 20 },
> +	{ V4L2_MBUS_FMT_YVYU10_2X10, 20 },
> +	{ V4L2_MBUS_FMT_Y12_1X12, 12 },
> +	{ V4L2_MBUS_FMT_UYVY8_1X16, 16 },
> +	{ V4L2_MBUS_FMT_VYUY8_1X16, 16 },
> +	{ V4L2_MBUS_FMT_YUYV8_1X16, 16 },
> +	{ V4L2_MBUS_FMT_YVYU8_1X16, 16 },
> +	{ V4L2_MBUS_FMT_YDYUYDYV8_1X16, 16 },
> +	{ V4L2_MBUS_FMT_UYVY10_1X20, 20 },
> +	{ V4L2_MBUS_FMT_VYUY10_1X20, 20 },
> +	{ V4L2_MBUS_FMT_YUYV10_1X20, 20 },
> +	{ V4L2_MBUS_FMT_YVYU10_1X20, 20 },
> +	{ V4L2_MBUS_FMT_YUV10_1X30, 30 },
> +	{ V4L2_MBUS_FMT_AYUV8_1X32, 32 },
> +	{ V4L2_MBUS_FMT_UYVY12_2X12, 24 },
> +	{ V4L2_MBUS_FMT_VYUY12_2X12, 24 },
> +	{ V4L2_MBUS_FMT_YUYV12_2X12, 24 },
> +	{ V4L2_MBUS_FMT_YVYU12_2X12, 24 },
> +	{ V4L2_MBUS_FMT_UYVY12_1X24, 24 },
> +	{ V4L2_MBUS_FMT_VYUY12_1X24, 24 },
> +	{ V4L2_MBUS_FMT_YUYV12_1X24, 24 },
> +	{ V4L2_MBUS_FMT_YVYU12_1X24, 24 },
> +	{ V4L2_MBUS_FMT_SBGGR8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SGBRG8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SGRBG8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SRGGB8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SBGGR10_ALAW8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SGBRG10_ALAW8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SRGGB10_ALAW8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, 8 },
> +	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, 16 },
> +	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
> +	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, 16 },
> +	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, 16 },
> +	{ V4L2_MBUS_FMT_SBGGR10_1X10, 10 },
> +	{ V4L2_MBUS_FMT_SGBRG10_1X10, 10 },
> +	{ V4L2_MBUS_FMT_SGRBG10_1X10, 10 },
> +	{ V4L2_MBUS_FMT_SRGGB10_1X10, 10 },
> +	{ V4L2_MBUS_FMT_SBGGR12_1X12, 24 },
> +	{ V4L2_MBUS_FMT_SGBRG12_1X12, 24 },
> +	{ V4L2_MBUS_FMT_SGRBG12_1X12, 24 },
> +	{ V4L2_MBUS_FMT_SRGGB12_1X12, 24 },
> +	{ V4L2_MBUS_FMT_JPEG_1X8, 8 },
> +	{ V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8, 8 },
> +	{ V4L2_MBUS_FMT_AHSV8888_1X32, 32 },
> +};
> +
> +uint8_t mbusToBpp(uint32_t mbus_code)
> +{
> +	const auto it = mbusToBppMap.find(mbus_code);
> +	if (it == mbusToBppMap.end()) {
> +		LOG(CameraSensor, Error) << "Unsupported media bus format: "
> +					 << mbus_code;
> +		/* Return 8 to avoid divisions by 0. */
> +		return 8;
> +	}
> +
> +	return it->second;
> +}
> +
> +}; /* namespace */

For the same reason we have the pixel format lookup functions as static 
members of V4L2VideoDevice shall we try to keep this V4L2 specific stuff 
in the V4L2 related classes / files ?

Apart from this I like this patch.

> +
>  /**
>   * \struct CameraSensorInfo
>   * \brief Report the image sensor characteristics
> @@ -482,6 +580,35 @@ int CameraSensor::setControls(ControlList *ctrls)
>   * \return The list of camera sensor properties
>   */
>  
> +/**
> + * \brief Assemble and return the camera sensor info
> + *
> + * This method is meant to be overridden by CameraSensor specialized sub-classes
> + * to report more detailed information about the camera sensor configuration.
> + *
> + * The base class implementation provides a stub implementation to support
> + * camera sensor without an associated sub-class specialization.
> + *
> + * \return An instance of CameraSensorInfo describing the sensor configuration
> + */
> +CameraSensorInfo CameraSensor::sensorInfo() const
> +{
> +	CameraSensorInfo info{};
> +
> +	/* Get format on pad #0 by default for generic camera sensor. */
> +	V4L2SubdeviceFormat format{};
> +	int ret = subdev_->getFormat(0, &format);
> +	if (ret)
> +		return {};
> +
> +	info.name = "generic_sensor";
> +	info.bitsPerPixel = mbusToBpp(format.mbus_code);
> +	info.outputSize.width = format.size.width;
> +	info.outputSize.height = format.size.height;
> +
> +	return info;
> +}
> +
>  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 acc6022cf0e8..94374a4d01dd 100644
> --- a/src/libcamera/include/camera_sensor.h
> +++ b/src/libcamera/include/camera_sensor.h
> @@ -69,6 +69,7 @@ public:
>  	int setControls(ControlList *ctrls);
>  
>  	const ControlList &properties() const { return properties_; }
> +	virtual CameraSensorInfo sensorInfo() const;
>  
>  protected:
>  	std::string logPrefix() const;
> -- 
> 2.25.1
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
Jacopo Mondi April 8, 2020, 12:35 p.m. UTC | #2
Hi Niklas,

On Wed, Apr 08, 2020 at 01:29:41AM +0200, Niklas Söderlund wrote:
> Hi Jacopo,
>
> Thanks for your work.
>
> On 2020-03-27 12:31:52 +0100, Jacopo Mondi wrote:
> > Add method to retrieve the CameraSensorInfo to the CameraSensor class.
> >
> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> > ---
> >  src/libcamera/camera_sensor.cpp       | 127 ++++++++++++++++++++++++++
> >  src/libcamera/include/camera_sensor.h |   1 +
> >  2 files changed, 128 insertions(+)
> >
> > diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
> > index df1d82d29f74..23204b05d062 100644
> > --- a/src/libcamera/camera_sensor.cpp
> > +++ b/src/libcamera/camera_sensor.cpp
> > @@ -11,10 +11,13 @@
> >  #include <float.h>
> >  #include <iomanip>
> >  #include <limits.h>
> > +#include <map>
> >  #include <math.h>
> >  #include <memory>
> >  #include <string.h>
> >
> > +#include <linux/v4l2-mediabus.h>
> > +
> >  #include <libcamera/property_ids.h>
> >
> >  #include "formats.h"
> > @@ -30,6 +33,101 @@ namespace libcamera {
> >
> >  LOG_DEFINE_CATEGORY(CameraSensor);
> >
> > +namespace {
> > +
> > +const std::map<uint32_t, uint8_t> mbusToBppMap = {
> > +	{ V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE, 16 },
> > +	{ V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, 16 },
> > +	{ V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, 16 },
> > +	{ V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, 16 },
> > +	{ V4L2_MBUS_FMT_BGR565_2X8_BE, 16 },
> > +	{ V4L2_MBUS_FMT_BGR565_2X8_LE, 16 },
> > +	{ V4L2_MBUS_FMT_RGB565_2X8_BE, 16 },
> > +	{ V4L2_MBUS_FMT_RGB565_2X8_LE, 16 },
> > +	{ V4L2_MBUS_FMT_RGB666_1X18, 18 },
> > +	{ V4L2_MBUS_FMT_RGB888_1X24, 24 },
> > +	{ V4L2_MBUS_FMT_RGB888_2X12_BE, 24 },
> > +	{ V4L2_MBUS_FMT_RGB888_2X12_LE, 24 },
> > +	{ V4L2_MBUS_FMT_ARGB8888_1X32, 32 },
> > +	{ V4L2_MBUS_FMT_Y8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_UV8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_UYVY8_1_5X8, 40 },
> > +	{ V4L2_MBUS_FMT_VYUY8_1_5X8, 40 },
> > +	{ V4L2_MBUS_FMT_YUYV8_1_5X8, 40 },
> > +	{ V4L2_MBUS_FMT_YVYU8_1_5X8, 40 },
> > +	{ V4L2_MBUS_FMT_UYVY8_2X8, 16 },
> > +	{ V4L2_MBUS_FMT_VYUY8_2X8, 16 },
> > +	{ V4L2_MBUS_FMT_YUYV8_2X8, 16 },
> > +	{ V4L2_MBUS_FMT_YVYU8_2X8, 16 },
> > +	{ V4L2_MBUS_FMT_Y10_1X10, 10 },
> > +	{ V4L2_MBUS_FMT_UYVY10_2X10, 20 },
> > +	{ V4L2_MBUS_FMT_VYUY10_2X10, 20 },
> > +	{ V4L2_MBUS_FMT_YUYV10_2X10, 20 },
> > +	{ V4L2_MBUS_FMT_YVYU10_2X10, 20 },
> > +	{ V4L2_MBUS_FMT_Y12_1X12, 12 },
> > +	{ V4L2_MBUS_FMT_UYVY8_1X16, 16 },
> > +	{ V4L2_MBUS_FMT_VYUY8_1X16, 16 },
> > +	{ V4L2_MBUS_FMT_YUYV8_1X16, 16 },
> > +	{ V4L2_MBUS_FMT_YVYU8_1X16, 16 },
> > +	{ V4L2_MBUS_FMT_YDYUYDYV8_1X16, 16 },
> > +	{ V4L2_MBUS_FMT_UYVY10_1X20, 20 },
> > +	{ V4L2_MBUS_FMT_VYUY10_1X20, 20 },
> > +	{ V4L2_MBUS_FMT_YUYV10_1X20, 20 },
> > +	{ V4L2_MBUS_FMT_YVYU10_1X20, 20 },
> > +	{ V4L2_MBUS_FMT_YUV10_1X30, 30 },
> > +	{ V4L2_MBUS_FMT_AYUV8_1X32, 32 },
> > +	{ V4L2_MBUS_FMT_UYVY12_2X12, 24 },
> > +	{ V4L2_MBUS_FMT_VYUY12_2X12, 24 },
> > +	{ V4L2_MBUS_FMT_YUYV12_2X12, 24 },
> > +	{ V4L2_MBUS_FMT_YVYU12_2X12, 24 },
> > +	{ V4L2_MBUS_FMT_UYVY12_1X24, 24 },
> > +	{ V4L2_MBUS_FMT_VYUY12_1X24, 24 },
> > +	{ V4L2_MBUS_FMT_YUYV12_1X24, 24 },
> > +	{ V4L2_MBUS_FMT_YVYU12_1X24, 24 },
> > +	{ V4L2_MBUS_FMT_SBGGR8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SGBRG8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SGRBG8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SRGGB8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SBGGR10_ALAW8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SGBRG10_ALAW8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SRGGB10_ALAW8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, 16 },
> > +	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
> > +	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, 16 },
> > +	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, 16 },
> > +	{ V4L2_MBUS_FMT_SBGGR10_1X10, 10 },
> > +	{ V4L2_MBUS_FMT_SGBRG10_1X10, 10 },
> > +	{ V4L2_MBUS_FMT_SGRBG10_1X10, 10 },
> > +	{ V4L2_MBUS_FMT_SRGGB10_1X10, 10 },
> > +	{ V4L2_MBUS_FMT_SBGGR12_1X12, 24 },
> > +	{ V4L2_MBUS_FMT_SGBRG12_1X12, 24 },
> > +	{ V4L2_MBUS_FMT_SGRBG12_1X12, 24 },
> > +	{ V4L2_MBUS_FMT_SRGGB12_1X12, 24 },
> > +	{ V4L2_MBUS_FMT_JPEG_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8, 8 },
> > +	{ V4L2_MBUS_FMT_AHSV8888_1X32, 32 },
> > +};
> > +
> > +uint8_t mbusToBpp(uint32_t mbus_code)
> > +{
> > +	const auto it = mbusToBppMap.find(mbus_code);
> > +	if (it == mbusToBppMap.end()) {
> > +		LOG(CameraSensor, Error) << "Unsupported media bus format: "
> > +					 << mbus_code;
> > +		/* Return 8 to avoid divisions by 0. */
> > +		return 8;
> > +	}
> > +
> > +	return it->second;
> > +}
> > +
> > +}; /* namespace */
>
> For the same reason we have the pixel format lookup functions as static
> members of V4L2VideoDevice shall we try to keep this V4L2 specific stuff
> in the V4L2 related classes / files ?

Indeed, in my long due new version all of this has been moved to
V4L2Subdevice.

To be precise, I have moved the table to v4l2_subdevice.cpp and
augmented V4L2SubdeviceFormat class with a .bitsPerPixel() method, so
the table is not exposed outside and the bit depth is expressed as a
proeprty of the format.

>
> Apart from this I like this patch.
>

Thanks, will send v1 somewhen soon

> > +
> >  /**
> >   * \struct CameraSensorInfo
> >   * \brief Report the image sensor characteristics
> > @@ -482,6 +580,35 @@ int CameraSensor::setControls(ControlList *ctrls)
> >   * \return The list of camera sensor properties
> >   */
> >
> > +/**
> > + * \brief Assemble and return the camera sensor info
> > + *
> > + * This method is meant to be overridden by CameraSensor specialized sub-classes
> > + * to report more detailed information about the camera sensor configuration.
> > + *
> > + * The base class implementation provides a stub implementation to support
> > + * camera sensor without an associated sub-class specialization.
> > + *
> > + * \return An instance of CameraSensorInfo describing the sensor configuration
> > + */
> > +CameraSensorInfo CameraSensor::sensorInfo() const
> > +{
> > +	CameraSensorInfo info{};
> > +
> > +	/* Get format on pad #0 by default for generic camera sensor. */
> > +	V4L2SubdeviceFormat format{};
> > +	int ret = subdev_->getFormat(0, &format);
> > +	if (ret)
> > +		return {};
> > +
> > +	info.name = "generic_sensor";
> > +	info.bitsPerPixel = mbusToBpp(format.mbus_code);
> > +	info.outputSize.width = format.size.width;
> > +	info.outputSize.height = format.size.height;
> > +
> > +	return info;
> > +}
> > +
> >  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 acc6022cf0e8..94374a4d01dd 100644
> > --- a/src/libcamera/include/camera_sensor.h
> > +++ b/src/libcamera/include/camera_sensor.h
> > @@ -69,6 +69,7 @@ public:
> >  	int setControls(ControlList *ctrls);
> >
> >  	const ControlList &properties() const { return properties_; }
> > +	virtual CameraSensorInfo sensorInfo() const;
> >
> >  protected:
> >  	std::string logPrefix() const;
> > --
> > 2.25.1
> >
> > _______________________________________________
> > libcamera-devel mailing list
> > libcamera-devel@lists.libcamera.org
> > https://lists.libcamera.org/listinfo/libcamera-devel
>
> --
> Regards,
> Niklas Söderlund

Patch

diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index df1d82d29f74..23204b05d062 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -11,10 +11,13 @@ 
 #include <float.h>
 #include <iomanip>
 #include <limits.h>
+#include <map>
 #include <math.h>
 #include <memory>
 #include <string.h>
 
+#include <linux/v4l2-mediabus.h>
+
 #include <libcamera/property_ids.h>
 
 #include "formats.h"
@@ -30,6 +33,101 @@  namespace libcamera {
 
 LOG_DEFINE_CATEGORY(CameraSensor);
 
+namespace {
+
+const std::map<uint32_t, uint8_t> mbusToBppMap = {
+	{ V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE, 16 },
+	{ V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, 16 },
+	{ V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, 16 },
+	{ V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, 16 },
+	{ V4L2_MBUS_FMT_BGR565_2X8_BE, 16 },
+	{ V4L2_MBUS_FMT_BGR565_2X8_LE, 16 },
+	{ V4L2_MBUS_FMT_RGB565_2X8_BE, 16 },
+	{ V4L2_MBUS_FMT_RGB565_2X8_LE, 16 },
+	{ V4L2_MBUS_FMT_RGB666_1X18, 18 },
+	{ V4L2_MBUS_FMT_RGB888_1X24, 24 },
+	{ V4L2_MBUS_FMT_RGB888_2X12_BE, 24 },
+	{ V4L2_MBUS_FMT_RGB888_2X12_LE, 24 },
+	{ V4L2_MBUS_FMT_ARGB8888_1X32, 32 },
+	{ V4L2_MBUS_FMT_Y8_1X8, 8 },
+	{ V4L2_MBUS_FMT_UV8_1X8, 8 },
+	{ V4L2_MBUS_FMT_UYVY8_1_5X8, 40 },
+	{ V4L2_MBUS_FMT_VYUY8_1_5X8, 40 },
+	{ V4L2_MBUS_FMT_YUYV8_1_5X8, 40 },
+	{ V4L2_MBUS_FMT_YVYU8_1_5X8, 40 },
+	{ V4L2_MBUS_FMT_UYVY8_2X8, 16 },
+	{ V4L2_MBUS_FMT_VYUY8_2X8, 16 },
+	{ V4L2_MBUS_FMT_YUYV8_2X8, 16 },
+	{ V4L2_MBUS_FMT_YVYU8_2X8, 16 },
+	{ V4L2_MBUS_FMT_Y10_1X10, 10 },
+	{ V4L2_MBUS_FMT_UYVY10_2X10, 20 },
+	{ V4L2_MBUS_FMT_VYUY10_2X10, 20 },
+	{ V4L2_MBUS_FMT_YUYV10_2X10, 20 },
+	{ V4L2_MBUS_FMT_YVYU10_2X10, 20 },
+	{ V4L2_MBUS_FMT_Y12_1X12, 12 },
+	{ V4L2_MBUS_FMT_UYVY8_1X16, 16 },
+	{ V4L2_MBUS_FMT_VYUY8_1X16, 16 },
+	{ V4L2_MBUS_FMT_YUYV8_1X16, 16 },
+	{ V4L2_MBUS_FMT_YVYU8_1X16, 16 },
+	{ V4L2_MBUS_FMT_YDYUYDYV8_1X16, 16 },
+	{ V4L2_MBUS_FMT_UYVY10_1X20, 20 },
+	{ V4L2_MBUS_FMT_VYUY10_1X20, 20 },
+	{ V4L2_MBUS_FMT_YUYV10_1X20, 20 },
+	{ V4L2_MBUS_FMT_YVYU10_1X20, 20 },
+	{ V4L2_MBUS_FMT_YUV10_1X30, 30 },
+	{ V4L2_MBUS_FMT_AYUV8_1X32, 32 },
+	{ V4L2_MBUS_FMT_UYVY12_2X12, 24 },
+	{ V4L2_MBUS_FMT_VYUY12_2X12, 24 },
+	{ V4L2_MBUS_FMT_YUYV12_2X12, 24 },
+	{ V4L2_MBUS_FMT_YVYU12_2X12, 24 },
+	{ V4L2_MBUS_FMT_UYVY12_1X24, 24 },
+	{ V4L2_MBUS_FMT_VYUY12_1X24, 24 },
+	{ V4L2_MBUS_FMT_YUYV12_1X24, 24 },
+	{ V4L2_MBUS_FMT_YVYU12_1X24, 24 },
+	{ V4L2_MBUS_FMT_SBGGR8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SGBRG8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SGRBG8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SRGGB8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SBGGR10_ALAW8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SGBRG10_ALAW8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SGRBG10_ALAW8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SRGGB10_ALAW8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, 8 },
+	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, 16 },
+	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
+	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, 16 },
+	{ V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, 16 },
+	{ V4L2_MBUS_FMT_SBGGR10_1X10, 10 },
+	{ V4L2_MBUS_FMT_SGBRG10_1X10, 10 },
+	{ V4L2_MBUS_FMT_SGRBG10_1X10, 10 },
+	{ V4L2_MBUS_FMT_SRGGB10_1X10, 10 },
+	{ V4L2_MBUS_FMT_SBGGR12_1X12, 24 },
+	{ V4L2_MBUS_FMT_SGBRG12_1X12, 24 },
+	{ V4L2_MBUS_FMT_SGRBG12_1X12, 24 },
+	{ V4L2_MBUS_FMT_SRGGB12_1X12, 24 },
+	{ V4L2_MBUS_FMT_JPEG_1X8, 8 },
+	{ V4L2_MBUS_FMT_S5C_UYVY_JPEG_1X8, 8 },
+	{ V4L2_MBUS_FMT_AHSV8888_1X32, 32 },
+};
+
+uint8_t mbusToBpp(uint32_t mbus_code)
+{
+	const auto it = mbusToBppMap.find(mbus_code);
+	if (it == mbusToBppMap.end()) {
+		LOG(CameraSensor, Error) << "Unsupported media bus format: "
+					 << mbus_code;
+		/* Return 8 to avoid divisions by 0. */
+		return 8;
+	}
+
+	return it->second;
+}
+
+}; /* namespace */
+
 /**
  * \struct CameraSensorInfo
  * \brief Report the image sensor characteristics
@@ -482,6 +580,35 @@  int CameraSensor::setControls(ControlList *ctrls)
  * \return The list of camera sensor properties
  */
 
+/**
+ * \brief Assemble and return the camera sensor info
+ *
+ * This method is meant to be overridden by CameraSensor specialized sub-classes
+ * to report more detailed information about the camera sensor configuration.
+ *
+ * The base class implementation provides a stub implementation to support
+ * camera sensor without an associated sub-class specialization.
+ *
+ * \return An instance of CameraSensorInfo describing the sensor configuration
+ */
+CameraSensorInfo CameraSensor::sensorInfo() const
+{
+	CameraSensorInfo info{};
+
+	/* Get format on pad #0 by default for generic camera sensor. */
+	V4L2SubdeviceFormat format{};
+	int ret = subdev_->getFormat(0, &format);
+	if (ret)
+		return {};
+
+	info.name = "generic_sensor";
+	info.bitsPerPixel = mbusToBpp(format.mbus_code);
+	info.outputSize.width = format.size.width;
+	info.outputSize.height = format.size.height;
+
+	return info;
+}
+
 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 acc6022cf0e8..94374a4d01dd 100644
--- a/src/libcamera/include/camera_sensor.h
+++ b/src/libcamera/include/camera_sensor.h
@@ -69,6 +69,7 @@  public:
 	int setControls(ControlList *ctrls);
 
 	const ControlList &properties() const { return properties_; }
+	virtual CameraSensorInfo sensorInfo() const;
 
 protected:
 	std::string logPrefix() const;