setPreviewTexture failed in MTK device
Asked Answered
D

3

7

Recently I am learning android Camera and OpenglES by grafika (Thanks fadden).It's good on most device, but I encounter bugs in some device, espacially MTK device(such as MT6580,MT8163...).

For example, when "CameraCaptureActivity" run in MTK. I am getting this error:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.setPreviewTexture(android.graphics.SurfaceTexture)' on a null object reference

so I changed "handleSetSurfaceTexture" function to this:

 private void handleSetSurfaceTexture(SurfaceTexture st) {
    if(mCamera == null)
    {
        Log.e(TAG, "mCamera return null");
        return;
    }
    st.setOnFrameAvailableListener(this);
    try {
        mCamera.setPreviewTexture(st);

    } catch (Exception ioe) {
        Log.e(TAG, "camera failed handleSetSurfaceTexture");
        throw new RuntimeException(ioe);
    }
    mCamera.startPreview();
}

Then error change to this:

java.lang.RuntimeException: java.io.IOException: setPreviewTexture failed at jp.co.cyberagent.android.gpuimage.grafika.CameraCaptureActivity.handleSetSurfaceTexture(CameraCaptureActivity.java:1150)

I read many other camera app source code, I guess maybe there are Synchronous problem with Camera and SurfaceRender in MTK device. So I change the code like this:

private void waitUntilSetup()
{
    long l = System.currentTimeMillis();
    while ((getMaxTextureSize() == 0) && (System.currentTimeMillis() - l < 3000L))
    {
        SystemClock.sleep(100L);
    }

    Log.e(TAG,"getMaxTextureSize() = " + getMaxTextureSize());
}

private int getMaxTextureSize() {
    int[] maxTextureSize = new int[1];
    GLES20.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);
    Log.e(TAG, "Max texture size = " + maxTextureSize[0]);
    return maxTextureSize[0];
}

private void handleSetSurfaceTexture(SurfaceTexture st) {
    //wait for gl
    waitUntilSetup();
    if(mCamera == null)
    {
        Log.e(TAG, "mCamera return null");
        return;
    }
    st.setOnFrameAvailableListener(this);
    try {
        mCamera.setPreviewTexture(st);
    } catch (Exception ioe) {
        Log.e(TAG, "camera failed handleSetSurfaceTexture");
        throw new RuntimeException(ioe);
    }
    mCamera.startPreview();
}

Unfortunately, "getMaxTextureSize()" return a useful number in other device, but I just get getMaxTextureSize()=0 in MTK device.

So I have these questions:

1) How to use surfaceRender/Camera/SurfaceTexture safely?

2) Why does this problem just happen in MTK?

any answer will be appreciate.

I add this and test again

    //get glVersion
    final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
    int nGLVersion = configurationInfo.reqGlEsVersion;
    final boolean supportsEs2 = (nGLVersion >= 0x20000);
    Log.e(TAG, "nGLVersion = " + nGLVersion + ", supportsEs2 = " + supportsEs2);

in two of the device result is:

nGLVersion = 131072, supportsEs2 = true

nGLVersion = 196608, supportsEs2 = true

I also get device info:

     String strDevice = Devices.getDeviceName();    //https://gist.github.com/jaredrummler/16ed4f1c14189375131d
     String strModel =  Build.MODEL;
     int nVersion = Build.VERSION.SDK_INT;
     Log.e(TAG, "strDeviceName = " + strDevice + ", strModel =" + strModel + ", nVersion =" + nVersion);

results:

strDevice = Alps k80_gmo, strModel =k80_gmo, nVersion =22

strDevice = Alps tb8163p3_64_sph, strModel =tb8163p3_64_sph, nVersion =22

By the way, It's ok at the first time open Camera and startpreview. But encounter "setPreviewTexture failed" when activity pause or reopen the Camera. I get some logs, when release camera:

CameraClient native_window_api_disconnect failed: Broken pipe (-32)

when reopen camera:

CameraClient native_window_api_connect failed: No such device (-19)

Probably there are problem with these device, but I also test some other Camera app in these device, and some of them performs well. So it must have a better way to use Camera and glsurfaceview.

Dextrality answered 11/8, 2015 at 14:1 Comment(5)
Grafika has a feature that dumps the GLES version info. What does it show for the manufacturer and version? It's a bit weird that GL_MAX_TEXTURE_SIZE is coming up zero.Mccurdy
I got these errors in cloud-testing platform. it's just show MTKXXXX. I will improve my test case and list manufacturer as soon as possible. Thanks for reply, faddenDextrality
Are you sure these are actual Android devices that have passed CTS? If not, it's entirely possible that features are missing.Mccurdy
By the way, It's ok at the first time open Camera and startpreview. But encounter "setPreviewTexture failed" when activity pause or reopen the Camera.Dextrality
Problems arising near Activity restarts are tricky to avoid with SurfaceView -- Grafika's "continuous capture" activity gets it wrong (github.com/google/grafika/issues/24) -- but they're usually consistent across devices. Maybe a race condition?Mccurdy
D
1

As fadden said, Maybe there is a race condition that causes "setPreviewTexture failed". Finnaly I find a solution from google camera2 sample code here : https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java. It uses "Semaphore" to solve the problem.

Dextrality answered 26/11, 2015 at 10:41 Comment(0)
K
2

I got the same issue on statement mCamera.setPreviewDisplay(holder) solved by putting statement

camera.stopPreview();

before

mCamera.setPreviewDisplay(holder)
Kazbek answered 18/7, 2016 at 9:8 Comment(0)
D
1

As fadden said, Maybe there is a race condition that causes "setPreviewTexture failed". Finnaly I find a solution from google camera2 sample code here : https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java. It uses "Semaphore" to solve the problem.

Dextrality answered 26/11, 2015 at 10:41 Comment(0)
E
0

I had the same problem recently and this post helped a lot. I am using highly modified version of grafika continuous capture program in an android powered dashcam for last 6 years and was brilliant. Chinese manufacturer recently released a device with multiple cameras, 5 simultaneously recording cameras and my program was failing on this error. It was a race condition and as I am working with multiple threaded environment, with up to 5 camera instances, some of the SurfaceTexture not released properly.

Solution was, after opening camera, making sure camera is opened, then set mCamera.setPreviewDisplay(null); before start previewing.

Hope this help someone.

Electro answered 5/12, 2023 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.