2012-03-19 21:09:42 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2012 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "device_info_android.h"
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
#include "ref_count.h"
|
|
|
|
|
#include "trace.h"
|
|
|
|
|
#include "video_capture_android.h"
|
|
|
|
|
|
|
|
|
|
namespace webrtc
|
|
|
|
|
{
|
2012-04-04 17:15:42 +00:00
|
|
|
|
2012-03-19 21:09:42 +00:00
|
|
|
namespace videocapturemodule
|
|
|
|
|
{
|
2012-04-04 17:15:42 +00:00
|
|
|
|
2013-02-20 23:13:46 +00:00
|
|
|
static jclass g_capabilityClass = NULL;
|
|
|
|
|
|
|
|
|
|
// static
|
|
|
|
|
void DeviceInfoAndroid::SetAndroidCaptureClasses(jclass capabilityClass) {
|
|
|
|
|
g_capabilityClass = capabilityClass;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
VideoCaptureModule::DeviceInfo*
|
|
|
|
|
VideoCaptureImpl::CreateDeviceInfo (const WebRtc_Word32 id) {
|
|
|
|
|
videocapturemodule::DeviceInfoAndroid *deviceInfo =
|
|
|
|
|
new videocapturemodule::DeviceInfoAndroid(id);
|
|
|
|
|
if (deviceInfo && deviceInfo->Init() != 0) {
|
|
|
|
|
delete deviceInfo;
|
|
|
|
|
deviceInfo = NULL;
|
|
|
|
|
}
|
|
|
|
|
return deviceInfo;
|
2012-03-19 21:09:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DeviceInfoAndroid::DeviceInfoAndroid(const WebRtc_Word32 id) :
|
2012-04-04 17:15:42 +00:00
|
|
|
DeviceInfoImpl(id) {
|
2012-03-19 21:09:42 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
WebRtc_Word32 DeviceInfoAndroid::Init() {
|
|
|
|
|
return 0;
|
2012-03-19 21:09:42 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
DeviceInfoAndroid::~DeviceInfoAndroid() {
|
2012-03-19 21:09:42 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
WebRtc_UWord32 DeviceInfoAndroid::NumberOfDevices() {
|
|
|
|
|
JNIEnv *env;
|
|
|
|
|
jclass javaCmDevInfoClass;
|
|
|
|
|
jobject javaCmDevInfoObject;
|
|
|
|
|
bool attached = false;
|
|
|
|
|
if (VideoCaptureAndroid::AttachAndUseAndroidDeviceInfoObjects(
|
|
|
|
|
env,
|
|
|
|
|
javaCmDevInfoClass,
|
|
|
|
|
javaCmDevInfoObject,
|
|
|
|
|
attached) != 0)
|
|
|
|
|
return 0;
|
2012-03-19 21:09:42 +00:00
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"%s GetMethodId", __FUNCTION__);
|
|
|
|
|
// get the method ID for the Android Java GetDeviceUniqueName name.
|
|
|
|
|
jmethodID cid = env->GetMethodID(javaCmDevInfoClass,
|
|
|
|
|
"NumberOfDevices",
|
|
|
|
|
"()I");
|
2012-03-19 21:09:42 +00:00
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
jint numberOfDevices = 0;
|
|
|
|
|
if (cid != NULL) {
|
2012-03-19 21:09:42 +00:00
|
|
|
WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id,
|
2012-04-04 17:15:42 +00:00
|
|
|
"%s Calling Number of devices", __FUNCTION__);
|
|
|
|
|
numberOfDevices = env->CallIntMethod(javaCmDevInfoObject, cid);
|
|
|
|
|
}
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
2012-03-19 21:09:42 +00:00
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
if (numberOfDevices > 0)
|
|
|
|
|
return numberOfDevices;
|
|
|
|
|
return 0;
|
2012-03-19 21:09:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WebRtc_Word32 DeviceInfoAndroid::GetDeviceName(
|
|
|
|
|
WebRtc_UWord32 deviceNumber,
|
|
|
|
|
char* deviceNameUTF8,
|
|
|
|
|
WebRtc_UWord32 deviceNameLength,
|
|
|
|
|
char* deviceUniqueIdUTF8,
|
|
|
|
|
WebRtc_UWord32 deviceUniqueIdUTF8Length,
|
|
|
|
|
char* /*productUniqueIdUTF8*/,
|
|
|
|
|
WebRtc_UWord32 /*productUniqueIdUTF8Length*/) {
|
|
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
JNIEnv *env;
|
|
|
|
|
jclass javaCmDevInfoClass;
|
|
|
|
|
jobject javaCmDevInfoObject;
|
|
|
|
|
WebRtc_Word32 result = 0;
|
|
|
|
|
bool attached = false;
|
|
|
|
|
if (VideoCaptureAndroid::AttachAndUseAndroidDeviceInfoObjects(
|
|
|
|
|
env,
|
|
|
|
|
javaCmDevInfoClass,
|
|
|
|
|
javaCmDevInfoObject,
|
|
|
|
|
attached)!= 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// get the method ID for the Android Java GetDeviceUniqueName name.
|
|
|
|
|
jmethodID cid = env->GetMethodID(javaCmDevInfoClass, "GetDeviceUniqueName",
|
|
|
|
|
"(I)Ljava/lang/String;");
|
|
|
|
|
if (cid != NULL) {
|
|
|
|
|
jobject javaDeviceNameObj = env->CallObjectMethod(javaCmDevInfoObject,
|
|
|
|
|
cid, deviceNumber);
|
|
|
|
|
if (javaDeviceNameObj == NULL) {
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"%s: Failed to get device name for device %d.",
|
|
|
|
|
__FUNCTION__, (int) deviceNumber);
|
|
|
|
|
result = -1;
|
|
|
|
|
} else {
|
|
|
|
|
jboolean isCopy;
|
|
|
|
|
const char* javaDeviceNameChar = env->GetStringUTFChars(
|
|
|
|
|
(jstring) javaDeviceNameObj
|
|
|
|
|
,&isCopy);
|
|
|
|
|
const jsize javaDeviceNameCharLength =
|
|
|
|
|
env->GetStringUTFLength((jstring) javaDeviceNameObj);
|
|
|
|
|
if ((WebRtc_UWord32) javaDeviceNameCharLength <
|
|
|
|
|
deviceUniqueIdUTF8Length) {
|
|
|
|
|
memcpy(deviceUniqueIdUTF8,
|
|
|
|
|
javaDeviceNameChar,
|
|
|
|
|
javaDeviceNameCharLength + 1);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture,
|
|
|
|
|
_id, "%s: deviceUniqueIdUTF8 to short.",
|
2012-03-19 21:09:42 +00:00
|
|
|
__FUNCTION__);
|
|
|
|
|
result = -1;
|
2012-04-04 17:15:42 +00:00
|
|
|
}
|
|
|
|
|
if ((WebRtc_UWord32) javaDeviceNameCharLength < deviceNameLength) {
|
|
|
|
|
memcpy(deviceNameUTF8,
|
|
|
|
|
javaDeviceNameChar,
|
|
|
|
|
javaDeviceNameCharLength + 1);
|
|
|
|
|
}
|
|
|
|
|
env->ReleaseStringUTFChars((jstring) javaDeviceNameObj,
|
|
|
|
|
javaDeviceNameChar);
|
|
|
|
|
} // javaDeviceNameObj == NULL
|
2012-03-19 21:09:42 +00:00
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1,
|
|
|
|
|
"%s: Failed to find GetDeviceUniqueName function id",
|
|
|
|
|
__FUNCTION__);
|
|
|
|
|
result = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
2012-03-19 21:09:42 +00:00
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceVideoCapture, -1,
|
|
|
|
|
"%s: result %d", __FUNCTION__, (int) result);
|
|
|
|
|
return result;
|
2012-03-19 21:09:42 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WebRtc_Word32 DeviceInfoAndroid::CreateCapabilityMap(
|
2012-04-04 17:15:42 +00:00
|
|
|
const char* deviceUniqueIdUTF8) {
|
2012-03-19 21:09:42 +00:00
|
|
|
MapItem* item = NULL;
|
|
|
|
|
while ((item = _captureCapabilities.Last())) {
|
|
|
|
|
delete (VideoCaptureCapability*) item->GetItem();
|
|
|
|
|
_captureCapabilities.Erase(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JNIEnv *env;
|
|
|
|
|
jclass javaCmDevInfoClass;
|
|
|
|
|
jobject javaCmDevInfoObject;
|
|
|
|
|
bool attached = false;
|
|
|
|
|
if (VideoCaptureAndroid::AttachAndUseAndroidDeviceInfoObjects(
|
|
|
|
|
env,
|
|
|
|
|
javaCmDevInfoClass,
|
|
|
|
|
javaCmDevInfoObject,
|
2012-04-04 17:15:42 +00:00
|
|
|
attached) != 0)
|
2012-03-19 21:09:42 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// Find the capability class
|
2013-02-20 23:13:46 +00:00
|
|
|
jclass javaCapClass = g_capabilityClass;
|
|
|
|
|
if (javaCapClass == NULL) {
|
2012-03-19 21:09:42 +00:00
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
|
2013-02-20 23:13:46 +00:00
|
|
|
"%s: SetAndroidCaptureClasses must be called first!",
|
2012-03-19 21:09:42 +00:00
|
|
|
__FUNCTION__);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get the method ID for the Android Java GetCapabilityArray .
|
2013-02-20 23:13:46 +00:00
|
|
|
jmethodID cid = env->GetMethodID(
|
|
|
|
|
javaCmDevInfoClass,
|
|
|
|
|
"GetCapabilityArray",
|
|
|
|
|
"(Ljava/lang/String;)[Lorg/webrtc/videoengine/CaptureCapabilityAndroid;");
|
2012-03-19 21:09:42 +00:00
|
|
|
if (cid == NULL) {
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"%s: Can't find method GetCapabilityArray.", __FUNCTION__);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
// Create a jstring so we can pass the deviceUniquName to the java method.
|
|
|
|
|
jstring capureIdString = env->NewStringUTF((char*) deviceUniqueIdUTF8);
|
|
|
|
|
|
|
|
|
|
if (capureIdString == NULL) {
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"%s: Can't create string for method GetCapabilityArray.",
|
|
|
|
|
__FUNCTION__);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
// Call the java class and get an array with capabilities back.
|
|
|
|
|
jobject javaCapabilitiesObj = env->CallObjectMethod(javaCmDevInfoObject,
|
|
|
|
|
cid, capureIdString);
|
|
|
|
|
if (!javaCapabilitiesObj) {
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"%s: Failed to call java GetCapabilityArray.",
|
|
|
|
|
__FUNCTION__);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-20 23:13:46 +00:00
|
|
|
jfieldID widthField = env->GetFieldID(javaCapClass, "width", "I");
|
|
|
|
|
jfieldID heigtField = env->GetFieldID(javaCapClass, "height", "I");
|
|
|
|
|
jfieldID maxFpsField = env->GetFieldID(javaCapClass, "maxFPS", "I");
|
2012-03-19 21:09:42 +00:00
|
|
|
if (widthField == NULL || heigtField == NULL || maxFpsField == NULL) {
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"%s: Failed to get field Id.", __FUNCTION__);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const jsize numberOfCapabilities =
|
|
|
|
|
env->GetArrayLength((jarray) javaCapabilitiesObj);
|
|
|
|
|
|
|
|
|
|
for (jsize i = 0; i < numberOfCapabilities; ++i) {
|
|
|
|
|
VideoCaptureCapability *cap = new VideoCaptureCapability();
|
|
|
|
|
jobject capabilityElement = env->GetObjectArrayElement(
|
|
|
|
|
(jobjectArray) javaCapabilitiesObj,
|
|
|
|
|
i);
|
|
|
|
|
|
|
|
|
|
cap->width = env->GetIntField(capabilityElement, widthField);
|
|
|
|
|
cap->height = env->GetIntField(capabilityElement, heigtField);
|
|
|
|
|
cap->expectedCaptureDelay = _expectedCaptureDelay;
|
|
|
|
|
cap->rawType = kVideoNV21;
|
|
|
|
|
cap->maxFPS = env->GetIntField(capabilityElement, maxFpsField);
|
2013-02-20 23:13:46 +00:00
|
|
|
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
|
2012-03-19 21:09:42 +00:00
|
|
|
"%s: Cap width %d, height %d, fps %d", __FUNCTION__,
|
|
|
|
|
cap->width, cap->height, cap->maxFPS);
|
|
|
|
|
_captureCapabilities.Insert(i, cap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_lastUsedDeviceNameLength = strlen((char*) deviceUniqueIdUTF8);
|
|
|
|
|
_lastUsedDeviceName = (char*) realloc(_lastUsedDeviceName,
|
|
|
|
|
_lastUsedDeviceNameLength + 1);
|
|
|
|
|
memcpy(_lastUsedDeviceName,
|
|
|
|
|
deviceUniqueIdUTF8,
|
|
|
|
|
_lastUsedDeviceNameLength + 1);
|
|
|
|
|
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"CreateCapabilityMap %d", _captureCapabilities.Size());
|
|
|
|
|
|
|
|
|
|
return _captureCapabilities.Size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WebRtc_Word32 DeviceInfoAndroid::GetOrientation(
|
|
|
|
|
const char* deviceUniqueIdUTF8,
|
2012-04-04 17:15:42 +00:00
|
|
|
VideoCaptureRotation& orientation) {
|
2012-03-19 21:09:42 +00:00
|
|
|
JNIEnv *env;
|
|
|
|
|
jclass javaCmDevInfoClass;
|
|
|
|
|
jobject javaCmDevInfoObject;
|
|
|
|
|
bool attached = false;
|
|
|
|
|
if (VideoCaptureAndroid::AttachAndUseAndroidDeviceInfoObjects(
|
|
|
|
|
env,
|
|
|
|
|
javaCmDevInfoClass,
|
|
|
|
|
javaCmDevInfoObject,
|
2012-04-04 17:15:42 +00:00
|
|
|
attached) != 0)
|
2012-03-19 21:09:42 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
// get the method ID for the Android Java GetOrientation .
|
|
|
|
|
jmethodID cid = env->GetMethodID(javaCmDevInfoClass, "GetOrientation",
|
|
|
|
|
"(Ljava/lang/String;)I");
|
|
|
|
|
if (cid == NULL) {
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"%s: Can't find method GetOrientation.", __FUNCTION__);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
// Create a jstring so we can pass the deviceUniquName to the java method.
|
|
|
|
|
jstring capureIdString = env->NewStringUTF((char*) deviceUniqueIdUTF8);
|
|
|
|
|
if (capureIdString == NULL) {
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
|
|
|
|
|
"%s: Can't create string for method GetCapabilityArray.",
|
|
|
|
|
__FUNCTION__);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
// Call the java class and get the orientation.
|
|
|
|
|
jint jorientation = env->CallIntMethod(javaCmDevInfoObject, cid,
|
|
|
|
|
capureIdString);
|
|
|
|
|
VideoCaptureAndroid::ReleaseAndroidDeviceInfoObjects(attached);
|
|
|
|
|
|
|
|
|
|
WebRtc_Word32 retValue = 0;
|
|
|
|
|
switch (jorientation) {
|
2012-04-04 17:15:42 +00:00
|
|
|
case -1: // Error
|
2012-03-19 21:09:42 +00:00
|
|
|
orientation = kCameraRotate0;
|
|
|
|
|
retValue = -1;
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
orientation = kCameraRotate0;
|
|
|
|
|
break;
|
|
|
|
|
case 90:
|
|
|
|
|
orientation = kCameraRotate90;
|
|
|
|
|
break;
|
|
|
|
|
case 180:
|
|
|
|
|
orientation = kCameraRotate180;
|
|
|
|
|
break;
|
|
|
|
|
case 270:
|
|
|
|
|
orientation = kCameraRotate270;
|
|
|
|
|
break;
|
|
|
|
|
case 360:
|
|
|
|
|
orientation = kCameraRotate0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return retValue;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 17:15:42 +00:00
|
|
|
} // namespace videocapturemodule
|
|
|
|
|
} // namespace webrtc
|