Search code examples
androidkotlinandroid-videoviewandroid-camera2

Android can't play video only audio after using camera2 API createCaptureSession


Android Version: 5.1

Hi, I've noticed that after my app uses camera2 API to createCaptureSession (snapshot/ record),my android device no longer play video correctly, only audio with the black screen... and it's not just my app, all other streaming apps occur the same problem. I need to reboot to fix this problem. BTW, my device is customized so I can't use ADB and this issue doesn't even happen in my simulator.. I just don't have any clue now, it's killing me. Can somebody help me please? I'll appreciate that..!! Below is how i createCaptureSession and release. Maybe there's something wrong with my code?

Snapshot:

...after camera opened
                cameraDevice = p0;

                previewTextureListener = PreviewSurfaceTextureListener()

                cameraPreview.surfaceTextureListener = previewTextureListener
                
                cameraPreview.setTransform(transform)

...after previewTextureListenerAvailable 

                val captureWidth = 1920
                val captureHeight = 1080

                previewSurfaceTexture = surfaceTexture

                previewSurfaceTexture?.setDefaultBufferSize(captureWidth, captureHeight)

                previewSurface = Surface(previewSurfaceTexture)

                val sessionStateCallback = SessionStateCallback()

                imageReader = ImageReader.newInstance(captureWidth, captureHeight, ImageFormat.JPEG, 1)

                imageReader?.setOnImageAvailableListener(ImageAvailableCallback(), cameraHandler)

                imageSurface = imageReader?.surface

                val outputs = mutableListOf(previewSurface, imageSurface)

                cameraDevice?.createCaptureSession(outputs, sessionStateCallback, mainHandler)

...after sessionStateConfigured

            val requestBuilder = cameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)

            requestBuilder?.addTarget(previewSurface!!)

            val request = requestBuilder?.build()

            cameraCaptureSession?.setRepeatingRequest(request!!, PreviewImageCallback(), mainHandler)

record:


        // Start a capture session
        cameraDevice?.createCaptureSession(listOf(previewSurface, mediaRecorder?.surface), RecordSessionStateCallback(), cameraHandler)

... after RecordSessionConfigured

            val recordRequest = cameraDevice?.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);

            recordRequest?.addTarget(previewSurface!!);

            recordRequest?.addTarget(mediaRecorder?.surface!!)

            cameraRecordSession?.setRepeatingRequest(recordRequest?.build()!!, PreviewImageCallback(), cameraHandler)

When the acivity onDestroy:

        cameraPreview?.surfaceTextureListener = null

        cameraCaptureSession?.stopRepeating()

        cameraCaptureSession?.close()

        cameraDevice?.close()

        cameraDevice = null

Solution

  • It's hard to tell without logs from the device, but most likely, there's something wrong in the media codec stack of the device. It's leaving the codecs in a bad state after your app is done with the MediaRecorder, requiring a reboot before they work again, for either encode or decode.

    It's possible the particular settings you're using for MediaRecord trigger this, but on a properly built device this shouldn't happen no matter what your settings are.

    Unfortunately, if that's the problem, it needs to be fixed within the codec HAL for the device, most likely, or in stagefright media code, if that's been modified from the AOSP version. Exactly what's wrong is impossible to know without logs, but a deadlock in codec shutdown would be one possibility.