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}
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
@ -46,22 +46,6 @@ int AndroidVideoCapturerJni::SetAndroidObjects(JNIEnv* jni,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
rtc::scoped_refptr<AndroidVideoCapturerJni>
|
||||
AndroidVideoCapturerJni::Create(JNIEnv* jni,
|
||||
jobject j_video_capture,
|
||||
jstring device_name) {
|
||||
LOG(LS_INFO) << "AndroidVideoCapturerJni::Create";
|
||||
rtc::scoped_refptr<AndroidVideoCapturerJni> capturer(
|
||||
new rtc::RefCountedObject<AndroidVideoCapturerJni>(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<webrtc::AndroidVideoCapturerDelegate> delegate =
|
||||
new rtc::RefCountedObject<AndroidVideoCapturerJni>(jni, j_video_capturer);
|
||||
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
|
||||
|
@ -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<AndroidVideoCapturerJni> 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();
|
||||
|
||||
|
@ -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, "<init>", "()V"));
|
||||
jobject j_video_capturer = jni->NewObject(j_video_capturer_class,
|
||||
j_videocapturer_ctor);
|
||||
CHECK_EXCEPTION(jni) << "error during NewObject";
|
||||
|
||||
rtc::scoped_refptr<AndroidVideoCapturerJni> 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<webrtc::AndroidVideoCapturer> capturer(
|
||||
jobject j_video_capturer = jni->NewObject(
|
||||
j_video_capturer_class,
|
||||
GetMethodID(jni, j_video_capturer_class, "<init>", "(I)V"), camera_id);
|
||||
CHECK_EXCEPTION(jni) << "error during creation of VideoCapturerAndroid";
|
||||
rtc::scoped_refptr<webrtc::AndroidVideoCapturerDelegate> delegate =
|
||||
new rtc::RefCountedObject<AndroidVideoCapturerJni>(jni, j_video_capturer);
|
||||
rtc::scoped_ptr<cricket::VideoCapturer> 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user