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() { |