[v11,0/7] Add VirtualPipelineHandler
mbox series

Message ID 20240907143110.2210711-1-chenghaoyang@google.com
Headers show
Series
  • Add VirtualPipelineHandler
Related show

Message

Cheng-Hao Yang Sept. 7, 2024, 2:28 p.m. UTC
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:
```
[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

Comments

Kieran Bingham Sept. 9, 2024, 12:45 p.m. UTC | #1
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@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
>
Cheng-Hao Yang Sept. 9, 2024, 2:11 p.m. UTC | #2
Thanks for the catch Kieran!

It's due to a bug in VirtualPipelineHandler::configure [1]:
I used `data->streamConfigs_[i].stream.configuration()`
before it's set in `Camera::configure()`. Should be using
`CameraConfiguration[i].configuration()` directly.
Will be fixed in v12.

[1]: https://patchwork.libcamera.org/patch/21196/

On Mon, Sep 9, 2024 at 8:45 PM Kieran Bingham <
kieran.bingham@ideasonboard.com> wrote:

> 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@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
> >
>