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

Review URL: https://codereview.webrtc.org/1684403002 .

Cr-Commit-Position: refs/heads/master@{#11582}
This commit is contained in:
Magnus Jedvert 2016-02-11 18:25:09 +01:00
parent 9f35d55c58
commit 09eab315fd
6 changed files with 36 additions and 108 deletions

View File

@ -223,7 +223,7 @@ public class VideoCapturerAndroidTestFixtures {
static public void release(VideoCapturerAndroid capturer) {
assertNotNull(capturer);
capturer.dispose();
capturer.release();
assertTrue(capturer.isReleased());
}
@ -297,9 +297,8 @@ public class VideoCapturerAndroidTestFixtures {
if (capturer.isCapturingToTexture()) {
capturer.surfaceHelper.returnTextureFrame();
}
capturer.dispose();
release(capturer);
assertTrue(capturer.isReleased());
assertTrue(events.onCameraOpeningCalled);
assertTrue(events.onFirstFrameAvailableCalled);
}
@ -324,8 +323,7 @@ public class VideoCapturerAndroidTestFixtures {
capturer.onOutputFormatRequest(640, 480, 15);
capturer.changeCaptureFormat(640, 480, 15);
capturer.dispose();
assertTrue(capturer.isReleased());
release(capturer);
}
static public void stopRestartVideoSource(VideoCapturerAndroid capturer)
@ -384,8 +382,7 @@ public class VideoCapturerAndroidTestFixtures {
capturer.surfaceHelper.returnTextureFrame();
}
}
capturer.dispose();
assertTrue(capturer.isReleased());
release(capturer);
}
static void waitUntilIdle(VideoCapturerAndroid capturer) throws InterruptedException {
@ -400,10 +397,9 @@ public class VideoCapturerAndroidTestFixtures {
static public void startWhileCameraIsAlreadyOpen(
VideoCapturerAndroid capturer, Context appContext) throws InterruptedException {
Camera camera = Camera.open(capturer.getCurrentCameraId());
final List<CaptureFormat> 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,
@ -417,16 +413,15 @@ public class VideoCapturerAndroidTestFixtures {
assertFalse(observer.WaitForCapturerToStart());
}
capturer.dispose();
release(capturer);
camera.release();
}
static public void startWhileCameraIsAlreadyOpenAndCloseCamera(
VideoCapturerAndroid capturer, Context appContext) throws InterruptedException {
Camera camera = Camera.open(capturer.getCurrentCameraId());
final List<CaptureFormat> 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,
@ -442,22 +437,20 @@ public class VideoCapturerAndroidTestFixtures {
if (capturer.isCapturingToTexture()) {
capturer.surfaceHelper.returnTextureFrame();
}
capturer.dispose();
assertTrue(capturer.isReleased());
release(capturer);
}
static public void startWhileCameraIsAlreadyOpenAndStop(
VideoCapturerAndroid capturer, Context appContext) throws InterruptedException {
Camera camera = Camera.open(capturer.getCurrentCameraId());
final List<CaptureFormat> 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();
capturer.dispose();
assertTrue(capturer.isReleased());
release(capturer);
camera.release();
}
@ -493,8 +486,7 @@ public class VideoCapturerAndroidTestFixtures {
capturer.surfaceHelper.returnTextureFrame();
}
capturer.dispose();
assertTrue(capturer.isReleased());
release(capturer);
}
static public void returnBufferLateEndToEnd(VideoCapturerAndroid capturer)
@ -553,8 +545,7 @@ public class VideoCapturerAndroidTestFixtures {
capturer.surfaceHelper.returnTextureFrame();
}
capturer.dispose();
assertTrue(capturer.isReleased());
release(capturer);
}
static public void scaleCameraOutput(VideoCapturerAndroid capturer) throws InterruptedException {

View File

@ -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 extends VideoCapturer implements
public class VideoCapturerAndroid implements
android.hardware.Camera.PreviewCallback,
SurfaceTextureHelper.OnTextureFrameAvailableListener {
private final static String TAG = "VideoCapturerAndroid";
@ -196,12 +196,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements
if (cameraId == -1) {
return null;
}
final VideoCapturerAndroid capturer = new VideoCapturerAndroid(cameraId, eventsHandler,
sharedEglContext);
capturer.setNativeCapturer(
nativeCreateVideoCapturer(capturer, capturer.surfaceHelper));
return capturer;
return new VideoCapturerAndroid(cameraId, eventsHandler, sharedEglContext);
}
public void printStackTrace() {
@ -302,11 +297,6 @@ public class VideoCapturerAndroid extends VideoCapturer 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;
@ -347,9 +337,9 @@ public class VideoCapturerAndroid extends VideoCapturer implements
return -1;
}
// 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() {
// Quits the camera thread. This needs to be done manually, otherwise the thread and handler will
// not be garbage collected.
public void release() {
Logging.d(TAG, "release");
if (isReleased()) {
throw new IllegalStateException("Already released");
@ -769,8 +759,4 @@ public class VideoCapturerAndroid extends VideoCapturer implements
private native void nativeOnOutputFormatRequest(long nativeCapturer,
int width, int height, int framerate);
}
private static native long nativeCreateVideoCapturer(
VideoCapturerAndroid videoCapturer,
SurfaceTextureHelper surfaceHelper);
}

View File

@ -213,16 +213,4 @@ 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<webrtc::AndroidVideoCapturerDelegate> delegate =
new rtc::RefCountedObject<AndroidVideoCapturerJni>(
jni, j_video_capturer, j_surface_texture_helper);
rtc::scoped_ptr<cricket::VideoCapturer> capturer(
new webrtc::AndroidVideoCapturer(delegate));
// Caller takes ownership of the cricket::VideoCapturer* pointer.
return jlongFromPointer(capturer.release());
}
} // namespace webrtc_jni

View File

@ -910,10 +910,6 @@ JOW(void, MediaSource_free)(JNIEnv*, jclass, jlong j_p) {
CHECK_RELEASE(reinterpret_cast<MediaSourceInterface*>(j_p));
}
JOW(void, VideoCapturer_free)(JNIEnv*, jclass, jlong j_p) {
delete reinterpret_cast<cricket::VideoCapturer*>(j_p);
}
JOW(void, VideoRenderer_freeWrappedVideoRenderer)(JNIEnv*, jclass, jlong j_p) {
delete reinterpret_cast<JavaVideoRendererWrapper*>(j_p);
}
@ -1216,16 +1212,26 @@ JOW(jlong, PeerConnectionFactory_nativeCreateLocalMediaStream)(
}
JOW(jlong, PeerConnectionFactory_nativeCreateVideoSource)(
JNIEnv* jni, jclass, jlong native_factory, jlong native_capturer,
JNIEnv* jni, jclass, jlong native_factory, jobject j_video_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<webrtc::AndroidVideoCapturerDelegate> delegate =
new rtc::RefCountedObject<AndroidVideoCapturerJni>(
jni, j_video_capturer, j_surface_texture_helper);
rtc::scoped_ptr<cricket::VideoCapturer> capturer(
new webrtc::AndroidVideoCapturer(delegate));
// Create a webrtc::VideoSourceInterface from the cricket::VideoCapturer,
// native factory and constraints.
scoped_ptr<ConstraintsWrapper> constraints(
new ConstraintsWrapper(jni, j_constraints));
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
factoryFromJava(native_factory));
rtc::scoped_refptr<VideoSourceInterface> source(
factory->CreateVideoSource(
reinterpret_cast<cricket::VideoCapturer*>(native_capturer),
constraints.get()));
factory->CreateVideoSource(capturer.release(), constraints.get()));
return (jlong)source.release();
}

View File

@ -108,10 +108,12 @@ 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(
VideoCapturer capturer, MediaConstraints constraints) {
VideoCapturerAndroid capturer, MediaConstraints constraints) {
return new VideoSource(nativeCreateVideoSource(
nativeFactory, capturer.takeNativeVideoCapturer(), constraints));
nativeFactory, capturer, constraints));
}
public VideoTrack createVideoTrack(String id, VideoSource source) {
@ -221,7 +223,7 @@ public class PeerConnectionFactory {
long nativeFactory, String label);
private static native long nativeCreateVideoSource(
long nativeFactory, long nativeVideoCapturer,
long nativeFactory, VideoCapturerAndroid videoCapturer,
MediaConstraints constraints);
private static native long nativeCreateVideoTrack(

View File

@ -1,45 +0,0 @@
/*
* 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);
}