From 2b679250fbd50b3c8d9ac266a42fbc8a1bd84167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85sa=20Persson?= Date: Mon, 15 Jun 2015 09:53:05 +0200 Subject: [PATCH] VideoCapturerAndroid: Add possibility to request a new resolution from the video adapter. BUG= R=glaznev@webrtc.org Review URL: https://codereview.webrtc.org/1178643006. Cr-Commit-Position: refs/heads/master@{#9434} --- .../org/webrtc/VideoCapturerAndroidTest.java | 3 ++ talk/app/webrtc/androidvideocapturer.cc | 9 +++++ talk/app/webrtc/androidvideocapturer.h | 3 ++ .../java/jni/androidvideocapturer_jni.cc | 28 ++++++++++++++ .../java/jni/androidvideocapturer_jni.h | 2 + .../src/org/webrtc/VideoCapturerAndroid.java | 37 +++++++++++++++++++ 6 files changed, 82 insertions(+) diff --git a/talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java b/talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java index e4141f02ad..657e94cd22 100644 --- a/talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java +++ b/talk/app/webrtc/androidtests/src/org/webrtc/VideoCapturerAndroidTest.java @@ -92,6 +92,9 @@ public class VideoCapturerAndroidTest extends ActivityTestCase { } } + @Override + public void OnOutputFormatRequest(int width, int height, int fps) {} + public boolean WaitForCapturerToStart() throws InterruptedException { synchronized (capturerStartLock) { capturerStartLock.wait(); diff --git a/talk/app/webrtc/androidvideocapturer.cc b/talk/app/webrtc/androidvideocapturer.cc index 2c9c031024..65f883ef9d 100644 --- a/talk/app/webrtc/androidvideocapturer.cc +++ b/talk/app/webrtc/androidvideocapturer.cc @@ -242,4 +242,13 @@ void AndroidVideoCapturer::OnIncomingFrame(void* frame_data, SignalFrameCaptured(this, frame_factory_->GetCapturedFrame()); } +void AndroidVideoCapturer::OnOutputFormatRequest( + int width, int height, int fps) { + CHECK(thread_checker_.CalledOnValidThread()); + const cricket::VideoFormat& current = video_adapter()->output_format(); + cricket::VideoFormat format( + width, height, cricket::VideoFormat::FpsToInterval(fps), current.fourcc); + video_adapter()->OnOutputFormatRequest(format); +} + } // namespace webrtc diff --git a/talk/app/webrtc/androidvideocapturer.h b/talk/app/webrtc/androidvideocapturer.h index 2dffb9c141..2cfbdd808a 100644 --- a/talk/app/webrtc/androidvideocapturer.h +++ b/talk/app/webrtc/androidvideocapturer.h @@ -74,6 +74,9 @@ class AndroidVideoCapturer : public cricket::VideoCapturer { int rotation, int64 time_stamp); + // Called from JNI to request a new video format. + void OnOutputFormatRequest(int width, int height, int fps); + AndroidVideoCapturerDelegate* delegate() { return delegate_.get(); } private: diff --git a/talk/app/webrtc/java/jni/androidvideocapturer_jni.cc b/talk/app/webrtc/java/jni/androidvideocapturer_jni.cc index 1fcf635ac0..3f3b7a6cad 100644 --- a/talk/app/webrtc/java/jni/androidvideocapturer_jni.cc +++ b/talk/app/webrtc/java/jni/androidvideocapturer_jni.cc @@ -182,6 +182,15 @@ void AndroidVideoCapturerJni::OnIncomingFrame(void* video_frame, this, video_frame, length, rotation, time_stamp)); } +void AndroidVideoCapturerJni::OnOutputFormatRequest(int width, + int height, + int fps) { + invoker_.AsyncInvoke( + thread_, + rtc::Bind(&AndroidVideoCapturerJni::OnOutputFormatRequest_w, + this, width, height, fps)); +} + void AndroidVideoCapturerJni::OnCapturerStarted_w(bool success) { CHECK(thread_checker_.CalledOnValidThread()); if (capturer_) { @@ -206,6 +215,17 @@ void AndroidVideoCapturerJni::OnIncomingFrame_w(void* video_frame, } } +void AndroidVideoCapturerJni::OnOutputFormatRequest_w(int width, + int height, + int fps) { + CHECK(thread_checker_.CalledOnValidThread()); + if (capturer_) { + capturer_->OnOutputFormatRequest(width, height, fps); + } else { + LOG(LS_WARNING) << "OnOutputFormatRequest_w is called for closed capturer."; + } +} + JNIEnv* AndroidVideoCapturerJni::jni() { return AttachCurrentThreadIfNeeded(); } JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnFrameCaptured) @@ -233,5 +253,13 @@ JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeCapturerStarted) j_success); } +JOW(void, VideoCapturerAndroid_00024NativeObserver_nativeOnOutputFormatRequest) + (JNIEnv* jni, jclass, jlong j_capturer, jint j_width, jint j_height, + jint j_fps) { + LOG(LS_INFO) << "NativeObserver_nativeOnOutputFormatRequest"; + reinterpret_cast(j_capturer)->OnOutputFormatRequest( + j_width, j_height, j_fps); +} + } // namespace webrtc_jni diff --git a/talk/app/webrtc/java/jni/androidvideocapturer_jni.h b/talk/app/webrtc/java/jni/androidvideocapturer_jni.h index 1e3ace224a..2747ac6da9 100644 --- a/talk/app/webrtc/java/jni/androidvideocapturer_jni.h +++ b/talk/app/webrtc/java/jni/androidvideocapturer_jni.h @@ -66,6 +66,7 @@ class AndroidVideoCapturerJni : public webrtc::AndroidVideoCapturerDelegate { int length, int rotation, int64 time_stamp); + void OnOutputFormatRequest(int width, int height, int fps); protected: AndroidVideoCapturerJni(JNIEnv* jni, jobject j_video_capturer); ~AndroidVideoCapturerJni(); @@ -79,6 +80,7 @@ private: int length, int rotation, int64 time_stamp); + void OnOutputFormatRequest_w(int width, int height, int fps); void ReturnBuffer_w(int64 time_stamp); JNIEnv* jni(); diff --git a/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java b/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java index e40cd1ac29..63388a22f6 100644 --- a/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java +++ b/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java @@ -270,6 +270,21 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba return true; } + // Requests a new output format from the video capturer. Captured frames + // by the camera will be scaled/or dropped by the video capturer. + public synchronized void onOutputFormatRequest( + final int width, final int height, final int fps) { + if (cameraThreadHandler == null) { + Log.e(TAG, "Calling onOutputFormatRequest() for already stopped camera."); + return; + } + cameraThreadHandler.post(new Runnable() { + @Override public void run() { + onOutputFormatRequestOnCameraThread(width, height, fps); + } + }); + } + private VideoCapturerAndroid() { Log.d(TAG, "VideoCapturerAndroid"); } @@ -641,6 +656,16 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba } } + private void onOutputFormatRequestOnCameraThread( + int width, int height, int fps) { + if (camera == null) { + return; + } + Log.d(TAG, "onOutputFormatRequestOnCameraThread: " + width + "x" + height + + "@" + fps); + frameObserver.OnOutputFormatRequest(width, height, fps); + } + synchronized void returnBuffer(final long timeStamp) { if (cameraThreadHandler == null) { // The camera has been stopped. @@ -919,6 +944,11 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba // VideoCapturerAndroid. abstract void OnFrameCaptured(byte[] data, int length, int rotation, long timeStamp); + + // Requests an output format from the video capturer. Captured frames + // by the camera will be scaled/or dropped by the video capturer. + // Called on a Java thread owned by VideoCapturerAndroid. + abstract void OnOutputFormatRequest(int width, int height, int fps); } // An implementation of CapturerObserver that forwards all calls from @@ -941,9 +971,16 @@ public class VideoCapturerAndroid extends VideoCapturer implements PreviewCallba nativeOnFrameCaptured(nativeCapturer, data, length, rotation, timeStamp); } + @Override + public void OnOutputFormatRequest(int width, int height, int fps) { + nativeOnOutputFormatRequest(nativeCapturer, width, height, fps); + } + private native void nativeCapturerStarted(long nativeCapturer, boolean success); private native void nativeOnFrameCaptured(long nativeCapturer, byte[] data, int length, int rotation, long timeStamp); + private native void nativeOnOutputFormatRequest(long nativeCapturer, + int width, int height, int fps); } }