Message ID | 20241108105117.137121-7-jacopo.mondi@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Quoting Jacopo Mondi (2024-11-08 10:51:16) > From: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > > Some sensors support producing and transmitting embedded data over a > stream separate from the image stream. Add support for this feature in > the CameraSensor interface, and implement it for the CameraSensorRaw > class. The CameraSensorLegacy uses the default stub implementation, as > the corresponding kernel drivers don't support embedded data. > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Nothing I can particularly comment on in this one so just a : Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > --- > include/libcamera/internal/camera_sensor.h | 5 ++ > src/libcamera/sensor/camera_sensor.cpp | 67 ++++++++++++++++++++ > src/libcamera/sensor/camera_sensor_raw.cpp | 72 ++++++++++++++++++++++ > 3 files changed, 144 insertions(+) > > diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h > index 8aafd82e6547..61bf1d7ca6de 100644 > --- a/include/libcamera/internal/camera_sensor.h > +++ b/include/libcamera/internal/camera_sensor.h > @@ -61,6 +61,11 @@ public: > Transform transform = Transform::Identity, > V4L2SubdeviceFormat *sensorFormat = nullptr) = 0; > > + virtual V4L2Subdevice::Stream imageStream() const; > + virtual std::optional<V4L2Subdevice::Stream> embeddedDataStream() const; > + virtual V4L2SubdeviceFormat embeddedDataFormat() const; > + virtual int setEmbeddedDataEnabled(bool enable); > + > virtual const ControlList &properties() const = 0; > virtual int sensorInfo(IPACameraSensorInfo *info) const = 0; > virtual Transform computeTransform(Orientation *orientation) const = 0; > diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp > index 54cf98b203fd..1217365b2a55 100644 > --- a/src/libcamera/sensor/camera_sensor.cpp > +++ b/src/libcamera/sensor/camera_sensor.cpp > @@ -196,6 +196,73 @@ CameraSensor::~CameraSensor() = default; > * error code otherwise > */ > > +/** > + * \brief Retrieve the image source stream > + * > + * Sensors that produce multiple streams do not guarantee that the image stream > + * is always assigned number 0. This function allows callers to retrieve the > + * image stream on the sensor's source pad, in order to configure the receiving > + * side accordingly. > + * > + * \return The image source stream > + */ > +V4L2Subdevice::Stream CameraSensor::imageStream() const > +{ > + return { 0, 0 }; > +} > + > +/** > + * \brief Retrieve the embedded data source stream > + * > + * Some sensors produce embedded data in a stream separate from the image > + * stream. This function indicates if the sensor supports this feature by > + * returning the embedded data stream on the sensor's source pad if available, > + * or an std::optional<> without a value otheriwse. > + * > + * \return The embedded data source stream > + */ > +std::optional<V4L2Subdevice::Stream> CameraSensor::embeddedDataStream() const > +{ > + return {}; > +} > + > +/** > + * \brief Retrieve the format on the embedded data stream > + * > + * When an embedded data stream is available, this function returns the > + * corresponding format on the sensor's source pad. The format may vary with > + * the image stream format, and should therefore be retrieved after configuring > + * the image stream. > + * > + * If the sensor doesn't support embedded data, this function returns a > + * default-constructed format. > + * > + * \return The format on the embedded data stream > + */ > +V4L2SubdeviceFormat CameraSensor::embeddedDataFormat() const > +{ > + return {}; > +} > + > +/** > + * \brief Enable or disable the embedded data stream > + * \param[in] enable True to enable the embedded data stream, false to disable it > + * > + * For sensors that support embedded data, this function enables or disables > + * generation of embedded data. Some of such sensors always produce embedded > + * data, in which case this function return -EISCONN if the caller attempts to > + * disable embedded data. > + * > + * If the sensor doesn't support embedded data, this function returns 0 when \a > + * enable is false, and -ENOSTR otherwise. > + * > + * \return 0 on success, or a negative error code otherwise > + */ > +int CameraSensor::setEmbeddedDataEnabled(bool enable) > +{ > + return enable ? -ENOSTR : 0; > +} > + > /** > * \fn CameraSensor::properties() > * \brief Retrieve the camera sensor properties > diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp > index 4c653121d547..9380ec7129f6 100644 > --- a/src/libcamera/sensor/camera_sensor_raw.cpp > +++ b/src/libcamera/sensor/camera_sensor_raw.cpp > @@ -84,6 +84,11 @@ public: > Transform transform = Transform::Identity, > V4L2SubdeviceFormat *sensorFormat = nullptr) override; > > + V4L2Subdevice::Stream imageStream() const override; > + std::optional<V4L2Subdevice::Stream> embeddedDataStream() const override; > + V4L2SubdeviceFormat embeddedDataFormat() const override; > + int setEmbeddedDataEnabled(bool enable) override; > + > const ControlList &properties() const override { return properties_; } > int sensorInfo(IPACameraSensorInfo *info) const override; > Transform computeTransform(Orientation *orientation) const override; > @@ -878,6 +883,73 @@ int CameraSensorRaw::applyConfiguration(const SensorConfiguration &config, > return 0; > } > > +V4L2Subdevice::Stream CameraSensorRaw::imageStream() const > +{ > + return streams_.image.source; > +} > + > +std::optional<V4L2Subdevice::Stream> CameraSensorRaw::embeddedDataStream() const > +{ > + if (!streams_.edata) > + return {}; > + > + return { streams_.edata->source }; > +} > + > +V4L2SubdeviceFormat CameraSensorRaw::embeddedDataFormat() const > +{ > + if (!streams_.edata) > + return {}; > + > + V4L2SubdeviceFormat format; > + int ret = subdev_->getFormat(streams_.edata->source, &format); > + if (ret) > + return {}; > + > + return format; > +} > + > +int CameraSensorRaw::setEmbeddedDataEnabled(bool enable) > +{ > + if (!streams_.edata) > + return enable ? -ENOSTR : 0; > + > + V4L2Subdevice::Routing routing{ 2 }; > + > + routing[0].sink = streams_.image.sink; > + routing[0].source = streams_.image.source; > + routing[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE; > + > + routing[1].sink = streams_.edata->sink; > + routing[1].source = streams_.edata->source; > + routing[1].flags = enable ? V4L2_SUBDEV_ROUTE_FL_ACTIVE : 0; > + > + int ret = subdev_->setRouting(&routing); > + if (ret) > + return ret; > + > + /* > + * Check if the embedded data stream has been enabled or disabled > + * correctly. Assume at least one route will match the embedded data > + * source stream, as there would be something seriously wrong > + * otherwise. > + */ > + bool enabled = false; > + > + for (const V4L2Subdevice::Route &route : routing) { > + if (route.source != streams_.edata->source) > + continue; > + > + enabled = route.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE; > + break; > + } > + > + if (enabled != enable) > + return enabled ? -EISCONN : -ENOSTR; > + > + return 0; > +} > + > int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const > { > info->model = model(); > -- > 2.47.0 >
diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h index 8aafd82e6547..61bf1d7ca6de 100644 --- a/include/libcamera/internal/camera_sensor.h +++ b/include/libcamera/internal/camera_sensor.h @@ -61,6 +61,11 @@ public: Transform transform = Transform::Identity, V4L2SubdeviceFormat *sensorFormat = nullptr) = 0; + virtual V4L2Subdevice::Stream imageStream() const; + virtual std::optional<V4L2Subdevice::Stream> embeddedDataStream() const; + virtual V4L2SubdeviceFormat embeddedDataFormat() const; + virtual int setEmbeddedDataEnabled(bool enable); + virtual const ControlList &properties() const = 0; virtual int sensorInfo(IPACameraSensorInfo *info) const = 0; virtual Transform computeTransform(Orientation *orientation) const = 0; diff --git a/src/libcamera/sensor/camera_sensor.cpp b/src/libcamera/sensor/camera_sensor.cpp index 54cf98b203fd..1217365b2a55 100644 --- a/src/libcamera/sensor/camera_sensor.cpp +++ b/src/libcamera/sensor/camera_sensor.cpp @@ -196,6 +196,73 @@ CameraSensor::~CameraSensor() = default; * error code otherwise */ +/** + * \brief Retrieve the image source stream + * + * Sensors that produce multiple streams do not guarantee that the image stream + * is always assigned number 0. This function allows callers to retrieve the + * image stream on the sensor's source pad, in order to configure the receiving + * side accordingly. + * + * \return The image source stream + */ +V4L2Subdevice::Stream CameraSensor::imageStream() const +{ + return { 0, 0 }; +} + +/** + * \brief Retrieve the embedded data source stream + * + * Some sensors produce embedded data in a stream separate from the image + * stream. This function indicates if the sensor supports this feature by + * returning the embedded data stream on the sensor's source pad if available, + * or an std::optional<> without a value otheriwse. + * + * \return The embedded data source stream + */ +std::optional<V4L2Subdevice::Stream> CameraSensor::embeddedDataStream() const +{ + return {}; +} + +/** + * \brief Retrieve the format on the embedded data stream + * + * When an embedded data stream is available, this function returns the + * corresponding format on the sensor's source pad. The format may vary with + * the image stream format, and should therefore be retrieved after configuring + * the image stream. + * + * If the sensor doesn't support embedded data, this function returns a + * default-constructed format. + * + * \return The format on the embedded data stream + */ +V4L2SubdeviceFormat CameraSensor::embeddedDataFormat() const +{ + return {}; +} + +/** + * \brief Enable or disable the embedded data stream + * \param[in] enable True to enable the embedded data stream, false to disable it + * + * For sensors that support embedded data, this function enables or disables + * generation of embedded data. Some of such sensors always produce embedded + * data, in which case this function return -EISCONN if the caller attempts to + * disable embedded data. + * + * If the sensor doesn't support embedded data, this function returns 0 when \a + * enable is false, and -ENOSTR otherwise. + * + * \return 0 on success, or a negative error code otherwise + */ +int CameraSensor::setEmbeddedDataEnabled(bool enable) +{ + return enable ? -ENOSTR : 0; +} + /** * \fn CameraSensor::properties() * \brief Retrieve the camera sensor properties diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp index 4c653121d547..9380ec7129f6 100644 --- a/src/libcamera/sensor/camera_sensor_raw.cpp +++ b/src/libcamera/sensor/camera_sensor_raw.cpp @@ -84,6 +84,11 @@ public: Transform transform = Transform::Identity, V4L2SubdeviceFormat *sensorFormat = nullptr) override; + V4L2Subdevice::Stream imageStream() const override; + std::optional<V4L2Subdevice::Stream> embeddedDataStream() const override; + V4L2SubdeviceFormat embeddedDataFormat() const override; + int setEmbeddedDataEnabled(bool enable) override; + const ControlList &properties() const override { return properties_; } int sensorInfo(IPACameraSensorInfo *info) const override; Transform computeTransform(Orientation *orientation) const override; @@ -878,6 +883,73 @@ int CameraSensorRaw::applyConfiguration(const SensorConfiguration &config, return 0; } +V4L2Subdevice::Stream CameraSensorRaw::imageStream() const +{ + return streams_.image.source; +} + +std::optional<V4L2Subdevice::Stream> CameraSensorRaw::embeddedDataStream() const +{ + if (!streams_.edata) + return {}; + + return { streams_.edata->source }; +} + +V4L2SubdeviceFormat CameraSensorRaw::embeddedDataFormat() const +{ + if (!streams_.edata) + return {}; + + V4L2SubdeviceFormat format; + int ret = subdev_->getFormat(streams_.edata->source, &format); + if (ret) + return {}; + + return format; +} + +int CameraSensorRaw::setEmbeddedDataEnabled(bool enable) +{ + if (!streams_.edata) + return enable ? -ENOSTR : 0; + + V4L2Subdevice::Routing routing{ 2 }; + + routing[0].sink = streams_.image.sink; + routing[0].source = streams_.image.source; + routing[0].flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE; + + routing[1].sink = streams_.edata->sink; + routing[1].source = streams_.edata->source; + routing[1].flags = enable ? V4L2_SUBDEV_ROUTE_FL_ACTIVE : 0; + + int ret = subdev_->setRouting(&routing); + if (ret) + return ret; + + /* + * Check if the embedded data stream has been enabled or disabled + * correctly. Assume at least one route will match the embedded data + * source stream, as there would be something seriously wrong + * otherwise. + */ + bool enabled = false; + + for (const V4L2Subdevice::Route &route : routing) { + if (route.source != streams_.edata->source) + continue; + + enabled = route.flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE; + break; + } + + if (enabled != enable) + return enabled ? -EISCONN : -ENOSTR; + + return 0; +} + int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const { info->model = model();