diff options
author | Niklas Söderlund <niklas.soderlund@ragnatech.se> | 2020-05-26 15:53:23 +0200 |
---|---|---|
committer | Niklas Söderlund <niklas.soderlund@ragnatech.se> | 2020-06-26 13:32:29 +0200 |
commit | 6bd3d7259ffc6e28c5bd2d2681a1d8993099e883 (patch) | |
tree | 376cab2b610b9d2cc43c4f936e873a355142aa55 /src/libcamera/pipeline/ipu3/ipu3.cpp | |
parent | 2cd95560219b45abb0f928172f2bdfcef32f5dce (diff) |
libcamera: ipu3: cio2: Move the CIO2Device class to separate files
In preparation of refactoring the IPU3 pipeline handler breakout the
CIO2Device into its own .cpp and .h file, no functional change.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/libcamera/pipeline/ipu3/ipu3.cpp')
-rw-r--r-- | src/libcamera/pipeline/ipu3/ipu3.cpp | 249 |
1 files changed, 2 insertions, 247 deletions
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 4fbc9ae5..6e5eb560 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -28,6 +28,8 @@ #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" +#include "cio2.h" + namespace libcamera { LOG_DEFINE_CATEGORY(IPU3) @@ -104,45 +106,6 @@ public: /* \todo Add param video device for 3A tuning */ }; -class CIO2Device -{ -public: - static constexpr unsigned int CIO2_BUFFER_COUNT = 4; - - CIO2Device() - : output_(nullptr), csi2_(nullptr), sensor_(nullptr) - { - } - - ~CIO2Device() - { - delete output_; - delete csi2_; - delete sensor_; - } - - int init(const MediaDevice *media, unsigned int index); - int configure(const Size &size, - V4L2DeviceFormat *outputFormat); - - int allocateBuffers(); - void freeBuffers(); - - FrameBuffer *getBuffer(); - void putBuffer(FrameBuffer *buffer); - - int start(); - int stop(); - - V4L2VideoDevice *output_; - V4L2Subdevice *csi2_; - CameraSensor *sensor_; - -private: - std::vector<std::unique_ptr<FrameBuffer>> buffers_; - std::queue<FrameBuffer *> availableBuffers_; -}; - class IPU3Stream : public Stream { public: @@ -1408,214 +1371,6 @@ int ImgUDevice::enableLinks(bool enable) return linkSetup(name_, PAD_STAT, statName, 0, enable); } -/*------------------------------------------------------------------------------ - * CIO2 Device - */ - -/** - * \brief Initialize components of the CIO2 device with \a index - * \param[in] media The CIO2 media device - * \param[in] index The CIO2 device index - * - * Create and open the video device and subdevices in the CIO2 instance at \a - * index, if a supported image sensor is connected to the CSI-2 receiver of - * this CIO2 instance. Enable the media links connecting the CIO2 components - * to prepare for capture operations and cached the sensor maximum size. - * - * \return 0 on success or a negative error code otherwise - * \retval -ENODEV No supported image sensor is connected to this CIO2 instance - */ -int CIO2Device::init(const MediaDevice *media, unsigned int index) -{ - int ret; - - /* - * Verify that a sensor subdevice is connected to this CIO2 instance - * and enable the media link between the two. - */ - std::string csi2Name = "ipu3-csi2 " + std::to_string(index); - MediaEntity *csi2Entity = media->getEntityByName(csi2Name); - const std::vector<MediaPad *> &pads = csi2Entity->pads(); - if (pads.empty()) - return -ENODEV; - - /* IPU3 CSI-2 receivers have a single sink pad at index 0. */ - MediaPad *sink = pads[0]; - const std::vector<MediaLink *> &links = sink->links(); - if (links.empty()) - return -ENODEV; - - MediaLink *link = links[0]; - MediaEntity *sensorEntity = link->source()->entity(); - sensor_ = new CameraSensor(sensorEntity); - ret = sensor_->init(); - if (ret) - return ret; - - ret = link->setEnabled(true); - if (ret) - return ret; - - /* - * Make sure the sensor produces at least one format compatible with - * the CIO2 requirements. - * - * utils::set_overlap requires the ranges to be sorted, keep the - * cio2Codes vector sorted in ascending order. - */ - const std::vector<unsigned int> cio2Codes{ MEDIA_BUS_FMT_SBGGR10_1X10, - MEDIA_BUS_FMT_SGRBG10_1X10, - MEDIA_BUS_FMT_SGBRG10_1X10, - MEDIA_BUS_FMT_SRGGB10_1X10 }; - const std::vector<unsigned int> &sensorCodes = sensor_->mbusCodes(); - if (!utils::set_overlap(sensorCodes.begin(), sensorCodes.end(), - cio2Codes.begin(), cio2Codes.end())) { - LOG(IPU3, Error) - << "Sensor " << sensor_->entity()->name() - << " has not format compatible with the IPU3"; - return -EINVAL; - } - - /* - * \todo Define when to open and close video device nodes, as they - * might impact on power consumption. - */ - - csi2_ = new V4L2Subdevice(csi2Entity); - ret = csi2_->open(); - if (ret) - return ret; - - std::string cio2Name = "ipu3-cio2 " + std::to_string(index); - output_ = V4L2VideoDevice::fromEntityName(media, cio2Name); - ret = output_->open(); - if (ret) - return ret; - - return 0; -} - -/** - * \brief Configure the CIO2 unit - * \param[in] size The requested CIO2 output frame size - * \param[out] outputFormat The CIO2 unit output image format - * \return 0 on success or a negative error code otherwise - */ -int CIO2Device::configure(const Size &size, - V4L2DeviceFormat *outputFormat) -{ - V4L2SubdeviceFormat sensorFormat; - int ret; - - /* - * Apply the selected format to the sensor, the CSI-2 receiver and - * the CIO2 output device. - */ - sensorFormat = sensor_->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10, - MEDIA_BUS_FMT_SGBRG10_1X10, - MEDIA_BUS_FMT_SGRBG10_1X10, - MEDIA_BUS_FMT_SRGGB10_1X10 }, - size); - ret = sensor_->setFormat(&sensorFormat); - if (ret) - return ret; - - ret = csi2_->setFormat(0, &sensorFormat); - if (ret) - return ret; - - V4L2PixelFormat v4l2Format; - switch (sensorFormat.mbus_code) { - case MEDIA_BUS_FMT_SBGGR10_1X10: - v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10); - break; - case MEDIA_BUS_FMT_SGBRG10_1X10: - v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10); - break; - case MEDIA_BUS_FMT_SGRBG10_1X10: - v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10); - break; - case MEDIA_BUS_FMT_SRGGB10_1X10: - v4l2Format = V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10); - break; - default: - return -EINVAL; - } - - outputFormat->fourcc = v4l2Format; - outputFormat->size = sensorFormat.size; - outputFormat->planesCount = 1; - - ret = output_->setFormat(outputFormat); - if (ret) - return ret; - - LOG(IPU3, Debug) << "CIO2 output format " << outputFormat->toString(); - - return 0; -} - -/** - * \brief Allocate frame buffers for the CIO2 output - * - * Allocate frame buffers in the CIO2 video device to be used to capture frames - * from the CIO2 output. The buffers are stored in the CIO2Device::buffers_ - * vector. - * - * \return Number of buffers allocated or negative error code - */ -int CIO2Device::allocateBuffers() -{ - int ret = output_->allocateBuffers(CIO2_BUFFER_COUNT, &buffers_); - if (ret < 0) - return ret; - - for (std::unique_ptr<FrameBuffer> &buffer : buffers_) - availableBuffers_.push(buffer.get()); - - return ret; -} - -void CIO2Device::freeBuffers() -{ - /* The default std::queue constructor is explicit with gcc 5 and 6. */ - availableBuffers_ = std::queue<FrameBuffer *>{}; - - buffers_.clear(); - - if (output_->releaseBuffers()) - LOG(IPU3, Error) << "Failed to release CIO2 buffers"; -} - -FrameBuffer *CIO2Device::getBuffer() -{ - if (availableBuffers_.empty()) { - LOG(IPU3, Error) << "CIO2 buffer underrun"; - return nullptr; - } - - FrameBuffer *buffer = availableBuffers_.front(); - - availableBuffers_.pop(); - - return buffer; -} - -void CIO2Device::putBuffer(FrameBuffer *buffer) -{ - availableBuffers_.push(buffer); -} - -int CIO2Device::start() -{ - return output_->streamOn(); -} - -int CIO2Device::stop() -{ - return output_->streamOff(); -} - REGISTER_PIPELINE_HANDLER(PipelineHandlerIPU3); } /* namespace libcamera */ |