[libcamera-devel,v4,0/3] lc-compliance: Add a libcamera compliance tool
mbox series

Message ID 20210329170250.937120-1-niklas.soderlund@ragnatech.se
Headers show
Series
  • lc-compliance: Add a libcamera compliance tool
Related show

Message

Niklas Söderlund March 29, 2021, 5:02 p.m. UTC
Hello,

This series adds a compliance tool to libcamera. It was developed out of
necessity while extending and debugging the IPU3 pipeline hander. Each
test in the tool so far have at one point triggered fatal issues in one
pipeline or another.

The tool is simple at the moment and only tests a single stream. As our
use-cases grow more complex I hope to find time to extend the tool to
cover more areas.

The tool also needs to grows a better structure for how to organize 
tests on file and selection to fit its execution environment. There are 
also many areas where the internal helpers can be refined. All in all 
this is an just a starting point that triggers some problems in our 
library that can be built upon and hopefully help us to avoid repeating 
the mistakes of our past.

Niklas Söderlund (3):
  meson: Move libevent dependency lookup
  lc-compliance: Add a libcamera compliance tool
  lc-compliance: Add test stopping single stream with requests queued

 src/cam/meson.build                  |   2 -
 src/lc-compliance/main.cpp           | 148 ++++++++++++++++++
 src/lc-compliance/meson.build        |  23 +++
 src/lc-compliance/results.cpp        |  75 ++++++++++
 src/lc-compliance/results.h          |  47 ++++++
 src/lc-compliance/simple_capture.cpp | 214 +++++++++++++++++++++++++++
 src/lc-compliance/simple_capture.h   |  68 +++++++++
 src/lc-compliance/single_stream.cpp  |  97 ++++++++++++
 src/lc-compliance/tests.h            |  16 ++
 src/meson.build                      |   4 +
 10 files changed, 692 insertions(+), 2 deletions(-)
 create mode 100644 src/lc-compliance/main.cpp
 create mode 100644 src/lc-compliance/meson.build
 create mode 100644 src/lc-compliance/results.cpp
 create mode 100644 src/lc-compliance/results.h
 create mode 100644 src/lc-compliance/simple_capture.cpp
 create mode 100644 src/lc-compliance/simple_capture.h
 create mode 100644 src/lc-compliance/single_stream.cpp
 create mode 100644 src/lc-compliance/tests.h

Comments

Nícolas F. R. A. Prado March 29, 2021, 7 p.m. UTC | #1
Hi Niklas,

Running lc-compliance on the Rock Pi 4 with a imx219 camera fails for me,
although I think this indicates a bug in the rkisp1 pipeline rather than in
lc-compliance.

I'm able to stream from the camera on this platform using cam.

These are my libcamera and kernel trees for reference:

https://gitlab.collabora.com/nfraprado/libcamera/-/tree/lc-compliance
https://gitlab.collabora.com/nfraprado/linux/-/tree/rockpi4-cam

First of all, as already mentioned on
https://patchwork.libcamera.org/cover/11542/#15629 , rkisp1 doesn't seem to
support raw streaming, thus the following SEGFAULT occurs:

	user@gst-build-sdk:~$ lc-compliance -c '/base/i2c@ff3d0000/sensor@10'
	[0:05:52.419438332] [336]  INFO Camera camera_manager.cpp:298 libcamera v0.0.0+2470-8029d912
	[0:05:52.442680790] [337]  WARN CameraSensor camera_sensor.cpp:306 'imx219 4-0010': Recommended V4L2 control 0x009a0922 not supported
	[0:05:52.442872415] [337]  WARN CameraSensor camera_sensor.cpp:358 'imx219 4-0010': The sensor kernel driver needs to be fixed
	[0:05:52.442946790] [337]  WARN CameraSensor camera_sensor.cpp:360 'imx219 4-0010': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information
	[0:05:52.449002374] [337]  WARN CameraSensor camera_sensor.cpp:473 'imx219 4-0010': Failed to retrieve the camera location
	Using camera /base/i2c@ff3d0000/sensor@10
	= Test role raw
	* Test single capture cycles
	[0:05:52.459568749] [336]  WARN RkISP1 rkisp1.cpp:537 Requested stream role not supported: 0
	Segmentation fault

Disabling the raw streaming though, I now get a "No BufferCache available to
queue." error:

	user@gst-build-sdk:~$ lc-compliance -c '/base/i2c@ff3d0000/sensor@10'
	[0:01:19.542206077] [326]  INFO Camera camera_manager.cpp:298 libcamera v0.0.0+2469-229601cc
	[0:01:19.566360452] [327]  WARN CameraSensor camera_sensor.cpp:306 'imx219 4-0010': Recommended V4L2 control 0x009a0922 not supported
	[0:01:19.566502785] [327]  WARN CameraSensor camera_sensor.cpp:358 'imx219 4-0010': The sensor kernel driver needs to be fixed
	[0:01:19.566545660] [327]  WARN CameraSensor camera_sensor.cpp:360 'imx219 4-0010': SSee Documentation/sensor_driver_requirements.rst in the libcamera sources for more information
	[0:01:19.574099160] [327]  WARN CameraSensor camera_sensor.cpp:473 'imx219 4-0010': Failed to retrieve the camera location
	Using camera /base/i2c@ff3d0000/sensor@10
	= Test role still
	* Test single capture cycles
	[0:01:19.585448577] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:19.587510869] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- SKIP: Camera needs 4 requests, can't test only 1
	[0:01:19.651448077] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:19.653177869] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- SKIP: Camera needs 4 requests, can't test only 2
	[0:01:19.714663619] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:19.716524952] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- SKIP: Camera needs 4 requests, can't test only 3
	[0:01:19.787002202] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:19.788506285] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 5 requests with 1 start cycles
	[0:01:20.442971911] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:20.444870327] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 8 requests with 1 start cycles
	[0:01:21.308764328] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:21.310607911] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 13 requests with 1 start cycles
	[0:01:22.508115453] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:22.509954953] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 21 requests with 1 start cycles
	[0:01:24.240576371] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:24.242428996] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 34 requests with 1 start cycles
	[0:01:26.839422081] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:26.841328081] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 55 requests with 1 start cycles
	[0:01:30.838071457] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:30.839926124] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 89 requests with 1 start cycles
	* Test multiple start/stop cycles
	[0:01:37.103226919] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:37.105141377] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- SKIP: Camera needs 4 requests, can't test only 1
	[0:01:37.175349669] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:37.177253044] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- SKIP: Camera needs 4 requests, can't test only 2
	[0:01:37.245730044] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:37.247179585] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- SKIP: Camera needs 4 requests, can't test only 3
	[0:01:37.310524961] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:37.312106044] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 5 requests with 3 start cycles
	[0:01:39.286329003] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:39.288254753] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 8 requests with 3 start cycles
	[0:01:41.875714796] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:41.877583088] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 13 requests with 3 start cycles
	[0:01:45.463695506] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:45.465565256] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 21 requests with 3 start cycles
	[0:01:50.632783759] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:50.635397967] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 34 requests with 3 start cycles
	[0:01:58.396298012] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:01:58.398886554] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 55 requests with 3 start cycles
	[0:02:10.352359601] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:02:10.354941726] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Balanced capture of 89 requests with 3 start cycles
	* Test unbalanced stop
	[0:02:29.101426527] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:02:29.103894902] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	- PASS: Unbalanced capture of 1 requests
	[0:02:29.482435069] [326]  INFO Camera camera.cpp:905 configuring streams: (0) 3280x2464-NV12
	[0:02:29.484985694] [327]  INFO IPARkISP1 rkisp1.cpp:127 Exposure: 4-3522 Gain: 1-232
	[0:02:29.969575319] [327] FATAL V4L2 v4l2_videodevice.cpp:1400 /dev/video0[13:cap]: No BufferCache available to queue.
	Backtrace:
	/usr/local/lib/libcamera.so(_ZN9libcamera15V4L2VideoDevice11queueBufferEPNS_11FrameBufferE+0xa8) [0x7fb33adfa8]
	/usr/local/lib/libcamera.so(_ZN9libcamera10RkISP1Path11queueBufferEPNS_11FrameBufferE+0x24) [0x7fb33f0a7c]
	/usr/local/lib/libcamera.so(_ZN9libcamera16RkISP1CameraData16queueFrameActionEjRKNS_3ipa6rkisp112RkISP1ActionE+0x110) [0x7fb33ed0f8]
	/usr/local/lib/libcamera.so(_ZN9libcamera17BoundMethodMemberINS_16RkISP1CameraDataEvJjRKNS_3ipa6rkisp112RkISP1ActionEEE8activateEjS6_b+0x9c) [0x7fb33f4f9c]
	/usr/local/lib/libcamera.so(_ZN9libcamera6SignalIJjRKNS_3ipa6rkisp112RkISP1ActionEEE4emitEjS5_+0x94) [0x7fb32e8f24]
	/usr/local/lib/libcamera.so(_ZN9libcamera3ipa6rkisp114IPAProxyRkISP122queueFrameActionThreadEjRKNS1_12RkISP1ActionE+0x7c) [0x7fb32e7c2c]
	/usr/local/lib/libcamera.so(_ZN9libcamera17BoundMethodMemberINS_3ipa6rkisp114IPAProxyRkISP1EvJjRKNS2_12RkISP1ActionEEE6invokeEjS6_+0x84) [0x7fb32eaf7c]
	/usr/local/lib/libcamera.so(_ZN9libcamera15BoundMethodArgsIvJjRKNS_3ipa6rkisp112RkISP1ActionEEE10invokePackIJLm0ELm1EEEEvPNS_19BoundMethodPackBaseESt16integer_sequenceImJXspT_EEE+0x5c) [0x7fb32eb210]
	/usr/local/lib/libcamera.so(_ZN9libcamera15BoundMethodArgsIvJjRKNS_3ipa6rkisp112RkISP1ActionEEE10invokePackEPNS_19BoundMethodPackBaseE+0x1c) [0x7fb32ead94]
	/usr/local/lib/libcamera.so(_ZN9libcamera13InvokeMessage6invokeEv+0x44) [0x7fb3383b5c]
	/usr/local/lib/libcamera.so(_ZN9libcamera6Object7messageEPNS_7MessageE+0x48) [0x7fb33840dc]
	/usr/local/lib/libcamera.so(_ZN9libcamera6Thread16dispatchMessagesENS_7Message4TypeE+0x1fc) [0x7fb3398b98]
	/usr/local/lib/libcamera.so(_ZN9libcamera3ipa6rkisp114IPAProxyRkISP110stopThreadEv+0xdc) [0x7fb32e6d40]
	/usr/local/lib/libcamera.so(_ZN9libcamera3ipa6rkisp114IPAProxyRkISP14stopEv+0x30) [0x7fb32e6c50]
	/usr/local/lib/libcamera.so(_ZN9libcamera21PipelineHandlerRkISP14stopEPNS_6CameraE+0x178) [0x7fb33ef484]
	/usr/local/lib/libcamera.so(_ZN9libcamera17BoundMethodMemberINS_15PipelineHandlerEvJPNS_6CameraEEE6invokeES3_+0x7c) [0x7fb3308c50]
	/usr/local/lib/libcamera.so(_ZN9libcamera15BoundMethodArgsIvJPNS_6CameraEEE10invokePackIJLm0EEEEvPNS_19BoundMethodPackBaseESt16integer_sequenceImJXspT_EEE+0x4c) [0x7fb33090cc]
	/usr/local/lib/libcamera.so(_ZN9libcamera15BoundMethodArgsIvJPNS_6CameraEEE10invokePackEPNS_19BoundMethodPackBaseE+0x1c) [0x7fb3308bc8]
	/usr/local/lib/libcamera.so(_ZN9libcamera13InvokeMessage6invokeEv+0x44) [0x7fb3383b5c]
	/usr/local/lib/libcamera.so(_ZN9libcamera6Object7messageEPNS_7MessageE+0x48) [0x7fb33840dc]
	/usr/local/lib/libcamera.so(_ZN9libcamera6Thread16dispatchMessagesENS_7Message4TypeE+0x1fc) [0x7fb3398b98]
	/usr/local/lib/libcamera.so(_ZN9libcamera19EventDispatcherPoll13processEventsEv+0x20) [0x7fb33569c0]
	/usr/local/lib/libcamera.so(_ZN9libcamera6Thread4execEv+0x78) [0x7fb3398164]
	/usr/local/lib/libcamera.so(_ZN9libcamera13CameraManager7Private3runEv+0xbc) [0x7fb3309d9c]
	/usr/local/lib/libcamera.so(_ZN9libcamera6Thread11startThreadEv+0x100) [0x7fb33980e0]
	/usr/local/lib/libcamera.so(_ZSt13__invoke_implIvMN9libcamera6ThreadEFvvEPS1_JEET_St21__invoke_memfun_derefOT0_OT1_DpOT2_+0x78) [0x7fb339c554]
	/usr/local/lib/libcamera.so(_ZSt8__invokeIMN9libcamera6ThreadEFvvEJPS1_EENSt15__invoke_resultIT_JDpT0_EE4typeEOS6_DpOS7_+0x38) [0x7fb339c46c]
	/usr/local/lib/libcamera.so(_ZNSt6thread8_InvokerISt5tupleIJMN9libcamera6ThreadEFvvEPS3_EEE9_M_invokeIJLm0ELm1EEEEvSt12_Index_tupleIJXspT_EEE+0x3c) [0x7fb339c3d0]
	/usr/local/lib/libcamera.so(_ZNSt6thread8_InvokerISt5tupleIJMN9libcamera6ThreadEFvvEPS3_EEEclEv+0x14) [0x7fb339c388]
	/usr/local/lib/libcamera.so(_ZNSt6thread11_State_implINS_8_InvokerISt5tupleIJMN9libcamera6ThreadEFvvEPS4_EEEEE6_M_runEv+0x18) [0x7fb339c368]
	Aborted

The comment in the code suggests that this is something that should be fixed in
the pipeline:

	/*
	 * Pipeline handlers should not requeue buffers after releasing the
	 * buffers on the device. Any occurence of this error should be fixed
	 * in the pipeline handler directly.
	 */

Also, just running it a second time after that error, a kernel panic occurs:

	[  195.788185] SError Interrupt on CPU1, code 0xbf000000 -- SError
	[  195.788205] CPU: 1 PID: 367 Comm: lc-compliance Not tainted 5.11.0-00001-g16b7543b296a #45
	[  195.788215] Hardware name: Radxa ROCK Pi 4A (DT)
	[  195.788224] pstate: 40000005 (nZcv daif -PAN -UAO -TCO BTYPE=--)
	[  195.788231] pc : get_random_u64+0x28/0xd4
	[  195.788238] lr : copy_process+0x2e8/0x1260
	[  195.788245] sp : ffffffc012103c10
	[  195.788252] x29: ffffffc012103c10 x28: ffffff80050d5700 
	[  195.788273] x27: ffffffc011a90fc4 x26: ffffff800d804e80 
	[  195.788290] x25: ffffff800d804e80 x24: ffffffc012828000 
	[  195.788308] x23: ffffff80050d1d00 x22: ffffffc011a358d0 
	[  195.788326] x21: ffffffc012103db0 x20: 0000000000000000 
	[  195.788343] x19: 00000000003d0f00 x18: 0000000000000000 
	[  195.788361] x17: 0000000000000000 x16: 0000000000000000 
	[  195.788379] x15: 0000000000000000 x14: 0000000000000000 
	[  195.788397] x13: 0000000000000000 x12: 0000000000000000 
	[  195.788414] x11: 0000000000000000 x10: 0000000000000000 
	[  195.788432] x9 : ffffffc01003ea00 x8 : 0000000000000000 
	[  195.788450] x7 : 0000000000000000 x6 : ffffff80050d6580 
	[  195.788467] x5 : 0000000000000000 x4 : 0000000000000000 
	[  195.788485] x3 : 0000000000000000 x2 : 0000000000000000 
	[  195.788502] x1 : ffffffffffffffff x0 : 0000000000000027 
	[  195.788521] Kernel panic - not syncing: Asynchronous SError Interrupt
	[  195.788532] CPU: 1 PID: 367 Comm: lc-compliance Not tainted 5.11.0-00001-g16b7543b296a #45
	[  195.788541] Hardware name: Radxa ROCK Pi 4A (DT)
	[  195.788548] Call trace:
	[  195.788554]  dump_backtrace+0x0/0x1b4
	[  195.788560]  show_stack+0x24/0x34
	[  195.788566]  dump_stack+0xcc/0x10c
	[  195.788573]  panic+0x170/0x348
	[  195.788579]  nmi_panic+0x7c/0xa0
	[  195.788585]  arm64_serror_panic+0x7c/0x88
	[  195.788592]  do_serror+0x2c/0x68
	[  195.788598]  el1_error+0x78/0xf0
	[  195.788604]  get_random_u64+0x28/0xd4
	[  195.788611]  copy_process+0x2e8/0x1260
	[  195.788617]  kernel_clone+0xa8/0x2b0
	[  195.788624]  __do_sys_clone+0x58/0x80
	[  195.788631]  __arm64_sys_clone+0x28/0x34
	[  195.788638]  el0_svc_common.constprop.0+0x114/0x188
	[  195.788645]  do_el0_svc+0x8c/0x98
	[  195.788651]  el0_svc+0x20/0x30
	[  195.788658]  el0_sync_handler+0x144/0x1f0
	[  195.788664]  el0_sync+0x174/0x180
	[  195.788713] SMP: stopping secondary CPUs
	[  195.788721] Kernel Offset: disabled
	[  195.788728] CPU features: 0x00040022,6100200c
	[  195.788735] Memory Limit: none

Just thought I'd document these issues in case it's reproducible by others as
well.

Thanks,
Nícolas
Laurent Pinchart March 29, 2021, 10:42 p.m. UTC | #2
Hi Niklas,

Thank you for the patch.

On Mon, Mar 29, 2021 at 07:02:48PM +0200, Niklas Söderlund wrote:
> The libevent library will be needed by both cam and the soon to be added
> lc-compliacne tool. Move the dependency lookup to a shared meson file to

s/compliacne/compliance/ (libcamera doesn't address skin issues yet)

> avoid having to look it up twice.
> 
> Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> ---
>  src/cam/meson.build | 2 --
>  src/meson.build     | 2 ++
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/src/cam/meson.build b/src/cam/meson.build
> index 5e1a7f387d60a98f..13e6201a08a214cf 100644
> --- a/src/cam/meson.build
> +++ b/src/cam/meson.build
> @@ -1,7 +1,5 @@
>  # SPDX-License-Identifier: CC0-1.0
>  
> -libevent = dependency('libevent_pthreads', required : get_option('cam'))
> -
>  if not libevent.found()

This is a bit of an annoying once, as if the 'cam' option is set to
enabled, it shouldn't be disabled silently. The cam option is new, so
the problem didn't occur before.

We could print an error message manually here if the 'cam' option is set
to enabled, but that's not great. I'm tempted to keep the code as-is and
duplicate the dependency() in the lc-compliance meson.build.

Sorry for the bad suggestion.

>      cam_enabled = false
>      subdir_done()
> diff --git a/src/meson.build b/src/meson.build
> index c908b0675773301d..14c49f6eeb1f5a01 100644
> --- a/src/meson.build
> +++ b/src/meson.build
> @@ -11,6 +11,8 @@ else
>      ipa_sign_module = false
>  endif
>  
> +libevent = dependency('libevent_pthreads', required : false)
> +
>  libcamera_objects = []
>  
>  # The 'android' subdir must be processed first, and the build targets