[libcamera-devel] [PATCH] libcamera: pipeline: simple: enable mplane devices using contiguous memory
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Fri Oct 9 02:05:41 CEST 2020
Hi Andrey,
On Fri, Oct 09, 2020 at 12:48:14AM +0300, Andrey Konovalov wrote:
> Hi,
>
> As suggested by Laurent during the discussion on #libcamera irc channel,
> I considered filtering out pixel formats not supported in libcamera in
> SimpleCameraData::init().
>
> The thing is that in SimpleCameraData::init() we only have the information
> from V4L2VideoDevice::formats() (enum_fmt ioctl) which doesn't include
> the number of memory planes for a given format.
> While in SimplePipelineHandler::configure() we have the data returned by
> s_fmt ioctl, so the number of memory planes for the format set is known,
> and I could easily use it in v1 of the patch.
>
> As libcamera currently supports only single memory plane (contiguous
> memory) formats, this is enough to filter out unsupported formats
> from what V4L2VideoDevice::formats() returns (easy to implement in
> SimpleCameraData::init()). And checking the number of memory planes
> for a given format isn't necessary.
>
> But after looking at SimpleCameraData::init(), it turned out that unsupported
> formats are filtered out by the already existing code:
>
> -----8<-----
> /*
> * Store the configuration in the formats_ map, mapping the
> * PixelFormat to the corresponding configuration. Any
> * previously stored value is overwritten, as the pipeline
> * handler currently doesn't care about how a particular
> * PixelFormat is achieved.
> */
> for (const auto &videoFormat : videoFormats) {
> PixelFormat pixelFormat = videoFormat.first.toPixelFormat();
> if (!pixelFormat)
> continue;
> -----8<-----
>
> V4L2PixelFormat::toPixelFormat() method checks if the V4L2 pixel format is present
> in the vpf2pf map, and if it is not there returns the invalid PixelFormat (with zero fourcc_).
>
> And indeed with the "if (video->caps().isMultiplanar())" check removed, and the NV61 entry
> commented out from the vpf2pf map (to simulate unsupported format) I've got:
>
> -----8<-----
> [2:29:09.524492795] [1396] DEBUG SimplePipeline simple.cpp:292 Adding configuration for 2592x1944 in pixel formats [ NV61, NV16]
> [2:29:09.524833004] [1396] WARN V4L2 v4l2_pixelformat.cpp:180 Unsupported V4L2 pixel format NV61
> [2:29:09.527873323] [1396] DEBUG Camera camera_manager.cpp:152 Pipeline handler "SimplePipelineHandler" matched
> Using camera /base/soc/cci at 1b0c000/i2c-bus at 0/camera_rear at 3c
> [2:29:09.529992233] [1395] DEBUG Camera camera.cpp:754 streams configuration: (0) 2592x1944-NV16
> [2:29:09.530364682] [1395] INFO Camera camera.cpp:811 configuring streams: (0) 2592x1944-NV16
> -----8<-----
>
> So the "unsupported" NV61 format was filtered out by the existing code, and NV16 was used for the capture instead.
>
> This leaves us with the two options for v2 of the patch:
> * v2a
> Just drop the "if (video->caps().isMultiplanar())" guard.
> Don't add any new checks. As unsupported formats are filtered out in SimpleCameraData::init(),
> and all the currently supported formats will just work with the simple pipeline handler.
> * v2b
> Only change the commit message in the v1 patch.
> To explain that the added check is no op in the current libcamera, but
> this "if (captureFormat.planesCount != 1)" will trigger and serve as the reminder to review
> the simple pipeline handler code when 1) libcamera gets support for non-contiguous formats,
> and 2) the hardware which uses such formats is enabled in the simple pipeline handler.
>
> What would be the best option?
I'd go for the second option, a reminder is useful, but I don't have a
very strong preference.
> On 07.10.2020 21:22, Kieran Bingham wrote:
> > On 07/10/2020 18:16, Andrey Konovalov wrote:
> >> On 07.10.2020 16:04, Kieran Bingham wrote:
> >>> On 07/10/2020 14:01, Niklas Söderlund wrote:
> >>>> On 2020-10-07 10:54:57 +0300, Andrey Konovalov wrote:
> >>>>> The current simple pipeline handler refuses to work with capture
> >>>>> devices
> >>>>> which have V4L2_CAP_VIDEO_CAPTURE_MPLANE flag set in the device
> >>>>> capabilities
> >>>>> field. This is too restrictive, as devices supporting the
> >>>>> multi-planar API
> >>>>> can be using contiguous memory for semi-planar and planar formats,
> >>>>> and this
> >>>>> would just work without any changes to libcamera.
> >>>>>
> >>>>> Drop the guard against MPLANE devices, and replace it with the check of
> >>>>> the number of planes in the format the simple pipeline handler is
> >>>>> going to
> >>>>> use for capture. This will let MPLANE devices which don't use
> >>>>> non-contiguous
> >>>>> memory for frame buffers to work with the simple pipeline handler.
> >>>>
> >>>> I wonder if the check should not be moved to SimpleCameraData::init()
> >>>> where the formats_ array is built. The array contains all supported
> >>>> formats of the camera and excluding mplaner formats from it will make it
> >>>> not show up at all for applications. Also validate() would Adjust if any
> >>>> format is asked for that is not in the formats_ array.
> >>
> >> Yes, this is a better option, thanks! I'll send the v2 shortly.
> >>
> >>> That sounds pretty good too. If we go that route, I think it will need a
> >>> highlighting '\todo: support mplane formats' so that it's clear/easy to
> >>> find the code which is mysteriously removing supported formats from a
> >>> device which is capable of using them ;-) (after we really support
> >>> Multiplanar).
> >>
> >> OK, will add the \todo.
> >> BTW, the "mplane format" in this context means the one using non-contiguous
> >> memory for frame buffers. E.g. 'NV16' I've tested is allowed, while 'NM16'
> >> (aka V4L2_PIX_FMT_NV16M) would be excluded.
> >
> > Yes indeed - Agreed ;-)
> >
> >>>>> Signed-off-by: Andrey Konovalov <andrey.konovalov at linaro.org>
> >>>>> ---
> >>>>> src/libcamera/pipeline/simple/simple.cpp | 12 ++++++------
> >>>>> 1 file changed, 6 insertions(+), 6 deletions(-)
> >>>>>
> >>>>> diff --git a/src/libcamera/pipeline/simple/simple.cpp
> >>>>> b/src/libcamera/pipeline/simple/simple.cpp
> >>>>> index 10223a9b..8dc23623 100644
> >>>>> --- a/src/libcamera/pipeline/simple/simple.cpp
> >>>>> +++ b/src/libcamera/pipeline/simple/simple.cpp
> >>>>> @@ -592,6 +592,12 @@ int SimplePipelineHandler::configure(Camera
> >>>>> *camera, CameraConfiguration *c)
> >>>>> if (ret)
> >>>>> return ret;
> >>>>> + if (captureFormat.planesCount != 1) {
> >>>>> + LOG(SimplePipeline, Error)
> >>>>> + << "Planar formats using non-contiguous memory not supported";
> >>>>> + return -EINVAL;
> >>>>> + }
> >>>>> +
> >>>>> if (captureFormat.fourcc != videoFormat ||
> >>>>> captureFormat.size != pipeConfig.captureSize) {
> >>>>> LOG(SimplePipeline, Error)
> >>>>> @@ -845,12 +851,6 @@ V4L2VideoDevice
> >>>>> *SimplePipelineHandler::video(const MediaEntity *entity)
> >>>>> if (video->open() < 0)
> >>>>> return nullptr;
> >>>>> - if (video->caps().isMultiplanar()) {
> >>>>> - LOG(SimplePipeline, Error)
> >>>>> - << "V4L2 multiplanar devices are not supported";
> >>>>> - return nullptr;
> >>>>> - }
> >>>>> -
> >>>>> video->bufferReady.connect(this, &SimplePipelineHandler::bufferReady);
> >>>>> auto element = videos_.emplace(entity, std::move(video));
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list