[PATCH v11 0/7] Add VirtualPipelineHandler
Cheng-Hao Yang
chenghaoyang at chromium.org
Mon Sep 9 16:11:35 CEST 2024
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 at 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 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
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20240909/a9151762/attachment.htm>
More information about the libcamera-devel
mailing list