【问题标题】:setPreviewTexture failed in MTK deviceMTK 设备中的 setPreviewTexture 失败
【发布时间】:2015-11-03 19:23:39
【问题描述】:

最近我正在学习 grafika 的 android Camera 和 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 设备中相机和 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,支持Es2 = true

nGLVersion = 196608,支持Es2 = 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 = 阿尔卑斯 k80_gmo, strModel =k80_gmo, nVersion =22

strDevice = 阿尔卑斯山 tb8163p3_64_sph,strModel =tb8163p3_64_sph,nVersion =22

顺便说一句,第一次打开Camera并开始预览是可以的。但是在活动暂停或重新打开相机时遇到“setPreviewTexture failed”。 释放相机时,我得到了一些日志:

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

重新打开相机时:

CameraClient native_window_api_connect 失败:没有这样的设备 (-19)

这些设备可能存在问题,但我也在这些设备中测试了其他一些相机应用,其中一些表现良好。所以它必须有更好的方式来使用Camera和glsurfaceview。

【问题讨论】:

  • Grafika 具有转储 GLES 版本信息的功能。它对制造商和版本显示了什么? GL_MAX_TEXTURE_SIZE 变为零有点奇怪。
  • 我在云测试平台遇到了这些错误。它只是显示 MTKXXXX。我会尽快改进我的测试用例并列出制造商。谢谢回复,fadden
  • 您确定这些是通过 CTS 的实际 Android 设备吗?如果没有,则完全有可能缺少功能。
  • 对了,第一次打开Camera并开始预览就可以了。但是在activity暂停或重新打开Camera时遇到“setPreviewTexture failed”。
  • 使用 SurfaceView 很难避免 Activity 重新启动附近出现的问题——Grafika 的“连续捕获”活动出错了 (github.com/google/grafika/issues/24)——但它们通常在不同设备上是一致的。也许是比赛条件?

标签: android android-camera glsurfaceview grafika


【解决方案1】:

我在语句 mCamera.setPreviewDisplay(holder) 上遇到了同样的问题,通过放置语句解决了

camera.stopPreview();

之前

mCamera.setPreviewDisplay(holder)

【讨论】:

    【解决方案2】:

    正如fadden 所说,也许存在导致“setPreviewTexture failed”的竞争条件。 Finnaly 我在这里找到了来自 google camera2 示例代码的解决方案:https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java。它使用“信号量”来解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多