Recently I am studying the Android and OpenglES camera from grafika (thanks fadden). This is good on most devices, but I encounter errors on some device, especially in the MTK device (e.g. MT6580, MT8163 ...).
For example, when the "CameraCaptureActivity" is executed in MTK. I get this error:
java.lang.NullPointerException: attempt to call the virtual method 'void android.hardware.Camera.setPreviewTexture (android.graphics.SurfaceTexture)' to reference a null object
so I replaced the handleSetSurfaceTexture function as follows:
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 the error will change to the following:
java.lang.RuntimeException: java.io.IOException: setPreviewTexture failed on jp.co.cyberagent.android.gpuimage.grafika.CameraCaptureActivity.handleSetSurfaceTexture (CameraCaptureActivity.java:1150)
I read a lot of other camera application source codes, maybe there is a synchronous issue with Camera and SurfaceRender in the MTK device. Therefore, I change the code as follows:
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) {
Unfortunately, "getMaxTextureSize ()" returns a useful number to another device, but I just get getMaxTextureSize () = 0 in the MTK device.
I have the following questions:
1) How to use Render / Camera / SurfaceTexture safely?
2) Why does this problem only occur in MTK?
Any answer would be appreciated.
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 results of the device:
nGLVersion = 131072, supports Es2 = true
nGLVersion = 196608, supports Es2 = true
I also get device information:
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 normally opens Camera and startpreview for the first time. But the “setPreviewTexture failed” collision when the activity pauses or reopens the camera. I get several magazines when I release the camera:
CameraClient error native_window_api_disconnect: damaged channel (-32)
when re-operating the camera:
Failed to call CameraClient native_window_api_connect: no such device (-19)
There are probably problems with this device, but I am also testing some other camera application on this device, and some of them work well. Therefore, it should have a better way to use Camera and glsurfaceview.