MTK设备中的setPreviewTexture失败

时间:2015-08-11 14:01:38

标签: android android-camera glsurfaceview grafika

最近我正在通过grafika学习安卓摄像头和OpenglES(感谢fadden)。它在大多数设备上都很好,但我遇到了某些设备中的错误,特别是MTK设备(如MT6580,MT8163 ......)。

例如,当“CameraCaptureActivity”在MTK中运行时。我收到了这个错误:

  

java.lang.NullPointerException:尝试在空对象引用上调用虚方法'void android.hardware.Camera.setPreviewTexture(android.graphics.SurfaceTexture)'

所以我将“handleSetSurfaceTexture”函数更改为:

 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();
}

然后错误更改为:

  

java.lang.RuntimeException:java.io.IOException:setPreviewTexture失败   在jp.co.cyberagent.android.gpuimage.grafika.CameraCaptureActivity.handleSetSurfaceTexture(CameraCaptureActivity.java:1150)

我读了许多其他相机应用程序源代码,我想可能在MTK设备中有Camera和SurfaceRender的同步问题。所以我改变了这样的代码:

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();
}

不幸的是,“getMaxTextureSize()”在其他设备中返回一个有用的数字,但我只是在MTK设备中得到了getMaxTextureSize()= 0。

所以我有这些问题:

1)如何安全地使用surfaceRender / Camera / SurfaceTexture?

2)为什么这个问题恰好发生在MTK?

任何答案都会受到赞赏。

我添加此项并再次测试

    //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);

中的两个设备结果是:

  

nGLVersion = 131072,supportsEs2 = true

     

nGLVersion = 196608,supportsEs2 = true

我也获得了设备信息:

     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);

结果:

  

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

     

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

顺便说一下,第一次打开Camera和startpreview就可以了。但是当活动暂停或重新打开相机时遇到“setPreviewTexture failed”。 发布相机时,我得到了一些日志:

  

CameraClient native_window_api_disconnect失败:管道损坏(-32)

重新打开相机时:

  

CameraClient native_window_api_connect失败:没有此类设备(-19)

这些设备可能存在问题,但我也会在这些设备上测试其他一些相机应用程序,其中一些效果不错。所以它必须有更好的方式来使用Camera和glsurfaceview。

2 个答案:

答案 0 :(得分:1)

正如法登所说,也许存在导致&#34; setPreviewTexture失败的竞争条件&#34;。 Finnaly我在这里找到了来自google camera2示例代码的解决方案:https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java。它使用&#34; Semaphore&#34;解决问题。

答案 1 :(得分:0)

我在语句mCamera.setPreviewDisplay(holder)上通过put语句解决了同样的问题

camera.stopPreview();

之前

mCamera.setPreviewDisplay(holder)