Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(448)

Side by Side Diff: talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java

Issue 1396013004: Android: Replace EGL14 with EGL10 (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Add comments for hardcoded EGL constants Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 13 matching lines...) Expand all
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 package org.webrtc; 28 package org.webrtc;
29 29
30 import android.content.Context; 30 import android.content.Context;
31 import android.graphics.SurfaceTexture; 31 import android.graphics.SurfaceTexture;
32 import android.hardware.Camera; 32 import android.hardware.Camera;
33 import android.hardware.Camera.PreviewCallback; 33 import android.hardware.Camera.PreviewCallback;
34 import android.opengl.EGLContext;
35 import android.opengl.GLES11Ext;
36 import android.opengl.GLES20;
37 import android.os.Handler; 34 import android.os.Handler;
38 import android.os.HandlerThread; 35 import android.os.HandlerThread;
39 import android.os.SystemClock; 36 import android.os.SystemClock;
40 import android.view.Surface; 37 import android.view.Surface;
41 import android.view.WindowManager; 38 import android.view.WindowManager;
42 39
43 import org.json.JSONException; 40 import org.json.JSONException;
44 import org.webrtc.CameraEnumerationAndroid.CaptureFormat; 41 import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
45 import org.webrtc.Logging; 42 import org.webrtc.Logging;
46 43
47 import java.io.IOException; 44 import java.io.IOException;
48 import java.nio.ByteBuffer; 45 import java.nio.ByteBuffer;
49 import java.util.ArrayList; 46 import java.util.ArrayList;
50 import java.util.HashMap; 47 import java.util.HashMap;
51 import java.util.HashSet; 48 import java.util.HashSet;
52 import java.util.IdentityHashMap; 49 import java.util.IdentityHashMap;
53 import java.util.List; 50 import java.util.List;
54 import java.util.Map; 51 import java.util.Map;
55 import java.util.Set; 52 import java.util.Set;
56 import java.util.concurrent.CountDownLatch; 53 import java.util.concurrent.CountDownLatch;
57 import java.util.concurrent.TimeUnit; 54 import java.util.concurrent.TimeUnit;
58 55
56 import javax.microedition.khronos.egl.EGLContext;
57 import javax.microedition.khronos.egl.EGL10;
58
59 // Android specific implementation of VideoCapturer. 59 // Android specific implementation of VideoCapturer.
60 // An instance of this class can be created by an application using 60 // An instance of this class can be created by an application using
61 // VideoCapturerAndroid.create(); 61 // VideoCapturerAndroid.create();
62 // This class extends VideoCapturer with a method to easily switch between the 62 // This class extends VideoCapturer with a method to easily switch between the
63 // front and back camera. It also provides methods for enumerating valid device 63 // front and back camera. It also provides methods for enumerating valid device
64 // names. 64 // names.
65 // 65 //
66 // Threading notes: this class is called from C++ code, Android Camera callbacks , and possibly 66 // Threading notes: this class is called from C++ code, Android Camera callbacks , and possibly
67 // arbitrary Java threads. All public entry points are thread safe, and delegate the work to the 67 // arbitrary Java threads. All public entry points are thread safe, and delegate the work to the
68 // camera thread. The internal *OnCameraThread() methods must check |camera| for null to check if 68 // camera thread. The internal *OnCameraThread() methods must check |camera| for null to check if
(...skipping 19 matching lines...) Expand all
88 private int requestedHeight; 88 private int requestedHeight;
89 private int requestedFramerate; 89 private int requestedFramerate;
90 // The capture format will be the closest supported format to the requested fo rmat. 90 // The capture format will be the closest supported format to the requested fo rmat.
91 private CaptureFormat captureFormat; 91 private CaptureFormat captureFormat;
92 private final Object pendingCameraSwitchLock = new Object(); 92 private final Object pendingCameraSwitchLock = new Object();
93 private volatile boolean pendingCameraSwitch; 93 private volatile boolean pendingCameraSwitch;
94 private CapturerObserver frameObserver = null; 94 private CapturerObserver frameObserver = null;
95 private final CameraEventsHandler eventsHandler; 95 private final CameraEventsHandler eventsHandler;
96 private boolean firstFrameReported; 96 private boolean firstFrameReported;
97 private final boolean isCapturingToTexture; 97 private final boolean isCapturingToTexture;
98 // |cameraGlTexture| is used with setPreviewTexture if the capturer is capturi ng to
99 // ByteBuffers.
100 private int cameraGlTexture;
101 // |cameraSurfaceTexture| is used with setPreviewTexture if the capturer is ca pturing to
102 // ByteBuffers. Must be a member, see issue webrtc:5021.
103 private SurfaceTexture cameraSurfaceTexture;
104 //|surfaceHelper| is used if the capturer is capturing to a texture. Capturing to textures require
105 // API level 17.
106 private final SurfaceTextureHelper surfaceHelper; 98 private final SurfaceTextureHelper surfaceHelper;
107 // The camera API can output one old frame after the camera has been switched or the resolution 99 // The camera API can output one old frame after the camera has been switched or the resolution
108 // has been changed. This flag is used for dropping the first frame after came ra restart. 100 // has been changed. This flag is used for dropping the first frame after came ra restart.
109 private boolean dropNextFrame = false; 101 private boolean dropNextFrame = false;
110 102
111 // Camera error callback. 103 // Camera error callback.
112 private final Camera.ErrorCallback cameraErrorCallback = 104 private final Camera.ErrorCallback cameraErrorCallback =
113 new Camera.ErrorCallback() { 105 new Camera.ErrorCallback() {
114 @Override 106 @Override
115 public void onError(int error, Camera camera) { 107 public void onError(int error, Camera camera) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // Invoked on failure, e.g. camera is stopped or only one camera available. 209 // Invoked on failure, e.g. camera is stopped or only one camera available.
218 void onCameraSwitchError(String errorDescription); 210 void onCameraSwitchError(String errorDescription);
219 } 211 }
220 212
221 public static VideoCapturerAndroid create(String name, 213 public static VideoCapturerAndroid create(String name,
222 CameraEventsHandler eventsHandler) { 214 CameraEventsHandler eventsHandler) {
223 return VideoCapturerAndroid.create(name, eventsHandler, null); 215 return VideoCapturerAndroid.create(name, eventsHandler, null);
224 } 216 }
225 217
226 public static VideoCapturerAndroid create(String name, 218 public static VideoCapturerAndroid create(String name,
227 CameraEventsHandler eventsHandler, Object sharedEglContext) { 219 CameraEventsHandler eventsHandler, EGLContext sharedEglContext) {
228 final int cameraId = lookupDeviceName(name); 220 final int cameraId = lookupDeviceName(name);
229 if (cameraId == -1) { 221 if (cameraId == -1) {
230 return null; 222 return null;
231 } 223 }
232 224
233 final VideoCapturerAndroid capturer = new VideoCapturerAndroid(cameraId, eve ntsHandler, 225 final VideoCapturerAndroid capturer = new VideoCapturerAndroid(cameraId, eve ntsHandler,
234 sharedEglContext); 226 sharedEglContext);
235 capturer.setNativeCapturer(nativeCreateVideoCapturer(capturer)); 227 capturer.setNativeCapturer(nativeCreateVideoCapturer(capturer));
236 return capturer; 228 return capturer;
237 } 229 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 private String getSupportedFormatsAsJson() throws JSONException { 322 private String getSupportedFormatsAsJson() throws JSONException {
331 return CameraEnumerationAndroid.getSupportedFormatsAsJson(getCurrentCameraId ()); 323 return CameraEnumerationAndroid.getSupportedFormatsAsJson(getCurrentCameraId ());
332 } 324 }
333 325
334 // Called from native VideoCapturer_nativeCreateVideoCapturer. 326 // Called from native VideoCapturer_nativeCreateVideoCapturer.
335 private VideoCapturerAndroid(int cameraId) { 327 private VideoCapturerAndroid(int cameraId) {
336 this(cameraId, null, null); 328 this(cameraId, null, null);
337 } 329 }
338 330
339 private VideoCapturerAndroid(int cameraId, CameraEventsHandler eventsHandler, 331 private VideoCapturerAndroid(int cameraId, CameraEventsHandler eventsHandler,
340 Object sharedContext) { 332 EGLContext sharedContext) {
341 Logging.d(TAG, "VideoCapturerAndroid"); 333 Logging.d(TAG, "VideoCapturerAndroid");
342 this.id = cameraId; 334 this.id = cameraId;
343 this.eventsHandler = eventsHandler; 335 this.eventsHandler = eventsHandler;
344 cameraThread = new HandlerThread(TAG); 336 cameraThread = new HandlerThread(TAG);
345 cameraThread.start(); 337 cameraThread.start();
346 cameraThreadHandler = new Handler(cameraThread.getLooper()); 338 cameraThreadHandler = new Handler(cameraThread.getLooper());
347 videoBuffers = new FramePool(cameraThread); 339 videoBuffers = new FramePool(cameraThread);
348 if (sharedContext != null) { 340 isCapturingToTexture = (sharedContext != null);
349 surfaceHelper = SurfaceTextureHelper.create((EGLContext)sharedContext, cam eraThreadHandler); 341 surfaceHelper = SurfaceTextureHelper.create(
342 isCapturingToTexture ? sharedContext : EGL10.EGL_NO_CONTEXT, cameraThrea dHandler);
343 if (isCapturingToTexture) {
350 surfaceHelper.setListener(this); 344 surfaceHelper.setListener(this);
351 isCapturingToTexture = true;
352 } else {
353 surfaceHelper = null;
354 isCapturingToTexture = false;
355 } 345 }
356 } 346 }
357 347
358 private void checkIsOnCameraThread() { 348 private void checkIsOnCameraThread() {
359 if (Thread.currentThread() != cameraThread) { 349 if (Thread.currentThread() != cameraThread) {
360 throw new IllegalStateException("Wrong thread"); 350 throw new IllegalStateException("Wrong thread");
361 } 351 }
362 } 352 }
363 353
364 // Returns the camera index for camera with name |deviceName|, or -1 if no suc h camera can be 354 // Returns the camera index for camera with name |deviceName|, or -1 if no suc h camera can be
(...skipping 25 matching lines...) Expand all
390 @Override 380 @Override
391 public void run() { 381 public void run() {
392 if (camera != null) { 382 if (camera != null) {
393 throw new IllegalStateException("Release called while camera is runnin g"); 383 throw new IllegalStateException("Release called while camera is runnin g");
394 } 384 }
395 if (cameraStatistics.pendingFramesCount() != 0) { 385 if (cameraStatistics.pendingFramesCount() != 0) {
396 throw new IllegalStateException("Release called with pending frames le ft"); 386 throw new IllegalStateException("Release called with pending frames le ft");
397 } 387 }
398 } 388 }
399 }); 389 });
400 if (isCapturingToTexture) { 390 surfaceHelper.disconnect();
401 surfaceHelper.disconnect();
402 }
403 cameraThread.quit(); 391 cameraThread.quit();
404 ThreadUtils.joinUninterruptibly(cameraThread); 392 ThreadUtils.joinUninterruptibly(cameraThread);
405 cameraThread = null; 393 cameraThread = null;
406 } 394 }
407 395
408 // Used for testing purposes to check if release() has been called. 396 // Used for testing purposes to check if release() has been called.
409 public boolean isReleased() { 397 public boolean isReleased() {
410 return (cameraThread == null); 398 return (cameraThread == null);
411 } 399 }
412 400
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 Logging.d(TAG, "Opening camera " + id); 436 Logging.d(TAG, "Opening camera " + id);
449 firstFrameReported = false; 437 firstFrameReported = false;
450 if (eventsHandler != null) { 438 if (eventsHandler != null) {
451 eventsHandler.onCameraOpening(id); 439 eventsHandler.onCameraOpening(id);
452 } 440 }
453 camera = Camera.open(id); 441 camera = Camera.open(id);
454 info = new Camera.CameraInfo(); 442 info = new Camera.CameraInfo();
455 Camera.getCameraInfo(id, info); 443 Camera.getCameraInfo(id, info);
456 } 444 }
457 try { 445 try {
458 if (isCapturingToTexture) { 446 camera.setPreviewTexture(surfaceHelper.getSurfaceTexture());
459 camera.setPreviewTexture(surfaceHelper.getSurfaceTexture());
460 } else {
461 cameraGlTexture = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL _OES);
462 cameraSurfaceTexture = new SurfaceTexture(cameraGlTexture);
463 camera.setPreviewTexture(cameraSurfaceTexture);
464 }
465 } catch (IOException e) { 447 } catch (IOException e) {
466 Logging.e(TAG, "setPreviewTexture failed", error); 448 Logging.e(TAG, "setPreviewTexture failed", error);
467 throw new RuntimeException(e); 449 throw new RuntimeException(e);
468 } 450 }
469 451
470 Logging.d(TAG, "Camera orientation: " + info.orientation + 452 Logging.d(TAG, "Camera orientation: " + info.orientation +
471 " .Device orientation: " + getDeviceOrientation()); 453 " .Device orientation: " + getDeviceOrientation());
472 camera.setErrorCallback(cameraErrorCallback); 454 camera.setErrorCallback(cameraErrorCallback);
473 startPreviewOnCameraThread(width, height, framerate); 455 startPreviewOnCameraThread(width, height, framerate);
474 frameObserver.onCapturerStarted(true); 456 frameObserver.onCapturerStarted(true);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 : " Pending buffers: " + cameraStatistics.pendingFramesTimeStamps () + ".")); 579 : " Pending buffers: " + cameraStatistics.pendingFramesTimeStamps () + "."));
598 } 580 }
599 captureFormat = null; 581 captureFormat = null;
600 582
601 Logging.d(TAG, "Release camera."); 583 Logging.d(TAG, "Release camera.");
602 camera.release(); 584 camera.release();
603 camera = null; 585 camera = null;
604 if (eventsHandler != null) { 586 if (eventsHandler != null) {
605 eventsHandler.onCameraClosed(); 587 eventsHandler.onCameraClosed();
606 } 588 }
607
608 if (cameraGlTexture != 0) {
609 GLES20.glDeleteTextures(1, new int[] {cameraGlTexture}, 0);
610 cameraGlTexture = 0;
611 }
612 if (cameraSurfaceTexture != null) {
613 cameraSurfaceTexture.release();
614 }
615 } 589 }
616 590
617 private void switchCameraOnCameraThread() { 591 private void switchCameraOnCameraThread() {
618 checkIsOnCameraThread(); 592 checkIsOnCameraThread();
619 Logging.d(TAG, "switchCameraOnCameraThread"); 593 Logging.d(TAG, "switchCameraOnCameraThread");
620 stopCaptureOnCameraThread(); 594 stopCaptureOnCameraThread();
621 synchronized (cameraIdLock) { 595 synchronized (cameraIdLock) {
622 id = (id + 1) % Camera.getNumberOfCameras(); 596 id = (id + 1) % Camera.getNumberOfCameras();
623 } 597 }
624 dropNextFrame = true; 598 dropNextFrame = true;
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 private native void nativeOnByteBufferFrameCaptured(long nativeCapturer, 887 private native void nativeOnByteBufferFrameCaptured(long nativeCapturer,
914 byte[] data, int length, int width, int height, int rotation, long timeS tamp); 888 byte[] data, int length, int width, int height, int rotation, long timeS tamp);
915 private native void nativeOnTextureFrameCaptured(long nativeCapturer, int wi dth, int height, 889 private native void nativeOnTextureFrameCaptured(long nativeCapturer, int wi dth, int height,
916 int oesTextureId, float[] transformMatrix, long timestamp); 890 int oesTextureId, float[] transformMatrix, long timestamp);
917 private native void nativeOnOutputFormatRequest(long nativeCapturer, 891 private native void nativeOnOutputFormatRequest(long nativeCapturer,
918 int width, int height, int framerate); 892 int width, int height, int framerate);
919 } 893 }
920 894
921 private static native long nativeCreateVideoCapturer(VideoCapturerAndroid vide oCapturer); 895 private static native long nativeCreateVideoCapturer(VideoCapturerAndroid vide oCapturer);
922 } 896 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698