From af71655b682d2c91a4843bfd911d11e5f68cfe86 Mon Sep 17 00:00:00 2001 From: kjellander Date: Thu, 11 Feb 2016 12:21:45 -0800 Subject: [PATCH] Revert of Android: Remove VideoCapturer (patchset #2 id:20001 of https://codereview.webrtc.org/1684403002/ ) Reason for revert: Breaks downstream compilation. Please reland in a non-breaking fashion. Original issue's description: > Android: Remove VideoCapturer > > This CL makes PeerConnectionFactory.createVideoSource() and nativeCreateVideoSource work directly with VideoCapturerAndroid instead of going via VideoCapturer. The native part is now created in nativeCreateVideoSource() instead of doing it immediately in VideoCapturerAndroid.create(). > > BUG=webrtc:5519 > R=perkj@webrtc.org > > Committed: https://crrev.com/09eab315fddc3432c19d8f662f4b9360f2a58010 > Cr-Commit-Position: refs/heads/master@{#11582} TBR=perkj@webrtc.org,magjed@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:5519 Review URL: https://codereview.webrtc.org/1690073002 Cr-Commit-Position: refs/heads/master@{#11586} --- .../VideoCapturerAndroidTestFixtures.java | 33 +++++++++----- .../org/webrtc/VideoCapturerAndroid.java | 24 +++++++--- .../api/java/jni/androidvideocapturer_jni.cc | 12 +++++ webrtc/api/java/jni/peerconnection_jni.cc | 22 ++++----- .../src/org/webrtc/PeerConnectionFactory.java | 8 ++-- .../java/src/org/webrtc/VideoCapturer.java | 45 +++++++++++++++++++ 6 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 webrtc/api/java/src/org/webrtc/VideoCapturer.java diff --git a/webrtc/api/androidtests/src/org/webrtc/VideoCapturerAndroidTestFixtures.java b/webrtc/api/androidtests/src/org/webrtc/VideoCapturerAndroidTestFixtures.java index c20ea2a6ff..4b41611032 100644 --- a/webrtc/api/androidtests/src/org/webrtc/VideoCapturerAndroidTestFixtures.java +++ b/webrtc/api/androidtests/src/org/webrtc/VideoCapturerAndroidTestFixtures.java @@ -223,7 +223,7 @@ public class VideoCapturerAndroidTestFixtures { static public void release(VideoCapturerAndroid capturer) { assertNotNull(capturer); - capturer.release(); + capturer.dispose(); assertTrue(capturer.isReleased()); } @@ -297,8 +297,9 @@ public class VideoCapturerAndroidTestFixtures { if (capturer.isCapturingToTexture()) { capturer.surfaceHelper.returnTextureFrame(); } - release(capturer); + capturer.dispose(); + assertTrue(capturer.isReleased()); assertTrue(events.onCameraOpeningCalled); assertTrue(events.onFirstFrameAvailableCalled); } @@ -323,7 +324,8 @@ public class VideoCapturerAndroidTestFixtures { capturer.onOutputFormatRequest(640, 480, 15); capturer.changeCaptureFormat(640, 480, 15); - release(capturer); + capturer.dispose(); + assertTrue(capturer.isReleased()); } static public void stopRestartVideoSource(VideoCapturerAndroid capturer) @@ -382,7 +384,8 @@ public class VideoCapturerAndroidTestFixtures { capturer.surfaceHelper.returnTextureFrame(); } } - release(capturer); + capturer.dispose(); + assertTrue(capturer.isReleased()); } static void waitUntilIdle(VideoCapturerAndroid capturer) throws InterruptedException { @@ -397,9 +400,10 @@ public class VideoCapturerAndroidTestFixtures { static public void startWhileCameraIsAlreadyOpen( VideoCapturerAndroid capturer, Context appContext) throws InterruptedException { + Camera camera = Camera.open(capturer.getCurrentCameraId()); + final List formats = capturer.getSupportedFormats(); final CameraEnumerationAndroid.CaptureFormat format = formats.get(0); - Camera camera = Camera.open(capturer.getCurrentCameraId()); final FakeCapturerObserver observer = new FakeCapturerObserver(); capturer.startCapture(format.width, format.height, format.maxFramerate, @@ -413,15 +417,16 @@ public class VideoCapturerAndroidTestFixtures { assertFalse(observer.WaitForCapturerToStart()); } - release(capturer); + capturer.dispose(); camera.release(); } static public void startWhileCameraIsAlreadyOpenAndCloseCamera( VideoCapturerAndroid capturer, Context appContext) throws InterruptedException { + Camera camera = Camera.open(capturer.getCurrentCameraId()); + final List formats = capturer.getSupportedFormats(); final CameraEnumerationAndroid.CaptureFormat format = formats.get(0); - Camera camera = Camera.open(capturer.getCurrentCameraId()); final FakeCapturerObserver observer = new FakeCapturerObserver(); capturer.startCapture(format.width, format.height, format.maxFramerate, @@ -437,20 +442,22 @@ public class VideoCapturerAndroidTestFixtures { if (capturer.isCapturingToTexture()) { capturer.surfaceHelper.returnTextureFrame(); } - release(capturer); + capturer.dispose(); + assertTrue(capturer.isReleased()); } static public void startWhileCameraIsAlreadyOpenAndStop( VideoCapturerAndroid capturer, Context appContext) throws InterruptedException { + Camera camera = Camera.open(capturer.getCurrentCameraId()); final List formats = capturer.getSupportedFormats(); final CameraEnumerationAndroid.CaptureFormat format = formats.get(0); - Camera camera = Camera.open(capturer.getCurrentCameraId()); final FakeCapturerObserver observer = new FakeCapturerObserver(); capturer.startCapture(format.width, format.height, format.maxFramerate, appContext, observer); capturer.stopCapture(); - release(capturer); + capturer.dispose(); + assertTrue(capturer.isReleased()); camera.release(); } @@ -486,7 +493,8 @@ public class VideoCapturerAndroidTestFixtures { capturer.surfaceHelper.returnTextureFrame(); } - release(capturer); + capturer.dispose(); + assertTrue(capturer.isReleased()); } static public void returnBufferLateEndToEnd(VideoCapturerAndroid capturer) @@ -545,7 +553,8 @@ public class VideoCapturerAndroidTestFixtures { capturer.surfaceHelper.returnTextureFrame(); } - release(capturer); + capturer.dispose(); + assertTrue(capturer.isReleased()); } static public void scaleCameraOutput(VideoCapturerAndroid capturer) throws InterruptedException { diff --git a/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java b/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java index b539f125c0..5edca3b83c 100644 --- a/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java +++ b/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java @@ -45,7 +45,7 @@ import java.util.concurrent.TimeUnit; // camera thread. The internal *OnCameraThread() methods must check |camera| for null to check if // the camera has been stopped. @SuppressWarnings("deprecation") -public class VideoCapturerAndroid implements +public class VideoCapturerAndroid extends VideoCapturer implements android.hardware.Camera.PreviewCallback, SurfaceTextureHelper.OnTextureFrameAvailableListener { private final static String TAG = "VideoCapturerAndroid"; @@ -196,7 +196,12 @@ public class VideoCapturerAndroid implements if (cameraId == -1) { return null; } - return new VideoCapturerAndroid(cameraId, eventsHandler, sharedEglContext); + + final VideoCapturerAndroid capturer = new VideoCapturerAndroid(cameraId, eventsHandler, + sharedEglContext); + capturer.setNativeCapturer( + nativeCreateVideoCapturer(capturer, capturer.surfaceHelper)); + return capturer; } public void printStackTrace() { @@ -297,6 +302,11 @@ public class VideoCapturerAndroid implements return CameraEnumerationAndroid.getSupportedFormatsAsJson(getCurrentCameraId()); } + // Called from native VideoCapturer_nativeCreateVideoCapturer. + private VideoCapturerAndroid(int cameraId) { + this(cameraId, null, null); + } + private VideoCapturerAndroid(int cameraId, CameraEventsHandler eventsHandler, EglBase.Context sharedContext) { this.id = cameraId; @@ -337,9 +347,9 @@ public class VideoCapturerAndroid implements return -1; } - // Quits the camera thread. This needs to be done manually, otherwise the thread and handler will - // not be garbage collected. - public void release() { + // Called by native code to quit the camera thread. This needs to be done manually, otherwise the + // thread and handler will not be garbage collected. + private void release() { Logging.d(TAG, "release"); if (isReleased()) { throw new IllegalStateException("Already released"); @@ -759,4 +769,8 @@ public class VideoCapturerAndroid implements private native void nativeOnOutputFormatRequest(long nativeCapturer, int width, int height, int framerate); } + + private static native long nativeCreateVideoCapturer( + VideoCapturerAndroid videoCapturer, + SurfaceTextureHelper surfaceHelper); } diff --git a/webrtc/api/java/jni/androidvideocapturer_jni.cc b/webrtc/api/java/jni/androidvideocapturer_jni.cc index 84d4380e8c..98dfd63845 100644 --- a/webrtc/api/java/jni/androidvideocapturer_jni.cc +++ b/webrtc/api/java/jni/androidvideocapturer_jni.cc @@ -213,4 +213,16 @@ JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnOutputFormatRequest) j_width, j_height, j_fps); } +JOW(jlong, VideoCapturerAndroid_nativeCreateVideoCapturer) + (JNIEnv* jni, jclass, + jobject j_video_capturer, jobject j_surface_texture_helper) { + rtc::scoped_refptr delegate = + new rtc::RefCountedObject( + jni, j_video_capturer, j_surface_texture_helper); + rtc::scoped_ptr capturer( + new webrtc::AndroidVideoCapturer(delegate)); + // Caller takes ownership of the cricket::VideoCapturer* pointer. + return jlongFromPointer(capturer.release()); +} + } // namespace webrtc_jni diff --git a/webrtc/api/java/jni/peerconnection_jni.cc b/webrtc/api/java/jni/peerconnection_jni.cc index 236ac71308..a19e79a624 100644 --- a/webrtc/api/java/jni/peerconnection_jni.cc +++ b/webrtc/api/java/jni/peerconnection_jni.cc @@ -910,6 +910,10 @@ JOW(void, MediaSource_free)(JNIEnv*, jclass, jlong j_p) { CHECK_RELEASE(reinterpret_cast(j_p)); } +JOW(void, VideoCapturer_free)(JNIEnv*, jclass, jlong j_p) { + delete reinterpret_cast(j_p); +} + JOW(void, VideoRenderer_freeWrappedVideoRenderer)(JNIEnv*, jclass, jlong j_p) { delete reinterpret_cast(j_p); } @@ -1212,26 +1216,16 @@ JOW(jlong, PeerConnectionFactory_nativeCreateLocalMediaStream)( } JOW(jlong, PeerConnectionFactory_nativeCreateVideoSource)( - JNIEnv* jni, jclass, jlong native_factory, jobject j_video_capturer, + JNIEnv* jni, jclass, jlong native_factory, jlong native_capturer, jobject j_constraints) { - // Create a cricket::VideoCapturer from |j_video_capturer|. - jobject j_surface_texture_helper = GetObjectField( - jni, j_video_capturer, - GetFieldID(jni, FindClass(jni, "org/webrtc/VideoCapturerAndroid"), - "surfaceHelper", "Lorg/webrtc/SurfaceTextureHelper;")); - rtc::scoped_refptr delegate = - new rtc::RefCountedObject( - jni, j_video_capturer, j_surface_texture_helper); - rtc::scoped_ptr capturer( - new webrtc::AndroidVideoCapturer(delegate)); - // Create a webrtc::VideoSourceInterface from the cricket::VideoCapturer, - // native factory and constraints. scoped_ptr constraints( new ConstraintsWrapper(jni, j_constraints)); rtc::scoped_refptr factory( factoryFromJava(native_factory)); rtc::scoped_refptr source( - factory->CreateVideoSource(capturer.release(), constraints.get())); + factory->CreateVideoSource( + reinterpret_cast(native_capturer), + constraints.get())); return (jlong)source.release(); } diff --git a/webrtc/api/java/src/org/webrtc/PeerConnectionFactory.java b/webrtc/api/java/src/org/webrtc/PeerConnectionFactory.java index e71c12f38a..ff6e89f809 100644 --- a/webrtc/api/java/src/org/webrtc/PeerConnectionFactory.java +++ b/webrtc/api/java/src/org/webrtc/PeerConnectionFactory.java @@ -108,12 +108,10 @@ public class PeerConnectionFactory { nativeCreateLocalMediaStream(nativeFactory, label)); } - // The VideoSource takes ownership of |capturer|, so capturer.release() should not be called - // manually after this. public VideoSource createVideoSource( - VideoCapturerAndroid capturer, MediaConstraints constraints) { + VideoCapturer capturer, MediaConstraints constraints) { return new VideoSource(nativeCreateVideoSource( - nativeFactory, capturer, constraints)); + nativeFactory, capturer.takeNativeVideoCapturer(), constraints)); } public VideoTrack createVideoTrack(String id, VideoSource source) { @@ -223,7 +221,7 @@ public class PeerConnectionFactory { long nativeFactory, String label); private static native long nativeCreateVideoSource( - long nativeFactory, VideoCapturerAndroid videoCapturer, + long nativeFactory, long nativeVideoCapturer, MediaConstraints constraints); private static native long nativeCreateVideoTrack( diff --git a/webrtc/api/java/src/org/webrtc/VideoCapturer.java b/webrtc/api/java/src/org/webrtc/VideoCapturer.java new file mode 100644 index 0000000000..9a479a3d07 --- /dev/null +++ b/webrtc/api/java/src/org/webrtc/VideoCapturer.java @@ -0,0 +1,45 @@ +/* + * Copyright 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +package org.webrtc; + +/** Java version of cricket::VideoCapturer. */ +// TODO(perkj): Merge VideoCapturer and VideoCapturerAndroid. +public class VideoCapturer { + private long nativeVideoCapturer; + + protected VideoCapturer() { + } + + // Sets |nativeCapturer| to be owned by VideoCapturer. + protected void setNativeCapturer(long nativeCapturer) { + this.nativeVideoCapturer = nativeCapturer; + } + + // Package-visible for PeerConnectionFactory. + long takeNativeVideoCapturer() { + if (nativeVideoCapturer == 0) { + throw new RuntimeException("Capturer can only be taken once!"); + } + long ret = nativeVideoCapturer; + nativeVideoCapturer = 0; + return ret; + } + + public void dispose() { + // No-op iff this capturer is owned by a source (see comment on + // PeerConnectionFactoryInterface::CreateVideoSource()). + if (nativeVideoCapturer != 0) { + free(nativeVideoCapturer); + } + } + + private static native void free(long nativeVideoCapturer); +}