From e0bce240652bcf4031ae61985938e968469d3f53 Mon Sep 17 00:00:00 2001 From: perkj Date: Mon, 5 Oct 2015 16:21:54 +0200 Subject: [PATCH] VideoCapturerAndroid: Add custom nativeCreateVideoCapturer() This CL shouldn't make any functional changes. It adds a new VideoCapturerAndroid.nativeCreateVideoCapturer() instead of always using VideoCapturer.nativeCreateVideoCapturer(). The purpose is to simplify androidvideocapturer_jni and VideoCapturerAndroid.create(). This way, it is possible to use the ctor instead of VideoCapturerAndroid.init() to initialize variables, and they can be made final etc. R=perkj@webrtc.org Review URL: https://codereview.webrtc.org/1360173002 . Cr-Commit-Position: refs/heads/master@{#10171} --- .../org/webrtc/VideoCapturerAndroid.java | 62 +++++++++---------- .../java/jni/androidvideocapturer_jni.cc | 36 +++-------- .../java/jni/androidvideocapturer_jni.h | 14 ++--- .../app/webrtc/java/jni/peerconnection_jni.cc | 26 ++++---- 4 files changed, 60 insertions(+), 78 deletions(-) diff --git a/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java b/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java index 8d330138a5..f0fbcccdb2 100644 --- a/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java +++ b/talk/app/webrtc/java/android/org/webrtc/VideoCapturerAndroid.java @@ -92,7 +92,7 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba private final Object pendingCameraSwitchLock = new Object(); private volatile boolean pendingCameraSwitch; private CapturerObserver frameObserver = null; - private CameraErrorHandler errorHandler = null; + private final CameraErrorHandler errorHandler; // Camera error callback. private final Camera.ErrorCallback cameraErrorCallback = @@ -155,15 +155,14 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba void onCameraSwitchError(String errorDescription); } - public static VideoCapturerAndroid create(String name, - CameraErrorHandler errorHandler) { - VideoCapturer capturer = VideoCapturer.create(name); - if (capturer != null) { - VideoCapturerAndroid capturerAndroid = (VideoCapturerAndroid) capturer; - capturerAndroid.errorHandler = errorHandler; - return capturerAndroid; + public static VideoCapturerAndroid create(String name, CameraErrorHandler errorHandler) { + final int cameraId = lookupDeviceName(name); + if (cameraId == -1) { + return null; } - return null; + final VideoCapturerAndroid capturer = new VideoCapturerAndroid(cameraId, errorHandler); + capturer.setNativeCapturer(nativeCreateVideoCapturer(capturer)); + return capturer; } // Switch camera to the next valid camera id. This can only be called while @@ -244,8 +243,15 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba return CameraEnumerationAndroid.getSupportedFormatsAsJson(getCurrentCameraId()); } - private VideoCapturerAndroid() { + // Called from native VideoCapturer_nativeCreateVideoCapturer. + private VideoCapturerAndroid(int cameraId) { + this(cameraId, null); + } + + private VideoCapturerAndroid(int cameraId, CameraErrorHandler errorHandler) { Logging.d(TAG, "VideoCapturerAndroid"); + this.id = cameraId; + this.errorHandler = errorHandler; cameraThread = new HandlerThread(TAG); cameraThread.start(); cameraThreadHandler = new Handler(cameraThread.getLooper()); @@ -258,30 +264,22 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba } } - // Called by native code. - // Initializes local variables for the camera named |deviceName|. If |deviceName| is empty, the - // first available device is used in order to be compatible with the generic VideoCapturer class. - boolean init(String deviceName) { - Logging.d(TAG, "init: " + deviceName); - if (deviceName == null) - return false; - + // Returns the camera index for camera with name |deviceName|, or -1 if no such camera can be + // found. If |deviceName| is empty, the first available device is used. + private static int lookupDeviceName(String deviceName) { + Logging.d(TAG, "lookupDeviceName: " + deviceName); + if (deviceName == null || Camera.getNumberOfCameras() == 0) { + return -1; + } if (deviceName.isEmpty()) { - synchronized (cameraIdLock) { - this.id = 0; - } - return true; - } else { - for (int i = 0; i < Camera.getNumberOfCameras(); ++i) { - if (deviceName.equals(CameraEnumerationAndroid.getDeviceName(i))) { - synchronized (cameraIdLock) { - this.id = i; - } - return true; - } + return 0; + } + for (int i = 0; i < Camera.getNumberOfCameras(); ++i) { + if (deviceName.equals(CameraEnumerationAndroid.getDeviceName(i))) { + return i; } } - return false; + return -1; } // Called by native code to quit the camera thread. This needs to be done manually, otherwise the @@ -769,4 +767,6 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba private native void nativeOnOutputFormatRequest(long nativeCapturer, int width, int height, int fps); } + + private static native long nativeCreateVideoCapturer(VideoCapturerAndroid videoCapturer); } diff --git a/talk/app/webrtc/java/jni/androidvideocapturer_jni.cc b/talk/app/webrtc/java/jni/androidvideocapturer_jni.cc index 74a9372d86..93b169526c 100644 --- a/talk/app/webrtc/java/jni/androidvideocapturer_jni.cc +++ b/talk/app/webrtc/java/jni/androidvideocapturer_jni.cc @@ -46,22 +46,6 @@ int AndroidVideoCapturerJni::SetAndroidObjects(JNIEnv* jni, return 0; } -// static -rtc::scoped_refptr -AndroidVideoCapturerJni::Create(JNIEnv* jni, - jobject j_video_capture, - jstring device_name) { - LOG(LS_INFO) << "AndroidVideoCapturerJni::Create"; - rtc::scoped_refptr capturer( - new rtc::RefCountedObject(jni, j_video_capture)); - - if (capturer->Init(device_name)) { - return capturer; - } - LOG(LS_ERROR) << "AndroidVideoCapturerJni init fails"; - return nullptr; -} - AndroidVideoCapturerJni::AndroidVideoCapturerJni(JNIEnv* jni, jobject j_video_capturer) : j_capturer_global_(jni, j_video_capturer), @@ -76,16 +60,6 @@ AndroidVideoCapturerJni::AndroidVideoCapturerJni(JNIEnv* jni, thread_checker_.DetachFromThread(); } -bool AndroidVideoCapturerJni::Init(jstring device_name) { - const jmethodID m(GetMethodID( - jni(), *j_video_capturer_class_, "init", "(Ljava/lang/String;)Z")); - if (!jni()->CallBooleanMethod(*j_capturer_global_, m, device_name)) { - return false; - } - CHECK_EXCEPTION(jni()) << "error during CallVoidMethod"; - return true; -} - AndroidVideoCapturerJni::~AndroidVideoCapturerJni() { LOG(LS_INFO) << "AndroidVideoCapturerJni dtor"; jni()->CallVoidMethod( @@ -246,4 +220,14 @@ JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnOutputFormatRequest) j_width, j_height, j_fps); } +JOW(jlong, VideoCapturerAndroid_nativeCreateVideoCapturer) + (JNIEnv* jni, jclass, jobject j_video_capturer) { + rtc::scoped_refptr delegate = + new rtc::RefCountedObject(jni, j_video_capturer); + 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/talk/app/webrtc/java/jni/androidvideocapturer_jni.h b/talk/app/webrtc/java/jni/androidvideocapturer_jni.h index c270439377..9a356d8c62 100644 --- a/talk/app/webrtc/java/jni/androidvideocapturer_jni.h +++ b/talk/app/webrtc/java/jni/androidvideocapturer_jni.h @@ -46,12 +46,7 @@ class AndroidVideoCapturerJni : public webrtc::AndroidVideoCapturerDelegate { public: static int SetAndroidObjects(JNIEnv* jni, jobject appliction_context); - // Creates a new instance of AndroidVideoCapturerJni. Returns a nullptr if - // it can't be created. This happens if |device_name| is invalid. - static rtc::scoped_refptr Create( - JNIEnv* jni, - jobject j_video_capture, // Instance of VideoCapturerAndroid - jstring device_name); // Name of the camera to use. + AndroidVideoCapturerJni(JNIEnv* jni, jobject j_video_capturer); void Start(int width, int height, int framerate, webrtc::AndroidVideoCapturer* capturer) override; @@ -68,12 +63,11 @@ class AndroidVideoCapturerJni : public webrtc::AndroidVideoCapturerDelegate { int rotation, int64 time_stamp); void OnOutputFormatRequest(int width, int height, int fps); -protected: - AndroidVideoCapturerJni(JNIEnv* jni, jobject j_video_capturer); + + protected: ~AndroidVideoCapturerJni(); -private: - bool Init(jstring device_name); + private: void ReturnBuffer(int64 time_stamp); JNIEnv* jni(); diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc index 67d51bd9cb..5fa1617644 100644 --- a/talk/app/webrtc/java/jni/peerconnection_jni.cc +++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc @@ -1672,17 +1672,21 @@ JOW(jobject, VideoCapturer_nativeCreateVideoCapturer)( #if defined(ANDROID) jclass j_video_capturer_class( FindClass(jni, "org/webrtc/VideoCapturerAndroid")); - const jmethodID j_videocapturer_ctor(GetMethodID( - jni, j_video_capturer_class, "", "()V")); - jobject j_video_capturer = jni->NewObject(j_video_capturer_class, - j_videocapturer_ctor); - CHECK_EXCEPTION(jni) << "error during NewObject"; - - rtc::scoped_refptr delegate = - AndroidVideoCapturerJni::Create(jni, j_video_capturer, j_device_name); - if (!delegate.get()) + const int camera_id = jni->CallStaticIntMethod( + j_video_capturer_class, + GetStaticMethodID(jni, j_video_capturer_class, "lookupDeviceName", + "(Ljava/lang/String;)I"), + j_device_name); + CHECK_EXCEPTION(jni) << "error during VideoCapturerAndroid.lookupDeviceName"; + if (camera_id == -1) return nullptr; - rtc::scoped_ptr capturer( + jobject j_video_capturer = jni->NewObject( + j_video_capturer_class, + GetMethodID(jni, j_video_capturer_class, "", "(I)V"), camera_id); + CHECK_EXCEPTION(jni) << "error during creation of VideoCapturerAndroid"; + rtc::scoped_refptr delegate = + new rtc::RefCountedObject(jni, j_video_capturer); + rtc::scoped_ptr capturer( new webrtc::AndroidVideoCapturer(delegate)); #else @@ -1712,7 +1716,7 @@ JOW(jobject, VideoCapturer_nativeCreateVideoCapturer)( jni, j_video_capturer_class, "setNativeCapturer", "(J)V")); jni->CallVoidMethod(j_video_capturer, j_videocapturer_set_native_capturer, - (jlong)capturer.release()); + jlongFromPointer(capturer.release())); CHECK_EXCEPTION(jni) << "error during setNativeCapturer"; return j_video_capturer; }