[PATCH v11 0/7] Add VirtualPipelineHandler
Kieran Bingham
kieran.bingham at ideasonboard.com
Mon Sep 9 14:45:28 CEST 2024
Hi Harvey,
Quoting Harvey Yang (2024-09-07 15:28:25)
> Hi all,
>
> This series adds virtual pipeline handler, which doesn't depend on any
> hardware, like camera sensor or ISP. Currently the configuration
> supports test patterns and images.
>
> It passed the gitlab pipeline:
> https://gitlab.freedesktop.org/chenghaoyang/libcamera/-/pipelines/1266568
>
> I failed to pass multi_stream_test when trying to enable multiple
> streams though. Please give me some hints what it tests and what I
> missed:
I tried to run this but it crashed.
I ran gdb --args ./build/gcc/src/apps/qcam/qcam and then chose virtual0:
And here's the backtraces:
(gdb) thread apply all bt
Thread 9 (Thread 0xffffda00eec0 (LWP 31018) "qcam"):
#0 0x0000fffff7c92ff0 in libcamera::TestPatternGenerator::shiftLeft (this=0xffffb8060d40, size=...) at ../../src/libcamera/pipeline/virtual/test_pattern_generator.cpp:50
#1 0x0000fffff7c92e2c in libcamera::TestPatternGenerator::generateFrame (this=0xffffb8060d40, size=..., buffer=0xffffb806fa00) at ../../src/libcamera/pipeline/virtual/test_pattern_generator.cpp:31
#2 0x0000fffff7c94870 in libcamera::PipelineHandlerVirtual::queueRequestDevice (this=0xffffb80464a0, camera=0xffffb808a4d0, request=0xffffdc015e20) at ../../src/libcamera/pipeline/virtual/virtual.cpp:234
#3 0x0000fffff7b76a30 in libcamera::PipelineHandler::doQueueRequest (this=0xffffb80464a0, request=0xffffdc015e20) at ../../src/libcamera/pipeline_handler.cpp:472
#4 0x0000fffff7b76ab8 in libcamera::PipelineHandler::doQueueRequests (this=0xffffb80464a0) at ../../src/libcamera/pipeline_handler.cpp:492
#5 0x0000fffff7b7dcac in libcamera::BoundMethodMember<libcamera::PipelineHandler, void>::invoke (this=0x8fdb40) at ../../include/libcamera/base/bound_method.h:191
#6 0x0000fffff7ad7368 in libcamera::BoundMethodArgs<void>::invokePack<, void>(libcamera::BoundMethodPackBase*, std::integer_sequence<unsigned long>) (this=0x8fdb40, pack=0xffffb806e100) at ../../include/libcamera/base/bound_method.h:115
#7 0x0000fffff7ad6728 in libcamera::BoundMethodArgs<void>::invokePack (this=0x8fdb40, pack=0xffffb806e100) at ../../include/libcamera/base/bound_method.h:124
#8 0x0000fffff7f46ed4 in libcamera::BoundMethodBase::activatePack (this=0x8fdb40, pack=std::shared_ptr<libcamera::BoundMethodPackBase> (use count 2, weak count 0) = {...}, deleteMethod=false) at ../../src/libcamera/base/bound_method.cpp:85
#9 0x0000fffff7b7dbc8 in libcamera::BoundMethodMember<libcamera::PipelineHandler, void>::activate (this=0x8fdb40, deleteMethod=false) at ../../include/libcamera/base/bound_method.h:184
#10 0x0000fffff7af33e4 in libcamera::Signal<>::emit() (this=0x8fda90) at ../../include/libcamera/base/signal.h:153
#11 0x0000fffff7b29b74 in libcamera::Request::Private::emitPrepareCompleted (this=0x8fda80) at ../../src/libcamera/request.cpp:190
#12 0x0000fffff7b29cf0 in libcamera::Request::Private::prepare (this=0x8fda80, timeout=std::chrono::duration = { 300ms }) at ../../src/libcamera/request.cpp:243
#13 0x0000fffff7b76968 in libcamera::PipelineHandler::queueRequest (this=0xffffb80464a0, request=0xffffdc015e20) at ../../src/libcamera/pipeline_handler.cpp:451
#14 0x0000fffff7b0b768 in libcamera::BoundMethodMember<libcamera::PipelineHandler, void, libcamera::Request*>::invoke (this=0x86ad50, args#0=0xffffdc015e20) at ../../include/libcamera/base/bound_method.h:191
#15 0x000000000044f6f4 in libcamera::BoundMethodArgs<void, libcamera::Request*>::invokePack<0ul, void> (this=0x86ad50, pack=0x86ada0) at ../../include/libcamera/base/bound_method.h:115
#16 0x000000000044f1a0 in libcamera::BoundMethodArgs<void, libcamera::Request*>::invokePack (this=0x86ad50, pack=0x86ada0) at ../../include/libcamera/base/bound_method.h:124
#17 0x0000fffff7f60fa8 in libcamera::InvokeMessage::invoke (this=0x86adc0) at ../../src/libcamera/base/message.cpp:153
#18 0x0000fffff7f489c8 in libcamera::Object::message (this=0xffffb80464a0, msg=0x86adc0) at ../../src/libcamera/base/object.cpp:211
#19 0x0000fffff7f62394 in libcamera::Thread::dispatchMessages (this=0x6993a0, type=libcamera::Message::None) at ../../src/libcamera/base/thread.cpp:602
#20 0x0000fffff7f51e08 in libcamera::EventDispatcherPoll::processEvents (this=0xffffb8074d40) at ../../src/libcamera/base/event_dispatcher_poll.cpp:146
#21 0x0000fffff7f618f4 in libcamera::Thread::exec (this=0x6993a0) at ../../src/libcamera/base/thread.cpp:306
#22 0x0000fffff7b0c5ec in libcamera::CameraManager::Private::run (this=0x699390) at ../../src/libcamera/camera_manager.cpp:87
#23 0x0000fffff7f61894 in libcamera::Thread::startThread (this=0x6993a0) at ../../src/libcamera/base/thread.cpp:284
#24 0x0000fffff7f65cf4 in std::__invoke_impl<void, void (libcamera::Thread::*)(), libcamera::Thread*> (__f=@0x707f90: (void (libcamera::Thread::*)(libcamera::Thread * const)) 0xfffff7f61794 <libcamera::Thread::startThread()>, __t=@0x707f88: 0x6993a0) at /usr/include/c++/14/bits/invoke.h:74
#25 0x0000fffff7f65c34 in std::__invoke<void (libcamera::Thread::*)(), libcamera::Thread*> (__fn=@0x707f90: (void (libcamera::Thread::*)(libcamera::Thread * const)) 0xfffff7f61794 <libcamera::Thread::startThread()>) at /usr/include/c++/14/bits/invoke.h:96
#26 0x0000fffff7f65b98 in std::thread::_Invoker<std::tuple<void (libcamera::Thread::*)(), libcamera::Thread*> >::_M_invoke<0ul, 1ul> (this=0x707f88) at /usr/include/c++/14/bits/std_thread.h:301
#27 0x0000fffff7f65b50 in std::thread::_Invoker<std::tuple<void (libcamera::Thread::*)(), libcamera::Thread*> >::operator() (this=0x707f88) at /usr/include/c++/14/bits/std_thread.h:308
#28 0x0000fffff7f65b30 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (libcamera::Thread::*)(), libcamera::Thread*> > >::_M_run (this=0x707f80) at /usr/include/c++/14/bits/std_thread.h:253
#29 0x0000fffff58e0200 in execute_native_thread_routine () at /lib64/libstdc++.so.6
#30 0x0000fffff56b6998 in start_thread () at /lib64/libc.so.6
#31 0x0000fffff572268c in thread_start () at /lib64/libc.so.6
Thread 8 (Thread 0xffffd960eec0 (LWP 31016) "qcam"):
#0 0x0000fffff57200a4 in syscall () at /lib64/libc.so.6
#1 0x0000fffff4c4c3d4 in g_cond_wait () at /lib64/libglib-2.0.so.0
#2 0x0000fffff4be985c in g_async_queue_pop_intern_unlocked () at /lib64/libglib-2.0.so.0
#3 0x0000fffff4be98ec in g_async_queue_pop () at /lib64/libglib-2.0.so.0
#4 0x0000ffffe1ce3414 in fc_thread_func () at /lib64/libpangoft2-1.0.so.0
#5 0x0000fffff4c54a20 in g_thread_proxy () at /lib64/libglib-2.0.so.0
#6 0x0000fffff56b6998 in start_thread () at /lib64/libc.so.6
#7 0x0000fffff572268c in thread_start () at /lib64/libc.so.6
Thread 6 (Thread 0xffffdaa0eec0 (LWP 31014) "gdbus"):
#0 0x0000fffff57170c4 in ppoll () at /lib64/libc.so.6
#1 0x0000fffff4c84284 in g_main_context_iterate_unlocked.isra () at /lib64/libglib-2.0.so.0
#2 0x0000fffff4c26fb0 in g_main_loop_run () at /lib64/libglib-2.0.so.0
#3 0x0000ffffe1133f64 in gdbus_shared_thread_func.lto_priv () at /lib64/libgio-2.0.so.0
#4 0x0000fffff4c54a20 in g_thread_proxy () at /lib64/libglib-2.0.so.0
#5 0x0000fffff56b6998 in start_thread () at /lib64/libc.so.6
#6 0x0000fffff572268c in thread_start () at /lib64/libc.so.6
Thread 5 (Thread 0xffffdb40eec0 (LWP 31013) "gmain"):
--Type <RET> for more, q to quit, c to continue without paging--
#0 0x0000fffff57170c4 in ppoll () at /lib64/libc.so.6
#1 0x0000fffff4c84284 in g_main_context_iterate_unlocked.isra () at /lib64/libglib-2.0.so.0
#2 0x0000fffff4c22264 in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#3 0x0000fffff4c222cc in glib_worker_main () at /lib64/libglib-2.0.so.0
#4 0x0000fffff4c54a20 in g_thread_proxy () at /lib64/libglib-2.0.so.0
#5 0x0000fffff56b6998 in start_thread () at /lib64/libc.so.6
#6 0x0000fffff572268c in thread_start () at /lib64/libc.so.6
Thread 4 (Thread 0xffffdbe0eec0 (LWP 31012) "pool-spawner"):
#0 0x0000fffff57200a4 in syscall () at /lib64/libc.so.6
#1 0x0000fffff4c4c3d4 in g_cond_wait () at /lib64/libglib-2.0.so.0
#2 0x0000fffff4be985c in g_async_queue_pop_intern_unlocked () at /lib64/libglib-2.0.so.0
#3 0x0000fffff4c557dc in g_thread_pool_spawn_thread () at /lib64/libglib-2.0.so.0
#4 0x0000fffff4c54a20 in g_thread_proxy () at /lib64/libglib-2.0.so.0
#5 0x0000fffff56b6998 in start_thread () at /lib64/libc.so.6
#6 0x0000fffff572268c in thread_start () at /lib64/libc.so.6
Thread 3 (Thread 0xffffe260eec0 (LWP 31011) "QXcbEventQueue"):
#0 0x0000fffff5716ad4 in poll () at /lib64/libc.so.6
#1 0x0000fffff1821814 in _xcb_conn_wait.part.0 () at /lib64/libxcb.so.1
#2 0x0000fffff18234d8 in xcb_wait_for_event () at /lib64/libxcb.so.1
#3 0x0000ffffe3720d6c in QXcbEventQueue::run() () at /lib64/libQt6XcbQpa.so.6
#4 0x0000fffff71384f4 in QThreadPrivate::start(void*) () at /lib64/libQt6Core.so.6
#5 0x0000fffff56b6998 in start_thread () at /lib64/libc.so.6
#6 0x0000fffff572268c in thread_start () at /lib64/libc.so.6
Thread 2 (Thread 0xffffe300eec0 (LWP 31010) "QDBusConnection"):
#0 0x0000fffff57170c4 in ppoll () at /lib64/libc.so.6
#1 0x0000fffff4c84284 in g_main_context_iterate_unlocked.isra () at /lib64/libglib-2.0.so.0
#2 0x0000fffff4c22264 in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#3 0x0000fffff7272658 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt6Core.so.6
#4 0x0000fffff6f7f694 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt6Core.so.6
#5 0x0000fffff70a4c4c in QThread::exec() () at /lib64/libQt6Core.so.6
#6 0x0000fffff408d790 in QDBusConnectionManager::run() () at /lib64/libQt6DBus.so.6
#7 0x0000fffff71384f4 in QThreadPrivate::start(void*) () at /lib64/libQt6Core.so.6
#8 0x0000fffff56b6998 in start_thread () at /lib64/libc.so.6
#9 0x0000fffff572268c in thread_start () at /lib64/libc.so.6
Thread 1 (Thread 0xfffff7fb1020 (LWP 31007) "qcam"):
#0 0x0000fffff5722668 in __clone3 () at /lib64/libc.so.6
#1 0x0000fffff5722474 in __clone3_internal () at /lib64/libc.so.6
#2 0x0000fffff5722508 in __clone_internal () at /lib64/libc.so.6
#3 0x0000fffff56b6508 in create_thread () at /lib64/libc.so.6
#4 0x0000fffff56b6fec in pthread_create at GLIBC_2.17 () at /lib64/libc.so.6
#5 0x0000fffff7137d54 in QThread::start(QThread::Priority) () at /lib64/libQt6Core.so.6
#6 0x0000fffff71414f0 in QThreadPoolPrivate::startThread(QRunnable*) () at /lib64/libQt6Core.so.6
#7 0x0000fffff71428cc in QThreadPoolPrivate::tryStart(QRunnable*) () at /lib64/libQt6Core.so.6
#8 0x0000fffff7142e08 in QThreadPool::start(QRunnable*, int) () at /lib64/libQt6Core.so.6
#9 0x0000fffff6b2261c in blend_color_argb(int, QT_FT_Span_ const*, void*) () at /lib64/libQt6Gui.so.6
#10 0x0000fffff66b3628 in bool drawLine<&(drawPixel(QCosmeticStroker*, int, int, int)), (anonymous namespace)::NoDasher>(QCosmeticStroker*, double, double, double, double, int) () at /lib64/libQt6Gui.so.6
#11 0x0000fffff66b3ffc in QCosmeticStroker::drawLine(QPointF const&, QPointF const&) () at /lib64/libQt6Gui.so.6
#12 0x0000fffff66ec12c in QRasterPaintEngine::drawLines(QLine const*, int) () at /lib64/libQt6Gui.so.6
#13 0x0000fffff5e906f0 in QFusionStyle::drawControl(QStyle::ControlElement, QStyleOption const*, QPainter*, QWidget const*) const () at /lib64/libQt6Widgets.so.6
#14 0x0000fffff5fb2198 in QToolBar::paintEvent(QPaintEvent*) () at /lib64/libQt6Widgets.so.6
#15 0x0000fffff5dceecc in QWidget::event(QEvent*) () at /lib64/libQt6Widgets.so.6
#16 0x0000fffff5d6ea18 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt6Widgets.so.6
#17 0x0000fffff6f71d58 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib64/libQt6Core.so.6
#18 0x0000fffff5dc598c in QWidgetPrivate::sendPaintEvent(QRegion const&) () at /lib64/libQt6Widgets.so.6
--Type <RET> for more, q to quit, c to continue without paging--
#19 0x0000fffff5dc5e48 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, QFlags<QWidgetPrivate::DrawWidgetFlag>, QPainter*, QWidgetRepaintManager*) () at /lib64/libQt6Widgets.so.6
#20 0x0000fffff5dc714c in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, QFlags<QWidgetPrivate::DrawWidgetFlag>, QPainter*, QWidgetRepaintManager*) () at /lib64/libQt6Widgets.so.6
#21 0x0000fffff5dc7040 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, QFlags<QWidgetPrivate::DrawWidgetFlag>, QPainter*, QWidgetRepaintManager*) () at /lib64/libQt6Widgets.so.6
#22 0x0000fffff5dc5ccc in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, QFlags<QWidgetPrivate::DrawWidgetFlag>, QPainter*, QWidgetRepaintManager*) () at /lib64/libQt6Widgets.so.6
#23 0x0000fffff5ddb794 in QWidgetRepaintManager::paintAndFlush() () at /lib64/libQt6Widgets.so.6
#24 0x0000fffff5dcf64c in QWidget::event(QEvent*) () at /lib64/libQt6Widgets.so.6
#25 0x000000000043aff0 in MainWindow::event (this=0x7c3c20, e=0x7662e0) at ../../src/apps/qcam/main_window.cpp:177
#26 0x0000fffff5d6ea18 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt6Widgets.so.6
#27 0x0000fffff6f71d58 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /lib64/libQt6Core.so.6
#28 0x0000fffff6f76068 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () at /lib64/libQt6Core.so.6
#29 0x0000fffff7272fd4 in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () at /lib64/libQt6Core.so.6
#30 0x0000fffff4c20b94 in g_main_context_dispatch_unlocked.lto_priv () at /lib64/libglib-2.0.so.0
#31 0x0000fffff4c841d0 in g_main_context_iterate_unlocked.isra () at /lib64/libglib-2.0.so.0
#32 0x0000fffff4c22264 in g_main_context_iteration () at /lib64/libglib-2.0.so.0
#33 0x0000fffff7272658 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt6Core.so.6
#34 0x0000fffff6f7f694 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /lib64/libQt6Core.so.6
#35 0x0000fffff6f7ac3c in QCoreApplication::exec() () at /lib64/libQt6Core.so.6
#36 0x0000000000439ae4 in main (argc=1, argv=0xffffffffeed8) at ../../src/apps/qcam/main.cpp:87
--
Kieran
> ```
> [295:43:43.910237144] [1441841] INFO IPAManager ipa_manager.cpp:137 libcamera is not installed. Adding '/usr/local/google/home/chenghaoyang/Workspace/libca
> mera/build/src/ipa' to the IPA search path
> [295:43:43.914030564] [1441841] INFO Camera camera_manager.cpp:325 libcamera v0.3.1+79-8ca4f033-dirty (2024-08-29T19:18:51UTC)
> [295:43:43.915493754] [1441844] ERROR DmaBufAllocator dma_buf_allocator.cpp:120 Could not open any dma-buf provider
> [295:43:43.919118835] [1441841] INFO IPAManager ipa_manager.cpp:137 libcamera is not installed. Adding '/usr/local/google/home/chenghaoyang/Workspace/libca
> mera/build/src/ipa' to the IPA search path
> [295:43:43.922245825] [1441841] INFO Camera camera_manager.cpp:325 libcamera v0.3.1+79-8ca4f033-dirty (2024-08-29T19:18:51UTC)
> [295:43:43.922820175] [1441846] ERROR DmaBufAllocator dma_buf_allocator.cpp:120 Could not open any dma-buf provider
> Unable to set the pipeline to the playing state.
> ```
>
> Gitlab pipeline failure:
> https://gitlab.freedesktop.org/chenghaoyang/libcamera/-/pipelines/1260412
>
> Update in v11:
> - Allowed a single value in the config file's frame_rates field.
>
> Update in v10:
> Apply fixes according to Jacopo's and Barnabás' comments.
> - Split test_pattern and path fields in the yaml format.
> - Let FrameGenerators control frameCount_.
> - Fixed match() returning values.
>
> Update in v9: Allocate contiguous memory for planes in the same
> FrameBuffer.
>
> BR,
> Harvey
>
> Harvey Yang (4):
> libcamera: add DmaBufAllocator::exportBuffers()
> libcamera: Remove PipelineHandler Fatal check of non-empty
> MediaDevices
> libcamera: virtual: Add VirtualPipelineHandler
> libcamera: software_isp: Refactor SoftwareIsp to use
> DmaBufAllocator::exportBuffers
>
> Konami Shu (3):
> libcamera: pipeline: Add test pattern for VirtualPipelineHandler
> libcamera: virtual: Read config and register cameras based on the
> config
> libcamera: virtual: Add ImageFrameGenerator
>
> .../libcamera/internal/dma_buf_allocator.h | 13 +
> meson.build | 1 +
> meson_options.txt | 3 +-
> src/android/meson.build | 19 --
> src/libcamera/dma_buf_allocator.cpp | 55 +++
> src/libcamera/pipeline/virtual/README.md | 50 +++
> .../pipeline/virtual/data/virtual.yaml | 36 ++
> .../pipeline/virtual/frame_generator.h | 28 ++
> .../virtual/image_frame_generator.cpp | 178 ++++++++++
> .../pipeline/virtual/image_frame_generator.h | 54 +++
> src/libcamera/pipeline/virtual/meson.build | 13 +
> src/libcamera/pipeline/virtual/parser.cpp | 257 ++++++++++++++
> src/libcamera/pipeline/virtual/parser.h | 44 +++
> .../virtual/test_pattern_generator.cpp | 140 ++++++++
> .../pipeline/virtual/test_pattern_generator.h | 57 ++++
> src/libcamera/pipeline/virtual/utils.h | 17 +
> src/libcamera/pipeline/virtual/virtual.cpp | 323 ++++++++++++++++++
> src/libcamera/pipeline/virtual/virtual.h | 107 ++++++
> src/libcamera/pipeline_handler.cpp | 11 +-
> src/libcamera/software_isp/software_isp.cpp | 20 +-
> src/meson.build | 19 ++
> 21 files changed, 1403 insertions(+), 42 deletions(-)
> create mode 100644 src/libcamera/pipeline/virtual/README.md
> create mode 100644 src/libcamera/pipeline/virtual/data/virtual.yaml
> create mode 100644 src/libcamera/pipeline/virtual/frame_generator.h
> create mode 100644 src/libcamera/pipeline/virtual/image_frame_generator.cpp
> create mode 100644 src/libcamera/pipeline/virtual/image_frame_generator.h
> create mode 100644 src/libcamera/pipeline/virtual/meson.build
> create mode 100644 src/libcamera/pipeline/virtual/parser.cpp
> create mode 100644 src/libcamera/pipeline/virtual/parser.h
> create mode 100644 src/libcamera/pipeline/virtual/test_pattern_generator.cpp
> create mode 100644 src/libcamera/pipeline/virtual/test_pattern_generator.h
> create mode 100644 src/libcamera/pipeline/virtual/utils.h
> create mode 100644 src/libcamera/pipeline/virtual/virtual.cpp
> create mode 100644 src/libcamera/pipeline/virtual/virtual.h
>
> --
> 2.46.0.469.g59c65b2a67-goog
>
More information about the libcamera-devel
mailing list