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}
This commit is contained in:
kjellander
2016-02-11 12:21:45 -08:00
committed by Commit bot
parent 73e2373af2
commit af71655b68
6 changed files with 108 additions and 36 deletions

View File

@ -223,7 +223,7 @@ public class VideoCapturerAndroidTestFixtures {
static public void release(VideoCapturerAndroid capturer) { static public void release(VideoCapturerAndroid capturer) {
assertNotNull(capturer); assertNotNull(capturer);
capturer.release(); capturer.dispose();
assertTrue(capturer.isReleased()); assertTrue(capturer.isReleased());
} }
@ -297,8 +297,9 @@ public class VideoCapturerAndroidTestFixtures {
if (capturer.isCapturingToTexture()) { if (capturer.isCapturingToTexture()) {
capturer.surfaceHelper.returnTextureFrame(); capturer.surfaceHelper.returnTextureFrame();
} }
release(capturer); capturer.dispose();
assertTrue(capturer.isReleased());
assertTrue(events.onCameraOpeningCalled); assertTrue(events.onCameraOpeningCalled);
assertTrue(events.onFirstFrameAvailableCalled); assertTrue(events.onFirstFrameAvailableCalled);
} }
@ -323,7 +324,8 @@ public class VideoCapturerAndroidTestFixtures {
capturer.onOutputFormatRequest(640, 480, 15); capturer.onOutputFormatRequest(640, 480, 15);
capturer.changeCaptureFormat(640, 480, 15); capturer.changeCaptureFormat(640, 480, 15);
release(capturer); capturer.dispose();
assertTrue(capturer.isReleased());
} }
static public void stopRestartVideoSource(VideoCapturerAndroid capturer) static public void stopRestartVideoSource(VideoCapturerAndroid capturer)
@ -382,7 +384,8 @@ public class VideoCapturerAndroidTestFixtures {
capturer.surfaceHelper.returnTextureFrame(); capturer.surfaceHelper.returnTextureFrame();
} }
} }
release(capturer); capturer.dispose();
assertTrue(capturer.isReleased());
} }
static void waitUntilIdle(VideoCapturerAndroid capturer) throws InterruptedException { static void waitUntilIdle(VideoCapturerAndroid capturer) throws InterruptedException {
@ -397,9 +400,10 @@ public class VideoCapturerAndroidTestFixtures {
static public void startWhileCameraIsAlreadyOpen( static public void startWhileCameraIsAlreadyOpen(
VideoCapturerAndroid capturer, Context appContext) throws InterruptedException { VideoCapturerAndroid capturer, Context appContext) throws InterruptedException {
Camera camera = Camera.open(capturer.getCurrentCameraId());
final List<CaptureFormat> formats = capturer.getSupportedFormats(); final List<CaptureFormat> formats = capturer.getSupportedFormats();
final CameraEnumerationAndroid.CaptureFormat format = formats.get(0); final CameraEnumerationAndroid.CaptureFormat format = formats.get(0);
Camera camera = Camera.open(capturer.getCurrentCameraId());
final FakeCapturerObserver observer = new FakeCapturerObserver(); final FakeCapturerObserver observer = new FakeCapturerObserver();
capturer.startCapture(format.width, format.height, format.maxFramerate, capturer.startCapture(format.width, format.height, format.maxFramerate,
@ -413,15 +417,16 @@ public class VideoCapturerAndroidTestFixtures {
assertFalse(observer.WaitForCapturerToStart()); assertFalse(observer.WaitForCapturerToStart());
} }
release(capturer); capturer.dispose();
camera.release(); camera.release();
} }
static public void startWhileCameraIsAlreadyOpenAndCloseCamera( static public void startWhileCameraIsAlreadyOpenAndCloseCamera(
VideoCapturerAndroid capturer, Context appContext) throws InterruptedException { VideoCapturerAndroid capturer, Context appContext) throws InterruptedException {
Camera camera = Camera.open(capturer.getCurrentCameraId());
final List<CaptureFormat> formats = capturer.getSupportedFormats(); final List<CaptureFormat> formats = capturer.getSupportedFormats();
final CameraEnumerationAndroid.CaptureFormat format = formats.get(0); final CameraEnumerationAndroid.CaptureFormat format = formats.get(0);
Camera camera = Camera.open(capturer.getCurrentCameraId());
final FakeCapturerObserver observer = new FakeCapturerObserver(); final FakeCapturerObserver observer = new FakeCapturerObserver();
capturer.startCapture(format.width, format.height, format.maxFramerate, capturer.startCapture(format.width, format.height, format.maxFramerate,
@ -437,20 +442,22 @@ public class VideoCapturerAndroidTestFixtures {
if (capturer.isCapturingToTexture()) { if (capturer.isCapturingToTexture()) {
capturer.surfaceHelper.returnTextureFrame(); capturer.surfaceHelper.returnTextureFrame();
} }
release(capturer); capturer.dispose();
assertTrue(capturer.isReleased());
} }
static public void startWhileCameraIsAlreadyOpenAndStop( static public void startWhileCameraIsAlreadyOpenAndStop(
VideoCapturerAndroid capturer, Context appContext) throws InterruptedException { VideoCapturerAndroid capturer, Context appContext) throws InterruptedException {
Camera camera = Camera.open(capturer.getCurrentCameraId());
final List<CaptureFormat> formats = capturer.getSupportedFormats(); final List<CaptureFormat> formats = capturer.getSupportedFormats();
final CameraEnumerationAndroid.CaptureFormat format = formats.get(0); final CameraEnumerationAndroid.CaptureFormat format = formats.get(0);
Camera camera = Camera.open(capturer.getCurrentCameraId());
final FakeCapturerObserver observer = new FakeCapturerObserver(); final FakeCapturerObserver observer = new FakeCapturerObserver();
capturer.startCapture(format.width, format.height, format.maxFramerate, capturer.startCapture(format.width, format.height, format.maxFramerate,
appContext, observer); appContext, observer);
capturer.stopCapture(); capturer.stopCapture();
release(capturer); capturer.dispose();
assertTrue(capturer.isReleased());
camera.release(); camera.release();
} }
@ -486,7 +493,8 @@ public class VideoCapturerAndroidTestFixtures {
capturer.surfaceHelper.returnTextureFrame(); capturer.surfaceHelper.returnTextureFrame();
} }
release(capturer); capturer.dispose();
assertTrue(capturer.isReleased());
} }
static public void returnBufferLateEndToEnd(VideoCapturerAndroid capturer) static public void returnBufferLateEndToEnd(VideoCapturerAndroid capturer)
@ -545,7 +553,8 @@ public class VideoCapturerAndroidTestFixtures {
capturer.surfaceHelper.returnTextureFrame(); capturer.surfaceHelper.returnTextureFrame();
} }
release(capturer); capturer.dispose();
assertTrue(capturer.isReleased());
} }
static public void scaleCameraOutput(VideoCapturerAndroid capturer) throws InterruptedException { 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 // camera thread. The internal *OnCameraThread() methods must check |camera| for null to check if
// the camera has been stopped. // the camera has been stopped.
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class VideoCapturerAndroid implements public class VideoCapturerAndroid extends VideoCapturer implements
android.hardware.Camera.PreviewCallback, android.hardware.Camera.PreviewCallback,
SurfaceTextureHelper.OnTextureFrameAvailableListener { SurfaceTextureHelper.OnTextureFrameAvailableListener {
private final static String TAG = "VideoCapturerAndroid"; private final static String TAG = "VideoCapturerAndroid";
@ -196,7 +196,12 @@ public class VideoCapturerAndroid implements
if (cameraId == -1) { if (cameraId == -1) {
return null; 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() { public void printStackTrace() {
@ -297,6 +302,11 @@ public class VideoCapturerAndroid implements
return CameraEnumerationAndroid.getSupportedFormatsAsJson(getCurrentCameraId()); return CameraEnumerationAndroid.getSupportedFormatsAsJson(getCurrentCameraId());
} }
// Called from native VideoCapturer_nativeCreateVideoCapturer.
private VideoCapturerAndroid(int cameraId) {
this(cameraId, null, null);
}
private VideoCapturerAndroid(int cameraId, CameraEventsHandler eventsHandler, private VideoCapturerAndroid(int cameraId, CameraEventsHandler eventsHandler,
EglBase.Context sharedContext) { EglBase.Context sharedContext) {
this.id = cameraId; this.id = cameraId;
@ -337,9 +347,9 @@ public class VideoCapturerAndroid implements
return -1; return -1;
} }
// Quits the camera thread. This needs to be done manually, otherwise the thread and handler will // Called by native code to quit the camera thread. This needs to be done manually, otherwise the
// not be garbage collected. // thread and handler will not be garbage collected.
public void release() { private void release() {
Logging.d(TAG, "release"); Logging.d(TAG, "release");
if (isReleased()) { if (isReleased()) {
throw new IllegalStateException("Already released"); throw new IllegalStateException("Already released");
@ -759,4 +769,8 @@ public class VideoCapturerAndroid implements
private native void nativeOnOutputFormatRequest(long nativeCapturer, private native void nativeOnOutputFormatRequest(long nativeCapturer,
int width, int height, int framerate); int width, int height, int framerate);
} }
private static native long nativeCreateVideoCapturer(
VideoCapturerAndroid videoCapturer,
SurfaceTextureHelper surfaceHelper);
} }

View File

@ -213,4 +213,16 @@ JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnOutputFormatRequest)
j_width, j_height, j_fps); 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 } // namespace webrtc_jni

View File

@ -910,6 +910,10 @@ JOW(void, MediaSource_free)(JNIEnv*, jclass, jlong j_p) {
CHECK_RELEASE(reinterpret_cast<MediaSourceInterface*>(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) { JOW(void, VideoRenderer_freeWrappedVideoRenderer)(JNIEnv*, jclass, jlong j_p) {
delete reinterpret_cast<JavaVideoRendererWrapper*>(j_p); delete reinterpret_cast<JavaVideoRendererWrapper*>(j_p);
} }
@ -1212,26 +1216,16 @@ JOW(jlong, PeerConnectionFactory_nativeCreateLocalMediaStream)(
} }
JOW(jlong, PeerConnectionFactory_nativeCreateVideoSource)( 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) { 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( scoped_ptr<ConstraintsWrapper> constraints(
new ConstraintsWrapper(jni, j_constraints)); new ConstraintsWrapper(jni, j_constraints));
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory( rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(
factoryFromJava(native_factory)); factoryFromJava(native_factory));
rtc::scoped_refptr<VideoSourceInterface> source( rtc::scoped_refptr<VideoSourceInterface> source(
factory->CreateVideoSource(capturer.release(), constraints.get())); factory->CreateVideoSource(
reinterpret_cast<cricket::VideoCapturer*>(native_capturer),
constraints.get()));
return (jlong)source.release(); return (jlong)source.release();
} }

View File

@ -108,12 +108,10 @@ public class PeerConnectionFactory {
nativeCreateLocalMediaStream(nativeFactory, label)); nativeCreateLocalMediaStream(nativeFactory, label));
} }
// The VideoSource takes ownership of |capturer|, so capturer.release() should not be called
// manually after this.
public VideoSource createVideoSource( public VideoSource createVideoSource(
VideoCapturerAndroid capturer, MediaConstraints constraints) { VideoCapturer capturer, MediaConstraints constraints) {
return new VideoSource(nativeCreateVideoSource( return new VideoSource(nativeCreateVideoSource(
nativeFactory, capturer, constraints)); nativeFactory, capturer.takeNativeVideoCapturer(), constraints));
} }
public VideoTrack createVideoTrack(String id, VideoSource source) { public VideoTrack createVideoTrack(String id, VideoSource source) {
@ -223,7 +221,7 @@ public class PeerConnectionFactory {
long nativeFactory, String label); long nativeFactory, String label);
private static native long nativeCreateVideoSource( private static native long nativeCreateVideoSource(
long nativeFactory, VideoCapturerAndroid videoCapturer, long nativeFactory, long nativeVideoCapturer,
MediaConstraints constraints); MediaConstraints constraints);
private static native long nativeCreateVideoTrack( private static native long nativeCreateVideoTrack(

View File

@ -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);
}