1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1187c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/modules/video_capture/android/video_capture_android.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13d3d2598c721994a90907527bfda9a119fbc27db3fischman@webrtc.org#include "webrtc/base/common.h" 1481cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org#include "webrtc/modules/utility/interface/helpers_android.h" 1581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org#include "webrtc/modules/video_capture/android/device_info_android.h" 1687c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 1781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org#include "webrtc/system_wrappers/interface/logcat_trace_context.h" 18ab52e9a726313a44423fe7a5988f4d1eff75a208glaznev@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 1987c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/system_wrappers/interface/ref_count.h" 2087c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.orgstatic JavaVM* g_jvm = NULL; 2381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.orgstatic jclass g_java_capturer_class = NULL; // VideoCaptureAndroid.class. 245101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.orgstatic jobject g_context = NULL; // Owned android.content.Context. 2581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org 2681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.orgnamespace webrtc { 2781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org 285101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org// Called by Java to get the global application context. 295101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.orgjobject JNICALL GetContext(JNIEnv* env, jclass) { 305101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org assert(g_context); 315101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org return g_context; 325101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org} 335101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org 3481cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org// Called by Java when the camera has a new frame to deliver. 3581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.orgvoid JNICALL ProvideCameraFrame( 3681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org JNIEnv* env, 3781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jobject, 3881cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jbyteArray javaCameraFrame, 3981cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jint length, 40ab52e9a726313a44423fe7a5988f4d1eff75a208glaznev@webrtc.org jlong timeStamp, 4181cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jlong context) { 4281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org webrtc::videocapturemodule::VideoCaptureAndroid* captureModule = 4381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org reinterpret_cast<webrtc::videocapturemodule::VideoCaptureAndroid*>( 4481cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org context); 4581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jbyte* cameraFrame = env->GetByteArrayElements(javaCameraFrame, NULL); 4681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org captureModule->OnIncomingFrame( 4781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org reinterpret_cast<uint8_t*>(cameraFrame), length, 0); 4881cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org env->ReleaseByteArrayElements(javaCameraFrame, cameraFrame, JNI_ABORT); 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 515101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org// Called by Java when the device orientation has changed. 525101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.orgvoid JNICALL OnOrientationChanged( 535101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org JNIEnv* env, jobject, jlong context, jint degrees) { 545101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org webrtc::videocapturemodule::VideoCaptureAndroid* captureModule = 555101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org reinterpret_cast<webrtc::videocapturemodule::VideoCaptureAndroid*>( 565101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org context); 575101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org degrees = (360 + degrees) % 360; 585101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org assert(degrees >= 0 && degrees < 360); 595101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org VideoCaptureRotation rotation = 605101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org (degrees <= 45 || degrees > 315) ? kCameraRotate0 : 615101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org (degrees > 45 && degrees <= 135) ? kCameraRotate90 : 625101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org (degrees > 135 && degrees <= 225) ? kCameraRotate180 : 635101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org (degrees > 225 && degrees <= 315) ? kCameraRotate270 : 645101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org kCameraRotate0; // Impossible. 655101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org int32_t status = 665101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org captureModule->VideoCaptureImpl::SetCaptureRotation(rotation); 67d3d2598c721994a90907527bfda9a119fbc27db3fischman@webrtc.org RTC_UNUSED(status); 685101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org assert(status == 0); 695101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org} 705101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org 715101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.orgint32_t SetCaptureAndroidVM(JavaVM* javaVM, jobject context) { 72ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org if (javaVM) { 73ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org assert(!g_jvm); 74ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org g_jvm = javaVM; 75ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org AttachThreadScoped ats(g_jvm); 765101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org g_context = ats.env()->NewGlobalRef(context); 7781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org 78ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org videocapturemodule::DeviceInfoAndroid::Initialize(ats.env()); 7981cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org 80ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org jclass j_capture_class = 81ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org ats.env()->FindClass("org/webrtc/videoengine/VideoCaptureAndroid"); 82ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org assert(j_capture_class); 83ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org g_java_capturer_class = 84ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org reinterpret_cast<jclass>(ats.env()->NewGlobalRef(j_capture_class)); 85ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org assert(g_java_capturer_class); 8681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org 875101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org JNINativeMethod native_methods[] = { 885101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org {"GetContext", 895101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org "()Landroid/content/Context;", 905101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org reinterpret_cast<void*>(&GetContext)}, 915101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org {"OnOrientationChanged", 925101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org "(JI)V", 935101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org reinterpret_cast<void*>(&OnOrientationChanged)}, 945101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org {"ProvideCameraFrame", 95ab52e9a726313a44423fe7a5988f4d1eff75a208glaznev@webrtc.org "([BIJJ)V", 965101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org reinterpret_cast<void*>(&ProvideCameraFrame)}}; 97ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org if (ats.env()->RegisterNatives(g_java_capturer_class, 985101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org native_methods, 3) != 0) 99ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org assert(false); 100ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org } else { 101ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org if (g_jvm) { 102ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org AttachThreadScoped ats(g_jvm); 103ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org ats.env()->UnregisterNatives(g_java_capturer_class); 104ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org ats.env()->DeleteGlobalRef(g_java_capturer_class); 105ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org g_java_capturer_class = NULL; 1065101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org ats.env()->DeleteGlobalRef(g_context); 1075101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org g_context = NULL; 108ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org videocapturemodule::DeviceInfoAndroid::DeInitialize(); 109ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org g_jvm = NULL; 110ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org } 111ca2c70f2bae88987267a2727449ac86330fb8dbdbraveyao@webrtc.org } 11281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org 11381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org return 0; 11481cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org} 11581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org 11681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.orgnamespace videocapturemodule { 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoCaptureModule* VideoCaptureImpl::Create( 119f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org const int32_t id, 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const char* deviceUniqueIdUTF8) { 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RefCountImpl<videocapturemodule::VideoCaptureAndroid>* implementation = 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org new RefCountImpl<videocapturemodule::VideoCaptureAndroid>(id); 12381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org if (implementation->Init(id, deviceUniqueIdUTF8) != 0) { 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete implementation; 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org implementation = NULL; 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return implementation; 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 13081cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.orgint32_t VideoCaptureAndroid::OnIncomingFrame(uint8_t* videoFrame, 13181cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org int32_t videoFrameLength, 13281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org int64_t captureTime) { 13382383d9b14ff8e5fedf5a70229eb0ac6b512909aglaznev@webrtc.org if (!_captureStarted) 13482383d9b14ff8e5fedf5a70229eb0ac6b512909aglaznev@webrtc.org return 0; 13581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org return IncomingFrame( 13681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org videoFrame, videoFrameLength, _captureCapability, captureTime); 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 139f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgVideoCaptureAndroid::VideoCaptureAndroid(const int32_t id) 14081cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org : VideoCaptureImpl(id), 14181cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org _deviceInfo(id), 14281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org _jCapturer(NULL), 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _captureStarted(false) { 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 146f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t VideoCaptureAndroid::Init(const int32_t id, 147f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org const char* deviceUniqueIdUTF8) { 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const int nameLength = strlen(deviceUniqueIdUTF8); 14981cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org if (nameLength >= kVideoCaptureUniqueNameLength) 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Store the device name 153ab52e9a726313a44423fe7a5988f4d1eff75a208glaznev@webrtc.org LOG(LS_INFO) << "VideoCaptureAndroid::Init: " << deviceUniqueIdUTF8; 154ab52e9a726313a44423fe7a5988f4d1eff75a208glaznev@webrtc.org size_t camera_id = 0; 155ab52e9a726313a44423fe7a5988f4d1eff75a208glaznev@webrtc.org if (!_deviceInfo.FindCameraIndex(deviceUniqueIdUTF8, &camera_id)) 156ab52e9a726313a44423fe7a5988f4d1eff75a208glaznev@webrtc.org return -1; 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _deviceUniqueId = new char[nameLength + 1]; 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(_deviceUniqueId, deviceUniqueIdUTF8, nameLength + 1); 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16081cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org AttachThreadScoped ats(g_jvm); 16181cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org JNIEnv* env = ats.env(); 16281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jmethodID ctor = env->GetMethodID(g_java_capturer_class, "<init>", "(IJ)V"); 16381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org assert(ctor); 16481cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jlong j_this = reinterpret_cast<intptr_t>(this); 16581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org _jCapturer = env->NewGlobalRef( 16681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org env->NewObject(g_java_capturer_class, ctor, camera_id, j_this)); 16781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org assert(_jCapturer); 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoCaptureAndroid::~VideoCaptureAndroid() { 17281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org // Ensure Java camera is released even if our caller didn't explicitly Stop. 17381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org if (_captureStarted) 17481cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org StopCapture(); 17581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org AttachThreadScoped ats(g_jvm); 17681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org ats.env()->DeleteGlobalRef(_jCapturer); 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 179f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t VideoCaptureAndroid::StartCapture( 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const VideoCaptureCapability& capability) { 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(&_apiCs); 18281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org AttachThreadScoped ats(g_jvm); 18381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org JNIEnv* env = ats.env(); 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org if (_deviceInfo.GetBestMatchedCapability( 18681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org _deviceUniqueId, capability, _captureCapability) < 0) { 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1, 18881cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org "%s: GetBestMatchedCapability failed: %dx%d", 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __FUNCTION__, capability.width, capability.height); 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 19381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org _captureDelay = _captureCapability.expectedCaptureDelay; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 19581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jmethodID j_start = 19681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org env->GetMethodID(g_java_capturer_class, "startCapture", "(IIII)Z"); 19781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org assert(j_start); 19881cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org int min_mfps = 0; 19981cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org int max_mfps = 0; 200b515322d1022f91bb98ed57b47749076db8218adfischman@webrtc.org _deviceInfo.GetMFpsRange(_deviceUniqueId, _captureCapability.maxFPS, 201b515322d1022f91bb98ed57b47749076db8218adfischman@webrtc.org &min_mfps, &max_mfps); 20281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org bool started = env->CallBooleanMethod(_jCapturer, j_start, 20381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org _captureCapability.width, 20481cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org _captureCapability.height, 20581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org min_mfps, max_mfps); 20681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org if (started) { 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _requestedCapability = capability; 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _captureStarted = true; 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 21081cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org return started ? 0 : -1; 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 213f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t VideoCaptureAndroid::StopCapture() { 21482383d9b14ff8e5fedf5a70229eb0ac6b512909aglaznev@webrtc.org _apiCs.Enter(); 21581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org AttachThreadScoped ats(g_jvm); 21681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org JNIEnv* env = ats.env(); 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(&_requestedCapability, 0, sizeof(_requestedCapability)); 21981cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org memset(&_captureCapability, 0, sizeof(_captureCapability)); 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _captureStarted = false; 22182383d9b14ff8e5fedf5a70229eb0ac6b512909aglaznev@webrtc.org // Exit critical section to avoid blocking camera thread inside 22282383d9b14ff8e5fedf5a70229eb0ac6b512909aglaznev@webrtc.org // onIncomingFrame() call. 22382383d9b14ff8e5fedf5a70229eb0ac6b512909aglaznev@webrtc.org _apiCs.Leave(); 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 22581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jmethodID j_stop = 22681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org env->GetMethodID(g_java_capturer_class, "stopCapture", "()Z"); 22781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org return env->CallBooleanMethod(_jCapturer, j_stop) ? 0 : -1; 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoCaptureAndroid::CaptureStarted() { 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(&_apiCs); 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return _captureStarted; 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 235f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t VideoCaptureAndroid::CaptureSettings( 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VideoCaptureCapability& settings) { 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(&_apiCs); 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org settings = _requestedCapability; 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 242f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t VideoCaptureAndroid::SetCaptureRotation( 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VideoCaptureRotation rotation) { 2445101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org int32_t status = VideoCaptureImpl::SetCaptureRotation(rotation); 2455101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org if (status != 0) 2465101f8464568c3233d0b95195247e2f63d9064cffischman@webrtc.org return status; 24781cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org 24881cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org AttachThreadScoped ats(g_jvm); 24981cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org JNIEnv* env = ats.env(); 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25181cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org jmethodID j_spr = 25281cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org env->GetMethodID(g_java_capturer_class, "setPreviewRotation", "(I)V"); 25381cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org assert(j_spr); 25481cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org int rotation_degrees; 25581cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org if (RotationInDegrees(rotation, &rotation_degrees) != 0) { 25681cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org assert(false); 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 25881cd5ca677e30076888b865dc28b35ed293bb4bcfischman@webrtc.org env->CallVoidMethod(_jCapturer, j_spr, rotation_degrees); 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace videocapturemodule 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 264