| Index: talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java
|
| diff --git a/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java b/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java
|
| index ec68ed504d0b370d496edeb5d83e74b3ea56ea9e..64e56c270469d63fdc459df924506febd134777d 100644
|
| --- a/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java
|
| +++ b/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java
|
| @@ -28,14 +28,16 @@
|
| package org.webrtc;
|
|
|
| import android.content.Context;
|
| +import android.graphics.SurfaceTexture;
|
| import android.hardware.Camera;
|
| import android.hardware.Camera.PreviewCallback;
|
| import android.opengl.EGL14;
|
| import android.opengl.EGLContext;
|
| +import android.opengl.GLES11Ext;
|
| +import android.opengl.GLES20;
|
| import android.os.Handler;
|
| import android.os.HandlerThread;
|
| import android.os.SystemClock;
|
| -import android.text.StaticLayout;
|
| import android.view.Surface;
|
| import android.view.WindowManager;
|
|
|
| @@ -93,6 +95,14 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
| private CapturerObserver frameObserver = null;
|
| private final CameraErrorHandler errorHandler;
|
| private final boolean isCapturingToTexture;
|
| + // |cameraGlTexture| is used with setPreviewTexture if the capturer is capturing to
|
| + // ByteBuffers.
|
| + private int cameraGlTexture;
|
| + // |cameraSurfaceTexture| is used with setPreviewTexture if the capturer is capturing to
|
| + // ByteBuffers. Must be a member, see issue webrtc:5021.
|
| + private SurfaceTexture cameraSurfaceTexture;
|
| + //|surfaceHelper| is used if the capturer is capturing to a texture. Capturing to textures require
|
| + // API level 17.
|
| private final SurfaceTextureHelper surfaceHelper;
|
| // The camera API can output one old frame after the camera has been switched or the resolution
|
| // has been changed. This flag is used for dropping the first frame after camera restart.
|
| @@ -205,14 +215,14 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
| }
|
|
|
| public static VideoCapturerAndroid create(String name,
|
| - CameraErrorHandler errorHandler, EGLContext sharedContext) {
|
| + CameraErrorHandler errorHandler, Object sharedEglContext) {
|
| final int cameraId = lookupDeviceName(name);
|
| if (cameraId == -1) {
|
| return null;
|
| }
|
|
|
| final VideoCapturerAndroid capturer = new VideoCapturerAndroid(cameraId, errorHandler,
|
| - sharedContext);
|
| + sharedEglContext);
|
| capturer.setNativeCapturer(nativeCreateVideoCapturer(capturer));
|
| return capturer;
|
| }
|
| @@ -306,7 +316,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
| }
|
|
|
| private VideoCapturerAndroid(int cameraId, CameraErrorHandler errorHandler,
|
| - EGLContext sharedContext) {
|
| + Object sharedContext) {
|
| Logging.d(TAG, "VideoCapturerAndroid");
|
| this.id = cameraId;
|
| this.errorHandler = errorHandler;
|
| @@ -314,12 +324,14 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
| cameraThread.start();
|
| cameraThreadHandler = new Handler(cameraThread.getLooper());
|
| videoBuffers = new FramePool(cameraThread);
|
| - surfaceHelper = SurfaceTextureHelper.create(
|
| - sharedContext == null ? EGL14.EGL_NO_CONTEXT : sharedContext, cameraThreadHandler);
|
| if (sharedContext != null) {
|
| + surfaceHelper = SurfaceTextureHelper.create((EGLContext)sharedContext, cameraThreadHandler);
|
| surfaceHelper.setListener(this);
|
| + isCapturingToTexture = true;
|
| + } else {
|
| + surfaceHelper = null;
|
| + isCapturingToTexture = false;
|
| }
|
| - isCapturingToTexture = sharedContext != null;
|
| }
|
|
|
| private void checkIsOnCameraThread() {
|
| @@ -353,7 +365,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
| if (isReleased()) {
|
| throw new IllegalStateException("Already released");
|
| }
|
| - cameraThreadHandler.post(new Runnable() {
|
| + ThreadUtils.invokeUninterruptibly(cameraThreadHandler, new Runnable() {
|
| @Override
|
| public void run() {
|
| if (camera != null) {
|
| @@ -364,9 +376,10 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
| }
|
| }
|
| });
|
| - surfaceHelper.disconnect();
|
| -
|
| - cameraThread.quitSafely();
|
| + if (isCapturingToTexture) {
|
| + surfaceHelper.disconnect();
|
| + }
|
| + cameraThread.quit();
|
| ThreadUtils.joinUninterruptibly(cameraThread);
|
| cameraThread = null;
|
| }
|
| @@ -417,7 +430,13 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
| Camera.getCameraInfo(id, info);
|
| }
|
| try {
|
| - camera.setPreviewTexture(surfaceHelper.getSurfaceTexture());
|
| + if (isCapturingToTexture) {
|
| + camera.setPreviewTexture(surfaceHelper.getSurfaceTexture());
|
| + } else {
|
| + cameraGlTexture = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
|
| + cameraSurfaceTexture = new SurfaceTexture(cameraGlTexture);
|
| + camera.setPreviewTexture(cameraSurfaceTexture);
|
| + }
|
| } catch (IOException e) {
|
| Logging.e(TAG, "setPreviewTexture failed", error);
|
| throw new RuntimeException(e);
|
| @@ -557,6 +576,14 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba
|
| Logging.d(TAG, "Release camera.");
|
| camera.release();
|
| camera = null;
|
| +
|
| + if (cameraGlTexture != 0) {
|
| + GLES20.glDeleteTextures(1, new int[] {cameraGlTexture}, 0);
|
| + cameraGlTexture = 0;
|
| + }
|
| + if (cameraSurfaceTexture != null) {
|
| + cameraSurfaceTexture.release();
|
| + }
|
| }
|
|
|
| private void switchCameraOnCameraThread() {
|
|
|