[libcamera-devel] [PATCH v3 09/11] libcamera: pipeline: Add a simple pipeline handler
Andrey Konovalov
andrey.konovalov at linaro.org
Wed Apr 8 19:52:00 CEST 2020
Hi Laurent,
On 04.04.2020 03:08, Laurent Pinchart wrote:
> Hi Andrey,
>
> On Fri, Apr 03, 2020 at 04:55:32PM +0300, Andrey Konovalov wrote:
>> On 20.03.2020 04:48, Laurent Pinchart wrote:
>>> From: Martijn Braam <martijn at brixit.nl>
>>>
>>> This new pipeline handler aims at supporting any simple device without
>>> requiring any device-specific code. Simple devices are currently defined
>>> as a graph made of one or multiple camera sensors and a single video
>>> node, with each sensor connected to the video node through a linear
>>> pipeline.
>>>
>>> The simple pipeline handler will automatically parse the media graph,
>>> enumerate sensors, build supported stream configurations, and configure
>>> the pipeline, without any device-specific knowledge. It doesn't support
>>> configuration of any processing in the pipeline at the moment, but may
>>> be extended to support simple processing such as format conversion or
>>> scaling in the future.
>>>
>>> The only device-specific information in the pipeline handler is the list
>>> of supported drivers, required for device matching. We may be able to
>>> remove this in the future by matching with the simple pipeline handler
>>> as a last resort option, after all other pipeline handlers have been
>>> tried.
>>>
>>> Signed-off-by: Martijn Braam <martijn at brixit.nl>
>>> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
>>> ---
>>> Changes since v2:
>>>
>>> - Log an error when setupFormats() fail
>>> - Propagate getFormat() and setFormat() errors to the caller of
>>> setupFormats()
>>> - Reorder variable declarations in validate()
>>> - Add \todo comment related to the selection of the default format
>>> - Use log Error instead of Info if pipeline isn't valid
>>> - Rebase on top of V4L2PixelFormat
>>>
>>> Changes since v1:
>>>
>>> - Rebase on top of buffer API rework
>>> - Expose stream formats
>>> - Rework camera data config
>>> ---
>>> src/libcamera/pipeline/meson.build | 1 +
>>> src/libcamera/pipeline/simple/meson.build | 3 +
>>> src/libcamera/pipeline/simple/simple.cpp | 710 ++++++++++++++++++++++
>>> 3 files changed, 714 insertions(+)
>>> create mode 100644 src/libcamera/pipeline/simple/meson.build
>>> create mode 100644 src/libcamera/pipeline/simple/simple.cpp
>>>
>>> diff --git a/src/libcamera/pipeline/meson.build b/src/libcamera/pipeline/meson.build
>>> index 0d466225a72e..606ba31a0319 100644
>>> --- a/src/libcamera/pipeline/meson.build
>>> +++ b/src/libcamera/pipeline/meson.build
>>> @@ -5,3 +5,4 @@ libcamera_sources += files([
>>>
>>> subdir('ipu3')
>>> subdir('rkisp1')
>>> +subdir('simple')
>>> diff --git a/src/libcamera/pipeline/simple/meson.build b/src/libcamera/pipeline/simple/meson.build
>>> new file mode 100644
>>> index 000000000000..4945a3e173cf
>>> --- /dev/null
>>> +++ b/src/libcamera/pipeline/simple/meson.build
>>> @@ -0,0 +1,3 @@
>>> +libcamera_sources += files([
>>> + 'simple.cpp',
>>> +])
>>> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
>>> new file mode 100644
>>> index 000000000000..545a99fe31ca
>>> --- /dev/null
>>> +++ b/src/libcamera/pipeline/simple/simple.cpp
<snip>
>>> + if (video_->caps().isMultiplanar()) {
>>> + LOG(SimplePipeline, Error)
>>> + << "V4L2 multiplanar devices are not supported";
>>> + return false;
>>
>> Same here. For the same reasons.
>
> Do you mean that your multiplanar device works with this series ?
qcom-camss uses multiplanar API for single-planar formats
(just like the current RPi's unicam driver iirc).
And on db410c with ov5640 sensor this works with this series
(if I am not trying to fix the enumeration of pipeline configurations).
Though (as it worked as is) I didn't check how exactly this happened.
Maybe I'll get better understanding of the details now that I am trying to figure out
why BA81 isn't currently working for me (see my earlier email today).
Thanks,
Andrey
>>> + }
>>> +
>>> + video_->bufferReady.connect(this, &SimplePipelineHandler::bufferReady);
>>> +
>>> + /*
>>> + * Create one camera data instance for each sensor and gather all
>>> + * entities in all pipelines.
>>> + */
>>> + std::vector<std::unique_ptr<SimpleCameraData>> pipelines;
>>> + std::set<MediaEntity *> entities;
>>> +
>>> + pipelines.reserve(sensors.size());
>>> +
>>> + for (MediaEntity *sensor : sensors) {
>>> + std::unique_ptr<SimpleCameraData> data =
>>> + std::make_unique<SimpleCameraData>(this, sensor,
>>> + videos[0]);
>>> + if (!data->isValid()) {
>>> + LOG(SimplePipeline, Error)
>>> + << "No valid pipeline for sensor '"
>>> + << sensor->name() << "', skipping";
>>> + continue;
>>> + }
>>> +
>>> + for (SimpleCameraData::Entity &entity : data->entities_)
>>> + entities.insert(entity.entity);
>>> +
>>> + pipelines.push_back(std::move(data));
>>> + }
>>> +
>>> + if (entities.empty())
>>> + return false;
>>> +
>>> + /* Create and open V4L2Subdev instances for all the entities. */
>>> + for (MediaEntity *entity : entities) {
>>> + auto elem = subdevs_.emplace(std::piecewise_construct,
>>> + std::forward_as_tuple(entity),
>>> + std::forward_as_tuple(entity));
>>> + V4L2Subdevice *subdev = &elem.first->second;
>>> + int ret = subdev->open();
>>> + if (ret < 0) {
>>> + LOG(SimplePipeline, Error)
>>> + << "Failed to open " << subdev->deviceNode()
>>> + << ": " << strerror(-ret);
>>> + return false;
>>> + }
>>> + }
>>> +
>>> + /* Initialize each pipeline and register a corresponding camera. */
>>> + for (std::unique_ptr<SimpleCameraData> &data : pipelines) {
>>> + int ret = data->init();
>>> + if (ret < 0)
>>> + continue;
>>> +
>>> + std::shared_ptr<Camera> camera =
>>> + Camera::create(this, data->sensor_->entity()->name(),
>>> + data->streams());
>>> + registerCamera(std::move(camera), std::move(data));
>>> + }
>>> +
>>> + return true;
>>> +}
>>> +
>>> +V4L2Subdevice *SimplePipelineHandler::subdev(const MediaEntity *entity)
>>> +{
>>> + auto iter = subdevs_.find(entity);
>>> + if (iter == subdevs_.end())
>>> + return nullptr;
>>> +
>>> + return &iter->second;
>>> +}
>>> +
>>> +/* -----------------------------------------------------------------------------
>>> + * Buffer Handling
>>> + */
>>> +
>>> +void SimplePipelineHandler::bufferReady(FrameBuffer *buffer)
>>> +{
>>> + ASSERT(activeCamera_);
>>> + Request *request = buffer->request();
>>> + completeBuffer(activeCamera_, request, buffer);
>>> + completeRequest(activeCamera_, request);
>>> +}
>>> +
>>> +REGISTER_PIPELINE_HANDLER(SimplePipelineHandler);
>>> +
>>> +} /* namespace libcamera */
>
More information about the libcamera-devel
mailing list