CameraX does not reopen camera - android

I am working on a camera app based on the sample CameraX app from Google that can be found on GitHub. Sometimes, when I reopen the app after running in the background, the camera won`t open and the preview screen remains black. When the app is opening the camera, normally the following log is shown:
D/PreviewView: Surface requested by Preview.
D/CameraStateRegistry: Recalculating open cameras:
Camera State
-------------------------------------------------------------------
Camera#f2ad3fe[id=0] OPENING
Camera#35c320a[id=1] UNKNOWN
-------------------------------------------------------------------
Open count: 1 (Max allowed: 1)
D/CameraStateRegistry: Recalculating open cameras:
Camera State
-------------------------------------------------------------------
Camera#f2ad3fe[id=0] OPEN
Camera#35c320a[id=1] UNKNOWN
-------------------------------------------------------------------
Open count: 1 (Max allowed: 1)
However, when the app does not open, only this log is shown:
Active and attached use case: [] for camera: 0
D/CameraStateRegistry: Recalculating open cameras:
Camera State
-------------------------------------------------------------------
Camera#f2ad3fe[id=0] OPENING
Camera#35c320a[id=1] UNKNOWN
-------------------------------------------------------------------
Open count: 1 (Max allowed: 1)
... without the notice that the camera has been opened correctly.
Any idea what is going wrong here and how to fix it?

Related

Android camera with api lvl33 and package name lenght > 30

I have a strange issue with the Android camera on Android 13.
My Application has a package name with a length that's greater than 30.
Whatever I do, e.g com.google.mlkit.barcode.Barcode , or creating a surface with androidx.camera, its always the same.Everything works fine until Android 12 and does not work with android 13.
But When I use a Flavour with a shorter package name (30 oder less), it works.
I reported this issue to google, but changing my flavours to shorter ones is not really an option in a productiv running app, does anyone have any idea how to avoid this?
I already updated target ad compiled sdk to 33 and use the newest stable versions of all implementations.
I have the following output in my logcat, if i start a surface on Android 13 with a long package name and the sreec stays just black:
CameraRepository de....Sass.dimadimadimadimadimadima D Added camera: 1
Camera2CameraInfo de....Sass.dimadimadimadimadimadima I Device Level: INFO_SUPPORTED_HARDWARE_LEVEL_3
CameraValidator de....Sass.dimadimadimadimadimadima D Verifying camera lens facing on SCW_sprout, lensFacingInteger: null
[...]
DeferrableSurface de....Sass.dimadimadimadimadimadima D Surface created[total_surfaces=2, used_surfaces=0](androidx.camera.core.impl.ImmediateSurface#ce8aba5}
DeferrableSurface de....Sass.dimadimadimadimadimadima D Surface created[total_surfaces=3, used_surfaces=0](androidx.camera.core.impl.ImmediateSurface#523af88}
Camera2CameraImpl de....Sass.dimadimadimadimadimadima D {Camera#b0329a4[id=0]} Use case ImageCapture:androidx.camera.core.ImageCapture-f64980f6-eaa9-435a-819f-8c8db175888e ACTIVE
PreviewView de....Sass.dimadimadimadimadimadima D Surface requested by Preview.
UseCaseAttachState de....Sass.dimadimadimadimadimadima D Active and attached use case: [] for camera: 0
Camera2CameraImpl de....Sass.dimadimadimadimadimadima D {Camera#b0329a4[id=0]} Use case Preview:androidx.camera.core.Preview-a1671e1e-e37b-4ab4-b0ad-8cd7ee2a695e ACTIVE
Camera2CameraImpl de....Sass.dimadimadimadimadimadima D {Camera#b0329a4[id=0]} Resetting Capture Session
Camera2CameraImpl de....Sass.dimadimadimadimadimadima D {Camera#b0329a4[id=0]} Releasing session in state INITIALIZED
Camera2CameraImpl de....Sass.dimadimadimadimadimadima D {Camera#b0329a4[id=0]} Attempting to force open the camera.
CameraStateRegistry de....Sass.dimadimadimadimadimadima D tryOpenCamera(Camera#b0329a4[id=0]) [Available Cameras: 1, Already Open: false (Previous state: null)] --> SUCCESS
CameraStateRegistry de....Sass.dimadimadimadimadimadima D Recalculating open cameras:
Camera#b0329a4[id=0] OPENING
Camera#49590e[id=1] UNKNOWN
Open count: 1 (Max allowed: 1)
Camera2CameraImpl de....Sass.dimadimadimadimadimadima D {Camera#b0329a4[id=0]} Opening camera.
Camera2CameraImpl de....Sass.dimadimadimadimadimadima D {Camera#b0329a4[id=0]} Transitioning camera internal state: INITIALIZED --> OPENING
CameraStateMachine de....Sass.dimadimadimadimadimadima D New public camera state CameraState{type=OPENING, error=null} from OPENING and null
CameraStateMachine de....Sass.dimadimadimadimadimadima D Publishing new public camera state CameraState{type=OPENING, error=null}
UseCaseAttachState de....Sass.dimadimadimadimadimadima D All use case: [androidx.camera.core.ImageCapture-f64980f6-eaa9-435a-819f-8c8db175888e89172630, androidx.camera.core.ImageAnalysis-98e2e014-5983-45be-9438-697f6ebd4550206087601, androidx.camera.core.Preview-a1671e1e-e37b-4ab4-b0ad-8cd7ee2a695e2326616] for camera: 0
libc de....Sass.dimadimadimadimadimadima W Access denied finding property "persist.vendor.camera.privapp.list"
CameraService pid-1414 I CameraService::connect call (PID -1 "de.supinfo.FISass.dimadimadimadimadimadima", camera ID 0) and Camera API version 2
CameraService pid-1414 I [hmdcb] CameraService::makeClient call (PID 25019 "de.supinfo.FISass.dimadimadimadimadimadima", camera ID 0) and Camera API version 2, g_isCTS 0, g_isCTS_V 0,
Camera2ClientBase pid-1414 I Camera 0: Opened. Client: de.supinfo.FISass.dimadimadimadimadimadima (PID 25019, UID 10007)
libc de....Sass.dimadimadimadimadimadima W Access denied finding property "vendor.camera.aux.packagelist"
CameraManagerGlobal de....Sass.dimadimadimadimadimadima E Camera 5 is not available. Ignore physical camera status change
libc de....Sass.dimadimadimadimadimadima W Access denied finding property "vendor.camera.aux.packagelist"
libc de.supinfo.FISass.pct W Access denied finding property "vendor.camera.aux.packagelist"`

CameraX TimeoutException Cannot complete surfaceList

I am going through the CameraX tutorial at Android Developers https://developer.android.com/codelabs/camerax-getting-started#3 using version 1.1.0 of the library. The logs look good at first, but later a TimeoutException is raised and the camera preview remains black:
(omitted)
D/CameraStateRegistry: Recalculating open cameras:
Camera State
-------------------------------------------------------------------
Camera#f35a3d7[id=0] OPEN
Camera#e46a673[id=1] UNKNOWN
-------------------------------------------------------------------
Open count: 1 (Max allowed: 1)
D/CameraStateMachine: New public camera state CameraState{type=OPEN, error=null} from OPEN and null
D/CameraStateMachine: Publishing new public camera state CameraState{type=OPEN, error=null}
D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-c7727ae2-d02c-4135-956c-a76c24deb02d40667318] for camera: 0
D/UseCaseAttachState: Active and attached use case: [androidx.camera.core.Preview-c7727ae2-d02c-4135-956c-a76c24deb02d40667318] for camera: 0
D/Camera2CameraImpl: {Camera#f35a3d7[id=0]} Transitioning camera internal state: OPENED --> OPENED
D/CameraStateMachine: New public camera state CameraState{type=OPEN, error=StateError{code=4, cause=java.util.concurrent.TimeoutException: Cannot complete surfaceList within 5000}} from OPEN and StateError{code=4, cause=java.util.concurrent.TimeoutException: Cannot complete surfaceList within 5000}
D/CameraStateMachine: Publishing new public camera state CameraState{type=OPEN, error=StateError{code=4, cause=java.util.concurrent.TimeoutException: Cannot complete surfaceList within 5000}}
My virtual hardware is Pixel 4 API 30, my Samsung A52s behaves in the same way. The code is the same as in the above tutorial, but in Java.
What am I doing wrong?

Android Camera2 ImageReader is not working with MediaRecorder on Samsung S21 family

For new Samsung S21 devices Image analysis is not working together with video recording.
If I'm adding surfaces for my capture session:
//surface of TextureView for preview
addTarget(previewSurface)
//surface of media recorder for video recording
addTarget(mediaRecorder.surface)
//surface of image reader for frame analysis
addTarget(imageReader.surface)
where imageReader is
ImageReader.newInstance(previewWidth, previewHeight, ImageFormat.YUV_420_888, 1)
Preview is not starting and the system output in log is:
Camera3-Status: addComponent: Adding new component 3 - streamId = 1, format = 35, width = 1280, height = 720
Camera3-OutputStream: configureConsumerQueueLocked: Consumer wants 1 buffers, HAL wants 0
Camera3-OutputStream: configureConsumerQueueLocked: Camera HAL requested max_buffer count: 0, requires at least 1
Camera3-Stream: finishConfiguration: Unable to configure stream 1 queue: Function not implemented (-38)
Camera3-Device: Camera 0: configureStreamsLocked: Can't finish configuring output stream 1: Function not implemented (-38)
CameraDeviceClient: endConfigure: Camera 0: Unsupported set of inputs/outputs provided
CameraDevice-JV-0: Stream configuration failed due to: endConfigure:593: Camera 0: Unsupported set of inputs/outputs provided
CameraCaptureSession: Session 0: Failed to create capture session; configuration failed
It worth to note, that image reader with ImageFormat.JPEG is working fine.
Is there anybody from Samsung to help me with workaround?

MediaCodec.createInputSurface() throws IllegalStateException on some devices

I'm working on a video processing app. The app has one Activity that contains a Fragment. The Fragment in turn contains a VideoSurfaceView derived from GLSurfaceView for me to show the preview of the video with effect (using OpenGL) to users. After previewing, users can start processing the video.
To process the video, I mainly apply the method described in here.
Everything works fine on most devices, but the Oppo Mirror 3 (Android 4.4). On this device, everytime I try to create an Surface using MediaCodec.createInputSurface(), it throws out java.lang.IllegalStateException with code -38.
E/OMXMaster: A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
E/SoftAVCEncoder: internalSetParameter: StoreMetadataInBuffersParams.nPortIndex not zero!
E/OMXNodeInstance: OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x80001001
E/ACodec: [OMX.google.h264.encoder] storeMetaDataInBuffers (output) failed w/ err -2147483648
E/OMXNodeInstance: createInputSurface requires COLOR_FormatSurface (AndroidOpaque) color format
E/ACodec: [OMX.google.h264.encoder] onCreateInputSurface returning error -38
E/VideoProcessing: java.lang.IllegalStateException
at android.media.MediaCodec.createInputSurface(Native Method)
at com.ltpquang.android.core.processing.codec.VideoEncoder.<init>(VideoEncoder.java:46)
at com.ltpquang.android.core.VideoProcessing.setupVideo(VideoProcessing.java:200)
at com.ltpquang.android.core.VideoProcessing.<init>(VideoProcessing.java:167)
at com.ltpquang.android.ui.activity.PreviewEditActivity.lambda$btNext$12(PreviewEditActivity.java:723)
at com.ltpquang.android.ui.activity.PreviewEditActivity.access$lambda$12(PreviewEditActivity.java)
at com.ltpquang.android.ui.activity.PreviewEditActivity$$Lambda$13.run(Unknown Source)
at java.lang.Thread.run(Thread.java:841)
Playing around a little bit, I observed that:
BEFORE creating and adding the VideoSurfaceView to the layout, I can create MediaCodec encoder and obtain the input surface successfully. And I can create as many as I want if I release the previous MediaCodec before creating a new one, otherwise I can only obtain one and only one input surface regardless how many MediaCodec I have.
AFTER creating and adding the VideoSurfaceView to the layout, there is no chance that I can get the input surface from the MediaCodec, it thows java.lang.IllegalStateException always.
I've tried removing the VideoSurfaceView from the layout, set it to null, before creating the surface, but no luck for me.
I also tried with suggestions from here, or here, but they didn't help.
From this, it seems that my device can only get the software codec. So that I cant create the input surface.
My question is:
Why was that?
If the device's resources is limited, what can I do (release something for example) to continue the process?
If it is related to the software codec, what should I do? How can I detect and release the resource?
Is this related to GL contexts? If yes, what should I do? Should I manage the contexts my self?

Min undequeued buffer count exceeded

I am using a SurfaceTexture to get preview frames in the following way.
First, I set a preview texture:
camera.setPreviewTexture(new SurfaceTexture(0));
Then, just before starting the preview and then each time onPreviewFrame is called, I set the callback buffer like this:
camera.addCallbackBuffer(buffer);
camera.setPreviewCallbackWithBuffer(this);
It works. Sometimes, I take a picture using camera.takePicture(null, null, callback), which results in calling onPictureTaken successfully. The image is saved. Since I want to restart the preview after the picture has been taken, I do the following:
try
{
camera.setPreviewTexture(new SurfaceTexture(0));
camera.startPreview();
}
...
The preview restarts and everything seems to be fine. But the following error is reported in my Logcat, seemingly after the preview has be restarted:
E/BufferQueue﹕ [unnamed-5682-5] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=5 undequeudCount=1)
Am I missing something? Should I release the old texture at some point?
Configuration: Samsung Galaxy S4, Samsung Galaxy S5, Nexus 5, running on Android KitKat.
EDIT: I am not sure wether it is linked or not, but after a while, my App does not take pictures anymore and the following messages appear continuously in my Logcat:
E/LocSvc_api_v02( 318): I/---> locClientSendReq line 2332 QMI_LOC_INJECT_SENSOR_DATA_REQ_V02
E/gsiff_dmn( 318): I/loc_api_resp_ind_callback: Received LocAPI Resp ind = 77
E/LocSvc_api_v02( 318): D/loc_sync_process_ind:172]: loc_sync_array not in use
E/LocSvc_utils_q( 318): D/msg_q_rcv: Received message 0xB899D940 rv = 0
E/gsiff_dmn( 318): I/gsiff_data_task: Handling message type = 4
E/gsiff_dmn( 318): I/gsiff_daemon_inject_sensor_data_handler: Sending Sensor Data to LocApi. opaque_id = 1226
E/LocSvc_api_v02( 318): I/---> locClientSendReq line 2332 QMI_LOC_INJECT_SENSOR_DATA_REQ_V02
E/gsiff_dmn( 318): I/loc_api_resp_ind_callback: Received LocAPI Resp ind = 77
E/LocSvc_api_v02( 318): D/loc_sync_process_ind:172]: loc_sync_array not in use
E/mm-camera( 284): [cpp_hardware_process_frame:997] Too many cpp frames dropped!!
E/mm-camera( 284): cpp_thread_handle_process_buf_event:224] get buffer fail. drop frame id:1845 identity:0x20002
W/QCamera2HWI( 269): [CHECK_BUF_LOCK] Too many preview buffer is locked by surfaceflinger : 29
E/mm-camera( 284): [cpp_hardware_process_frame:997] Too many cpp frames dropped!!
E/mm-camera( 284): cpp_thread_handle_process_buf_event:224] get buffer fail. drop frame id:1846 identity:0x20002
EDIT 2: If, instead of a new SurfaceTexture(0), I always use the same SurfaceTexture (that I keep as a member), then some errors disappear and the App continues to work. The min undequeued buffer count exceeded error and the Too many preview buffer is locked by surfaceflinger warning stay.
It seems that the camera is holding something in its buffer that is not dequeued by your activity. You have to find the way to clear the camera buffer when you start a new preview.
As you can find in Android documentation about Camera class :
The buffer queue will be cleared if this method [setPreviewCallbackWithBuffer] is called with a null callback, setPreviewCallback(Camera.PreviewCallback) is called, or setOneShotPreviewCallback(Camera.PreviewCallback) is called.
So maybe it is enough to remove your callback when you take a picture and then reinstatiate it when you restart your preview.

Categories

Resources