[{"id":35618,"web_url":"https://patchwork.libcamera.org/comment/35618/","msgid":"<f2660468-fef4-4d99-b6ef-f279bdee20ae@collabora.com>","date":"2025-08-29T08:50:42","subject":"Re: [PATCH v2 12/37] libcamera: software_isp: Start the ISP thread\n\tin configure","submitter":{"id":140,"url":"https://patchwork.libcamera.org/api/people/140/","name":"Robert Mader","email":"robert.mader@collabora.com"},"content":"Hi,\n\nOn 24.08.25 02:48, Bryan O'Donoghue wrote:\n> EGL is not thread-safe and in fact associates invisible handles with the\n> threadid of the calling context.\n>\n> As a result we need to make Deabyer::configure() and Debayer::process() in SoftISP execute on\n> the same thread.\n>\n> When we call Debayer::configure() in the egl class this will setup and egl context\n> for us which is associated with the calling thread context. Hence when\n> Debayer::process(); runs it must run in the same thread as\n> Debayer::configure() or the hidden Gegl context handles will not point\n> to the same place.\n>\n> Move start thread into configure() as a first step towards this.\n>\n> Signed-off-by: Bryan O'Donoghue<bryan.odonoghue@linaro.org>\n> ---\n>   src/libcamera/software_isp/software_isp.cpp | 6 +++---\n>   1 file changed, 3 insertions(+), 3 deletions(-)\n>\n> diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\n> index 28e2a360e7e6d5071e7b97c2bffc60478d245a60..7bee8f0681dd5cedcd81950ed49f611b514e763d 100644\n> --- a/src/libcamera/software_isp/software_isp.cpp\n> +++ b/src/libcamera/software_isp/software_isp.cpp\n> @@ -159,8 +159,6 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n>   \t\t\t\t\t    metadataReady.emit(frame, metadata);\n>   \t\t\t\t    });\n>   \tipa_->setSensorControls.connect(this, &SoftwareIsp::setSensorCtrls);\n> -\n> -\tdebayer_->moveToThread(&ispWorkerThread_);\n>   }\n>   \n>   SoftwareIsp::~SoftwareIsp()\n> @@ -262,6 +260,9 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg,\n>   \tif (ret < 0)\n>   \t\treturn ret;\n>   \n> +\tdebayer_->moveToThread(&ispWorkerThread_);\n\nWhen testing with my OnePlus6 via Pipewire/Snapshot, I reliably hit an \nassert here whenever starting a camera for the second time. I.e. when \nswitching to another camera and back, or when closing Snapshot (or some \nother app) and starting it again I get the following crash/bt (every time):\n\n(gdb) bt\n#0  __restore_sigs (set=set@entry=0xffff8f465b40) at ./arch/aarch64/syscall_arch.h:48\n#1  0x0000ffff92e71e6c in raise (sig=sig@entry=6) at src/signal/raise.c:11\n#2  0x0000ffff92e40628 in abort () at src/exit/abort.c:11\n#3  0x0000ffff9195c244 in libcamera::LogMessage::~LogMessage (this=0xffff8f465c38) at ../src/libcamera/base/log.cpp:867\n#4  0x0000ffff91952348 in libcamera::Object::assertThreadBound (this=this@entry=0xffff8f4266a0, message=message@entry=0xffff91961638 \"Object can't be moved from another thread\") at ../src/libcamera/base/object.cpp:253\n#5  0x0000ffff91952864 in libcamera::Object::moveToThread (this=0xffff8f4266a0, thread=thread@entry=0xffff8f431750) at ../src/libcamera/base/object.cpp:308\n#6  0x0000ffff91ab78d4 in libcamera::SoftwareIsp::configure (this=0xffff8f431680, inputCfg=..., outputCfgs=..., configInfo=...) at ../src/libcamera/software_isp/software_isp.cpp:280\n#7  0x0000ffff91a93564 in libcamera::SimplePipelineHandler::configure (this=<optimized out>, camera=<optimized out>, c=<optimized out>) at /usr/include/c++/15.2.0/bits/unique_ptr.h:193\n#8  0x0000ffff91a17620 in libcamera::BoundMethodArgs<int, libcamera::Camera*, libcamera::CameraConfiguration*>::invokePack<0ul, 1ul> (this=<optimized out>, pack=0xffff85436b20) at ../include/libcamera/base/bound_method.h:100\n#9  libcamera::BoundMethodArgs<int, libcamera::Camera*, libcamera::CameraConfiguration*>::invokePack (this=<optimized out>, pack=0xffff85436b20) at ../include/libcamera/base/bound_method.h:111\n#10 0x0000ffff91951ff8 in libcamera::Object::message (this=<optimized out>, msg=<optimized out>) at ../src/libcamera/base/object.cpp:211\n#11 libcamera::Object::message (this=<optimized out>, msg=<optimized out>) at ../src/libcamera/base/object.cpp:201\n#12 0x0000ffff9195e13c in libcamera::Thread::dispatchMessages (this=0xffff91b4fb70, type=type@entry=libcamera::Message::None, receiver=receiver@entry=0x0) at ../src/libcamera/base/thread.cpp:654\n#13 0x0000ffff9195625c in libcamera::EventDispatcherPoll::processEvents (this=0xffff91e02780) at ../src/libcamera/base/event_dispatcher_poll.cpp:146\n#14 0x0000ffff9195d928 in libcamera::Thread::exec (this=this@entry=0xffff91b4fb70) at ../src/libcamera/base/thread.cpp:311\n#15 0x0000ffff91a1a940 in libcamera::CameraManager::Private::run (this=0xffff91b4fb60) at ../src/libcamera/camera_manager.cpp:89\n#16 0x0000ffff916f557c in ?? () from /usr/lib/libstdc++.so.6\n#17 0x0000ffff92e82534 in start (p=0xffff8f466dd0) at src/thread/pthread_create.c:207\n#18 0x0000ffff92e8092c in __clone () at src/thread/aarch64/clone.s:28\n\nand the logs\n\nERROR Object object.cpp:252 Object can't be moved from another thread\nFATAL default object.cpp:253 assertion \"false\" failed in assertThreadBound()\n\nGiven that this is common code this applies independently of whether\n\nLIBCAMERA_SOFTISP_MODE=gpu\n\nis set.\n\n> +\tispWorkerThread_.start();\n> +\n>   \treturn debayer_->configure(inputCfg, outputCfgs, ccmEnabled_);\n>   }\n>   \n> @@ -343,7 +344,6 @@ int SoftwareIsp::start()\n>   \tif (ret)\n>   \t\treturn ret;\n>   \n> -\tispWorkerThread_.start();\n>   \treturn 0;\n>   }\n>   \n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id BA2A0BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 29 Aug 2025 08:50:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BBBCE6931A;\n\tFri, 29 Aug 2025 10:50:50 +0200 (CEST)","from sender4-op-o12.zoho.com (sender4-op-o12.zoho.com\n\t[136.143.188.12])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CD32E692DF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 29 Aug 2025 10:50:48 +0200 (CEST)","by mx.zohomail.com with SMTPS id 1756457444505870.3531323457801;\n\tFri, 29 Aug 2025 01:50:44 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=collabora.com\n\theader.i=robert.mader@collabora.com header.b=\"JgrV3zyl\"; \n\tdkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1756457446; cv=none; \n\td=zohomail.com; s=zohoarc; \n\tb=bpLiyE23gHYHEu9ppzSu+aJdTYgZX4jLtjJCyqtcH1uVeIDBf1IDqu7aoqclMe5pA8fLPuueraEUxI1C5ElqBomCp6w/+ClIPQLGZPXQ8EtDp5gpo/DUO5lxyWpUWGALHli9xNLXsRJ3BSL0Gpcoh8d0tWXWdZgwlKufMjQhdCE=","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; \n\ts=zohoarc; t=1756457446;\n\th=Content-Type:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To:Cc;\n\tbh=ODBFsjGtDEQ8XaBEB3DIK65VeSnCZsNqae6uWs9Azv8=; \n\tb=O+PdjcHYpgX9NJJ0mByMHp0L0jdlPpHlcd2doLkeAp+PeXJp12WDujO69rO90xrgAB04/QtLCNQ6j06eFwVqkKNDOL7eNHIToA8bqJaqDiMRfFMEqPkXtRFGJxPLb9jz/pIOK4bQ2iW3RLHvyxiCwdjJM39FPygAcM1/xpSRoJs=","ARC-Authentication-Results":"i=1; mx.zohomail.com;\n\tdkim=pass  header.i=collabora.com;\n\tspf=pass  smtp.mailfrom=robert.mader@collabora.com;\n\tdmarc=pass header.from=<robert.mader@collabora.com>","DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1756457446;\n\ts=zohomail; d=collabora.com; i=robert.mader@collabora.com;\n\th=Content-Type:Message-ID:Date:Date:MIME-Version:Subject:Subject:To:To:References:From:From:In-Reply-To:Message-Id:Reply-To:Cc;\n\tbh=ODBFsjGtDEQ8XaBEB3DIK65VeSnCZsNqae6uWs9Azv8=;\n\tb=JgrV3zylJMnqtwttVbztWuJAYMoZNbNGZThx0p/hvjlZUxrtPS2eRqA9MhfKjkUi\n\tgTzlDx8sSbpD82eBimGu1OtznMJUzr7PTPiuZWjpThcAzkfzFve83EqOF0sFLOhYrLD\n\tL2Davi4/9Fp/h6FjtOvyGizKrEt5AweDOe7anTZc=","Content-Type":"multipart/alternative;\n\tboundary=\"------------UjoGoWrrUBFVCl9ZeOncW5XM\"","Message-ID":"<f2660468-fef4-4d99-b6ef-f279bdee20ae@collabora.com>","Date":"Fri, 29 Aug 2025 10:50:42 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2 12/37] libcamera: software_isp: Start the ISP thread\n\tin configure","To":"libcamera-devel@lists.libcamera.org","References":"<20250824-b4-v0-5-2-gpuisp-v2-a-v2-0-96f4576c814e@linaro.org>\n\t<20250824-b4-v0-5-2-gpuisp-v2-a-v2-12-96f4576c814e@linaro.org>","Content-Language":"en-US, de-DE","From":"Robert Mader <robert.mader@collabora.com>","In-Reply-To":"<20250824-b4-v0-5-2-gpuisp-v2-a-v2-12-96f4576c814e@linaro.org>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35619,"web_url":"https://patchwork.libcamera.org/comment/35619/","msgid":"<449281d9-b0ea-4b00-a6fc-57ec7ee50d44@ideasonboard.com>","date":"2025-08-29T09:03:34","subject":"Re: [PATCH v2 12/37] libcamera: software_isp: Start the ISP thread\n\tin configure","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2025. 08. 29. 10:50 keltezéssel, Robert Mader írta:\n> Hi,\n> \n> On 24.08.25 02:48, Bryan O'Donoghue wrote:\n>> EGL is not thread-safe and in fact associates invisible handles with the\n>> threadid of the calling context.\n>>\n>> As a result we need to make Deabyer::configure() and Debayer::process() in SoftISP execute on\n>> the same thread.\n>>\n>> When we call Debayer::configure() in the egl class this will setup and egl context\n>> for us which is associated with the calling thread context. Hence when\n>> Debayer::process(); runs it must run in the same thread as\n>> Debayer::configure() or the hidden Gegl context handles will not point\n>> to the same place.\n>>\n>> Move start thread into configure() as a first step towards this.\n>>\n>> Signed-off-by: Bryan O'Donoghue<bryan.odonoghue@linaro.org>\n>> ---\n>>   src/libcamera/software_isp/software_isp.cpp | 6 +++---\n>>   1 file changed, 3 insertions(+), 3 deletions(-)\n>>\n>> diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\n>> index 28e2a360e7e6d5071e7b97c2bffc60478d245a60..7bee8f0681dd5cedcd81950ed49f611b514e763d 100644\n>> --- a/src/libcamera/software_isp/software_isp.cpp\n>> +++ b/src/libcamera/software_isp/software_isp.cpp\n>> @@ -159,8 +159,6 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n>>   \t\t\t\t\t    metadataReady.emit(frame, metadata);\n>>   \t\t\t\t    });\n>>   \tipa_->setSensorControls.connect(this, &SoftwareIsp::setSensorCtrls);\n>> -\n>> -\tdebayer_->moveToThread(&ispWorkerThread_);\n>>   }\n>>\n>>   SoftwareIsp::~SoftwareIsp()\n>> @@ -262,6 +260,9 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg,\n>>   \tif (ret < 0)\n>>   \t\treturn ret;\n>>\n>> +\tdebayer_->moveToThread(&ispWorkerThread_);\n> \n> When testing with my OnePlus6 via Pipewire/Snapshot, I reliably hit an assert here whenever starting a camera for the second time. I.e. when switching to another camera and back, or when closing Snapshot (or some other app) and starting it again I get the following crash/bt (every time):\n> \n> (gdb) bt\n> #0  __restore_sigs (set=set@entry=0xffff8f465b40) at ./arch/aarch64/syscall_arch.h:48\n> #1  0x0000ffff92e71e6c in raise (sig=sig@entry=6) at src/signal/raise.c:11\n> #2  0x0000ffff92e40628 in abort () at src/exit/abort.c:11\n> #3  0x0000ffff9195c244 in libcamera::LogMessage::~LogMessage (this=0xffff8f465c38) at ../src/libcamera/base/log.cpp:867\n> #4  0x0000ffff91952348 in libcamera::Object::assertThreadBound (this=this@entry=0xffff8f4266a0, message=message@entry=0xffff91961638 \"Object can't be moved from another thread\") at ../src/libcamera/base/object.cpp:253\n> #5  0x0000ffff91952864 in libcamera::Object::moveToThread (this=0xffff8f4266a0, thread=thread@entry=0xffff8f431750) at ../src/libcamera/base/object.cpp:308\n> #6  0x0000ffff91ab78d4 in libcamera::SoftwareIsp::configure (this=0xffff8f431680, inputCfg=..., outputCfgs=..., configInfo=...) at ../src/libcamera/software_isp/software_isp.cpp:280\n> #7  0x0000ffff91a93564 in libcamera::SimplePipelineHandler::configure (this=<optimized out>, camera=<optimized out>, c=<optimized out>) at /usr/include/c++/15.2.0/bits/unique_ptr.h:193\n> #8  0x0000ffff91a17620 in libcamera::BoundMethodArgs<int, libcamera::Camera*, libcamera::CameraConfiguration*>::invokePack<0ul, 1ul> (this=<optimized out>, pack=0xffff85436b20) at ../include/libcamera/base/bound_method.h:100\n> #9  libcamera::BoundMethodArgs<int, libcamera::Camera*, libcamera::CameraConfiguration*>::invokePack (this=<optimized out>, pack=0xffff85436b20) at ../include/libcamera/base/bound_method.h:111\n> #10 0x0000ffff91951ff8 in libcamera::Object::message (this=<optimized out>, msg=<optimized out>) at ../src/libcamera/base/object.cpp:211\n> #11 libcamera::Object::message (this=<optimized out>, msg=<optimized out>) at ../src/libcamera/base/object.cpp:201\n> #12 0x0000ffff9195e13c in libcamera::Thread::dispatchMessages (this=0xffff91b4fb70, type=type@entry=libcamera::Message::None, receiver=receiver@entry=0x0) at ../src/libcamera/base/thread.cpp:654\n> #13 0x0000ffff9195625c in libcamera::EventDispatcherPoll::processEvents (this=0xffff91e02780) at ../src/libcamera/base/event_dispatcher_poll.cpp:146\n> #14 0x0000ffff9195d928 in libcamera::Thread::exec (this=this@entry=0xffff91b4fb70) at ../src/libcamera/base/thread.cpp:311\n> #15 0x0000ffff91a1a940 in libcamera::CameraManager::Private::run (this=0xffff91b4fb60) at ../src/libcamera/camera_manager.cpp:89\n> #16 0x0000ffff916f557c in ?? () from /usr/lib/libstdc++.so.6\n> #17 0x0000ffff92e82534 in start (p=0xffff8f466dd0) at src/thread/pthread_create.c:207\n> #18 0x0000ffff92e8092c in __clone () at src/thread/aarch64/clone.s:28\n> \n> and the logs\n> \n> ERROR Object object.cpp:252 Object can't be moved from another thread\n> FATAL default object.cpp:253 assertion \"false\" failed in assertThreadBound()\n\nA thread can only be moved from its current thread. So the when this code runs\nthe second time, `*debayer_` object is already on `ispWorkerThread_`, which is\nnot the current thread, hence the assertion.\n\nIt's not clear to me why moving the object in the constructor is not sufficient, I think\njust adding `ispWorkerThread_.start()` in `SoftwareIsp::configure()` should be sufficient.\nRemoving it from `SoftwareIsp::start()` is also not quite right because then a\nconfigure-start-stop-start-stop sequence won't work as expected as far as I can tell.\nOr maybe the thread can be started in the constructor and kept running.\n\n\nRegards,\nBarnabás Pőcze\n\n\n> \n> Given that this is common code this applies independently of whether\n> \n> LIBCAMERA_SOFTISP_MODE=gpu\n> \n> is set.\n> \n>> +\tispWorkerThread_.start();\n>> +\n>>   \treturn debayer_->configure(inputCfg, outputCfgs, ccmEnabled_);\n>>   }\n>>\n>> @@ -343,7 +344,6 @@ int SoftwareIsp::start()\n>>   \tif (ret)\n>>   \t\treturn ret;\n>>\n>> -\tispWorkerThread_.start();\n>>   \treturn 0;\n>>   }\n>>\n>>\n> --\n> Robert Mader\n> Consultant Software Developer\n> \n> Collabora Ltd.\n> Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK\n> Registered in England & Wales, no. 5513718\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 7B2E3BEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 29 Aug 2025 09:03:42 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D76966931A;\n\tFri, 29 Aug 2025 11:03:40 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3C4E4692DF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 29 Aug 2025 11:03:39 +0200 (CEST)","from [192.168.33.19] (185.221.143.232.nat.pool.zt.hu\n\t[185.221.143.232])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id CB5224B31;\n\tFri, 29 Aug 2025 11:02:33 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"WM5zOO5O\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1756458153;\n\tbh=RhNtvvE1EFzpb1RE6mFseKhJLuMu6IHnyFhT8rd0Euk=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=WM5zOO5OqrbXvJO4Gegx0eyvKej8dezezp6AWPx3NuBV/eXnNlG1wnvqeNKU+BuQZ\n\todZG1cTR34lr2oTLBodIMxRn/3ygOEkQQS9EbC4nxOjSrFiZdqquEp3LeMap/Y67fa\n\tbBquKtQZYQtftnBAtwLjmsdyvn55UzVKQmTPWYm0=","Message-ID":"<449281d9-b0ea-4b00-a6fc-57ec7ee50d44@ideasonboard.com>","Date":"Fri, 29 Aug 2025 11:03:34 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2 12/37] libcamera: software_isp: Start the ISP thread\n\tin configure","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20250824-b4-v0-5-2-gpuisp-v2-a-v2-0-96f4576c814e@linaro.org>\n\t<20250824-b4-v0-5-2-gpuisp-v2-a-v2-12-96f4576c814e@linaro.org>\n\t<VSNaYnMAU411VXykI7q9JTjOP9Ui_mLOwi2WBYI1ufm4T031qwxUK74_SI_I5MYy5rbG0ArW75C8VYiqQMPZTw==@protonmail.internalid>\n\t<f2660468-fef4-4d99-b6ef-f279bdee20ae@collabora.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<f2660468-fef4-4d99-b6ef-f279bdee20ae@collabora.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":35783,"web_url":"https://patchwork.libcamera.org/comment/35783/","msgid":"<b5430dac-55b1-4e74-a943-26589847777a@collabora.com>","date":"2025-09-11T13:09:17","subject":"Re: [PATCH v2 12/37] libcamera: software_isp: Start the ISP thread\n\tin configure","submitter":{"id":140,"url":"https://patchwork.libcamera.org/api/people/140/","name":"Robert Mader","email":"robert.mader@collabora.com"},"content":"On 29.08.25 11:03, Barnabás Pőcze wrote:\n> 2025. 08. 29. 10:50 keltezéssel, Robert Mader írta:\n>> Hi,\n>>\n>> On 24.08.25 02:48, Bryan O'Donoghue wrote:\n>>> EGL is not thread-safe and in fact associates invisible handles with \n>>> the\n>>> threadid of the calling context.\n>>>\n>>> As a result we need to make Deabyer::configure() and \n>>> Debayer::process() in SoftISP execute on\n>>> the same thread.\n>>>\n>>> When we call Debayer::configure() in the egl class this will setup \n>>> and egl context\n>>> for us which is associated with the calling thread context. Hence when\n>>> Debayer::process(); runs it must run in the same thread as\n>>> Debayer::configure() or the hidden Gegl context handles will not point\n>>> to the same place.\n>>>\n>>> Move start thread into configure() as a first step towards this.\n>>>\n>>> Signed-off-by: Bryan O'Donoghue<bryan.odonoghue@linaro.org>\n>>> ---\n>>>   src/libcamera/software_isp/software_isp.cpp | 6 +++---\n>>>   1 file changed, 3 insertions(+), 3 deletions(-)\n>>>\n>>> diff --git a/src/libcamera/software_isp/software_isp.cpp \n>>> b/src/libcamera/software_isp/software_isp.cpp\n>>> index \n>>> 28e2a360e7e6d5071e7b97c2bffc60478d245a60..7bee8f0681dd5cedcd81950ed49f611b514e763d \n>>> 100644\n>>> --- a/src/libcamera/software_isp/software_isp.cpp\n>>> +++ b/src/libcamera/software_isp/software_isp.cpp\n>>> @@ -159,8 +159,6 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, \n>>> const CameraSensor *sensor,\n>>>                           metadataReady.emit(frame, metadata);\n>>>                       });\n>>>       ipa_->setSensorControls.connect(this, \n>>> &SoftwareIsp::setSensorCtrls);\n>>> -\n>>> -    debayer_->moveToThread(&ispWorkerThread_);\n>>>   }\n>>>\n>>>   SoftwareIsp::~SoftwareIsp()\n>>> @@ -262,6 +260,9 @@ int SoftwareIsp::configure(const \n>>> StreamConfiguration &inputCfg,\n>>>       if (ret < 0)\n>>>           return ret;\n>>>\n>>> +    debayer_->moveToThread(&ispWorkerThread_);\n>>\n>> When testing with my OnePlus6 via Pipewire/Snapshot, I reliably hit \n>> an assert here whenever starting a camera for the second time. I.e. \n>> when switching to another camera and back, or when closing Snapshot \n>> (or some other app) and starting it again I get the following \n>> crash/bt (every time):\n>>\n>> (gdb) bt\n>> #0  __restore_sigs (set=set@entry=0xffff8f465b40) at \n>> ./arch/aarch64/syscall_arch.h:48\n>> #1  0x0000ffff92e71e6c in raise (sig=sig@entry=6) at \n>> src/signal/raise.c:11\n>> #2  0x0000ffff92e40628 in abort () at src/exit/abort.c:11\n>> #3  0x0000ffff9195c244 in libcamera::LogMessage::~LogMessage \n>> (this=0xffff8f465c38) at ../src/libcamera/base/log.cpp:867\n>> #4  0x0000ffff91952348 in libcamera::Object::assertThreadBound \n>> (this=this@entry=0xffff8f4266a0, message=message@entry=0xffff91961638 \n>> \"Object can't be moved from another thread\") at \n>> ../src/libcamera/base/object.cpp:253\n>> #5  0x0000ffff91952864 in libcamera::Object::moveToThread \n>> (this=0xffff8f4266a0, thread=thread@entry=0xffff8f431750) at \n>> ../src/libcamera/base/object.cpp:308\n>> #6  0x0000ffff91ab78d4 in libcamera::SoftwareIsp::configure \n>> (this=0xffff8f431680, inputCfg=..., outputCfgs=..., configInfo=...) \n>> at ../src/libcamera/software_isp/software_isp.cpp:280\n>> #7  0x0000ffff91a93564 in libcamera::SimplePipelineHandler::configure \n>> (this=<optimized out>, camera=<optimized out>, c=<optimized out>) at \n>> /usr/include/c++/15.2.0/bits/unique_ptr.h:193\n>> #8  0x0000ffff91a17620 in libcamera::BoundMethodArgs<int, \n>> libcamera::Camera*, libcamera::CameraConfiguration*>::invokePack<0ul, \n>> 1ul> (this=<optimized out>, pack=0xffff85436b20) at \n>> ../include/libcamera/base/bound_method.h:100\n>> #9  libcamera::BoundMethodArgs<int, libcamera::Camera*, \n>> libcamera::CameraConfiguration*>::invokePack (this=<optimized out>, \n>> pack=0xffff85436b20) at ../include/libcamera/base/bound_method.h:111\n>> #10 0x0000ffff91951ff8 in libcamera::Object::message (this=<optimized \n>> out>, msg=<optimized out>) at ../src/libcamera/base/object.cpp:211\n>> #11 libcamera::Object::message (this=<optimized out>, msg=<optimized \n>> out>) at ../src/libcamera/base/object.cpp:201\n>> #12 0x0000ffff9195e13c in libcamera::Thread::dispatchMessages \n>> (this=0xffff91b4fb70, type=type@entry=libcamera::Message::None, \n>> receiver=receiver@entry=0x0) at ../src/libcamera/base/thread.cpp:654\n>> #13 0x0000ffff9195625c in \n>> libcamera::EventDispatcherPoll::processEvents (this=0xffff91e02780) \n>> at ../src/libcamera/base/event_dispatcher_poll.cpp:146\n>> #14 0x0000ffff9195d928 in libcamera::Thread::exec \n>> (this=this@entry=0xffff91b4fb70) at ../src/libcamera/base/thread.cpp:311\n>> #15 0x0000ffff91a1a940 in libcamera::CameraManager::Private::run \n>> (this=0xffff91b4fb60) at ../src/libcamera/camera_manager.cpp:89\n>> #16 0x0000ffff916f557c in ?? () from /usr/lib/libstdc++.so.6\n>> #17 0x0000ffff92e82534 in start (p=0xffff8f466dd0) at \n>> src/thread/pthread_create.c:207\n>> #18 0x0000ffff92e8092c in __clone () at src/thread/aarch64/clone.s:28\n>>\n>> and the logs\n>>\n>> ERROR Object object.cpp:252 Object can't be moved from another thread\n>> FATAL default object.cpp:253 assertion \"false\" failed in \n>> assertThreadBound()\n>\n> A thread can only be moved from its current thread. So the when this \n> code runs\n> the second time, `*debayer_` object is already on `ispWorkerThread_`, \n> which is\n> not the current thread, hence the assertion.\n>\n> It's not clear to me why moving the object in the constructor is not \n> sufficient, I think\n> just adding `ispWorkerThread_.start()` in `SoftwareIsp::configure()` \n> should be sufficient.\n> Removing it from `SoftwareIsp::start()` is also not quite right \n> because then a\n> configure-start-stop-start-stop sequence won't work as expected as far \n> as I can tell.\n> Or maybe the thread can be started in the constructor and kept running.\n\nI had another look and can confirm that moving\n\ndebayer_->moveToThread(&ispWorkerThread_);\n\nback to the constructor (leaving `ispWorkerThread_.start();` and the \nlater added `debayer_->invokeMethod()` in place) solves the issue here \nand makes the branch run pretty robust for me.\n\nRegarding the described sequence: I guess another option could be to \ncall `ispWorkerThread_.start();` in both `configure()` and `start()` as \nrepeated calls get ignored. IIUC that should only have negative \nconsequences - in the form of minor wasted resources -  if a successfull \n`configure()` is never followed up with a `start()`.\n\nP.S.: I added a fixup commit to \nhttps://gitlab.freedesktop.org/rmader/libcamera/-/commits/gpuisp-v2-buffer-import \nin case anybody wants to try this with PW.\n\nP.S.S.: on a Librem5 - when combined with upcoming PW, GTK, Snapshot, \nMesa and forcing on GLES 3.0 - this can almost rival Millipixels \nperformance wise already - really really cool!\n\nRegards,\n\nRobert\n\n>\n> Regards,\n> Barnabás Pőcze\n>\n>\n>>\n>> Given that this is common code this applies independently of whether\n>>\n>> LIBCAMERA_SOFTISP_MODE=gpu\n>>\n>> is set.\n>>\n>>> +    ispWorkerThread_.start();\n>>> +\n>>>       return debayer_->configure(inputCfg, outputCfgs, ccmEnabled_);\n>>>   }\n>>>\n>>> @@ -343,7 +344,6 @@ int SoftwareIsp::start()\n>>>       if (ret)\n>>>           return ret;\n>>>\n>>> -    ispWorkerThread_.start();\n>>>       return 0;\n>>>   }\n>>>\n>>>\n>> -- \n>> Robert Mader\n>> Consultant Software Developer\n>>\n>> Collabora Ltd.\n>> Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK\n>> Registered in England & Wales, no. 5513718\n>>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 1A3E2BDB13\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 11 Sep 2025 13:09:29 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 207EF69371;\n\tThu, 11 Sep 2025 15:09:28 +0200 (CEST)","from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com\n\t[136.143.188.112])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BC91969339\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 11 Sep 2025 15:09:26 +0200 (CEST)","by mx.zohomail.com with SMTPS id 1757596161403663.4625003503721;\n\tThu, 11 Sep 2025 06:09:21 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=collabora.com\n\theader.i=robert.mader@collabora.com header.b=\"YWmnoHcU\"; \n\tdkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1757596162; cv=none; \n\td=zohomail.com; s=zohoarc; \n\tb=MVgfoZJJZpS0gHRk3RSdWhvSzSlx7XnZTHzhNuKMAU7kWmjFNVTaAV3WpPZ8B0HsHDBAHAF9hB5X5pp3S7FyUWefgcRcWYo3EtpbVqQNIWQB2GE5B1u1Fh3v+MbkQ8nrYeCmkmofXIz0lILfwWoVKYNqnrvGwM1/trOiXTdQjy8=","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; \n\ts=zohoarc; t=1757596162;\n\th=Content-Type:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To:Cc;\n\tbh=Cz71iO3FHkwiIVH3yqGA2T7S2PNXmyIdUJ3bUGSJ66w=; \n\tb=Xi40UVv7BvQkwYDA1ZKUSy4JFPjGlj+BNe7HeliFq1D1oLdgGPiE6RhiPfEh4yZBSunRWk8nTdmnQcdS82uCYGM5WND375nv4TWxHXR8sXP4FSi7t3ZsVfOEladDyHRdGZ9qJ2CvoG/Vi7CV7r0A/BV1mPA/IBzIyLiK2ffegQk=","ARC-Authentication-Results":"i=1; mx.zohomail.com;\n\tdkim=pass  header.i=collabora.com;\n\tspf=pass  smtp.mailfrom=robert.mader@collabora.com;\n\tdmarc=pass header.from=<robert.mader@collabora.com>","DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1757596162;\n\ts=zohomail; d=collabora.com; i=robert.mader@collabora.com;\n\th=Content-Type:Message-ID:Date:Date:MIME-Version:Subject:Subject:To:To:References:From:From:In-Reply-To:Message-Id:Reply-To:Cc;\n\tbh=Cz71iO3FHkwiIVH3yqGA2T7S2PNXmyIdUJ3bUGSJ66w=;\n\tb=YWmnoHcUf6p/WGTSF+0IDdNqOT8Nj6xFvZIrrpxiCHxdtiS8rC7L/4+j7MRuQgK+\n\t9grLj4GUGdJuSDW2FVBJUUAknE1Yc/bzB1jynZbGvWR/NdGOXYxeHyUe4hGrXHiU79z\n\twf0dw2FFFf+J5/F5wNSzRzqdSAlcDLihIp4JPq3k=","Content-Type":"multipart/alternative;\n\tboundary=\"------------xcqluwMyOHsFdjOJ8Isb0TeT\"","Message-ID":"<b5430dac-55b1-4e74-a943-26589847777a@collabora.com>","Date":"Thu, 11 Sep 2025 15:09:17 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2 12/37] libcamera: software_isp: Start the ISP thread\n\tin configure","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20250824-b4-v0-5-2-gpuisp-v2-a-v2-0-96f4576c814e@linaro.org>\n\t<20250824-b4-v0-5-2-gpuisp-v2-a-v2-12-96f4576c814e@linaro.org>\n\t<VSNaYnMAU411VXykI7q9JTjOP9Ui_mLOwi2WBYI1ufm4T031qwxUK74_SI_I5MYy5rbG0ArW75C8VYiqQMPZTw==@protonmail.internalid>\n\t<f2660468-fef4-4d99-b6ef-f279bdee20ae@collabora.com>\n\t<449281d9-b0ea-4b00-a6fc-57ec7ee50d44@ideasonboard.com>","Content-Language":"en-US, de-DE","From":"Robert Mader <robert.mader@collabora.com>","In-Reply-To":"<449281d9-b0ea-4b00-a6fc-57ec7ee50d44@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":36125,"web_url":"https://patchwork.libcamera.org/comment/36125/","msgid":"<97b68ec2-7b70-473d-8200-0163f0381fc8@nxsw.ie>","date":"2025-10-04T14:54:11","subject":"Re: [PATCH v2 12/37] libcamera: software_isp: Start the ISP thread\n\tin configure","submitter":{"id":226,"url":"https://patchwork.libcamera.org/api/people/226/","name":"Bryan O'Donoghue","email":"bod.linux@nxsw.ie"},"content":"On 11/09/2025 14:09, Robert Mader wrote:\n> P.S.: I added a fixup commit to https://gitlab.freedesktop.org/rmader/ \n> libcamera/-/commits/gpuisp-v2-buffer-import in case anybody wants to try \n> this with PW.\n\nI took this fix and squashed it into the relevant patch - adding you as \nCo-developed-by and Signed-off-by.\n\n---\nbod","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 31C12C324C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat,  4 Oct 2025 14:54:19 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id EE8A86B5F3;\n\tSat,  4 Oct 2025 16:54:17 +0200 (CEST)","from sea.source.kernel.org (sea.source.kernel.org [172.234.252.31])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 18DFD613AB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat,  4 Oct 2025 16:54:16 +0200 (CEST)","from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58])\n\tby sea.source.kernel.org (Postfix) with ESMTP id 40E5842148;\n\tSat,  4 Oct 2025 14:54:14 +0000 (UTC)","by smtp.kernel.org (Postfix) with ESMTPSA id 463F4C4CEF1;\n\tSat,  4 Oct 2025 14:54:13 +0000 (UTC)"],"Message-ID":"<97b68ec2-7b70-473d-8200-0163f0381fc8@nxsw.ie>","Date":"Sat, 4 Oct 2025 15:54:11 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2 12/37] libcamera: software_isp: Start the ISP thread\n\tin configure","To":"Robert Mader <robert.mader@collabora.com>, =?utf-8?q?Barnab=C3=A1s_P?=\n\t=?utf-8?b?xZFjemU=?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20250824-b4-v0-5-2-gpuisp-v2-a-v2-0-96f4576c814e@linaro.org>\n\t<20250824-b4-v0-5-2-gpuisp-v2-a-v2-12-96f4576c814e@linaro.org>\n\t<VSNaYnMAU411VXykI7q9JTjOP9Ui_mLOwi2WBYI1ufm4T031qwxUK74_SI_I5MYy5rbG0ArW75C8VYiqQMPZTw==@protonmail.internalid>\n\t<f2660468-fef4-4d99-b6ef-f279bdee20ae@collabora.com>\n\t<449281d9-b0ea-4b00-a6fc-57ec7ee50d44@ideasonboard.com>\n\t<aZyWsa-wo7qCkvE5Sp2D5e21Gg9eiqM48YFjiGbnUJaCeIC8b4Km6E6dSvw-5XrlPIIdv1-lnE2F5gNqqSofJg==@protonmail.internalid>\n\t<b5430dac-55b1-4e74-a943-26589847777a@collabora.com>","From":"Bryan O'Donoghue <bod.linux@nxsw.ie>","Content-Language":"en-US","In-Reply-To":"<b5430dac-55b1-4e74-a943-26589847777a@collabora.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]