CameraX preview usecase attachedSurfaceResolution property returns wrong resolution on some devices

411 views
Skip to first unread message

Sergey Dobranos

unread,
Jun 23, 2022, 8:57:30 AM6/23/22
to Android CameraX Discussion Group
version: 1.1.0-beta03
problem devices: Samsung A51 A52 A70 S8 S21, One+ 6
correct devices: Mi 10T Pro, Redmi Note 10 Pro

In our app we use preview usecase to transfer viewfinder frames from cameraX to openGL scene.
We need to know strict resolution of frames in video stream to make correct scale and position transformation in openGL.

On some samsung devices (see list and more) property returns 1440*1080 (aspect 4/3) and when we place unit on scene
with 4/3 aspect we see stretched picture by larger side. But when we set unit size with 1/1 aspect (square) - picture is
fine => frame size in stream is actualy square. But when we launch same code on Xiaomi devices - all fine - resolution that
property returns (1600*1200) is actual aspect ratio of stream and unit on openGL fine (but if we set square aspect for samsung may work
=> on xiaomi devices picture stretches). We are in confuse how to find out actual resolution of preview stream.

We trying to:
- set Preview.Builder().setTargetResolution() - have no effect in most cases except 1/1 aspect (i.e. 1080*1080) on some devices fix (but produce other issues)
- set Preview.Builder().setTargetAspectRatio() - no effect with preview on samsungs
- set ViewPort with custom sizes to UseCaseGroup.Builder() and than bindToLifecycle - no effect

How we work:
- gen openGL texture = GLUtils.genTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, false)
- create from them SurfaceTexture = SurfaceTexture(textureId) (setOnFrameAvailableListener { ..updateTexImage() ..redraw() })
- create from them Surface = Surface(surfaceTexture)
- provide 'surface' into preview preview.setSurfaceProvider { request -> request.provideSurface(surface, executor) { .. } }
- bind camera provider.bindToLifecycle(lifecycleOwner, selector, preview, capture)
- get frames resolution preview.attachedSurfaceResolution.toPointF()

Xi Zhang (张熹)

unread,
Jun 23, 2022, 9:50:07 AM6/23/22
to Sergey Dobranos, Android CameraX Discussion Group
CameraX does not guarantee the resolution set in Preview#setTargetResolution() due to device limitations. Preview#attachedSurfaceResolution does return the resolution currently being used by the camera but it's only available after the Preview is bound. 

A simpler way would be just using the resolution in SurfaceRequest. I updated your code sample:

preview.setSurfaceProvider { 
   request -> {
      val textureId = GLUtils.genTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, false)
      val surfaceTexture = SurfaceTexture(textureId) (setOnFrameAvailableListener { ..updateTexImage() ..redraw() })
      // set the resolution.
      surfaceTexture.setDefaultBufferSize(request.resolution.size.getWidth(), request.resolution.getHeight());
      val surface = Surface(surfaceTexture)
      request.provideSurface(surface, executor) { 
           // Don't forget to release the Surface! (And only after this callback is invoked)
           surfaceTexture.release()
           surface.release()
      } 
   }
}


--
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/eb0fa091-7941-4356-9a89-99c7b52ad20dn%40android.com.

Sergey Dobranos

unread,
Jun 24, 2022, 8:26:55 AM6/24/22
to Android CameraX Discussion Group, Xi Zhang, Android CameraX Discussion Group, Sergey Dobranos
Thank you for quick response! You really helped us. Our issue was with surfaceTexture.setDefaultBufferSize - we puted here device screen size and call this method in a litle bit differ place.

четверг, 23 июня 2022 г. в 16:50:07 UTC+3, Xi Zhang:
Reply all
Reply to author
Forward
0 new messages