orc*_*ang 6 android glsurfaceview android-camera grafika
最近我正在通过grafika(感谢fadden)学习安卓摄像头和OpenglES.它在大多数设备上都很好,但我遇到了一些设备中的错误,特别是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();
}
Run Code Online (Sandbox Code Playgroud)
然后错误更改为:
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();
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,"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);
Run Code Online (Sandbox Code Playgroud)
在两个设备的结果是:
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);
Run Code Online (Sandbox Code Playgroud)
结果:
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.
正如 fadden 所说,也许存在导致“setPreviewTexture 失败”的竞争条件。最后我从谷歌camera2示例代码中找到了一个解决方案: https: //github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java。它使用“信号量”来解决这个问题。
| 归档时间: |
|
| 查看次数: |
3199 次 |
| 最近记录: |