Commit Graph

1813 Commits

Author SHA1 Message Date
Jacopo Mondi 2a938efc8c libcamera: ipu3: Split controls init/update
In order to prepare for updating the Camera controls limits when a new
camera configuration is applied, split the initControls() function in
two:
- updateControls() to actually compute controls values
- initControls() to initialize the sensor configuration and call
  updateControls

Update the functions documentation accordingly.

No functional changes intended.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-10-15 09:32:30 +02:00
Jacopo Mondi 2dab504a9b libcamera: ipu3: Rationalize constant expressions names
Following the previous patch that moved all the ImgU-related contants in
the ImgUDevice class namespace and that aligned their naming scheme to
the 'kNameOfConstant' scheme, apply the same changes to the other
components of the IPU3 pipeline handler.

Cosmetic change, no functional changes intended.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15 09:32:28 +02:00
Jacopo Mondi 3bd3b95a09 libcamera: ipu3: Centralize ImgU sizes definition
The definition of several constants that describe the ImgU
characteristics are spread between two files: ipu3.cpp and imgu.cpp.

As the ipu3.cpp uses definitions from the imgu.cpp file, in order to
remove the usage of magic numbers, it is required to move the
definitions to a common header file where they are accessible to the
other .cpp modules.

Move all the definitions of the ImgU sizes and alignments to the
ImgUDevice class as static constexpr and update their users accordingly.

Cosmetic changes, no functional changes intended.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-10-15 09:30:55 +02:00
Jacopo Mondi 1e9826ff71 libcamera: ipu3: Use the optimal sensor size
As reported by commit 7208e70211 ("libcamera: ipu3: Always use sensor
full frame size") the current implementation of the IPU3 pipeline
handler always uses the sensor resolution as the ImgU input frame size in
order to work around an issue with the ImgU configuration procedure.

Now that the frame selection policy has been modified in the CIO2Device
class implementation to comply with the requirements of the ImgU
configuration script we can remove the workaround and select the most
opportune sensor size to feed the ImgU with.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-10-15 09:25:04 +02:00
Laurent Pinchart 2f75a7e5b8 libcamera: v4l2_subdevice: Set format field to V4L2_FIELD_NONE
libcamera doesn't support interlaced formats, set the field to
V4L2_FIELD_NONE explicitly instead of relying on drivers to interpret
V4L2_FIELD_ANY the way we want it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15 05:05:46 +03:00
Laurent Pinchart 211d6f5ca6 libcamera: media_device: Print link information when setup fails
When setting up a link fails, the error message doesn't specify which
link is being acted on. This makes debugging more difficult than it
should be. Improve the message by printing the link information.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15 05:05:45 +03:00
Laurent Pinchart 90a1720926 libcamera: base: backtrace: Fallback to libunwind for symbolic names
libunwind has an API to provide symbolic names for functions. It's less
optimal than using backtrace_symbols() or libdw, as it doesn't allow
deferring the symbolic names lookup, but it can be usefull as a fallback
if no other option is available.

A sample backtrace when falling back to libunwind looks like

libcamera::VimcCameraData::init()+0xbd
libcamera::PipelineHandlerVimc::match(libcamera::DeviceEnumerator*)+0x3e0
libcamera::CameraManager::Private::createPipelineHandlers()+0x1a7
libcamera::CameraManager::Private::init()+0x98
libcamera::CameraManager::Private::run()+0x9f
libcamera::Thread::startThread()+0xee
decltype(*(std::__1::forward<libcamera::Thread*>(fp0)).*fp()) std::__1::__invoke<void (libcamera::Thread::*)(), libcamera::Thread*, void>(void (libcamera::Thread::*&&)(), libcamera::Thread*&&)+0x77
void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*, 2ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*>&, std::__1::__tuple_indices<2ul>)+0x3e
void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*> >(void*)+0x62
start_thread+0xde
???

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15 05:05:28 +03:00
Laurent Pinchart a7c7f58d59 libcamera: base: backtrace: Use libunwind when available
libunwind is an alternative to glibc's backtrace() to extract a
backtrace. Use it when available to extend backtrace support to more
platforms.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15 05:05:25 +03:00
Laurent Pinchart f8d76fe79b libcamera: base: backtrace: Use libdw to provide symbolic names
libdw provides access to debugging information. This allows creating
better stack trace entries, with file names and line numbers, but also
with demangled symbols as the symbol name is available and can be passed
to abi::__cxa_demangle().

With libdw, the backtrace previously generated by backtrace_symbols()

src/cam/../libcamera/libcamera.so(_ZN9libcamera14VimcCameraData4initEv+0xbd) [0x7f7dbb73222d]
src/cam/../libcamera/libcamera.so(_ZN9libcamera19PipelineHandlerVimc5matchEPNS_16DeviceEnumeratorE+0x3e0) [0x7f7dbb731c40]
src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private22createPipelineHandlersEv+0x1a7) [0x7f7dbb5ea027]
src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private4initEv+0x98) [0x7f7dbb5e9dc8]
src/cam/../libcamera/libcamera.so(_ZN9libcamera13CameraManager7Private3runEv+0x9f) [0x7f7dbb5e9c5f]
src/cam/../libcamera/base/libcamera-base.so(_ZN9libcamera6Thread11startThreadEv+0xee) [0x7f7dbb3e95be]
src/cam/../libcamera/base/libcamera-base.so(+0x4f9d7) [0x7f7dbb3ec9d7]
src/cam/../libcamera/base/libcamera-base.so(+0x4f90e) [0x7f7dbb3ec90e]
src/cam/../libcamera/base/libcamera-base.so(+0x4f2c2) [0x7f7dbb3ec2c2]
/lib64/libpthread.so.0(+0x7e8e) [0x7f7dbab65e8e]
/lib64/libc.so.6(clone+0x3f) [0x7f7dbb10b26f]

becomes

libcamera::VimcCameraData::init()+0xbd (src/libcamera/libcamera.so [0x00007f9de605b22d])
libcamera::PipelineHandlerVimc::match(libcamera::DeviceEnumerator*)+0x3e0 (src/libcamera/libcamera.so [0x00007f9de605ac40])
libcamera::CameraManager::Private::createPipelineHandlers()+0x1a7 (src/libcamera/libcamera.so [0x00007f9de5f13027])
libcamera::CameraManager::Private::init()+0x98 (src/libcamera/libcamera.so [0x00007f9de5f12dc8])
libcamera::CameraManager::Private::run()+0x9f (src/libcamera/libcamera.so [0x00007f9de5f12c5f])
libcamera::Thread::startThread()+0xee (src/libcamera/base/libcamera-base.so [0x00007f9de5d125be])
decltype(*(std::__1::forward<libcamera::Thread*>(fp0)).*fp()) std::__1::__invoke<void (libcamera::Thread::*)(), libcamera::Thread*, void>(void (libcamera::Thread::*&&)(), libcamera::Thread*&&)+0x77 (src/libcamera/base/libcamera-base.so [0x00007f9de5d159d7])
void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*, 2ul>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*>&, std::__1::__tuple_indices<2ul>)+0x3e (src/libcamera/base/libcamera-base.so [0x00007f9de5d1590e])
void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (libcamera::Thread::*)(), libcamera::Thread*> >(void*)+0x62 (src/libcamera/base/libcamera-base.so [0x00007f9de5d152c2])
start_thread+0xde (/var/tmp/portage/sys-libs/glibc-2.33-r1/work/glibc-2.33/nptl/pthread_create.c:482)
__clone+0x3f (../sysdeps/unix/sysv/linux/x86_64/clone.S:97)

The stack entries related to libcamera are missing source file name and
line information, which will be investigated separately, but this is
still an improvement.

Use libdw when available, falling back to backtrace_symbols() otherwise,
or if libdw fails for any reason.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15 05:05:23 +03:00
Laurent Pinchart bae9d2bdb3 libcamera: base: Add Backtrace class
Create a new class to abstract generation and access to call stack
backtraces. The current implementation depends on the glibc backtrace()
implementation and is copied from the logger. Future development will
bring support for libunwind, transparently for the users of the class.

The logger backtrace implementation is dropped, replaced by usage of the
new Backtrace class.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-10-15 05:05:20 +03:00
Laurent Pinchart ca5fb99409 libcamera: pipeline: ipu3: Use new Size grownBy() and shrunkBy() helpers
The Size class has new helpers that can simplify the code in the IPU3
pipeline handler. Use them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-10-15 05:05:19 +03:00
Laurent Pinchart e229b35edf libcamera: geometry: Add Size members to grown or shrink by a margin
Add four new member functions to the Size class (two in-place and two
const) to grow and shrink a Size by given margins.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-10-15 05:05:17 +03:00
David Plowman 962df634bd pipeline: raspberrypi: Create empty control lists correctly
When the pipeline handler start() method is supplied with a NULL list
of controls, we send an empty control list to the IPA. When the IPA is
running in isolated mode the control list goes through the data
serializer, for which it must be marked correctly as a list of
"controls::controls", otherwise the IPA process will abort.

The IPA has a similar problem returning a control list in its
configure() method. We must be careful to initialise it properly even
when empty.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-10-07 01:05:29 +03:00
David Plowman a733e0647a libcamera: Fix crash caused by reading uninitialised delayed controls
The cause is that we read out delayed values using a frame's sequence
number (DelayedControls::get). But we fill the values up
(DelayedControls::applyControls) incrementing writeCount by only one
even if the sequence number has jumped by several since last
time. This is exactly what happens when frames are being dropped.

So the fix is to increment writeCount by "as much as the sequence
number has jumped since last time", which means that we just follow
the sequence number directly.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=74
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-10-05 15:19:04 +03:00
Hirokazu Honda 3c059b9164 libcamera: camera_sensor: Reverse the key and value of test pattern mode map
The key and value of the test pattern mode are originally the index of
v4l2 control and the corresponding test pattern mode control value.
This key and value are useful in the initialization for reporting
available test pattern modes. However, the map of the reversed key and
value is much more useful in applying a requested test pattern mode.
Reverses the key and value of the map as the initialization is one
time but the test pattern mode request will be multiple times.

Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-10-05 03:30:36 +03:00
Javier Martinez Canillas e00149fccb meson: Set a SONAME version in the libcamera libraries
The libcamera and libcamera-base libraries are currently unversioned, but
donwstream users expect these to have a proper SONAME version in order to
package them.

A stable release has not yet happened because the project is still under
development and the API/ABI might change. But having a versioned SONAME
would allow distributions to package libcamera, without the need to add
any downstream patch to set the version.

Since the "0.0.0" version is already used in different places, let's also
use that as the library version. The meson build system will use the first
part of the version ("0") as the SONAME version, which is aligned with the
convention used by other projects:

$ ls /lib64/libcamera*so* -1
/lib64/libcamera-base.so
/lib64/libcamera-base.so.0
/lib64/libcamera-base.so.0.0.0
/lib64/libcamera.so
/lib64/libcamera.so.0
/lib64/libcamera.so.0.0.0

$ objdump -p /lib64/libcamera.so.0.0.0 | grep SONAME
  SONAME               libcamera.so.0

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-28 11:08:29 +03:00
Laurent Pinchart 496e4467d2 libcamera: control_serializer: Fix usage of uninitialized variable
The idMap variable may be used uninitialized in the
ControlSerializer::deserialize<ControlList>() function as reported by
gcc 11:

../../src/libcamera/control_serializer.cpp: In member function ‘T libcamera::ControlSerializer::deserialize(libcamera::ByteStreamBuffer&) [with T = libcamera::ControlList]’:
../../src/libcamera/control_serializer.cpp:609:33: error: ‘idMap’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  609 |         ControlList ctrls(*idMap);
      |

This is due to a missing default case in a switch/case. Fix it by adding
the default case.

Fixes: 6b1404fc4836 ("libcamera: control_serializer: Fix usage of uninitialized variable")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-09-28 00:43:57 +03:00
Jacopo Mondi 11e9d19288 libcamera: control_serializer: Separate the handles space
Two independent instances of the ControlSerializer class are in use at
the IPC boundaries, one in the Proxy class that serializes data from the
pipeline handler to the IPA, and one in the ProxyWorker which serializes
data in the opposite direction.

Each instance operates autonomously, without any centralized point of
control, and each one assigns a numerical handle to each ControlInfoMap
it serializes. This creates a risk of potential collision on the handle
values, as both instances will use the same numerical space and
are not aware of what handles has been already used by the instance "on
the other side".

To fix that, partition the handles numerical space by initializing the
control serializer with a seed according to the role of the component
that creates the serializer and increment the handle number by 2, to
avoid any collision risk.

While this is temporary and rather hacky solution, it solves an issue
with isolated IPA modules without too much complexity added.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-27 14:39:15 +02:00
Jacopo Mondi 23c2b8a9ca libcamera: control_serializer: Serialize info::def()
The ControlInfo class was originally designed to only transport
the control's minimum and maximum values which represent the control's
valid limits.

Later the default value of the control has been added to the ControlInfo
class, but the control serializer implementation has not been updated
accordingly.

This causes issues in IPA modules making use of ControlInfo::def() as,
when running in isolation, they would receive 0.

Fix that by serializing and deserializing the additional ControlValue
and update the protocol description accordingly.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-27 14:37:45 +02:00
Jacopo Mondi b516ffb3bd libcamera: control_serializer: Use the right idmap
When a ControlList is deserialized, the code searches for a valid
ControlInfoMap in the local cache and use its id map to initialize the
list. If no valid ControlInfoMap is found, as it's usually the case
for lists transporting libcamera controls and properties, the globally
defined controls::controls id map is used unconditionally.

This breaks the deserialization of libcamera properties, for which a
wrong idmap is used at construction time.

As the serialization header now transports an id_map_type field, store
the idmap type at serialization time, and re-use it at
deserialization time to identify the correct id map.

Also make the validation stricter by imposing to list of V4L2 controls to
have an associated ControlInfoMap available, as there is no globally
defined idmap for such controls.

To be able to retrieve the idmap associated with a ControlList, add an
accessor function to the ControlList class.

It might be worth in future using a ControlInfoMap to initialize the
deserialized ControlList to implement controls validation against their
limit. As such validation is not implemented at the moment, maintain the
current behaviour and initialize the control list with an idmap.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-27 14:37:39 +02:00
Jacopo Mondi 4c1fc33d8a libcamera: ipu3: Drop entityControls map
The IPA::configure() function has an IPAConfigInfo parameters which
contains a map of numerical indexes to ControlInfoMap instances.

This is a leftover of the old IPA protocol, where it was not possible to
specify a rich interface as it is possible today and each entity
ControlInfoMap was indexed by a numerical id and stored in a map.

Now that the IPA interface allows to specify parameters by name, drop the
map and send the sensor's control info map only.

If we'll need more ControlInfoMap to be shared with the IPA, a new parameter
can be added to IPAConfigInfo.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-09-27 14:35:51 +02:00
Laurent Pinchart 72e8e03719 libcamera: camera_manager: Fix utils.h #include location
The utils.h header #include is separate from the rest of the group for
no reason. Move it to where it should be.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-09-26 15:59:09 +03:00
Laurent Pinchart d4e15331cb libcamera: v4l2_videodevice: Don't move planes to construct FrameBuffer
The FrameBuffer class has no constructor that takes an rvalue reference
to planes. The std::move() is thus misleading as a copy will still take
place. Drop it to clarify the code, no functional change is introduced.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2021-09-24 13:25:33 +03:00
Fabrice Fontaine c52e8429cc libcamera: base: Add libatomic dependency
Add libatomic dependency which is needed since the addition of the base
support library in commit 27aff949fb ("libcamera/base: Move extended
base functionality") to avoid the following build failure:

/tmp/instance-0/output-1/host/opt/ext-toolchain/bin/../lib/gcc/sparc-buildroot-linux-uclibc/9.3.0/../../../../sparc-buildroot-linux-uclibc/bin/ld: src/libcamera/base/libcamera-base.so.p/message.cpp.o: in function `libcamera::Message::registerMessageType()':
message.cpp:(.text+0x290): undefined reference to `__atomic_fetch_add_4'

Fixes: 27aff949fb ("libcamera/base: Move extended base functionality")
Fixes: http://autobuild.buildroot.org/results/6e3471df8e9312a1789ca05ae70cc2283bfeec23
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-19 20:48:57 +03:00
Kieran Bingham 4cf7a8fc0b libcamera: v4l2_videodevice: Handle unexpected buffers
A kernel bug can lead to unexpected buffers being dequeued where we
haven't entered the buffer in our queuedBuffers_ list.

This causes invalid accesses if not handled correctly within libcamera,
and while it is a kernel issue, we can protect against unpatched
kernels to provide a more suitable error message.

This is fixed in the kernel by commit c592b46907ad ("media:
videobuf2-core: dequeue if start_streaming fails") [0]

[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c592b46907ad

Handle unexpected buffers by returning a nullptr, and move cache
management after the validation of the buffer.

Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-09-14 12:54:45 +01:00
Paul Elder 9f9c224c7b libcamera: v4l2_pixelformat: Add helper function to get the description
Add a helper function to V4L2PixelFormat for retrieving the V4L2
description string.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
2021-09-10 10:32:57 +09:00
Paul Elder ba155eadb9 libcamera: v4l2_pixelformat: Add entries for NV24 and NV42
The entries for NV24 and NV42 were missing from the V4L2PixelFormat map.
Add them.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
2021-09-10 10:26:55 +09:00
Paul Elder 67f0def9ba libcamera: v4l2_pixelformat: Add V4L2 description strings
Add V4L2 description strings to the map of V4L2 formats. To achieve
this, create an Info struct to wrap them. Update the one current user of
the old map.

This will be used later in the V4L2 compatibility layer to report the
V4L2 format description.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
2021-09-10 10:26:39 +09:00
Kieran Bingham 3d297f7ac8 libcamera: controls: Use a const ControlValidator
The ControlValidator passed to a ControlList constructor
is used, but not modified.

Make it const.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-09-09 15:58:23 +01:00
Laurent Pinchart 32635054bc libcamera: framebuffer: Prevent modifying the number of metadata planes
The number of metadata planes should always match the number of frame
buffer planes. Enforce this by making the vector private and providing
accessor functions.

As this changes the public API, update all in-tree users accordingly.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:18:31 +03:00
Laurent Pinchart 9df775c757 libcamera: framebuffer: Allocate metadata planes at construction time
The metadata planes are allocated by V4L2VideoDevice when dequeuing a
buffer. This causes the metadata planes to only be allocated after a
buffer gets dequeued, and doesn't provide any strong guarantee that
their number matches the number of FrameBuffer planes. The lack of this
invariant makes the FrameBuffer class fragile.

As a first step towards fixing this, allocate the metadata planes when
the FrameBuffer is constructed. The FrameMetadata API should be further
improved by preventing a change in the number of planes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:18:28 +03:00
Laurent Pinchart 0f4d81c2bf libcamera: v4l2_videodevice: Use utils::enumerate()
Replace a manual counter with the utils::enumerate() utility function.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:18:27 +03:00
Laurent Pinchart c64f7eb5c0 libcamera: v4l2_videodevice: Split planes when dequeuing buffer
When dequeueing a buffer from a V4L2VideoDevice, the number of planes in
the FrameBuffer may not match the number of V4L2 buffer planes if the
PixelFormat is multi-planar (has multiple colour planes) and the V4L2
format is single-planar (has a single buffer plane). In this case, we
need to split the single V4L2 buffer plane into FrameBuffer planes. Do
so, and add checks to reject invalid V4L2 buffers in case of a driver
issue.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:18:24 +03:00
Laurent Pinchart cc035f611f libcamera: v4l2_videodevice: Coalesce planes when queuing buffer
When queueing a buffer to a V4L2VideoDevice, the number of planes in the
FrameBuffer may not match the number of V4L2 buffer planes if the
PixelFormat is multi-planar (has multiple colour planes) and the V4L2
format is single-planar (has a single buffer plane). In this case, we
need to coalesce all FrameBuffer planes into a single V4L2 buffer plane.
Do so, and add validity checks to reject frame buffers that can't be
described using a single V4L2 buffer plane.

This change prepares for proper multi-planar support, but isn't expected
to result in a change of behaviour with existing pipeline handlers, as
none of them queue an output buffer with multiple FrameBuffer planes or
use non-contiguous buffers for either capture or output.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:18:19 +03:00
Laurent Pinchart 88589a2531 libcamera: v4l2_videodevice: Take stride into account to compute offsets
When creating FrameBuffer instances, the V4L2VideoDevice computes plane
offsets using minimal stride for the format. This doesn't always produce
a valid result when the device requires padding at the end of lines. Fix
it by computing offsets using the stride reported by V4L2.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-09-07 19:18:18 +03:00
Laurent Pinchart 17b9db376c libcamera: v4l2_videodevice: Document plane handling in createBuffer()
The V4L2VideoDevice::createBuffer() calculates offsets manually when
using a multi-planar pixel format and a single-planar V4L2 format. The
process isn't trivial, document it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-09-07 19:18:16 +03:00
Laurent Pinchart 6d98fe5b68 libcamera: v4l2_videodevice: Cache PixelFormatInfo
Cache the PixelFormatInfo instead of looking it up in every call to
createBuffer(). This prepares for usage of the info in queueBuffer(), to
avoid a looking every time a buffer is queued.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:18:13 +03:00
Laurent Pinchart 81a38f4373 libcamera: framebuffer: Add a function to check if planes are contiguous
Multi-planar frame buffers can store their planes contiguously in
memory, or split them in discontiguous memory areas. Add a private
function to check in which of these two categories the frame buffer
belongs. This will be used to correctly handle the differences between
the V4L2 single and multi planar APIs.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:18:09 +03:00
Laurent Pinchart 78875938e9 libcamera: framebuffer: Move planes check to constructor
The FrameBuffer::planes() function checks that planes are correctly
initialized with an offset. This can be done at construction time
instead, as the planes are constant. The backtrace generated by the
assertion will show where the faulty frame buffer is created instead of
where it is used, easing debugging.

As the runtime overhead is reduced, there's no real need to drop the
assertion in the future anymore, it can be useful to ensure that the
planes are correctly populated by the caller. Drop the comment that
calls for removing the check.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:18:08 +03:00
Laurent Pinchart 1b0bd492c2 libcamera: formats: Support V4L2 non-contiguous formats
V4L2 describes multi-planar formats with different 4CCs depending on
whether or not the planes are stored contiguously in memory. Support
this when translating between PixelFormat and V4L2PixelFormat.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
2021-09-07 19:17:57 +03:00
Laurent Pinchart 94cbaa381a libcamera: formats: Add planeSize() helpers to PixelFormatInfo
Add two helpers functions to the PixelFormatInfo class to compute the
byte size of a given plane, taking the frame size, the stride, the
alignment constraints and the vertical subsampling into account.

Use the new functions through the code base to replace manual
implementations.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:17:54 +03:00
Laurent Pinchart e85978ef5f libcamera: formats: Move plane info structure to PixelFormatInfo
Move the PixelFormatPlaneInfo structure within the PixelFormatInfo class
definition and rename it to Plane, to align the naming scheme with other
parts of libcamera, such as FrameBuffer::Plane or FrameMetadata::Plane.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2021-09-07 19:17:50 +03:00
Laurent Pinchart 9a8c0365f7 libcamera: Use V4L2PixelFormat::fromPixelFormat()
Replace manual searches for V4L2 pixel format in the PixelFormatInfo
with the V4L2PixelFormat::fromPixelFormat() helper function. This
prepares for multi-planar support that will modify how V4L2 pixel
formats are stored in PixelFormatInfo.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2021-09-07 19:17:49 +03:00
Laurent Pinchart 395d43d6d7 libcamera: v4l2_videodevice: Drop toV4L2PixelFormat()
The V4L2VideoDevice::toV4L2PixelFormat() function is incorrectly
implemented, as it will pick a multi-planar format if the device
supports the multi-planar API, even if only single-planar formats are
supported. This currently works because the implementation calls
V4L2PixelFormat::fromPixelFormat(), which ignores the multiplanar
argument and always returns a single-planar format.

Fixing this isn't trivial. As we don't need to support multi-planar V4L2
formats at this point, drop the function instead of pretending
everything is fine, and call V4L2PixelFormat::fromPixelFormat() directly
from pipeline handlers. As the single-planar case is the most common,
set the multiplanar argument to false by default to avoid long lines.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:17:46 +03:00
Laurent Pinchart 8e18f8d45f libcamera: file_descriptor: Add a function to retrieve the inode
The inode is useful to check if two file descriptors refer to the same
file. Add a function to retrieve it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
2021-09-07 19:17:38 +03:00
Martin Kepplinger 06e53199c2 libcamera: Add hi846 camera sensor properties
Add camera sensor properties for the Hynix hi846 sensor. The part is
also called YACG4D0C9SHC and a datasheet can be found at
https://product.skhynix.com/products/cis/cis.go

This is the selfie camera in the Librem 5 phone.

Signed-off-by: Martin Kepplinger <martin.kepplinger@puri.sm>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-07 02:11:15 +03:00
Laurent Pinchart 3335d5a504 libcamera: Drop emitter object pointer from signal arguments
Many signals used in internal and public APIs carry the emitter pointer
as a signal argument. This was done to allow slots connected to multiple
signal instances to differentiate between emitters. While starting from
a good intention of facilitating the implementation of slots, it turned
out to be a bad API design as the signal isn't meant to know what it
will be connected to, and thus shouldn't carry parameters that are
solely meant to support a use case specific to the connected slot.

These pointers turn out to be unused in all slots but one. In the only
case where it is needed, it can be obtained by wrapping the slot in a
lambda function when connecting the signal. Do so, and drop the emitter
pointer from all signals.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-09-02 01:16:45 +03:00
Laurent Pinchart 3f662ae3c0 libcamera: Don't use emitter object pointer argument to slot
In many cases, the emitter object passed as a pointer from signals to
slots is also available as a class member. Use the class member when
this occurs, to prepare for removal of the emitter object pointer from
signals.

In test/event.cpp, this additionally requires moving the EventNotifier
to a class member.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-09-02 01:16:45 +03:00
Laurent Pinchart 58720e1dc9 libcamera: base: signal: Support connecting signals to functors
It can be useful to connect a signal to a functor, and in particular a
lambda function, while still operating in the context of a receiver
object (to support both object-based disconnection and queued
connections to Object instances).

Add a BoundMethodFunctor class to bind a functor, and a corresponding
Signal::connect() function. There is no corresponding disconnect()
function, as a lambda passed to connect() can't be later passed to
disconnect(). Disconnection typically uses disconnect(T *object), which
will cover the vast majority of use cases.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-09-02 01:16:45 +03:00
Laurent Pinchart eb5c4ead88 libcamera: Use simpler Signal::disconnect() function
When disconnecting a signal from a receiver, it is usually not necessary
to specify the receiver's slot function explicitly, as the signal is
often connected to a single slot for a given receiver. We can thus use a
simpler version of Signal::disconnect() that takes a pointer to the
receiver object only. This reduces code size, as the disconnect()
function is a template function.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-09-02 01:16:44 +03:00