[libcamera-devel] [PATCH] libcamera: Allow concurrent use of cameras from same pipeline handler

Kieran Bingham kieran.bingham at ideasonboard.com
Wed Aug 10 23:22:13 CEST 2022


Quoting Laurent Pinchart (2022-08-10 18:11:19)
> Hi Kieran,
> 
> On Wed, Aug 10, 2022 at 05:55:04PM +0100, Kieran Bingham wrote:
> > Quoting David Plowman (2022-08-10 16:24:55)
> > > On Wed, 10 Aug 2022 at 16:07, Kieran Bingham wrote:
> > > > Quoting Laurent Pinchart (2022-07-21 22:03:51)
> > > > > libcamera implements a pipeline handler locking mechanism based on
> > > > > advisory locks on media devices, to prevent concurrent access to cameras
> > > > > from the same pipeline handler from different processes (this only works
> > > > > between multiple libcamera instances, as other processes won't use
> > > > > advisory locks on media devices).
> > > > >
> > > > > A side effect of the implementation prevents multiple cameras created by
> > > > > the same pipeline handler from being used concurrently. Fix this by
> > > > > turning the PipelineHandler lock() and unlock() functions into acquire()
> > > > > and release(), with a use count to replace the boolean lock flag. The
> > > > > Camera class is updated accordingly.
> > > > >
> > > > > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > > > > ---
> > > > > This may help addressing the problem reported in "[RFC PATCH] qcam: Fix
> > > > > IPU3 camera switching".
> > > >
> > > > This does indeed fix things for me on IPU3 testing with qcam.
> > > > It however seemed to introduce a regression in CTS (which perhaps
> > > > Harvey's patches will then resolve)
> > 
> > I've re-run this through CTS, and the regression is (unsurprisingly):
> > 
> >  android.hardware.camera2.cts.MultiViewTest#testDualCameraPreview
> > 
> >  android.hardware.camera2.CameraAccessException: CAMERA_ERROR (3): endConfigure:513: Camera 1: Error configuring streams: Function not implemented (-38)
> >       at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:810)
> >       at android.hardware.camera2.impl.ICameraDeviceUserWrapper.endConfigure(ICameraDeviceUserWrapper.java:115)
> >       at android.hardware.camera2.impl.CameraDeviceImpl.configureStreamsChecked(CameraDeviceImpl.java:480)
> >       at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSessionInternal(CameraDeviceImpl.java:680)
> >       at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSession(CameraDeviceImpl.java:523)
> >       at android.hardware.camera2.cts.CameraTestUtils.configureCameraSession(CameraTestUtils.java:770)
> >       at android.hardware.camera2.cts.CameraTestUtils.configureCameraSession(CameraTestUtils.java:911)
> >       at android.hardware.camera2.cts.testcases.Camera2MultiViewTestCase$CameraHolder.startPreview(Camera2MultiViewTestCase.java:490)
> >       at android.hardware.camera2.cts.testcases.Camera2MultiViewTestCase.startPreview(Camera2MultiViewTestCase.java:252)
> >       at android.hardware.camera2.cts.MultiViewTest.startTextureViewPreview(MultiViewTest.java:881)
> >       at android.hardware.camera2.cts.MultiViewTest.testDualCameraPreview(MultiViewTest.java:228)
> >       at java.lang.reflect.Method.invoke(Native Method)
> >       at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:220)
> >       at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:205)
> >       at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:192)
> >       at junit.framework.TestCase.runBare(TestCase.java:134)
> >       at junit.framework.TestResult$1.protect(TestResult.java:115)
> >       at androidx.test.internal.runner.junit3.AndroidTestResult.runProtected(AndroidTestResult.java:73)
> >       at junit.framework.TestResult.run(TestResult.java:118)
> >       at androidx.test.internal.runner.junit3.AndroidTestResult.run(AndroidTestResult.java:51)
> >       at junit.framework.TestCase.run(TestCase.java:124)
> >       at androidx.test.internal.runner.junit3.NonLeakyTestSuite$NonLeakyTest.run(NonLeakyTestSuite.java:62)
> >       at androidx.test.internal.runner.junit3.AndroidTestSuite$2.run(AndroidTestSuite.java:101)
> >       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
> >       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
> >       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
> >       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
> >       at java.lang.Thread.run(Thread.java:764)
> > Caused by: android.os.ServiceSpecificException: endConfigure:513: Camera 1: Error configuring streams: Function not implemented (-38) (code 10)
> >       at android.os.Parcel.createException(Parcel.java:1964)
> >       at android.os.Parcel.readException(Parcel.java:1918)
> >       at android.os.Parcel.readException(Parcel.java:1868)
> >       at android.hardware.camera2.ICameraDeviceUser$Stub$Proxy.endConfigure(ICameraDeviceUser.java:451)
> >       at android.hardware.camera2.impl.ICameraDeviceUserWrapper.endConfigure(ICameraDeviceUserWrapper.java:112)
> >       ... 26 more
> > 
> > Given we'll know the exact cause of this regression, it's a single test
> > fail; it's already not supported, and we anticipate a solution
> > coming from the ChromeOS team - I don't mind merging this patch early
> > with the regression noted.
> 
> I'll add the following paragraph to the commit message:
> 
> As a consequence of this change, the IPU3 pipeline handler will fail to
> operate properly when the cameras it exposes are operated concurrently.
> The android.hardware.camera2.cts.MultiViewTest#testDualCameraPreview
> test fails as a result. This should be fixed in the IPU3 pipeline
> handler to implement mutual exclusion between cameras.

Interesting to note, that before this patch - the Chrome Camera App
can't switch cameras (much like qcam can't) - and now it can. I hope
that the mutual exclusion doesn't re-introduce this limitation ;-)

--
Kieran


More information about the libcamera-devel mailing list