libcamera: pipeline: rkisp1: Convert to use MediaPipeline
Use the new MediaPipeline to manage and identify all sensors connected to complex pipelines that can connect to the CSI2 receiver before the ISP. This can include chained multiplexors that supply multiple cameras, so make use of the MediaDevice::locateEntities to search for all cameras and construct a pipeline for each. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Acked-by: Stefan Klug <stefan.klug@ideasonboard.com>
This commit is contained in:
parent
f1721c2f9f
commit
8751369c5b
1 changed files with 32 additions and 54 deletions
|
@ -42,6 +42,7 @@
|
||||||
#include "libcamera/internal/framebuffer.h"
|
#include "libcamera/internal/framebuffer.h"
|
||||||
#include "libcamera/internal/ipa_manager.h"
|
#include "libcamera/internal/ipa_manager.h"
|
||||||
#include "libcamera/internal/media_device.h"
|
#include "libcamera/internal/media_device.h"
|
||||||
|
#include "libcamera/internal/media_pipeline.h"
|
||||||
#include "libcamera/internal/pipeline_handler.h"
|
#include "libcamera/internal/pipeline_handler.h"
|
||||||
#include "libcamera/internal/v4l2_subdevice.h"
|
#include "libcamera/internal/v4l2_subdevice.h"
|
||||||
#include "libcamera/internal/v4l2_videodevice.h"
|
#include "libcamera/internal/v4l2_videodevice.h"
|
||||||
|
@ -116,6 +117,11 @@ public:
|
||||||
|
|
||||||
ControlInfoMap ipaControls_;
|
ControlInfoMap ipaControls_;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All entities in the pipeline, from the camera sensor to the RKISP1.
|
||||||
|
*/
|
||||||
|
MediaPipeline pipe_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paramsComputed(unsigned int frame, unsigned int bytesused);
|
void paramsComputed(unsigned int frame, unsigned int bytesused);
|
||||||
void setSensorControls(unsigned int frame,
|
void setSensorControls(unsigned int frame,
|
||||||
|
@ -180,8 +186,7 @@ private:
|
||||||
friend RkISP1CameraConfiguration;
|
friend RkISP1CameraConfiguration;
|
||||||
friend RkISP1Frames;
|
friend RkISP1Frames;
|
||||||
|
|
||||||
int initLinks(Camera *camera, const CameraSensor *sensor,
|
int initLinks(Camera *camera, const RkISP1CameraConfiguration &config);
|
||||||
const RkISP1CameraConfiguration &config);
|
|
||||||
int createCamera(MediaEntity *sensor);
|
int createCamera(MediaEntity *sensor);
|
||||||
void tryCompleteRequest(RkISP1FrameInfo *info);
|
void tryCompleteRequest(RkISP1FrameInfo *info);
|
||||||
void imageBufferReady(FrameBuffer *buffer);
|
void imageBufferReady(FrameBuffer *buffer);
|
||||||
|
@ -199,7 +204,6 @@ private:
|
||||||
std::unique_ptr<V4L2Subdevice> isp_;
|
std::unique_ptr<V4L2Subdevice> isp_;
|
||||||
std::unique_ptr<V4L2VideoDevice> param_;
|
std::unique_ptr<V4L2VideoDevice> param_;
|
||||||
std::unique_ptr<V4L2VideoDevice> stat_;
|
std::unique_ptr<V4L2VideoDevice> stat_;
|
||||||
std::unique_ptr<V4L2Subdevice> csi_;
|
|
||||||
|
|
||||||
bool hasSelfPath_;
|
bool hasSelfPath_;
|
||||||
bool isRaw_;
|
bool isRaw_;
|
||||||
|
@ -223,8 +227,6 @@ private:
|
||||||
std::queue<FrameBuffer *> availableStatBuffers_;
|
std::queue<FrameBuffer *> availableStatBuffers_;
|
||||||
|
|
||||||
Camera *activeCamera_;
|
Camera *activeCamera_;
|
||||||
|
|
||||||
const MediaPad *ispSink_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
RkISP1Frames::RkISP1Frames(PipelineHandler *pipe)
|
RkISP1Frames::RkISP1Frames(PipelineHandler *pipe)
|
||||||
|
@ -798,7 +800,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
|
||||||
CameraSensor *sensor = data->sensor_.get();
|
CameraSensor *sensor = data->sensor_.get();
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = initLinks(camera, sensor, *config);
|
ret = initLinks(camera, *config);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -821,12 +823,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
|
||||||
|
|
||||||
LOG(RkISP1, Debug) << "Sensor configured with " << format;
|
LOG(RkISP1, Debug) << "Sensor configured with " << format;
|
||||||
|
|
||||||
if (csi_) {
|
/* Propagate format through the internal media pipeline up to the ISP */
|
||||||
ret = csi_->setFormat(0, &format);
|
ret = data->pipe_.configure(sensor, &format);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
|
LOG(RkISP1, Debug) << "Configuring ISP with : " << format;
|
||||||
ret = isp_->setFormat(0, &format);
|
ret = isp_->setFormat(0, &format);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1201,7 +1203,6 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int PipelineHandlerRkISP1::initLinks(Camera *camera,
|
int PipelineHandlerRkISP1::initLinks(Camera *camera,
|
||||||
const CameraSensor *sensor,
|
|
||||||
const RkISP1CameraConfiguration &config)
|
const RkISP1CameraConfiguration &config)
|
||||||
{
|
{
|
||||||
RkISP1CameraData *data = cameraData(camera);
|
RkISP1CameraData *data = cameraData(camera);
|
||||||
|
@ -1212,31 +1213,16 @@ int PipelineHandlerRkISP1::initLinks(Camera *camera,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure the sensor links: enable the link corresponding to this
|
* Configure the sensor links: enable the links corresponding to this
|
||||||
* camera.
|
* pipeline all the way up to the ISP, through any connected CSI receiver.
|
||||||
*/
|
*/
|
||||||
for (MediaLink *link : ispSink_->links()) {
|
ret = data->pipe_.initLinks();
|
||||||
if (link->source()->entity() != sensor->entity())
|
if (ret) {
|
||||||
continue;
|
LOG(RkISP1, Error) << "Failed to set up pipe links";
|
||||||
|
|
||||||
LOG(RkISP1, Debug)
|
|
||||||
<< "Enabling link from sensor '"
|
|
||||||
<< link->source()->entity()->name()
|
|
||||||
<< "' to ISP";
|
|
||||||
|
|
||||||
ret = link->setEnabled(true);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (csi_) {
|
|
||||||
MediaLink *link = isp_->entity()->getPadByIndex(0)->links().at(0);
|
|
||||||
|
|
||||||
ret = link->setEnabled(true);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Configure the paths after the ISP */
|
||||||
for (const StreamConfiguration &cfg : config) {
|
for (const StreamConfiguration &cfg : config) {
|
||||||
if (cfg.stream() == &data->mainPathStream_)
|
if (cfg.stream() == &data->mainPathStream_)
|
||||||
ret = data->mainPath_->setEnabled(true);
|
ret = data->mainPath_->setEnabled(true);
|
||||||
|
@ -1312,6 +1298,13 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
|
||||||
std::make_unique<RkISP1CameraData>(this, &mainPath_,
|
std::make_unique<RkISP1CameraData>(this, &mainPath_,
|
||||||
hasSelfPath_ ? &selfPath_ : nullptr);
|
hasSelfPath_ ? &selfPath_ : nullptr);
|
||||||
|
|
||||||
|
/* Identify the pipeline path between the sensor and the rkisp1_isp */
|
||||||
|
ret = data->pipe_.init(sensor, "rkisp1_isp");
|
||||||
|
if (ret) {
|
||||||
|
LOG(RkISP1, Error) << "Failed to identify path from sensor to sink";
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
data->sensor_ = CameraSensorFactoryBase::create(sensor);
|
data->sensor_ = CameraSensorFactoryBase::create(sensor);
|
||||||
if (!data->sensor_)
|
if (!data->sensor_)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -1347,6 +1340,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
|
||||||
const std::string &id = data->sensor_->id();
|
const std::string &id = data->sensor_->id();
|
||||||
std::shared_ptr<Camera> camera =
|
std::shared_ptr<Camera> camera =
|
||||||
Camera::create(std::move(data), id, streams);
|
Camera::create(std::move(data), id, streams);
|
||||||
|
|
||||||
registerCamera(std::move(camera));
|
registerCamera(std::move(camera));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1354,8 +1348,6 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
|
||||||
|
|
||||||
bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
|
bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
|
||||||
{
|
{
|
||||||
const MediaPad *pad;
|
|
||||||
|
|
||||||
DeviceMatch dm("rkisp1");
|
DeviceMatch dm("rkisp1");
|
||||||
dm.add("rkisp1_isp");
|
dm.add("rkisp1_isp");
|
||||||
dm.add("rkisp1_resizer_mainpath");
|
dm.add("rkisp1_resizer_mainpath");
|
||||||
|
@ -1380,22 +1372,6 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
|
||||||
if (isp_->open() < 0)
|
if (isp_->open() < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Locate and open the optional CSI-2 receiver. */
|
|
||||||
ispSink_ = isp_->entity()->getPadByIndex(0);
|
|
||||||
if (!ispSink_ || ispSink_->links().empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pad = ispSink_->links().at(0)->source();
|
|
||||||
if (pad->entity()->function() == MEDIA_ENT_F_VID_IF_BRIDGE) {
|
|
||||||
csi_ = std::make_unique<V4L2Subdevice>(pad->entity());
|
|
||||||
if (csi_->open() < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ispSink_ = csi_->entity()->getPadByIndex(0);
|
|
||||||
if (!ispSink_)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Locate and open the stats and params video nodes. */
|
/* Locate and open the stats and params video nodes. */
|
||||||
stat_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_stats");
|
stat_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_stats");
|
||||||
if (stat_->open() < 0)
|
if (stat_->open() < 0)
|
||||||
|
@ -1446,8 +1422,10 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
|
||||||
* camera instance for each of them.
|
* camera instance for each of them.
|
||||||
*/
|
*/
|
||||||
bool registered = false;
|
bool registered = false;
|
||||||
for (MediaLink *link : ispSink_->links()) {
|
|
||||||
if (!createCamera(link->source()->entity()))
|
for (MediaEntity *entity : media_->locateEntities(MEDIA_ENT_F_CAM_SENSOR)) {
|
||||||
|
LOG(RkISP1, Debug) << "Identified " << entity->name();
|
||||||
|
if (!createCamera(entity))
|
||||||
registered = true;
|
registered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue