How to get currently selected camera?

373 views
Skip to first unread message

Robert

unread,
Nov 3, 2021, 8:38:02 PM11/3/21
to Android CameraX Discussion Group
How do I get the currently selected camera?

I'm interested in knowing when the new selection, which I set, is actually realized.

Background is, I have implemented a custom viewer which suitably transforms the surface according to the camera characteristics and displays the result. But when switching cameras I get a short display of the previous camera's image but using the transform characteristics of the newly selected camera.

It looks like the transform for the new camera is engaging too soon. Building the new transform characteristics depends on bindToLifecycle(), which I expected to have implemented the camera switch on completion. But it appears this is not the case.

Since image flow is discrete in frames, a per frame test would probably be an OK alternative to a callback.

   "androidx.camera:camera-core:1.1.0-alpha08",
   "androidx.camera:camera-camera2:1.1.0-alpha08",
   "androidx.camera:camera-lifecycle:1.1.0-alpha08",
   "androidx.lifecycle:lifecycle-process:2.3.0",
   "androidx.core:core:1.3.2"


Scott Nien

unread,
Nov 4, 2021, 2:21:22 AM11/4/21
to Robert, Android CameraX Discussion Group
Hi Robert, 

Please try CameraState API   It allows you to get notified of the state of the given camera. 

I guess after you receive the OPEN state of the next camera,  you can start to change the transform characteristics.    Not sure if it works though,  please give it a try. 

--
You received this message because you are subscribed to the Google Groups "Android CameraX Discussion Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to camerax-develop...@android.com.
To view this discussion on the web visit https://groups.google.com/a/android.com/d/msgid/camerax-developers/92d3bd57-ab6f-4625-a883-9c9462eb30b1n%40android.com.

Robert

unread,
Nov 4, 2021, 1:04:11 PM11/4/21
to Android CameraX Discussion Group, Scott Nien, Android CameraX Discussion Group, Robert
Thanks for the response.

I should have included that I already tried the listenable future CameraStata.
cameraState.getType() == CameraState.Type.OPEN
This is 'immediately' true after the new bindToLifecycle() following setting CameraSelector to a new camera.

On my Pixel5 it takes about 0.5 sec for the images from the new camera to appear. In normal operation of some camera there (of course) is no half second latency.

Scott Nien

unread,
Nov 4, 2021, 10:55:56 PM11/4/21
to Robert, Android CameraX Discussion Group
Hi Robert, 

cameraState.getType() == CameraState.Type.OPEN
This is 'immediately' true after the new bindToLifecycle() following setting CameraSelector to a new camera.

The cameraState you observe could be from the previous camera ,  not the next camera.  
Can you double check that ?    

Robert

unread,
Nov 5, 2021, 12:12:15 AM11/5/21
to Android CameraX Discussion Group, Scott Nien, Android CameraX Discussion Group, Robert
How do I check the which camera is reporting?

Currently I am using getType() from .getCameraInfo().getCameraState().getValue() on each frame.

Scott Nien

unread,
Nov 5, 2021, 3:10:53 AM11/5/21
to Robert, Android CameraX Discussion Group
You can not check which camera the observer is reporting within the observer but you should be able to know it when you register the observer to the cameraState. 

For example, 

        // start switching the camera 
         unbind()
        camera = cameraProvider.bindToLifecycle( this, currentCameraSelector....)

        val cameraStateSelector = currentCameraSelector.  // this is required to bind the cameraSelector to the following observer lambda. 
        camera.cameraInfo.cameraState.removeObservers(this)
        camera.cameraInfo.cameraState.observe(this) { cameraState -> 
             if (cameraStateSelector.lensFacing == CameraSelector.LENS_FACING_FRONT) {
                 Log.d("AAAAA", "front camera state: ${cameraState}")
             } else {
                 Log.d("AAAAA", "back camera state: ${cameraState}")
             }
        }

Robert

unread,
Nov 5, 2021, 10:54:18 PM11/5/21
to Android CameraX Discussion Group, Scott Nien, Android CameraX Discussion Group, Robert
The example didn't help. Could you please say that again in Java, I was unable to translate the Kotlin.

Also I don't understand how it could work:

1) The camera state changes to OPENING immediately after bindToLifecycle() then to OPEN some few frames later, but that OPEN transition occurs about half a second before the new camera image. Knowing the camera state is OPEN doesn't address the issue.

2) Because cameraSelector is static. So it seems cameraStateSelector would also be static. I see the comment about bind, but don't know how it applies in this context.

Scott Nien

unread,
Nov 8, 2021, 4:45:36 AM11/8/21
to Robert, Android CameraX Discussion Group
See comments in line. 

On Sat, Nov 6, 2021 at 10:54 AM Robert <planckp...@gmail.com> wrote:
The example didn't help. Could you please say that again in Java, I was unable to translate the Kotlin.

Also I don't understand how it could work:

1) The camera state changes to OPENING immediately after bindToLifecycle() then to OPEN some few frames later, but that OPEN transition occurs about half a second before the new camera image. Knowing the camera state is OPEN doesn't address the issue.
Maybe waiting one more frame after the OPEN state will do ?  
Use onSurfaceTextureUpdated if you use TextureView  or use OnFrameAvailableListener if you use SurfaceTexture directly. 


2) Because cameraSelector is static. So it seems cameraStateSelector would also be static. I see the comment about bind, but don't know how it applies in this context.
I mean ,  both for kotlin and java. you can bind some local variable into a closure(lambda) so that within the closure, it can read the correct one.  (also known as variable capturing) 

On the other hand,  if you read a member variable in the lambda,  all observers will get the same value which is wrong.  

Robert

unread,
Nov 8, 2021, 9:17:29 PM11/8/21
to Android CameraX Discussion Group, Scott Nien, Android CameraX Discussion Group, Robert
> Maybe waiting one more frame after the OPEN state will do ?  

Waiting for 16 or 17 frames works (at least on a Pixel 5), as I said previously it is about half a second.
It seems this would not be a reliably portable approach.

> Use onSurfaceTextureUpdated if you use TextureView 

As I said previously, I am using a custom View

> or use OnFrameAvailableListener if you use SurfaceTexture directly. 

This works, YES!
OnFrameAvailable() is not called during that half second after switching front/back.
Right now I do not check OPEN, I will investigate if there is a case where this is necessary.

Thank you for your help, and patience.

Scott Nien

unread,
Nov 8, 2021, 9:51:46 PM11/8/21
to Robert, Android CameraX Discussion Group
You are welcome.  Glad to see you find the solution!
Reply all
Reply to author
Forward
0 new messages