Merge pull request #4083 from mshabunin:java-engine
@ -1,45 +0,0 @@ |
||||
IF(NOT ANDROID OR ANDROID_NATIVE_API_LEVEL LESS 8) |
||||
ocv_module_disable(androidcamera) |
||||
ENDIF() |
||||
|
||||
set(the_description "Auxiliary module for Android native camera support") |
||||
set(OPENCV_MODULE_TYPE STATIC) |
||||
|
||||
ocv_define_module(androidcamera INTERNAL opencv_core log dl) |
||||
ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/camera_wrapper" "${OpenCV_SOURCE_DIR}/platforms/android/service/engine/jni/include") |
||||
|
||||
# Android source tree for native camera |
||||
SET (ANDROID_SOURCE_TREE "ANDROID_SOURCE_TREE-NOTFOUND" CACHE PATH |
||||
"Path to Android source tree. Set this variable to path to your Android sources to compile libnative_camera_rx.x.x.so for your Android") |
||||
SET(BUILD_ANDROID_CAMERA_WRAPPER OFF) |
||||
if(ANDROID_SOURCE_TREE) |
||||
FILE(STRINGS "${ANDROID_SOURCE_TREE}/development/sdk/platform_source.properties" ANDROID_VERSION REGEX "Platform\\.Version=[0-9]+\\.[0-9]+(\\.[0-9]+)?" ) |
||||
string(REGEX REPLACE "Platform\\.Version=([0-9]+\\.[0-9]+(\\.[0-9]+)?)" "\\1" ANDROID_VERSION "${ANDROID_VERSION}") |
||||
if(ANDROID_VERSION MATCHES "^[0-9]+\\.[0-9]+$") |
||||
SET(ANDROID_VERSION "${ANDROID_VERSION}.0") |
||||
endif() |
||||
if(NOT "${ANDROID_VERSION}" STREQUAL "") |
||||
SET(BUILD_ANDROID_CAMERA_WRAPPER ON) |
||||
set(ANDROID_VERSION "${ANDROID_VERSION}" CACHE INTERNAL "Version of Android source tree") |
||||
endif() |
||||
endif() |
||||
set(BUILD_ANDROID_CAMERA_WRAPPER ${BUILD_ANDROID_CAMERA_WRAPPER} CACHE INTERNAL "Build new wrapper for Android") |
||||
MARK_AS_ADVANCED(ANDROID_SOURCE_TREE) |
||||
|
||||
# process wrapper libs |
||||
if(BUILD_ANDROID_CAMERA_WRAPPER) |
||||
add_subdirectory(camera_wrapper) |
||||
else() |
||||
file(GLOB camera_wrappers "${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/lib/${ANDROID_NDK_ABI_NAME}/libnative_camera_r*.so") |
||||
|
||||
foreach(wrapper ${camera_wrappers}) |
||||
ADD_CUSTOM_COMMAND( |
||||
TARGET ${the_module} POST_BUILD |
||||
COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${LIBRARY_OUTPUT_PATH}" |
||||
) |
||||
get_filename_component(wrapper_name "${wrapper}" NAME) |
||||
install(FILES "${LIBRARY_OUTPUT_PATH}/${wrapper_name}" |
||||
DESTINATION ${OPENCV_LIB_INSTALL_PATH} |
||||
COMPONENT libs) |
||||
endforeach() |
||||
endif() |
@ -1,66 +0,0 @@ |
||||
SET (the_target native_camera_r${ANDROID_VERSION}) |
||||
|
||||
project(${the_target}) |
||||
|
||||
link_directories("${ANDROID_SOURCE_TREE}/out/target/product/generic/system/lib") |
||||
|
||||
if (ANDROID_VERSION VERSION_LESS "4.1") |
||||
INCLUDE_DIRECTORIES(BEFORE |
||||
${ANDROID_SOURCE_TREE} |
||||
${ANDROID_SOURCE_TREE}/frameworks/base/include/ui |
||||
${ANDROID_SOURCE_TREE}/frameworks/base/include/surfaceflinger |
||||
${ANDROID_SOURCE_TREE}/frameworks/base/include/camera |
||||
${ANDROID_SOURCE_TREE}/frameworks/base/include/media |
||||
${ANDROID_SOURCE_TREE}/frameworks/base/include |
||||
${ANDROID_SOURCE_TREE}/system/core/include |
||||
${ANDROID_SOURCE_TREE}/hardware/libhardware/include |
||||
${ANDROID_SOURCE_TREE}/frameworks/base/native/include |
||||
${ANDROID_SOURCE_TREE}/frameworks/base/opengl/include |
||||
) |
||||
else() |
||||
INCLUDE_DIRECTORIES(BEFORE |
||||
${ANDROID_SOURCE_TREE} |
||||
${ANDROID_SOURCE_TREE}/frameworks/native/include |
||||
${ANDROID_SOURCE_TREE}/frameworks/av/include |
||||
${ANDROID_SOURCE_TREE}/system/core/include |
||||
${ANDROID_SOURCE_TREE}/hardware/libhardware/include |
||||
) |
||||
endif() |
||||
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) |
||||
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE}") |
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}") |
||||
SET(CMAKE_C_FLAGS_RELEASE "") |
||||
SET(CMAKE_CXX_FLAGS_RELEASE "") |
||||
|
||||
string(REPLACE "-O3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") |
||||
string(REPLACE "-frtti" "-fno-rtti" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") # because Android libraries are built without rtti |
||||
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -fno-strict-aliasing -finline-limit=64 -fuse-cxa-atexit" ) |
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os -fno-strict-aliasing -finline-limit=64 -fuse-cxa-atexit") |
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack") |
||||
|
||||
ADD_LIBRARY(${the_target} SHARED camera_wrapper.h camera_wrapper.cpp) |
||||
|
||||
string(REGEX REPLACE "[.]" "_" LIBRARY_DEF ${ANDROID_VERSION}) |
||||
add_definitions(-DANDROID_r${LIBRARY_DEF}) |
||||
|
||||
ocv_target_link_libraries(${the_target} c m dl utils camera_client binder log) |
||||
|
||||
if(NOT ANDROID_VERSION VERSION_LESS "3.0.0") |
||||
target_link_libraries(${the_target} gui ) |
||||
endif() |
||||
|
||||
SET_TARGET_PROPERTIES(${the_target} PROPERTIES |
||||
OUTPUT_NAME "${the_target}" |
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} |
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} |
||||
) |
||||
|
||||
if (NOT (CMAKE_BUILD_TYPE MATCHES "Debug")) |
||||
ADD_CUSTOM_COMMAND( TARGET ${the_target} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${LIBRARY_OUTPUT_PATH}/lib${the_target}.so" ) |
||||
endif() |
||||
|
||||
|
||||
install(TARGETS ${the_target} LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT libs) |
@ -1,70 +0,0 @@ |
||||
*** src2.3.3/frameworks/base/include/camera/Camera.h 2011-04-04 20:18:36.718480237 +0400
|
||||
--- src_mock3.0.1/frameworks/base/include/camera/Camera.h 2012-01-15 20:51:36.000000000 +0400
|
||||
***************
|
||||
*** 20,25 ****
|
||||
--- 20,27 ----
|
||||
#include <utils/Timers.h>
|
||||
#include <camera/ICameraClient.h>
|
||||
|
||||
+ #include <gui/ISurfaceTexture.h>
|
||||
+
|
||||
namespace android {
|
||||
|
||||
class ISurface;
|
||||
***************
|
||||
*** 76,81 ****
|
||||
--- 78,90 ----
|
||||
CAMERA_MSG_POSTVIEW_FRAME = 0x040,
|
||||
CAMERA_MSG_RAW_IMAGE = 0x080,
|
||||
CAMERA_MSG_COMPRESSED_IMAGE = 0x100,
|
||||
+
|
||||
+ #ifdef OMAP_ENHANCEMENT
|
||||
+
|
||||
+ CAMERA_MSG_BURST_IMAGE = 0x200,
|
||||
+
|
||||
+ #endif
|
||||
+
|
||||
CAMERA_MSG_ALL_MSGS = 0x1FF
|
||||
};
|
||||
|
||||
***************
|
||||
*** 144,150 ****
|
||||
--- 153,164 ----
|
||||
public:
|
||||
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
|
||||
virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
|
||||
+ #ifdef OMAP_ENHANCEMENT
|
||||
+ virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr,
|
||||
+ uint32_t offset=0, uint32_t stride=0) = 0;
|
||||
+ #else
|
||||
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
|
||||
+ #endif
|
||||
};
|
||||
|
||||
class Camera : public BnCameraClient, public IBinder::DeathRecipient
|
||||
***************
|
||||
*** 170,175 ****
|
||||
--- 184,191 ----
|
||||
status_t setPreviewDisplay(const sp<Surface>& surface);
|
||||
status_t setPreviewDisplay(const sp<ISurface>& surface);
|
||||
|
||||
+ // pass the SurfaceTexture object to the Camera
|
||||
+ status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture);
|
||||
// start preview mode, must call setPreviewDisplay first
|
||||
status_t startPreview();
|
||||
|
||||
***************
|
||||
*** 215,221 ****
|
||||
--- 231,242 ----
|
||||
// ICameraClient interface
|
||||
virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
|
||||
virtual void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
|
||||
+ #ifdef OMAP_ENHANCEMENT
|
||||
+ virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr,
|
||||
+ uint32_t offset=0, uint32_t stride=0);
|
||||
+ #else
|
||||
virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
|
||||
+ #endif
|
||||
|
||||
sp<ICamera> remote();
|
||||
|
@ -1,14 +0,0 @@ |
||||
*** src2.3.3/frameworks/base/include/camera/ICamera.h 2011-04-04 20:18:36.718480237 +0400
|
||||
--- src_mock3.0.1/frameworks/base/include/camera/ICamera.h 2012-01-15 20:50:30.000000000 +0400
|
||||
***************
|
||||
*** 48,53 ****
|
||||
--- 48,56 ----
|
||||
// pass the buffered ISurface to the camera service
|
||||
virtual status_t setPreviewDisplay(const sp<ISurface>& surface) = 0;
|
||||
|
||||
+ // pass the preview texture. This is for 3.0 and higher versions of Android
|
||||
+ setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture) = 0;
|
||||
+
|
||||
// set the preview callback flag to affect how the received frames from
|
||||
// preview are handled.
|
||||
virtual void setPreviewCallbackFlag(int flag) = 0;
|
@ -1,9 +0,0 @@ |
||||
Building camera wrapper for Android 3.0.1: |
||||
|
||||
1) Get sources of Android 2.3.x (2.3.3 were used) |
||||
2) Apply patches provided with this instruction to frameworks/base/include/camera/ICamera.h and frameworks/base/include/camera/Camera.h |
||||
3) Get frameworks/base/include/gui/ISurfaceTexture.h and frameworks/base/include/gui/SurfaceTexture.h from Android 4.0.x (4.0.3 were used) sources and add them to your source tree. |
||||
4) Apply provided patch to the frameworks/base/include/gui/SurfaceTexture.h. |
||||
5) Pull /system/lib from your device running Andoid 3.x.x |
||||
6) Edit <Android Root>/development/sdk/platform_source.properties file. Set Android version to 3.0.1. |
||||
7) Build wrapper as normal using this modified source tree. |
@ -1,37 +0,0 @@ |
||||
*** src4.0.3/src/frameworks/base/include/gui/SurfaceTexture.h 2012-01-18 16:32:41.424750385 +0400
|
||||
--- src_mock3.0.1/frameworks/base/include/gui/SurfaceTexture.h 2012-01-12 21:28:14.000000000 +0400
|
||||
***************
|
||||
*** 68,75 ****
|
||||
// texture will be bound in updateTexImage. useFenceSync specifies whether
|
||||
// fences should be used to synchronize access to buffers if that behavior
|
||||
// is enabled at compile-time.
|
||||
! SurfaceTexture(GLuint tex, bool allowSynchronousMode = true,
|
||||
! GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true);
|
||||
|
||||
virtual ~SurfaceTexture();
|
||||
|
||||
--- 68,74 ----
|
||||
// texture will be bound in updateTexImage. useFenceSync specifies whether
|
||||
// fences should be used to synchronize access to buffers if that behavior
|
||||
// is enabled at compile-time.
|
||||
! SurfaceTexture(GLuint tex);
|
||||
|
||||
virtual ~SurfaceTexture();
|
||||
|
||||
***************
|
||||
*** 280,286 ****
|
||||
mBufferState(BufferSlot::FREE),
|
||||
mRequestBufferCalled(false),
|
||||
mTransform(0),
|
||||
! mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
|
||||
mTimestamp(0),
|
||||
mFrameNumber(0),
|
||||
mFence(EGL_NO_SYNC_KHR) {
|
||||
--- 279,285 ----
|
||||
mBufferState(BufferSlot::FREE),
|
||||
mRequestBufferCalled(false),
|
||||
mTransform(0),
|
||||
! mScalingMode(0),
|
||||
mTimestamp(0),
|
||||
mFrameNumber(0),
|
||||
mFence(EGL_NO_SYNC_KHR) {
|
@ -1,16 +0,0 @@ |
||||
typedef bool (*CameraCallback)(void* buffer, size_t bufferSize, void* userData); |
||||
|
||||
typedef void* (*InitCameraConnectC)(void* cameraCallback, int cameraId, void* userData); |
||||
typedef void (*CloseCameraConnectC)(void**); |
||||
typedef double (*GetCameraPropertyC)(void* camera, int propIdx); |
||||
typedef void (*SetCameraPropertyC)(void* camera, int propIdx, double value); |
||||
typedef void (*ApplyCameraPropertiesC)(void** camera); |
||||
|
||||
extern "C" |
||||
{ |
||||
void* initCameraConnectC(void* cameraCallback, int cameraId, void* userData); |
||||
void closeCameraConnectC(void**); |
||||
double getCameraPropertyC(void* camera, int propIdx); |
||||
void setCameraPropertyC(void* camera, int propIdx, double value); |
||||
void applyCameraPropertiesC(void** camera); |
||||
} |
@ -1,55 +0,0 @@ |
||||
#ifndef _CAMERAACTIVITY_H_ |
||||
#define _CAMERAACTIVITY_H_ |
||||
|
||||
#include <camera_properties.h> |
||||
|
||||
/** @defgroup androidcamera Android Camera Support
|
||||
*/ |
||||
|
||||
//! @addtogroup androidcamera
|
||||
//! @{
|
||||
|
||||
class CameraActivity |
||||
{ |
||||
public: |
||||
enum ErrorCode { |
||||
NO_ERROR=0, |
||||
ERROR_WRONG_FRAME_SIZE, |
||||
ERROR_WRONG_POINTER_CAMERA_WRAPPER, |
||||
ERROR_CAMERA_CONNECTED, |
||||
ERROR_CANNOT_OPEN_CAMERA_WRAPPER_LIB, |
||||
ERROR_CANNOT_GET_FUNCTION_FROM_CAMERA_WRAPPER_LIB, |
||||
ERROR_CANNOT_INITIALIZE_CONNECTION, |
||||
ERROR_ISNT_CONNECTED, |
||||
ERROR_JAVA_VM_CANNOT_GET_CLASS, |
||||
ERROR_JAVA_VM_CANNOT_GET_FIELD, |
||||
ERROR_CANNOT_SET_PREVIEW_DISPLAY, |
||||
|
||||
ERROR_UNKNOWN=255 |
||||
}; |
||||
|
||||
CameraActivity(); |
||||
virtual ~CameraActivity(); |
||||
virtual bool onFrameBuffer(void* buffer, int bufferSize); |
||||
|
||||
ErrorCode connect(int cameraId = 0); |
||||
void disconnect(); |
||||
bool isConnected() const; |
||||
|
||||
double getProperty(int propIdx); |
||||
void setProperty(int propIdx, double value); |
||||
void applyProperties(); |
||||
|
||||
int getFrameWidth(); |
||||
int getFrameHeight(); |
||||
|
||||
static void setPathLibFolder(const char* path); |
||||
private: |
||||
void* camera; |
||||
int frameWidth; |
||||
int frameHeight; |
||||
}; |
||||
|
||||
//! @}
|
||||
|
||||
#endif |
@ -1,75 +0,0 @@ |
||||
#ifndef CAMERA_PROPERTIES_H |
||||
#define CAMERA_PROPERTIES_H |
||||
|
||||
//! @addtogroup androidcamera
|
||||
//! @{
|
||||
|
||||
enum { |
||||
ANDROID_CAMERA_PROPERTY_FRAMEWIDTH = 0, |
||||
ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT = 1, |
||||
ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING = 2, |
||||
ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING = 3, |
||||
ANDROID_CAMERA_PROPERTY_FPS = 4, |
||||
ANDROID_CAMERA_PROPERTY_EXPOSURE = 5, |
||||
ANDROID_CAMERA_PROPERTY_FLASH_MODE = 101, |
||||
ANDROID_CAMERA_PROPERTY_FOCUS_MODE = 102, |
||||
ANDROID_CAMERA_PROPERTY_WHITE_BALANCE = 103, |
||||
ANDROID_CAMERA_PROPERTY_ANTIBANDING = 104, |
||||
ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH = 105, |
||||
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR = 106, |
||||
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL = 107, |
||||
ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR = 108, |
||||
ANDROID_CAMERA_PROPERTY_EXPOSE_LOCK = 109, |
||||
ANDROID_CAMERA_PROPERTY_WHITEBALANCE_LOCK = 110 |
||||
}; |
||||
|
||||
|
||||
enum { |
||||
ANDROID_CAMERA_FLASH_MODE_AUTO = 0, |
||||
ANDROID_CAMERA_FLASH_MODE_OFF, |
||||
ANDROID_CAMERA_FLASH_MODE_ON, |
||||
ANDROID_CAMERA_FLASH_MODE_RED_EYE, |
||||
ANDROID_CAMERA_FLASH_MODE_TORCH, |
||||
ANDROID_CAMERA_FLASH_MODES_NUM |
||||
}; |
||||
|
||||
enum { |
||||
ANDROID_CAMERA_FOCUS_MODE_AUTO = 0, |
||||
ANDROID_CAMERA_FOCUS_MODE_CONTINUOUS_VIDEO, |
||||
ANDROID_CAMERA_FOCUS_MODE_EDOF, |
||||
ANDROID_CAMERA_FOCUS_MODE_FIXED, |
||||
ANDROID_CAMERA_FOCUS_MODE_INFINITY, |
||||
ANDROID_CAMERA_FOCUS_MODE_MACRO, |
||||
ANDROID_CAMERA_FOCUS_MODE_CONTINUOUS_PICTURE, |
||||
ANDROID_CAMERA_FOCUS_MODES_NUM |
||||
}; |
||||
|
||||
enum { |
||||
ANDROID_CAMERA_WHITE_BALANCE_AUTO = 0, |
||||
ANDROID_CAMERA_WHITE_BALANCE_CLOUDY_DAYLIGHT, |
||||
ANDROID_CAMERA_WHITE_BALANCE_DAYLIGHT, |
||||
ANDROID_CAMERA_WHITE_BALANCE_FLUORESCENT, |
||||
ANDROID_CAMERA_WHITE_BALANCE_INCANDESCENT, |
||||
ANDROID_CAMERA_WHITE_BALANCE_SHADE, |
||||
ANDROID_CAMERA_WHITE_BALANCE_TWILIGHT, |
||||
ANDROID_CAMERA_WHITE_BALANCE_WARM_FLUORESCENT, |
||||
ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM |
||||
}; |
||||
|
||||
enum { |
||||
ANDROID_CAMERA_ANTIBANDING_50HZ = 0, |
||||
ANDROID_CAMERA_ANTIBANDING_60HZ, |
||||
ANDROID_CAMERA_ANTIBANDING_AUTO, |
||||
ANDROID_CAMERA_ANTIBANDING_OFF, |
||||
ANDROID_CAMERA_ANTIBANDING_MODES_NUM |
||||
}; |
||||
|
||||
enum { |
||||
ANDROID_CAMERA_FOCUS_DISTANCE_NEAR_INDEX = 0, |
||||
ANDROID_CAMERA_FOCUS_DISTANCE_OPTIMAL_INDEX, |
||||
ANDROID_CAMERA_FOCUS_DISTANCE_FAR_INDEX |
||||
}; |
||||
|
||||
//! @}
|
||||
|
||||
#endif // CAMERA_PROPERTIES_H
|
@ -1,451 +0,0 @@ |
||||
#include <dlfcn.h> |
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#include <dirent.h> |
||||
#include <android/log.h> |
||||
#include <cctype> |
||||
#include <vector> |
||||
#include <algorithm> |
||||
#include <opencv2/core/version.hpp> |
||||
#include "camera_activity.hpp" |
||||
#include "camera_wrapper.h" |
||||
#include "EngineCommon.h" |
||||
|
||||
#include "opencv2/core.hpp" |
||||
|
||||
#undef LOG_TAG |
||||
#undef LOGE |
||||
#undef LOGD |
||||
#undef LOGI |
||||
|
||||
#define LOG_TAG "OpenCV::camera" |
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) |
||||
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) |
||||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) |
||||
|
||||
///////
|
||||
// Debug
|
||||
#include <stdio.h> |
||||
#include <sys/types.h> |
||||
#include <dirent.h> |
||||
|
||||
struct str_greater |
||||
{ |
||||
bool operator() (const cv::String& a, const cv::String& b) { return a > b; } |
||||
}; |
||||
|
||||
class CameraWrapperConnector |
||||
{ |
||||
public: |
||||
static CameraActivity::ErrorCode connect(int cameraId, CameraActivity* pCameraActivity, void** camera); |
||||
static CameraActivity::ErrorCode disconnect(void** camera); |
||||
static CameraActivity::ErrorCode setProperty(void* camera, int propIdx, double value); |
||||
static CameraActivity::ErrorCode getProperty(void* camera, int propIdx, double* value); |
||||
static CameraActivity::ErrorCode applyProperties(void** ppcamera); |
||||
|
||||
static void setPathLibFolder(const cv::String& path); |
||||
|
||||
private: |
||||
static cv::String pathLibFolder; |
||||
static bool isConnectedToLib; |
||||
|
||||
static cv::String getPathLibFolder(); |
||||
static cv::String getDefaultPathLibFolder(); |
||||
static CameraActivity::ErrorCode connectToLib(); |
||||
static CameraActivity::ErrorCode getSymbolFromLib(void * libHandle, const char* symbolName, void** ppSymbol); |
||||
static void fillListWrapperLibs(const cv::String& folderPath, std::vector<cv::String>& listLibs); |
||||
|
||||
static InitCameraConnectC pInitCameraC; |
||||
static CloseCameraConnectC pCloseCameraC; |
||||
static GetCameraPropertyC pGetPropertyC; |
||||
static SetCameraPropertyC pSetPropertyC; |
||||
static ApplyCameraPropertiesC pApplyPropertiesC; |
||||
|
||||
friend bool nextFrame(void* buffer, size_t bufferSize, void* userData); |
||||
}; |
||||
|
||||
cv::String CameraWrapperConnector::pathLibFolder; |
||||
|
||||
bool CameraWrapperConnector::isConnectedToLib = false; |
||||
InitCameraConnectC CameraWrapperConnector::pInitCameraC = 0; |
||||
CloseCameraConnectC CameraWrapperConnector::pCloseCameraC = 0; |
||||
GetCameraPropertyC CameraWrapperConnector::pGetPropertyC = 0; |
||||
SetCameraPropertyC CameraWrapperConnector::pSetPropertyC = 0; |
||||
ApplyCameraPropertiesC CameraWrapperConnector::pApplyPropertiesC = 0; |
||||
|
||||
#define INIT_CAMERA_SYMBOL_NAME "initCameraConnectC" |
||||
#define CLOSE_CAMERA_SYMBOL_NAME "closeCameraConnectC" |
||||
#define SET_CAMERA_PROPERTY_SYMBOL_NAME "setCameraPropertyC" |
||||
#define GET_CAMERA_PROPERTY_SYMBOL_NAME "getCameraPropertyC" |
||||
#define APPLY_CAMERA_PROPERTIES_SYMBOL_NAME "applyCameraPropertiesC" |
||||
#define PREFIX_CAMERA_WRAPPER_LIB "libnative_camera" |
||||
|
||||
|
||||
bool nextFrame(void* buffer, size_t bufferSize, void* userData) |
||||
{ |
||||
if (userData == NULL) |
||||
return true; |
||||
|
||||
return ((CameraActivity*)userData)->onFrameBuffer(buffer, bufferSize); |
||||
} |
||||
|
||||
CameraActivity::ErrorCode CameraWrapperConnector::connect(int cameraId, CameraActivity* pCameraActivity, void** camera) |
||||
{ |
||||
if (pCameraActivity == NULL) |
||||
{ |
||||
LOGE("CameraWrapperConnector::connect error: wrong pointer to CameraActivity object"); |
||||
return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode errcode=connectToLib(); |
||||
if (errcode) return errcode; |
||||
|
||||
void* cmr = (*pInitCameraC)((void*)nextFrame, cameraId, (void*)pCameraActivity); |
||||
if (!cmr) |
||||
{ |
||||
LOGE("CameraWrapperConnector::connectWrapper ERROR: the initializing function returned false"); |
||||
return CameraActivity::ERROR_CANNOT_INITIALIZE_CONNECTION; |
||||
} |
||||
|
||||
*camera = cmr; |
||||
return CameraActivity::NO_ERROR; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode CameraWrapperConnector::disconnect(void** camera) |
||||
{ |
||||
if (camera == NULL || *camera == NULL) |
||||
{ |
||||
LOGE("CameraWrapperConnector::disconnect error: wrong pointer to camera object"); |
||||
return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode errcode=connectToLib(); |
||||
if (errcode) return errcode; |
||||
|
||||
(*pCloseCameraC)(camera); |
||||
|
||||
return CameraActivity::NO_ERROR; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode CameraWrapperConnector::setProperty(void* camera, int propIdx, double value) |
||||
{ |
||||
if (camera == NULL) |
||||
{ |
||||
LOGE("CameraWrapperConnector::setProperty error: wrong pointer to camera object"); |
||||
return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER; |
||||
} |
||||
|
||||
(*pSetPropertyC)(camera, propIdx, value); |
||||
|
||||
return CameraActivity::NO_ERROR; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode CameraWrapperConnector::getProperty(void* camera, int propIdx, double* value) |
||||
{ |
||||
if (camera == NULL) |
||||
{ |
||||
LOGE("CameraWrapperConnector::getProperty error: wrong pointer to camera object"); |
||||
return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER; |
||||
} |
||||
LOGE("calling (*pGetPropertyC)(%p, %d)", camera, propIdx); |
||||
*value = (*pGetPropertyC)(camera, propIdx); |
||||
return CameraActivity::NO_ERROR; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode CameraWrapperConnector::applyProperties(void** ppcamera) |
||||
{ |
||||
if ((ppcamera == NULL) || (*ppcamera == NULL)) |
||||
{ |
||||
LOGE("CameraWrapperConnector::applyProperties error: wrong pointer to camera object"); |
||||
return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER; |
||||
} |
||||
|
||||
(*pApplyPropertiesC)(ppcamera); |
||||
return CameraActivity::NO_ERROR; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode CameraWrapperConnector::connectToLib() |
||||
{ |
||||
if (isConnectedToLib) { |
||||
return CameraActivity::NO_ERROR; |
||||
} |
||||
|
||||
dlerror(); |
||||
cv::String folderPath = getPathLibFolder(); |
||||
if (folderPath.empty()) |
||||
{ |
||||
LOGD("Trying to find native camera in default OpenCV packages"); |
||||
folderPath = getDefaultPathLibFolder(); |
||||
} |
||||
|
||||
LOGD("CameraWrapperConnector::connectToLib: folderPath=%s", folderPath.c_str()); |
||||
|
||||
std::vector<cv::String> listLibs; |
||||
fillListWrapperLibs(folderPath, listLibs); |
||||
std::sort(listLibs.begin(), listLibs.end(), str_greater()); |
||||
|
||||
void * libHandle=0; |
||||
cv::String cur_path; |
||||
for(size_t i = 0; i < listLibs.size(); i++) { |
||||
cur_path=folderPath + listLibs[i]; |
||||
LOGD("try to load library '%s'", listLibs[i].c_str()); |
||||
libHandle=dlopen(cur_path.c_str(), RTLD_LAZY); |
||||
if (libHandle) { |
||||
LOGD("Loaded library '%s'", cur_path.c_str()); |
||||
break; |
||||
} else { |
||||
LOGD("CameraWrapperConnector::connectToLib ERROR: cannot dlopen camera wrapper library %s, dlerror=\"%s\"", |
||||
cur_path.c_str(), dlerror()); |
||||
} |
||||
} |
||||
|
||||
if (!libHandle) { |
||||
LOGE("CameraWrapperConnector::connectToLib ERROR: cannot dlopen camera wrapper library"); |
||||
return CameraActivity::ERROR_CANNOT_OPEN_CAMERA_WRAPPER_LIB; |
||||
} |
||||
|
||||
InitCameraConnectC pInit_C; |
||||
CloseCameraConnectC pClose_C; |
||||
GetCameraPropertyC pGetProp_C; |
||||
SetCameraPropertyC pSetProp_C; |
||||
ApplyCameraPropertiesC pApplyProp_C; |
||||
|
||||
CameraActivity::ErrorCode res; |
||||
|
||||
res = getSymbolFromLib(libHandle, (const char*)INIT_CAMERA_SYMBOL_NAME, (void**)(&pInit_C)); |
||||
if (res) return res; |
||||
|
||||
res = getSymbolFromLib(libHandle, CLOSE_CAMERA_SYMBOL_NAME, (void**)(&pClose_C)); |
||||
if (res) return res; |
||||
|
||||
res = getSymbolFromLib(libHandle, GET_CAMERA_PROPERTY_SYMBOL_NAME, (void**)(&pGetProp_C)); |
||||
if (res) return res; |
||||
|
||||
res = getSymbolFromLib(libHandle, SET_CAMERA_PROPERTY_SYMBOL_NAME, (void**)(&pSetProp_C)); |
||||
if (res) return res; |
||||
|
||||
res = getSymbolFromLib(libHandle, APPLY_CAMERA_PROPERTIES_SYMBOL_NAME, (void**)(&pApplyProp_C)); |
||||
if (res) return res; |
||||
|
||||
pInitCameraC = pInit_C; |
||||
pCloseCameraC = pClose_C; |
||||
pGetPropertyC = pGetProp_C; |
||||
pSetPropertyC = pSetProp_C; |
||||
pApplyPropertiesC = pApplyProp_C; |
||||
isConnectedToLib=true; |
||||
|
||||
return CameraActivity::NO_ERROR; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode CameraWrapperConnector::getSymbolFromLib(void* libHandle, const char* symbolName, void** ppSymbol) |
||||
{ |
||||
dlerror(); |
||||
*(void **) (ppSymbol)=dlsym(libHandle, symbolName); |
||||
|
||||
const char* error_dlsym_init=dlerror(); |
||||
if (error_dlsym_init) { |
||||
LOGE("CameraWrapperConnector::getSymbolFromLib ERROR: cannot get symbol of the function '%s' from the camera wrapper library, dlerror=\"%s\"", |
||||
symbolName, error_dlsym_init); |
||||
return CameraActivity::ERROR_CANNOT_GET_FUNCTION_FROM_CAMERA_WRAPPER_LIB; |
||||
} |
||||
return CameraActivity::NO_ERROR; |
||||
} |
||||
|
||||
void CameraWrapperConnector::fillListWrapperLibs(const cv::String& folderPath, std::vector<cv::String>& listLibs) |
||||
{ |
||||
DIR *dp; |
||||
struct dirent *ep; |
||||
|
||||
dp = opendir (folderPath.c_str()); |
||||
if (dp != NULL) |
||||
{ |
||||
while ((ep = readdir (dp))) { |
||||
const char* cur_name=ep->d_name; |
||||
if (strstr(cur_name, PREFIX_CAMERA_WRAPPER_LIB)) { |
||||
listLibs.push_back(cur_name); |
||||
LOGE("||%s", cur_name); |
||||
} |
||||
} |
||||
(void) closedir (dp); |
||||
} |
||||
} |
||||
|
||||
cv::String CameraWrapperConnector::getDefaultPathLibFolder() |
||||
{ |
||||
#define BIN_PACKAGE_NAME(x) "org.opencv.lib_v" CVAUX_STR(CV_VERSION_MAJOR) CVAUX_STR(CV_VERSION_MINOR) "_" x |
||||
const char* const packageList[] = {BIN_PACKAGE_NAME("armv7a"), OPENCV_ENGINE_PACKAGE}; |
||||
for (size_t i = 0; i < sizeof(packageList)/sizeof(packageList[0]); i++) |
||||
{ |
||||
char path[128]; |
||||
sprintf(path, "/data/data/%s/lib/", packageList[i]); |
||||
LOGD("Trying package \"%s\" (\"%s\")", packageList[i], path); |
||||
|
||||
DIR* dir = opendir(path); |
||||
if (!dir) |
||||
{ |
||||
LOGD("Package not found"); |
||||
continue; |
||||
} |
||||
else |
||||
{ |
||||
closedir(dir); |
||||
return path; |
||||
} |
||||
} |
||||
|
||||
return cv::String(); |
||||
} |
||||
|
||||
cv::String CameraWrapperConnector::getPathLibFolder() |
||||
{ |
||||
if (!pathLibFolder.empty()) |
||||
return pathLibFolder; |
||||
|
||||
Dl_info dl_info; |
||||
if(0 != dladdr((void *)nextFrame, &dl_info)) |
||||
{ |
||||
LOGD("Library name: %s", dl_info.dli_fname); |
||||
LOGD("Library base address: %p", dl_info.dli_fbase); |
||||
|
||||
const char* libName=dl_info.dli_fname; |
||||
while( ((*libName)=='/') || ((*libName)=='.') ) |
||||
libName++; |
||||
|
||||
FILE* file = fopen("/proc/self/smaps", "rt"); |
||||
|
||||
if(file) |
||||
{ |
||||
char lineBuf[2048]; |
||||
while (fgets(lineBuf, sizeof lineBuf, file) != NULL) |
||||
{ |
||||
//verify that line ends with library name
|
||||
int lineLength = strlen(lineBuf); |
||||
int libNameLength = strlen(libName); |
||||
|
||||
//trim end
|
||||
for(int i = lineLength - 1; i >= 0 && isspace(lineBuf[i]); --i) |
||||
{ |
||||
lineBuf[i] = 0; |
||||
--lineLength; |
||||
} |
||||
|
||||
if (0 != strncmp(lineBuf + lineLength - libNameLength, libName, libNameLength)) |
||||
{ |
||||
//the line does not contain the library name
|
||||
continue; |
||||
} |
||||
|
||||
//extract path from smaps line
|
||||
char* pathBegin = strchr(lineBuf, '/'); |
||||
if (0 == pathBegin) |
||||
{ |
||||
LOGE("Strange error: could not find path beginning in lin \"%s\"", lineBuf); |
||||
continue; |
||||
} |
||||
|
||||
char* pathEnd = strrchr(pathBegin, '/'); |
||||
pathEnd[1] = 0; |
||||
|
||||
LOGD("Libraries folder found: %s", pathBegin); |
||||
|
||||
fclose(file); |
||||
return pathBegin; |
||||
} |
||||
fclose(file); |
||||
LOGE("Could not find library path"); |
||||
} |
||||
else |
||||
{ |
||||
LOGE("Could not read /proc/self/smaps"); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LOGE("Could not get library name and base address"); |
||||
} |
||||
|
||||
return cv::String(); |
||||
} |
||||
|
||||
void CameraWrapperConnector::setPathLibFolder(const cv::String& path) |
||||
{ |
||||
pathLibFolder=path; |
||||
} |
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CameraActivity::CameraActivity() : camera(0), frameWidth(-1), frameHeight(-1) |
||||
{ |
||||
} |
||||
|
||||
CameraActivity::~CameraActivity() |
||||
{ |
||||
if (camera != 0) |
||||
disconnect(); |
||||
} |
||||
|
||||
bool CameraActivity::onFrameBuffer(void* /*buffer*/, int /*bufferSize*/) |
||||
{ |
||||
LOGD("CameraActivity::onFrameBuffer - empty callback"); |
||||
return true; |
||||
} |
||||
|
||||
void CameraActivity::disconnect() |
||||
{ |
||||
CameraWrapperConnector::disconnect(&camera); |
||||
} |
||||
|
||||
bool CameraActivity::isConnected() const |
||||
{ |
||||
return camera != 0; |
||||
} |
||||
|
||||
CameraActivity::ErrorCode CameraActivity::connect(int cameraId) |
||||
{ |
||||
ErrorCode rescode = CameraWrapperConnector::connect(cameraId, this, &camera); |
||||
if (rescode) return rescode; |
||||
|
||||
return NO_ERROR; |
||||
} |
||||
|
||||
double CameraActivity::getProperty(int propIdx) |
||||
{ |
||||
double propVal; |
||||
ErrorCode rescode = CameraWrapperConnector::getProperty(camera, propIdx, &propVal); |
||||
if (rescode) return -1; |
||||
return propVal; |
||||
} |
||||
|
||||
void CameraActivity::setProperty(int propIdx, double value) |
||||
{ |
||||
CameraWrapperConnector::setProperty(camera, propIdx, value); |
||||
} |
||||
|
||||
void CameraActivity::applyProperties() |
||||
{ |
||||
frameWidth = -1; |
||||
frameHeight = -1; |
||||
CameraWrapperConnector::applyProperties(&camera); |
||||
frameWidth = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEWIDTH); |
||||
frameHeight = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT); |
||||
} |
||||
|
||||
int CameraActivity::getFrameWidth() |
||||
{ |
||||
if (frameWidth <= 0) |
||||
frameWidth = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEWIDTH); |
||||
return frameWidth; |
||||
} |
||||
|
||||
int CameraActivity::getFrameHeight() |
||||
{ |
||||
if (frameHeight <= 0) |
||||
frameHeight = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT); |
||||
return frameHeight; |
||||
} |
||||
|
||||
void CameraActivity::setPathLibFolder(const char* path) |
||||
{ |
||||
CameraWrapperConnector::setPathLibFolder(path); |
||||
} |
@ -1,182 +0,0 @@ |
||||
package org.opencv.android; |
||||
|
||||
import org.opencv.core.Mat; |
||||
import org.opencv.core.Size; |
||||
import org.opencv.videoio.Videoio; |
||||
import org.opencv.videoio.VideoCapture; |
||||
|
||||
import android.content.Context; |
||||
import android.util.AttributeSet; |
||||
import android.util.Log; |
||||
import android.view.ViewGroup.LayoutParams; |
||||
|
||||
/** |
||||
* This class is an implementation of a bridge between SurfaceView and native OpenCV camera. |
||||
* Due to the big amount of work done, by the base class this child is only responsible |
||||
* for creating camera, destroying camera and delivering frames while camera is enabled |
||||
*/ |
||||
public class NativeCameraView extends CameraBridgeViewBase { |
||||
|
||||
public static final String TAG = "NativeCameraView"; |
||||
private boolean mStopThread; |
||||
private Thread mThread; |
||||
|
||||
protected VideoCapture mCamera; |
||||
protected NativeCameraFrame mFrame; |
||||
|
||||
public NativeCameraView(Context context, int cameraId) { |
||||
super(context, cameraId); |
||||
} |
||||
|
||||
public NativeCameraView(Context context, AttributeSet attrs) { |
||||
super(context, attrs); |
||||
} |
||||
|
||||
@Override |
||||
protected boolean connectCamera(int width, int height) { |
||||
|
||||
/* 1. We need to instantiate camera |
||||
* 2. We need to start thread which will be getting frames |
||||
*/ |
||||
/* First step - initialize camera connection */ |
||||
if (!initializeCamera(width, height)) |
||||
return false; |
||||
|
||||
/* now we can start update thread */ |
||||
mThread = new Thread(new CameraWorker()); |
||||
mThread.start(); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
protected void disconnectCamera() { |
||||
/* 1. We need to stop thread which updating the frames |
||||
* 2. Stop camera and release it |
||||
*/ |
||||
if (mThread != null) { |
||||
try { |
||||
mStopThread = true; |
||||
mThread.join(); |
||||
} catch (InterruptedException e) { |
||||
e.printStackTrace(); |
||||
} finally { |
||||
mThread = null; |
||||
mStopThread = false; |
||||
} |
||||
} |
||||
|
||||
/* Now release camera */ |
||||
releaseCamera(); |
||||
} |
||||
|
||||
public static class OpenCvSizeAccessor implements ListItemAccessor { |
||||
|
||||
public int getWidth(Object obj) { |
||||
Size size = (Size)obj; |
||||
return (int)size.width; |
||||
} |
||||
|
||||
public int getHeight(Object obj) { |
||||
Size size = (Size)obj; |
||||
return (int)size.height; |
||||
} |
||||
|
||||
} |
||||
|
||||
private boolean initializeCamera(int width, int height) { |
||||
synchronized (this) { |
||||
|
||||
if (mCameraIndex == -1) |
||||
mCamera = new VideoCapture(Videoio.CV_CAP_ANDROID); |
||||
else |
||||
mCamera = new VideoCapture(Videoio.CV_CAP_ANDROID + mCameraIndex); |
||||
|
||||
if (mCamera == null) |
||||
return false; |
||||
|
||||
if (mCamera.isOpened() == false) |
||||
return false; |
||||
|
||||
mFrame = new NativeCameraFrame(mCamera); |
||||
|
||||
java.util.List<Size> sizes = mCamera.getSupportedPreviewSizes(); |
||||
|
||||
/* Select the size that fits surface considering maximum size allowed */ |
||||
Size frameSize = calculateCameraFrameSize(sizes, new OpenCvSizeAccessor(), width, height); |
||||
|
||||
mFrameWidth = (int)frameSize.width; |
||||
mFrameHeight = (int)frameSize.height; |
||||
|
||||
if ((getLayoutParams().width == LayoutParams.MATCH_PARENT) && (getLayoutParams().height == LayoutParams.MATCH_PARENT)) |
||||
mScale = Math.min(((float)height)/mFrameHeight, ((float)width)/mFrameWidth); |
||||
else |
||||
mScale = 0; |
||||
|
||||
if (mFpsMeter != null) { |
||||
mFpsMeter.setResolution(mFrameWidth, mFrameHeight); |
||||
} |
||||
|
||||
AllocateCache(); |
||||
|
||||
mCamera.set(Videoio.CV_CAP_PROP_FRAME_WIDTH, frameSize.width); |
||||
mCamera.set(Videoio.CV_CAP_PROP_FRAME_HEIGHT, frameSize.height); |
||||
} |
||||
|
||||
Log.i(TAG, "Selected camera frame size = (" + mFrameWidth + ", " + mFrameHeight + ")"); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private void releaseCamera() { |
||||
synchronized (this) { |
||||
if (mFrame != null) mFrame.release(); |
||||
if (mCamera != null) mCamera.release(); |
||||
} |
||||
} |
||||
|
||||
private static class NativeCameraFrame implements CvCameraViewFrame { |
||||
|
||||
@Override |
||||
public Mat rgba() { |
||||
mCapture.retrieve(mRgba, Videoio.CV_CAP_ANDROID_COLOR_FRAME_RGBA); |
||||
return mRgba; |
||||
} |
||||
|
||||
@Override |
||||
public Mat gray() { |
||||
mCapture.retrieve(mGray, Videoio.CV_CAP_ANDROID_GREY_FRAME); |
||||
return mGray; |
||||
} |
||||
|
||||
public NativeCameraFrame(VideoCapture capture) { |
||||
mCapture = capture; |
||||
mGray = new Mat(); |
||||
mRgba = new Mat(); |
||||
} |
||||
|
||||
public void release() { |
||||
if (mGray != null) mGray.release(); |
||||
if (mRgba != null) mRgba.release(); |
||||
} |
||||
|
||||
private VideoCapture mCapture; |
||||
private Mat mRgba; |
||||
private Mat mGray; |
||||
}; |
||||
|
||||
private class CameraWorker implements Runnable { |
||||
|
||||
public void run() { |
||||
do { |
||||
if (!mCamera.grab()) { |
||||
Log.e(TAG, "Camera frame grab failed"); |
||||
break; |
||||
} |
||||
|
||||
deliverAndDrawFrame(mFrame); |
||||
} while (!mStopThread); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,4 +1,4 @@ |
||||
package org.opencv.engine3; |
||||
package org.opencv.engine; |
||||
|
||||
/** |
||||
* Class provides a Java interface for OpenCV Engine Service. It's synchronous with native OpenCVEngine class. |
@ -1,554 +0,0 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp" |
||||
|
||||
#ifdef HAVE_ANDROID_NATIVE_CAMERA |
||||
|
||||
#include <opencv2/imgproc.hpp> |
||||
#include <pthread.h> |
||||
#include <android/log.h> |
||||
#include <camera_activity.hpp> |
||||
|
||||
#undef LOG_TAG |
||||
#undef LOGD |
||||
#undef LOGE |
||||
#undef LOGI |
||||
#define LOG_TAG "OpenCV::camera" |
||||
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) |
||||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) |
||||
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) |
||||
|
||||
class VideoIOAndroidCameraActivity; |
||||
|
||||
class CvCapture_Android : public CvCapture |
||||
{ |
||||
public: |
||||
CvCapture_Android(int); |
||||
virtual ~CvCapture_Android(); |
||||
|
||||
virtual double getProperty(int propIdx) const; |
||||
virtual bool setProperty(int probIdx, double propVal); |
||||
virtual bool grabFrame(); |
||||
virtual IplImage* retrieveFrame(int outputType); |
||||
virtual int getCaptureDomain() { return CV_CAP_ANDROID; } |
||||
|
||||
bool isOpened() const; |
||||
|
||||
protected: |
||||
struct OutputMap |
||||
{ |
||||
public: |
||||
cv::Mat mat; |
||||
IplImage* getIplImagePtr(); |
||||
private: |
||||
IplImage iplHeader; |
||||
}; |
||||
|
||||
CameraActivity* m_activity; |
||||
|
||||
//raw from camera
|
||||
int m_width; |
||||
int m_height; |
||||
cv::Mat m_frameYUV420; |
||||
cv::Mat m_frameYUV420next; |
||||
|
||||
enum YUVformat |
||||
{ |
||||
noformat = 0, |
||||
yuv420sp, |
||||
yvu420sp, |
||||
yuvUnknown |
||||
}; |
||||
|
||||
YUVformat m_frameFormat; |
||||
|
||||
void setFrame(const void* buffer, int bufferSize); |
||||
|
||||
private: |
||||
bool m_isOpened; |
||||
bool m_CameraParamsChanged; |
||||
|
||||
//frames counter for statistics
|
||||
int m_framesGrabbed; |
||||
|
||||
//cached converted frames
|
||||
OutputMap m_frameGray; |
||||
OutputMap m_frameColor; |
||||
bool m_hasGray; |
||||
bool m_hasColor; |
||||
|
||||
enum CvCapture_Android_DataState { |
||||
CVCAPTURE_ANDROID_STATE_NO_FRAME=0, |
||||
CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED, |
||||
CVCAPTURE_ANDROID_STATE_HAS_FRAME_GRABBED |
||||
}; |
||||
volatile CvCapture_Android_DataState m_dataState; |
||||
|
||||
//synchronization
|
||||
pthread_mutex_t m_nextFrameMutex; |
||||
pthread_cond_t m_nextFrameCond; |
||||
volatile bool m_waitingNextFrame; |
||||
volatile bool m_shouldAutoGrab; |
||||
|
||||
void prepareCacheForYUV(int width, int height); |
||||
bool convertYUV2Grey(int width, int height, const unsigned char* yuv, cv::Mat& resmat); |
||||
bool convertYUV2BGR(int width, int height, const unsigned char* yuv, cv::Mat& resmat, bool inRGBorder, bool withAlpha); |
||||
|
||||
friend class VideoIOAndroidCameraActivity; |
||||
}; |
||||
|
||||
|
||||
class VideoIOAndroidCameraActivity : public CameraActivity |
||||
{ |
||||
public: |
||||
VideoIOAndroidCameraActivity(CvCapture_Android* capture) |
||||
{ |
||||
m_capture = capture; |
||||
m_framesReceived = 0; |
||||
} |
||||
|
||||
virtual bool onFrameBuffer(void* buffer, int bufferSize) |
||||
{ |
||||
if(isConnected() && buffer != 0 && bufferSize > 0) |
||||
{ |
||||
m_framesReceived++; |
||||
if (m_capture->m_waitingNextFrame || m_capture->m_shouldAutoGrab) |
||||
{ |
||||
pthread_mutex_lock(&m_capture->m_nextFrameMutex); |
||||
|
||||
m_capture->setFrame(buffer, bufferSize); |
||||
|
||||
pthread_cond_broadcast(&m_capture->m_nextFrameCond); |
||||
pthread_mutex_unlock(&m_capture->m_nextFrameMutex); |
||||
} |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
void LogFramesRate() |
||||
{ |
||||
LOGI("FRAMES received: %d grabbed: %d", m_framesReceived, m_capture->m_framesGrabbed); |
||||
} |
||||
|
||||
private: |
||||
CvCapture_Android* m_capture; |
||||
int m_framesReceived; |
||||
}; |
||||
|
||||
IplImage* CvCapture_Android::OutputMap::getIplImagePtr() |
||||
{ |
||||
if( mat.empty() ) |
||||
return 0; |
||||
|
||||
iplHeader = IplImage(mat); |
||||
return &iplHeader; |
||||
} |
||||
|
||||
CvCapture_Android::CvCapture_Android(int cameraId) |
||||
{ |
||||
//defaults
|
||||
m_width = 0; |
||||
m_height = 0; |
||||
m_activity = 0; |
||||
m_isOpened = false; |
||||
// m_frameYUV420 = 0;
|
||||
// m_frameYUV420next = 0;
|
||||
m_hasGray = false; |
||||
m_hasColor = false; |
||||
m_dataState = CVCAPTURE_ANDROID_STATE_NO_FRAME; |
||||
m_waitingNextFrame = false; |
||||
m_shouldAutoGrab = false; |
||||
m_framesGrabbed = 0; |
||||
m_CameraParamsChanged = false; |
||||
m_frameFormat = noformat; |
||||
|
||||
//try connect to camera
|
||||
LOGD("CvCapture_Android::CvCapture_Android(%i)", cameraId); |
||||
m_activity = new VideoIOAndroidCameraActivity(this); |
||||
|
||||
if (m_activity == 0) return; |
||||
|
||||
pthread_mutex_init(&m_nextFrameMutex, NULL); |
||||
pthread_cond_init (&m_nextFrameCond, NULL); |
||||
|
||||
CameraActivity::ErrorCode errcode = m_activity->connect(cameraId); |
||||
|
||||
if(errcode == CameraActivity::NO_ERROR) |
||||
m_isOpened = true; |
||||
else |
||||
{ |
||||
LOGE("Native_camera returned opening error: %d", errcode); |
||||
delete m_activity; |
||||
m_activity = 0; |
||||
} |
||||
} |
||||
|
||||
bool CvCapture_Android::isOpened() const |
||||
{ |
||||
return m_isOpened; |
||||
} |
||||
|
||||
CvCapture_Android::~CvCapture_Android() |
||||
{ |
||||
if (m_activity) |
||||
{ |
||||
((VideoIOAndroidCameraActivity*)m_activity)->LogFramesRate(); |
||||
|
||||
pthread_mutex_lock(&m_nextFrameMutex); |
||||
|
||||
// unsigned char *tmp1=m_frameYUV420;
|
||||
// unsigned char *tmp2=m_frameYUV420next;
|
||||
// m_frameYUV420 = 0;
|
||||
// m_frameYUV420next = 0;
|
||||
// delete tmp1;
|
||||
// delete tmp2;
|
||||
|
||||
m_dataState=CVCAPTURE_ANDROID_STATE_NO_FRAME; |
||||
pthread_cond_broadcast(&m_nextFrameCond); |
||||
|
||||
pthread_mutex_unlock(&m_nextFrameMutex); |
||||
|
||||
//m_activity->disconnect() will be automatically called inside destructor;
|
||||
delete m_activity; |
||||
m_activity = 0; |
||||
|
||||
pthread_mutex_destroy(&m_nextFrameMutex); |
||||
pthread_cond_destroy(&m_nextFrameCond); |
||||
} |
||||
} |
||||
|
||||
double CvCapture_Android::getProperty( int propIdx ) const |
||||
{ |
||||
switch ( propIdx ) |
||||
{ |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
return (double)m_activity->getFrameWidth(); |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
return (double)m_activity->getFrameHeight(); |
||||
case CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING); |
||||
case CV_CAP_PROP_PREVIEW_FORMAT: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING); |
||||
case CV_CAP_PROP_FPS: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FPS); |
||||
case CV_CAP_PROP_EXPOSURE: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_EXPOSURE); |
||||
case CV_CAP_PROP_ANDROID_FLASH_MODE: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FLASH_MODE); |
||||
case CV_CAP_PROP_ANDROID_FOCUS_MODE: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_MODE); |
||||
case CV_CAP_PROP_ANDROID_WHITE_BALANCE: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_WHITE_BALANCE); |
||||
case CV_CAP_PROP_ANDROID_ANTIBANDING: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_ANTIBANDING); |
||||
case CV_CAP_PROP_ANDROID_FOCAL_LENGTH: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH); |
||||
case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR); |
||||
case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL); |
||||
case CV_CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR); |
||||
case CV_CAP_PROP_ANDROID_EXPOSE_LOCK: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_EXPOSE_LOCK); |
||||
case CV_CAP_PROP_ANDROID_WHITEBALANCE_LOCK: |
||||
return (double)m_activity->getProperty(ANDROID_CAMERA_PROPERTY_WHITEBALANCE_LOCK); |
||||
default: |
||||
CV_Error( CV_StsOutOfRange, "Failed attempt to GET unsupported camera property." ); |
||||
break; |
||||
} |
||||
return -1.0; |
||||
} |
||||
|
||||
bool CvCapture_Android::setProperty( int propIdx, double propValue ) |
||||
{ |
||||
bool res = false; |
||||
if( isOpened() ) |
||||
{ |
||||
switch ( propIdx ) |
||||
{ |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FRAMEWIDTH, propValue); |
||||
break; |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT, propValue); |
||||
break; |
||||
case CV_CAP_PROP_AUTOGRAB: |
||||
m_shouldAutoGrab=(propValue != 0); |
||||
break; |
||||
case CV_CAP_PROP_EXPOSURE: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_EXPOSURE, propValue); |
||||
break; |
||||
case CV_CAP_PROP_ANDROID_FLASH_MODE: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FLASH_MODE, propValue); |
||||
break; |
||||
case CV_CAP_PROP_ANDROID_FOCUS_MODE: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_FOCUS_MODE, propValue); |
||||
break; |
||||
case CV_CAP_PROP_ANDROID_WHITE_BALANCE: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_WHITE_BALANCE, propValue); |
||||
break; |
||||
case CV_CAP_PROP_ANDROID_ANTIBANDING: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_ANTIBANDING, propValue); |
||||
break; |
||||
case CV_CAP_PROP_ANDROID_EXPOSE_LOCK: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_EXPOSE_LOCK, propValue); |
||||
break; |
||||
case CV_CAP_PROP_ANDROID_WHITEBALANCE_LOCK: |
||||
m_activity->setProperty(ANDROID_CAMERA_PROPERTY_WHITEBALANCE_LOCK, propValue); |
||||
break; |
||||
default: |
||||
CV_Error( CV_StsOutOfRange, "Failed attempt to SET unsupported camera property." ); |
||||
return false; |
||||
} |
||||
|
||||
// Only changes in frame size require camera restart
|
||||
if ((propIdx == CV_CAP_PROP_FRAME_WIDTH) || (propIdx == CV_CAP_PROP_FRAME_HEIGHT)) |
||||
{ // property for videoio class CvCapture_Android only
|
||||
m_CameraParamsChanged = true; |
||||
} |
||||
|
||||
res = true; |
||||
} |
||||
|
||||
return res; |
||||
} |
||||
|
||||
bool CvCapture_Android::grabFrame() |
||||
{ |
||||
if( !isOpened() ) { |
||||
LOGE("CvCapture_Android::grabFrame(): camera is not opened"); |
||||
return false; |
||||
} |
||||
|
||||
bool res=false; |
||||
pthread_mutex_lock(&m_nextFrameMutex); |
||||
if (m_CameraParamsChanged) |
||||
{ |
||||
m_activity->applyProperties(); |
||||
m_CameraParamsChanged = false; |
||||
m_dataState = CVCAPTURE_ANDROID_STATE_NO_FRAME;//we will wait new frame
|
||||
} |
||||
|
||||
if (m_dataState != CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED) |
||||
{ |
||||
m_waitingNextFrame = true; |
||||
pthread_cond_wait(&m_nextFrameCond, &m_nextFrameMutex); |
||||
} |
||||
|
||||
if (m_dataState == CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED) |
||||
{ |
||||
//LOGD("CvCapture_Android::grabFrame: get new frame");
|
||||
//swap current and new frames
|
||||
cv::swap(m_frameYUV420, m_frameYUV420next); |
||||
|
||||
//discard cached frames
|
||||
m_hasGray = false; |
||||
m_hasColor = false; |
||||
|
||||
m_dataState=CVCAPTURE_ANDROID_STATE_HAS_FRAME_GRABBED; |
||||
m_framesGrabbed++; |
||||
|
||||
res=true; |
||||
} else { |
||||
LOGE("CvCapture_Android::grabFrame: NO new frame"); |
||||
} |
||||
|
||||
|
||||
int res_unlock=pthread_mutex_unlock(&m_nextFrameMutex); |
||||
if (res_unlock) { |
||||
LOGE("Error in CvCapture_Android::grabFrame: pthread_mutex_unlock returned %d --- probably, this object has been destroyed", res_unlock); |
||||
return false; |
||||
} |
||||
|
||||
return res; |
||||
} |
||||
|
||||
IplImage* CvCapture_Android::retrieveFrame( int outputType ) |
||||
{ |
||||
IplImage* image = NULL; |
||||
|
||||
cv::Mat m_frameYUV420_ref = m_frameYUV420; |
||||
unsigned char *current_frameYUV420=m_frameYUV420_ref.ptr(); |
||||
//Attention! all the operations in this function below should occupy less time than the period between two frames from camera
|
||||
if (NULL != current_frameYUV420) |
||||
{ |
||||
if (m_frameFormat == noformat) |
||||
{ |
||||
union {double prop; const char* name;} u; |
||||
u.prop = getProperty(CV_CAP_PROP_PREVIEW_FORMAT); |
||||
if (0 == strcmp(u.name, "yuv420sp")) |
||||
m_frameFormat = yuv420sp; |
||||
else if (0 == strcmp(u.name, "yvu420sp")) |
||||
m_frameFormat = yvu420sp; |
||||
else |
||||
m_frameFormat = yuvUnknown; |
||||
} |
||||
|
||||
switch(outputType) |
||||
{ |
||||
case CV_CAP_ANDROID_GREY_FRAME: |
||||
if (!m_hasGray) |
||||
if (!(m_hasGray = convertYUV2Grey(m_width, m_height, current_frameYUV420, m_frameGray.mat))) |
||||
return NULL; |
||||
image = m_frameGray.getIplImagePtr(); |
||||
break; |
||||
case CV_CAP_ANDROID_COLOR_FRAME_BGR: case CV_CAP_ANDROID_COLOR_FRAME_RGB: |
||||
if (!m_hasColor) |
||||
if (!(m_hasColor = convertYUV2BGR(m_width, m_height, current_frameYUV420, m_frameColor.mat, outputType == CV_CAP_ANDROID_COLOR_FRAME_RGB, false))) |
||||
return NULL; |
||||
image = m_frameColor.getIplImagePtr(); |
||||
break; |
||||
case CV_CAP_ANDROID_COLOR_FRAME_BGRA: case CV_CAP_ANDROID_COLOR_FRAME_RGBA: |
||||
if (!m_hasColor) |
||||
if (!(m_hasColor = convertYUV2BGR(m_width, m_height, current_frameYUV420, m_frameColor.mat, outputType == CV_CAP_ANDROID_COLOR_FRAME_RGBA, true))) |
||||
return NULL; |
||||
image = m_frameColor.getIplImagePtr(); |
||||
break; |
||||
default: |
||||
LOGE("Unsupported frame output format: %d", outputType); |
||||
CV_Error( CV_StsOutOfRange, "Output frame format is not supported." ); |
||||
image = NULL; |
||||
break; |
||||
} |
||||
} |
||||
return image; |
||||
} |
||||
|
||||
//Attention: this method should be called inside pthread_mutex_lock(m_nextFrameMutex) only
|
||||
void CvCapture_Android::setFrame(const void* buffer, int bufferSize) |
||||
{ |
||||
int width = m_activity->getFrameWidth(); |
||||
int height = m_activity->getFrameHeight(); |
||||
int expectedSize = (width * height * 3) >> 1; |
||||
|
||||
if ( expectedSize != bufferSize) |
||||
{ |
||||
LOGE("ERROR reading YUV buffer: width=%d, height=%d, size=%d, receivedSize=%d", width, height, expectedSize, bufferSize); |
||||
return; |
||||
} |
||||
|
||||
//allocate memory if needed
|
||||
prepareCacheForYUV(width, height); |
||||
|
||||
//copy data
|
||||
cv::Mat m_frameYUV420next_ref = m_frameYUV420next; |
||||
memcpy(m_frameYUV420next_ref.ptr(), buffer, bufferSize); |
||||
// LOGD("CvCapture_Android::setFrame -- memcpy is done");
|
||||
// ((VideoIOAndroidCameraActivity*)m_activity)->LogFramesRate();
|
||||
|
||||
m_dataState = CVCAPTURE_ANDROID_STATE_HAS_NEW_FRAME_UNGRABBED; |
||||
m_waitingNextFrame = false;//set flag that no more frames required at this moment
|
||||
} |
||||
|
||||
//Attention: this method should be called inside pthread_mutex_lock(m_nextFrameMutex) only
|
||||
void CvCapture_Android::prepareCacheForYUV(int width, int height) |
||||
{ |
||||
if (width != m_width || height != m_height) |
||||
{ |
||||
LOGD("CvCapture_Android::prepareCacheForYUV: Changing size of buffers: from width=%d height=%d to width=%d height=%d", m_width, m_height, width, height); |
||||
m_width = width; |
||||
m_height = height; |
||||
/*
|
||||
unsigned char *tmp = m_frameYUV420next; |
||||
m_frameYUV420next = new unsigned char [width * height * 3 / 2]; |
||||
if (tmp != NULL) |
||||
{ |
||||
delete[] tmp; |
||||
} |
||||
|
||||
tmp = m_frameYUV420; |
||||
m_frameYUV420 = new unsigned char [width * height * 3 / 2]; |
||||
if (tmp != NULL) |
||||
{ |
||||
delete[] tmp; |
||||
}*/ |
||||
m_frameYUV420.create(height * 3 / 2, width, CV_8UC1); |
||||
m_frameYUV420next.create(height * 3 / 2, width, CV_8UC1); |
||||
} |
||||
} |
||||
|
||||
bool CvCapture_Android::convertYUV2Grey(int width, int height, const unsigned char* yuv, cv::Mat& resmat) |
||||
{ |
||||
if (yuv == 0) return false; |
||||
if (m_frameFormat != yuv420sp && m_frameFormat != yvu420sp) return false; |
||||
#define ALWAYS_COPY_GRAY 0 |
||||
#if ALWAYS_COPY_GRAY |
||||
resmat.create(height, width, CV_8UC1); |
||||
unsigned char* matBuff = resmat.ptr<unsigned char> (0); |
||||
memcpy(matBuff, yuv, width * height); |
||||
#else |
||||
resmat = cv::Mat(height, width, CV_8UC1, (void*)yuv); |
||||
#endif |
||||
return !resmat.empty(); |
||||
} |
||||
|
||||
bool CvCapture_Android::convertYUV2BGR(int width, int height, const unsigned char* yuv, cv::Mat& resmat, bool inRGBorder, bool withAlpha) |
||||
{ |
||||
if (yuv == 0) return false; |
||||
if (m_frameFormat != yuv420sp && m_frameFormat != yvu420sp) return false; |
||||
|
||||
CV_Assert(width % 2 == 0 && height % 2 == 0); |
||||
|
||||
cv::Mat src(height*3/2, width, CV_8UC1, (void*)yuv); |
||||
|
||||
if (m_frameFormat == yuv420sp) |
||||
cv::cvtColor(src, resmat, inRGBorder ? CV_YUV420sp2RGB : CV_YUV420sp2BGR, withAlpha ? 4 : 3); |
||||
else if (m_frameFormat == yvu420sp) |
||||
cv::cvtColor(src, resmat, inRGBorder ? CV_YUV2RGB_NV21 : CV_YUV2BGR_NV12, withAlpha ? 4 : 3); |
||||
|
||||
return !resmat.empty(); |
||||
} |
||||
|
||||
CvCapture* cvCreateCameraCapture_Android( int cameraId ) |
||||
{ |
||||
CvCapture_Android* capture = new CvCapture_Android(cameraId); |
||||
|
||||
if( capture->isOpened() ) |
||||
return capture; |
||||
|
||||
delete capture; |
||||
return 0; |
||||
} |
||||
|
||||
#endif |
@ -1,6 +0,0 @@ |
||||
******** |
||||
Java API |
||||
******** |
||||
|
||||
|
||||
Java API reference (JavaDoc): external `link <http://docs.opencv.org/java/>`_. |
@ -1,42 +0,0 @@ |
||||
project(libopencv_info) |
||||
if(NOT ANDROID_PACKAGE_RELEASE) |
||||
set(ANDROID_PACKAGE_RELEASE 1) |
||||
endif() |
||||
|
||||
if(NOT ANDROID_PACKAGE_PLATFORM) |
||||
if(ARMEABI_V7A) |
||||
if(NEON) |
||||
set(ANDROID_PACKAGE_PLATFORM armv7a_neon) |
||||
else() |
||||
set(ANDROID_PACKAGE_PLATFORM armv7a) |
||||
endif() |
||||
elseif(ARMEABI_V6) |
||||
set(ANDROID_PACKAGE_PLATFORM armv6) |
||||
elseif(ARMEABI) |
||||
set(ANDROID_PACKAGE_PLATFORM armv5) |
||||
elseif(X86) |
||||
set(ANDROID_PACKAGE_PLATFORM x86) |
||||
elseif(MIPS) |
||||
set(ANDROID_PACKAGE_PLATFORM mips) |
||||
else() |
||||
message(ERROR "Can not automatically determine the value for ANDROID_PACKAGE_PLATFORM") |
||||
endif() |
||||
endif() |
||||
|
||||
string(REPLACE "-fvisibility=hidden" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") |
||||
string(REPLACE "-fvisibility-inlines-hidden" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") |
||||
|
||||
add_definitions(-DANDROID_PACKAGE_RELEASE=${ANDROID_PACKAGE_RELEASE} -DANDROID_PACKAGE_PLATFORM="${ANDROID_PACKAGE_PLATFORM}") |
||||
|
||||
include_directories(jni/BinderComponent jni/include "${OpenCV_SOURCE_DIR}/modules/core/include") |
||||
|
||||
add_library(opencv_info SHARED info.c) |
||||
|
||||
set_target_properties(${the_module} PROPERTIES |
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH} |
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} |
||||
INSTALL_NAME_DIR lib |
||||
) |
||||
|
||||
get_filename_component(lib_name "libopencv_info.so" NAME) |
||||
install(FILES "${LIBRARY_OUTPUT_PATH}/${lib_name}" DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT libs) |
@ -1,31 +0,0 @@ |
||||
#include "opencv2/core/version.hpp" |
||||
#include <jni.h> |
||||
|
||||
const char* GetPackageName(void); |
||||
const char* GetRevision(void); |
||||
const char* GetLibraryList(void); |
||||
JNIEXPORT jstring JNICALL Java_org_opencv_android_StaticHelper_getLibraryList(JNIEnv *, jclass); |
||||
|
||||
#define PACKAGE_NAME "org.opencv.lib_v" CVAUX_STR(CV_VERSION_MAJOR) CVAUX_STR(CV_VERSION_MINOR) "_" ANDROID_PACKAGE_PLATFORM |
||||
#define PACKAGE_REVISION CVAUX_STR(CV_VERSION_REVISION) "." CVAUX_STR(ANDROID_PACKAGE_RELEASE) |
||||
|
||||
const char* GetPackageName(void) |
||||
{ |
||||
return PACKAGE_NAME; |
||||
} |
||||
|
||||
const char* GetRevision(void) |
||||
{ |
||||
return PACKAGE_REVISION; |
||||
} |
||||
|
||||
const char* GetLibraryList(void) |
||||
{ |
||||
return ""; |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_android_StaticHelper_getLibraryList(JNIEnv * env, jclass clazz) |
||||
{ |
||||
(void)clazz; |
||||
return (*env)->NewStringUTF(env, GetLibraryList()); |
||||
} |
@ -1,15 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="org.opencv.lib_v@OPENCV_VERSION_MAJOR@@OPENCV_VERSION_MINOR@_@ANDROID_PACKAGE_PLATFORM@" |
||||
android:versionCode="@OPENCV_VERSION_PATCH@0@ANDROID_PACKAGE_RELEASE@" |
||||
android:versionName="@OPENCV_VERSION_PATCH@.@ANDROID_PACKAGE_RELEASE@" > |
||||
|
||||
<uses-sdk android:minSdkVersion="@ANDROID_SDK_VERSION@" /> |
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/> |
||||
|
||||
<application |
||||
android:icon="@drawable/icon" |
||||
android:label="@string/app_name" > |
||||
</application> |
||||
|
||||
</manifest> |
@ -1,94 +0,0 @@ |
||||
if(NOT ANDROID_PACKAGE_RELEASE) |
||||
set(ANDROID_PACKAGE_RELEASE 1) |
||||
endif() |
||||
|
||||
if(NOT ANDROID_PACKAGE_PLATFORM) |
||||
if(ARMEABI_V7A) |
||||
if(NEON) |
||||
set(ANDROID_PACKAGE_PLATFORM armv7a_neon) |
||||
else() |
||||
set(ANDROID_PACKAGE_PLATFORM armv7a) |
||||
endif() |
||||
elseif(ARMEABI_V6) |
||||
set(ANDROID_PACKAGE_PLATFORM armv6) |
||||
elseif(ARMEABI) |
||||
set(ANDROID_PACKAGE_PLATFORM armv5) |
||||
elseif(X86) |
||||
set(ANDROID_PACKAGE_PLATFORM x86) |
||||
elseif(MIPS) |
||||
set(ANDROID_PACKAGE_PLATFORM mips) |
||||
else() |
||||
message(ERROR "Can not automatically determine the value for ANDROID_PACKAGE_PLATFORM") |
||||
endif() |
||||
endif() |
||||
|
||||
if(NOT ANDROID_PACKAGE_PLATFORM_NAME) |
||||
if(ARMEABI_V7A) |
||||
if(NEON) |
||||
set(ANDROID_PACKAGE_PLATFORM_NAME "armeabi-v7a with NEON") |
||||
else() |
||||
set(ANDROID_PACKAGE_PLATFORM_NAME "armeabi-v7a") |
||||
endif() |
||||
elseif(ARMEABI_V6) |
||||
set(ANDROID_PACKAGE_PLATFORM_NAME "armeabi-v6") |
||||
elseif(ARMEABI) |
||||
set(ANDROID_PACKAGE_PLATFORM_NAME "armeabi") |
||||
elseif(X86) |
||||
set(ANDROID_PACKAGE_PLATFORM_NAME "x86") |
||||
elseif(MIPS) |
||||
set(ANDROID_PACKAGE_PLATFORM_NAME "mips") |
||||
else() |
||||
message(ERROR "Can not automatically determine the value for ANDROID_PACKAGE_PLATFORM_NAME") |
||||
endif() |
||||
endif() |
||||
|
||||
if("${ANDROID_NATIVE_API_LEVEL}" MATCHES "[1-9][0-9]*$") |
||||
set(ANDROID_SDK_VERSION ${CMAKE_MATCH_0}) |
||||
endif() |
||||
|
||||
if(NOT ANDROID_SDK_VERSION GREATER 7) |
||||
set(ANDROID_SDK_VERSION 8) |
||||
endif() |
||||
|
||||
set(PACKAGE_DIR "${OpenCV_BINARY_DIR}/package") |
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${ANDROID_MANIFEST_FILE}" "${PACKAGE_DIR}/${ANDROID_MANIFEST_FILE}" @ONLY) |
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/values/strings.xml" "${PACKAGE_DIR}/res/values/strings.xml" @ONLY) |
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/res/drawable/icon.png" "${PACKAGE_DIR}/res/drawable/icon.png" COPYONLY) |
||||
|
||||
set(target_name "OpenCV_${OPENCV_VERSION}_binary_pack_${ANDROID_PACKAGE_PLATFORM}") |
||||
get_target_property(opencv_java_location opencv_java LOCATION) |
||||
|
||||
set(android_proj_target_files ${ANDROID_PROJECT_FILES}) |
||||
ocv_list_add_prefix(android_proj_target_files "${PACKAGE_DIR}/") |
||||
android_get_compatible_target(android_proj_sdk_target ${ANDROID_SDK_VERSION}) |
||||
set(APK_NAME "${PACKAGE_DIR}/bin/${target_name}-release-unsigned.apk") |
||||
|
||||
file(GLOB camera_wrappers "${OpenCV_SOURCE_DIR}/3rdparty/lib/${ANDROID_NDK_ABI_NAME}/libnative_camera_r*.so") |
||||
set(CAMERA_LIB_COMMANDS "") |
||||
|
||||
foreach(wrapper ${camera_wrappers}) |
||||
list(APPEND CAMERA_LIB_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/") |
||||
endforeach() |
||||
|
||||
add_custom_command( |
||||
OUTPUT "${APK_NAME}" |
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PACKAGE_DIR}/libs" |
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PACKAGE_DIR}/bin" |
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory "${PACKAGE_DIR}/gen" |
||||
COMMAND ${CMAKE_COMMAND} -E remove ${android_proj_target_files} |
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${PACKAGE_DIR}/src" |
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/" |
||||
${CAMERA_LIB_COMMANDS} |
||||
COMMAND ${CMAKE_COMMAND} -E copy "${opencv_java_location}" "${PACKAGE_DIR}/libs/${ANDROID_NDK_ABI_NAME}/" |
||||
COMMAND ${ANDROID_EXECUTABLE} --silent update project --path "${PACKAGE_DIR}" --target "${android_proj_sdk_target}" --name "${target_name}" |
||||
COMMAND ${ANT_EXECUTABLE} -q -noinput -k release |
||||
COMMAND ${CMAKE_COMMAND} -E touch "${APK_NAME}" |
||||
WORKING_DIRECTORY "${PACKAGE_DIR}" |
||||
MAIN_DEPENDENCY "${PACKAGE_DIR}/${ANDROID_MANIFEST_FILE}" |
||||
DEPENDS "${OpenCV_BINARY_DIR}/bin/classes.jar.dephelper" "${PACKAGE_DIR}/res/values/strings.xml" "${PACKAGE_DIR}/res/drawable/icon.png" ${camera_wrappers} opencv_java |
||||
) |
||||
|
||||
install(FILES "${APK_NAME}" DESTINATION "apk/" COMPONENT libs) |
||||
add_custom_target(android_package ALL SOURCES "${APK_NAME}" ) |
||||
add_dependencies(android_package opencv_java) |
Before Width: | Height: | Size: 2.0 KiB |
@ -1,6 +0,0 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<resources> |
||||
|
||||
<string name="app_name">OCV @OPENCV_VERSION_MAJOR@.@OPENCV_VERSION_MINOR@ pack @ANDROID_PACKAGE_PLATFORM_NAME@</string> |
||||
|
||||
</resources> |
@ -1,9 +0,0 @@ |
||||
############################ |
||||
OpenCV4Android Reference |
||||
############################ |
||||
|
||||
.. toctree:: |
||||
:maxdepth: 2 |
||||
|
||||
service/doc/index.rst |
||||
java.rst |
@ -1,6 +1,5 @@ |
||||
if(BUILD_ANDROID_SERVICE) |
||||
add_subdirectory(engine) |
||||
#add_subdirectory(engine_test) |
||||
endif() |
||||
|
||||
install(FILES "readme.txt" DESTINATION "apk/" COMPONENT libs) |
||||
|
@ -1,43 +0,0 @@ |
||||
#!/usr/bin/python |
||||
|
||||
import os |
||||
import sys |
||||
import shutil |
||||
|
||||
LOCAL_LOG_PATH = os.path.join(os.getcwd(), "logs") |
||||
|
||||
if (__name__ == "__main__"): |
||||
if (not os.path.exists(LOCAL_LOG_PATH)): |
||||
os.makedirs(LOCAL_LOG_PATH) |
||||
|
||||
print("Building native part of OpenCV Manager...") |
||||
HomeDir = os.getcwd() |
||||
os.chdir(os.path.join(HomeDir, "engine")) |
||||
shutil.rmtree(os.path.join(HomeDir, "engine", "libs"), ignore_errors=True) |
||||
shutil.rmtree(os.path.join(HomeDir, "engine", "obj"), ignore_errors=True) |
||||
BuildCommand = "ndk-build V=1 > \"%s\" 2>&1" % os.path.join(LOCAL_LOG_PATH, "build.log") |
||||
#print(BuildCommand) |
||||
res = os.system(BuildCommand) |
||||
if (0 == res): |
||||
print("Build\t[OK]") |
||||
else: |
||||
print("Build\t[FAILED]") |
||||
sys.exit(-1) |
||||
|
||||
os.chdir(HomeDir) |
||||
ConfFile = open("device.conf", "rt") |
||||
|
||||
for s in ConfFile.readlines(): |
||||
keys = s.split(";") |
||||
if (len(keys) < 2): |
||||
print("Error: invalid config line: \"%s\"" % s) |
||||
continue |
||||
Arch = keys[0] |
||||
Name = keys[1] |
||||
print("testing \"%s\" arch" % Arch) |
||||
print("Pushing to device \"%s\"" % Name) |
||||
PushCommand = "%s \"%s\" \"%s\" 2>&1" % (os.path.join(HomeDir, "push_native.py"), Arch, Name) |
||||
os.system(PushCommand) |
||||
print("Testing on device \"%s\"" % Name) |
||||
TestCommand = "%s \"%s\" \"%s\" 2>&1" % (os.path.join(HomeDir, "test_native.py"), Arch, Name) |
||||
os.system(TestCommand) |
@ -1,3 +0,0 @@ |
||||
armeabi;15c000000581404; |
||||
x86;0123456789ABCDEF; |
||||
mips;Novo7 Basic; |
@ -1,63 +0,0 @@ |
||||
********************************************* |
||||
Base Loader Callback Interface Implementation |
||||
********************************************* |
||||
|
||||
.. highlight:: java |
||||
.. class:: BaseLoaderCallback |
||||
|
||||
Basic implementation of ``LoaderCallbackInterface``. Logic of this implementation is |
||||
well-described by the following scheme: |
||||
|
||||
.. image:: img/AndroidAppUsageModel.png |
||||
|
||||
Using in Java Activity |
||||
---------------------- |
||||
|
||||
There is a very base code snippet implementing the async initialization with ``BaseLoaderCallback``. |
||||
See the "15-puzzle" OpenCV sample for details. |
||||
|
||||
.. code-block:: java |
||||
:linenos: |
||||
|
||||
public class MyActivity extends Activity implements HelperCallbackInterface |
||||
{ |
||||
private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) { |
||||
@Override |
||||
public void onManagerConnected(int status) { |
||||
switch (status) { |
||||
case LoaderCallbackInterface.SUCCESS: |
||||
{ |
||||
Log.i(TAG, "OpenCV loaded successfully"); |
||||
// Create and set View |
||||
mView = new puzzle15View(mAppContext); |
||||
setContentView(mView); |
||||
} break; |
||||
default: |
||||
{ |
||||
super.onManagerConnected(status); |
||||
} break; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
/** Call on every application resume **/ |
||||
@Override |
||||
protected void onResume() |
||||
{ |
||||
Log.i(TAG, "Called onResume"); |
||||
super.onResume(); |
||||
|
||||
Log.i(TAG, "Trying to load OpenCV library"); |
||||
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mOpenCVCallBack)) |
||||
{ |
||||
Log.e(TAG, "Cannot connect to OpenCV Manager"); |
||||
} |
||||
} |
||||
|
||||
Using in Service |
||||
---------------- |
||||
|
||||
Default ``BaseLoaderCallback`` implementation treats application context as ``Activity`` and calls |
||||
``Activity.finish()`` method to exit in case of initialization failure. |
||||
To override this behavior you need to override ``finish()`` method of ``BaseLoaderCallback`` class |
||||
and implement your own finalization method. |
@ -1,38 +0,0 @@ |
||||
************************** |
||||
Install Callback Interface |
||||
************************** |
||||
.. highlight:: java |
||||
.. class:: InstallCallbackInterface |
||||
|
||||
Callback interface for package installation or update. |
||||
|
||||
String getPackageName() |
||||
----------------------- |
||||
|
||||
.. method:: String getPackageName() |
||||
|
||||
Get name of a package to be installed. |
||||
|
||||
:rtype: string; |
||||
:return: returns package name, i.e. "OpenCV Manager Service" or "OpenCV library". |
||||
|
||||
void install() |
||||
-------------- |
||||
|
||||
.. method:: void install() |
||||
|
||||
Installation of package has been approved. |
||||
|
||||
void cancel() |
||||
------------- |
||||
|
||||
.. method:: void cancel() |
||||
|
||||
Installation of package has been cancelled. |
||||
|
||||
void wait_install() |
||||
------------------- |
||||
|
||||
.. method:: void wait_install() |
||||
|
||||
Wait for package installation. |
@ -1,44 +0,0 @@ |
||||
|
||||
.. _Android_OpenCV_Manager_Intro: |
||||
|
||||
************ |
||||
Introduction |
||||
************ |
||||
|
||||
.. highlight:: java |
||||
|
||||
OpenCV Manager is an Android service targeted to manage OpenCV library binaries on end users devices. |
||||
It allows sharing the OpenCV dynamic libraries between applications on the same device. The Manager |
||||
provides the following benefits\: |
||||
|
||||
#. Less memory usage. All apps use the same binaries from service and do not keep native libs inside themselves; |
||||
#. Hardware specific optimizations for all supported platforms; |
||||
#. Trusted OpenCV library source. All packages with OpenCV are published on Google Play market; |
||||
#. Regular updates and bug fixes; |
||||
|
||||
Usage model for end user |
||||
------------------------ |
||||
|
||||
.. image:: img/AndroidAppUsageModel.png |
||||
|
||||
First OpenCV app\: |
||||
|
||||
#. Any OpenCV-dependent app is installed from Google Play marketplace or manually; |
||||
#. At the first launch, it suggests installation of OpenCV Manager; |
||||
#. Then OpenCV Manager is downloaded and installed, using the Google Play application. |
||||
#. When Manager has been started, the application suggests installation of OpenCV library for the |
||||
target device architecture if it is necessary; |
||||
#. After the installation is finished, the app may be launched. |
||||
|
||||
Subsequent launches of OpenCV apps\: |
||||
|
||||
#. Any OpenCV-dependent app is installed from Google Play market or manually; |
||||
#. At the first launch, the app starts as usually; |
||||
#. If the selected OpenCV version is not installed, OpenCV Manager suggests installing OpenCV |
||||
library for the target device through Google Play marketplace; |
||||
#. After the installation is finished, the app may be launched. |
||||
|
||||
Architecture of OpenCV Manager |
||||
------------------------------ |
||||
|
||||
.. image:: img/Structure.png |
@ -1,69 +0,0 @@ |
||||
****************** |
||||
Java OpenCV Loader |
||||
****************** |
||||
|
||||
.. highlight:: java |
||||
.. Class:: OpenCVLoader |
||||
|
||||
Helper class provides common initialization methods for OpenCV library. |
||||
|
||||
boolean initDebug() |
||||
------------------- |
||||
|
||||
.. method:: static boolean initDebug() |
||||
|
||||
Loads and initializes OpenCV library from within current application package. Roughly it is |
||||
analog of ``system.loadLibrary("opencv_java")``. |
||||
|
||||
:rtype: boolean; |
||||
:return: returns true if initialization of OpenCV was successful. |
||||
|
||||
.. note:: This method is deprecated for production code. It is designed for experimental and local |
||||
development purposes only. If you want to publish your app use approach with async |
||||
initialization. |
||||
|
||||
boolean initAsync() |
||||
------------------- |
||||
|
||||
.. method:: static boolean initAsync(String Version, Context AppContext, LoaderCallbackInterface Callback) |
||||
|
||||
Loads and initializes OpenCV library using OpenCV Manager. |
||||
|
||||
:param Version: OpenCV Library version. |
||||
:param AppContext: application context for connecting to the service. |
||||
:param Callback: object, that implements ``LoaderCallbackInterface`` for handling connection |
||||
status (see ``BaseLoaderCallback``). |
||||
|
||||
:rtype: boolean; |
||||
:return: returns true if initialization of OpenCV starts successfully. |
||||
|
||||
OpenCV version constants |
||||
------------------------- |
||||
|
||||
.. data:: OPENCV_VERSION_2_4_2 |
||||
|
||||
OpenCV Library version 2.4.2 |
||||
|
||||
.. data:: OPENCV_VERSION_2_4_3 |
||||
|
||||
OpenCV Library version 2.4.3 |
||||
|
||||
.. data:: OPENCV_VERSION_2_4_4 |
||||
|
||||
OpenCV Library version 2.4.4 |
||||
|
||||
.. data:: OPENCV_VERSION_2_4_5 |
||||
|
||||
OpenCV Library version 2.4.5 |
||||
|
||||
.. data:: OPENCV_VERSION_2_4_6 |
||||
|
||||
OpenCV Library version 2.4.6 |
||||
|
||||
.. data:: OPENCV_VERSION_2_4_7 |
||||
|
||||
OpenCV Library version 2.4.7 |
||||
|
||||
.. data:: OPENCV_VERSION_2_4_8 |
||||
|
||||
OpenCV Library version 2.4.8 |
@ -1,49 +0,0 @@ |
||||
************************* |
||||
Loader Callback Interface |
||||
************************* |
||||
|
||||
.. highlight:: java |
||||
.. class:: LoaderCallbackInterface |
||||
|
||||
Interface for a callback object in case of asynchronous initialization of OpenCV. |
||||
|
||||
void onManagerConnected() |
||||
------------------------- |
||||
|
||||
.. method:: void onManagerConnected(int status) |
||||
|
||||
Callback method that is called after OpenCV library initialization. |
||||
|
||||
:param status: status of initialization (see "Initialization Status Constants" section below). |
||||
|
||||
void onPackageInstall() |
||||
----------------------- |
||||
|
||||
.. method:: void onPackageInstall(InstallCallbackInterface Callback) |
||||
|
||||
Callback method that is called in case when package installation is needed. |
||||
|
||||
:param callback: answer object with ``install`` and ``cancel`` methods and package description. |
||||
|
||||
Initialization status constants |
||||
------------------------------- |
||||
|
||||
.. data:: SUCCESS |
||||
|
||||
OpenCV initialization finished successfully |
||||
|
||||
.. data:: MARKET_ERROR |
||||
|
||||
Google Play (Android Market) application cannot be invoked |
||||
|
||||
.. data:: INSTALL_CANCELED |
||||
|
||||
OpenCV library installation was cancelled by user |
||||
|
||||
.. data:: INCOMPATIBLE_MANAGER_VERSION |
||||
|
||||
Version of OpenCV Manager is incompatible with this app. Manager update is needed. |
||||
|
||||
.. data:: INIT_FAILED |
||||
|
||||
OpenCV library initialization failed |
@ -1,32 +0,0 @@ |
||||
Manager Workflow |
||||
**************** |
||||
|
||||
.. _manager_selection: |
||||
|
||||
.. include:: ../readme.txt |
||||
|
||||
First application start |
||||
----------------------- |
||||
|
||||
There is no OpenCV Manager or OpenCV libraries: |
||||
|
||||
.. image:: img/NoService.png |
||||
|
||||
Additional library package installation |
||||
--------------------------------------- |
||||
|
||||
There is an OpenCV Manager service, but it does not contain appropriate OpenCV library. |
||||
If OpenCV library installation has been approved\: |
||||
|
||||
.. image:: img/LibInstallAproved.png |
||||
|
||||
If OpenCV library installation has been cancelled\: |
||||
|
||||
.. image:: img/LibInstallCanceled.png |
||||
|
||||
Regular application start |
||||
------------------------- |
||||
|
||||
OpenCV Manager and OpenCV library has been already installed. |
||||
|
||||
.. image:: img/LibInstalled.png |
@ -1,23 +0,0 @@ |
||||
#!/usr/bin/python |
||||
|
||||
import os |
||||
|
||||
TARGET_PATH = "img" |
||||
|
||||
pipe = os.popen("which dia") |
||||
DiaPath = pipe.readline() |
||||
DiaPath = DiaPath.strip("\n"); |
||||
pipe.close() |
||||
|
||||
if ("" == DiaPath): |
||||
print("Error: Dia tool was not found") |
||||
exit(-1) |
||||
|
||||
print("Dia tool: \"%s\"" % DiaPath) |
||||
|
||||
if (not os.path.exists(TARGET_PATH)): |
||||
os.mkdir("img") |
||||
|
||||
for filename in os.listdir("."): |
||||
if ("dia" == filename[-3:]): |
||||
os.system("%s --export %s %s" % (DiaPath, os.path.join(TARGET_PATH, filename[0:len(filename)-4] + ".png"), filename)) |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 35 KiB |
@ -1,18 +0,0 @@ |
||||
|
||||
.. _Android_OpenCV_Manager: |
||||
|
||||
*********************** |
||||
Android OpenCV Manager |
||||
*********************** |
||||
|
||||
Contents: |
||||
|
||||
.. toctree:: |
||||
:maxdepth: 2 |
||||
|
||||
Intro |
||||
UseCases |
||||
JavaHelper |
||||
BaseLoaderCallback |
||||
LoaderCallbackInterface |
||||
InstallCallbackInterface |
@ -1,99 +1,3 @@ |
||||
set(engine OpenCVEngine) |
||||
set(JNI_LIB_NAME ${engine} ${engine}_jni) |
||||
|
||||
unset(__android_project_chain CACHE) |
||||
add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 9 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON IGNORE_MANIFEST ON ) |
||||
|
||||
set(ANDROID_PLATFORM_VERSION_CODE "0") |
||||
|
||||
if(ARMEABI_V7A) |
||||
if (ANDROID_NATIVE_API_LEVEL LESS 9) |
||||
set(ANDROID_PLATFORM_VERSION_CODE "2") |
||||
else() |
||||
set(ANDROID_PLATFORM_VERSION_CODE "3") |
||||
endif() |
||||
elseif(ARM64_V8A) |
||||
set(ANDROID_PLATFORM_VERSION_CODE "4") |
||||
elseif(ARMEABI_V6) |
||||
set(ANDROID_PLATFORM_VERSION_CODE "1") |
||||
elseif(ARMEABI) |
||||
set(ANDROID_PLATFORM_VERSION_CODE "1") |
||||
elseif(X86) |
||||
set(ANDROID_PLATFORM_VERSION_CODE "5") |
||||
elseif(MIPS) |
||||
set(ANDROID_PLATFORM_VERSION_CODE "6") |
||||
else() |
||||
message(WARNING "Can not automatically determine the value for ANDROID_PLATFORM_VERSION_CODE") |
||||
endif() |
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${ANDROID_MANIFEST_FILE}" "${OpenCV_BINARY_DIR}/platforms/android/service/engine/.build/${ANDROID_MANIFEST_FILE}" @ONLY) |
||||
|
||||
link_directories( |
||||
"${ANDROID_SOURCE_TREE}/out/target/product/generic/system/lib" |
||||
"${ANDROID_SOURCE_TREE}/out/target/product/${ANDROID_PRODUCT}/system/lib" |
||||
"${ANDROID_SOURCE_TREE}/bin/${ANDROID_ARCH_NAME}") |
||||
|
||||
file(GLOB engine_files "jni/BinderComponent/*.cpp" "jni/BinderComponent/*.h" "jni/include/*.h") |
||||
set(engine_libs "z" "binder" "log" "utils") |
||||
|
||||
if (TEGRA_DETECTOR) |
||||
if (ANDROID_NATIVE_API_LEVEL GREATER 8) |
||||
add_definitions(-DUSE_TEGRA_HW_DETECTOR) |
||||
list(APPEND engine_libs ${TEGRA_DETECTOR} GLESv2 EGL) |
||||
else() |
||||
message(FATAL_ERROR "Tegra detector required native api level 9 or above") |
||||
endif() |
||||
endif() |
||||
|
||||
# -D__SUPPORT_ARMEABI_FEATURES key is also available |
||||
add_definitions(-DPLATFORM_ANDROID -D__SUPPORT_ARMEABI_V7A_FEATURES -D__SUPPORT_TEGRA3 -D__SUPPORT_MIPS) |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions") |
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-allow-shlib-undefined") |
||||
string(REPLACE "-fvisibility=hidden" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") |
||||
string(REPLACE "-fvisibility-inlines-hidden" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") |
||||
|
||||
include_directories("jni/BinderComponent" "jni/include") |
||||
include_directories(SYSTEM "${ANDROID_SOURCE_TREE}/frameworks/base/include" "${ANDROID_SOURCE_TREE}/system/core/include") |
||||
add_library(${engine} SHARED ${engine_files}) |
||||
target_link_libraries(${engine} ${engine_libs}) |
||||
|
||||
set_target_properties(${engine} PROPERTIES |
||||
OUTPUT_NAME ${engine} |
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.build/libs/${ANDROID_NDK_ABI_NAME}" |
||||
) |
||||
|
||||
get_target_property(engine_lib_location ${engine} LOCATION) |
||||
add_custom_command(TARGET ${engine} POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${engine_lib_location}") |
||||
|
||||
file(GLOB engine_jni_files "jni/JNIWrapper/*.cpp" "jni/JNIWrapper/*.h" "jni/include/*.h") |
||||
list(APPEND engine_jni_files jni/NativeService/CommonPackageManager.cpp jni/NativeService/PackageInfo.cpp) |
||||
|
||||
include_directories( |
||||
jni/include jni/JNIWrapper |
||||
jni/NativeService |
||||
jni/BinderComponent |
||||
"${ANDROID_SOURCE_TREE}/frameworks/base/include" |
||||
"${ANDROID_SOURCE_TREE}/system/core/include" |
||||
"${ANDROID_SOURCE_TREE}/frameworks/base/core/jni" |
||||
) |
||||
|
||||
add_library(${engine}_jni SHARED ${engine_jni_files}) |
||||
target_link_libraries(${engine}_jni z binder log utils android_runtime ${engine}) |
||||
|
||||
set_target_properties(${engine}_jni PROPERTIES |
||||
OUTPUT_NAME ${engine}_jni |
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.build/libs/${ANDROID_NDK_ABI_NAME}" |
||||
) |
||||
|
||||
get_target_property(engine_lib_location ${engine}_jni LOCATION) |
||||
add_custom_command(TARGET ${engine}_jni POST_BUILD COMMAND ${CMAKE_STRIP} --strip-unneeded "${engine_lib_location}") |
||||
|
||||
# native tests |
||||
add_definitions(-DGTEST_HAS_CLONE=0 -DANDROID -DGTEST_HAS_TR1_TUPLE=0) |
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-allow-shlib-undefined") |
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/jni/Tests) |
||||
file(GLOB engine_test_files "jni/Tests/*.cpp") |
||||
|
||||
add_executable(opencv_test_engine ${engine_test_files} jni/Tests/gtest/gtest-all.cpp) |
||||
target_link_libraries(opencv_test_engine z binder log utils android_runtime ${engine} ${engine}_jni) |
||||
unset(__android_project_chain CACHE) |
||||
add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 9 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON IGNORE_MANIFEST ON COPY_LIBS ON) |
||||
|
@ -1,86 +0,0 @@ |
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Binder component library
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
include $(CLEAR_VARS) |
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
BinderComponent/OpenCVEngine.cpp \
|
||||
BinderComponent/BnOpenCVEngine.cpp \
|
||||
BinderComponent/BpOpenCVEngine.cpp \
|
||||
BinderComponent/ProcReader.cpp \
|
||||
BinderComponent/TegraDetector.cpp \
|
||||
BinderComponent/StringUtils.cpp \
|
||||
BinderComponent/HardwareDetector.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/BinderComponent \
|
||||
$(TOP)/frameworks/base/include \
|
||||
$(TOP)/system/core/include
|
||||
|
||||
LOCAL_CFLAGS += -DPLATFORM_ANDROID
|
||||
LOCAL_CFLAGS += -D__SUPPORT_ARMEABI_V7A_FEATURES
|
||||
LOCAL_CFLAGS += -D__SUPPORT_TEGRA3
|
||||
LOCAL_CFLAGS += -D__SUPPORT_MIPS
|
||||
#LOCAL_CFLAGS += -D__SUPPORT_ARMEABI_FEATURES
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
|
||||
LOCAL_MODULE := libOpenCVEngine
|
||||
|
||||
LOCAL_LDLIBS += -lz -lbinder -llog -lutils
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-allow-shlib-undefined
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY) |
||||
|
||||
#---------------------------------------------------------------------
|
||||
# JNI library for Java service
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
include $(CLEAR_VARS) |
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
JNIWrapper/OpenCVEngine_jni.cpp \
|
||||
NativeService/CommonPackageManager.cpp \
|
||||
JNIWrapper/JavaBasedPackageManager.cpp \
|
||||
NativeService/PackageInfo.cpp \
|
||||
JNIWrapper/HardwareDetector_jni.cpp \
|
||||
JNIWrapper/OpenCVLibraryInfo.cpp
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH)/include \
|
||||
$(LOCAL_PATH)/JNIWrapper \
|
||||
$(LOCAL_PATH)/NativeService \
|
||||
$(LOCAL_PATH)/BinderComponent \
|
||||
$(TOP)/frameworks/base/include \
|
||||
$(TOP)/system/core/include \
|
||||
$(TOP)/frameworks/base/core/jni
|
||||
|
||||
LOCAL_PRELINK_MODULE := false
|
||||
|
||||
LOCAL_CFLAGS += -DPLATFORM_ANDROID
|
||||
LOCAL_CFLAGS += -D__SUPPORT_ARMEABI_V7A_FEATURES
|
||||
LOCAL_CFLAGS += -D__SUPPORT_TEGRA3
|
||||
LOCAL_CFLAGS += -D__SUPPORT_MIPS
|
||||
#LOCAL_CFLAGS += -D__SUPPORT_ARMEABI_FEATURES
|
||||
|
||||
LOCAL_MODULE := libOpenCVEngine_jni
|
||||
|
||||
LOCAL_LDLIBS += -lz -lbinder -llog -lutils -landroid_runtime
|
||||
LOCAL_SHARED_LIBRARIES = libOpenCVEngine
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY) |
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Native test application
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
#include $(LOCAL_PATH)/Tests/Tests.mk
|
@ -1,6 +0,0 @@ |
||||
APP_ABI := armeabi x86 mips
|
||||
APP_PLATFORM := android-8
|
||||
APP_STL := stlport_static
|
||||
APP_CPPFLAGS := -fno-rtti -fno-exceptions
|
||||
NDK_TOOLCHAIN_VERSION=4.4.3
|
||||
#APP_OPTIM := debug
|
@ -1,72 +0,0 @@ |
||||
#include "EngineCommon.h" |
||||
#include "IOpenCVEngine.h" |
||||
#include "BnOpenCVEngine.h" |
||||
#include <utils/Log.h> |
||||
#include <utils/String8.h> |
||||
#include <utils/String16.h> |
||||
|
||||
using namespace android; |
||||
|
||||
BnOpenCVEngine::~BnOpenCVEngine() |
||||
{ |
||||
} |
||||
|
||||
// Notes about data transaction:
|
||||
// Java Binder Wrapper call readInt32 before reading return data
|
||||
// It treet this in value as exception code
|
||||
// OnTransact method support this feature
|
||||
status_t BnOpenCVEngine::onTransact(uint32_t code, const Parcel& data, android::Parcel* reply, uint32_t flags) |
||||
{ |
||||
LOGD("OpenCVEngine::OnTransact(%u,%u)", code, flags); |
||||
|
||||
switch(code) |
||||
{ |
||||
case OCVE_GET_ENGINE_VERSION: |
||||
{ |
||||
LOGD("OpenCVEngine OCVE_GET_ENGINE_VERSION request"); |
||||
CHECK_INTERFACE(IOpenCVEngine, data, reply); |
||||
LOGD("OpenCVEngine::GetVersion()"); |
||||
reply->writeInt32(0); |
||||
return reply->writeInt32(GetVersion()); |
||||
} break; |
||||
case OCVE_GET_LIB_PATH_BY_VERSION: |
||||
{ |
||||
LOGD("OpenCVEngine OCVE_GET_LIB_PATH_BY_VERSION request"); |
||||
CHECK_INTERFACE(IOpenCVEngine, data, reply); |
||||
const String16 version = data.readString16(); |
||||
LOGD("OpenCVEngine::GetLibPathByVersion(%s)", String8(version).string()); |
||||
String16 path = GetLibPathByVersion(version); |
||||
reply->writeInt32(0); |
||||
return reply->writeString16(path); |
||||
} break; |
||||
case OCVE_GET_LIB_LIST: |
||||
{ |
||||
LOGD("OpenCVEngine OCVE_GET_LIB_LIST request"); |
||||
CHECK_INTERFACE(IOpenCVEngine, data, reply); |
||||
const String16 version = data.readString16(); |
||||
LOGD("OpenCVEngine::GetLibraryList(%s)", String8(version).string()); |
||||
String16 path = GetLibraryList(version); |
||||
reply->writeInt32(0); |
||||
return reply->writeString16(path); |
||||
} break; |
||||
case OCVE_INSTALL_VERSION: |
||||
{ |
||||
LOGD("OpenCVEngine OCVE_INSTALL_VERSION request"); |
||||
CHECK_INTERFACE(IOpenCVEngine, data, reply); |
||||
const String16 version = data.readString16(); |
||||
LOGD("OpenCVEngine::InstallVersion(%s)", String8(version).string()); |
||||
bool result = InstallVersion(version); |
||||
reply->writeInt32(0); |
||||
int res = reply->writeInt32(static_cast<int32_t>(result)); |
||||
LOGD("InstallVersion call to Binder finished with res %d", res); |
||||
return res; |
||||
} break; |
||||
default: |
||||
{ |
||||
LOGD("OpenCVEngine unknown request"); |
||||
return BBinder::onTransact(code, data, reply, flags); |
||||
} |
||||
} |
||||
|
||||
return android::NO_ERROR; |
||||
} |
@ -1,21 +0,0 @@ |
||||
#ifndef __BP_OPENCV_ENGINE_H__ |
||||
#define __BP_OPENCV_ENGINE_H__ |
||||
|
||||
#include "EngineCommon.h" |
||||
#include "IOpenCVEngine.h" |
||||
#include <binder/IInterface.h> |
||||
#include <binder/Parcel.h> |
||||
#include <utils/String16.h> |
||||
|
||||
class BnOpenCVEngine: public android::BnInterface<IOpenCVEngine> |
||||
{ |
||||
public: |
||||
android::status_t onTransact(uint32_t code, |
||||
const android::Parcel &data, |
||||
android::Parcel *reply, |
||||
uint32_t flags); |
||||
virtual ~BnOpenCVEngine(); |
||||
|
||||
}; |
||||
|
||||
#endif |
@ -1,71 +0,0 @@ |
||||
#include "IOpenCVEngine.h" |
||||
#include "BpOpenCVEngine.h" |
||||
|
||||
using namespace android; |
||||
|
||||
BpOpenCVEngine::BpOpenCVEngine(const sp<IBinder>& impl): |
||||
BpInterface<IOpenCVEngine>(impl) |
||||
{ |
||||
} |
||||
|
||||
BpOpenCVEngine::~BpOpenCVEngine() |
||||
{ |
||||
} |
||||
|
||||
// Notes about data transaction:
|
||||
// Java Binder Wrapper call readInt32 before reading return data
|
||||
// It treet this in value as exception code
|
||||
// This implementation support this feature
|
||||
|
||||
int BpOpenCVEngine::GetVersion() |
||||
{ |
||||
Parcel data, reply; |
||||
|
||||
data.writeInterfaceToken(IOpenCVEngine::descriptor); |
||||
remote()->transact(OCVE_GET_ENGINE_VERSION, data, &reply, 0); |
||||
// read exception code
|
||||
reply.readInt32(); |
||||
|
||||
return reply.readInt32(); |
||||
} |
||||
|
||||
String16 BpOpenCVEngine::GetLibPathByVersion(String16 version) |
||||
{ |
||||
Parcel data, reply; |
||||
|
||||
data.writeInterfaceToken(IOpenCVEngine::descriptor); |
||||
data.writeString16(version); |
||||
remote()->transact(OCVE_GET_LIB_PATH_BY_VERSION, data, &reply, 0); |
||||
// read exception code
|
||||
reply.readInt32(); |
||||
|
||||
return reply.readString16(); |
||||
} |
||||
|
||||
android::String16 BpOpenCVEngine::GetLibraryList(String16 version) |
||||
{ |
||||
Parcel data, reply; |
||||
|
||||
data.writeInterfaceToken(IOpenCVEngine::descriptor); |
||||
data.writeString16(version); |
||||
remote()->transact(OCVE_GET_LIB_LIST, data, &reply, 0); |
||||
// read exception code
|
||||
reply.readInt32(); |
||||
|
||||
return reply.readString16(); |
||||
} |
||||
|
||||
bool BpOpenCVEngine::InstallVersion(String16 version) |
||||
{ |
||||
Parcel data, reply; |
||||
|
||||
data.writeInterfaceToken(IOpenCVEngine::descriptor); |
||||
data.writeString16(version); |
||||
remote()->transact(OCVE_INSTALL_VERSION, data, &reply, 0); |
||||
// read exception code
|
||||
reply.readInt32(); |
||||
|
||||
return static_cast<bool>(reply.readInt32()); |
||||
} |
||||
|
||||
IMPLEMENT_META_INTERFACE(OpenCVEngine, OPECV_ENGINE_CLASSNAME) |
@ -1,20 +0,0 @@ |
||||
#ifndef __BP_OPENCV_ENGINE_H__ |
||||
#define __BP_OPENCV_ENGINE_H__ |
||||
|
||||
#include "IOpenCVEngine.h" |
||||
#include <binder/IInterface.h> |
||||
#include <binder/Parcel.h> |
||||
#include <utils/String16.h> |
||||
|
||||
class BpOpenCVEngine: public android::BpInterface<IOpenCVEngine> |
||||
{ |
||||
public: |
||||
BpOpenCVEngine(const android::sp<android::IBinder>& impl); |
||||
virtual ~BpOpenCVEngine(); |
||||
virtual int GetVersion(); |
||||
virtual android::String16 GetLibPathByVersion(android::String16 version); |
||||
virtual android::String16 GetLibraryList(android::String16 version); |
||||
virtual bool InstallVersion(android::String16 version); |
||||
}; |
||||
|
||||
#endif |
@ -1,203 +0,0 @@ |
||||
#include "HardwareDetector.h" |
||||
#include "TegraDetector.h" |
||||
#include "ProcReader.h" |
||||
#include "EngineCommon.h" |
||||
#include "StringUtils.h" |
||||
#include <utils/Log.h> |
||||
|
||||
using namespace std; |
||||
|
||||
int GetCpuID() |
||||
{ |
||||
int result = 0; |
||||
map<string, string> cpu_info = GetCpuInfo(); |
||||
map<string, string>::const_iterator it; |
||||
|
||||
#if defined(__i386__) |
||||
LOGD("Using X86 HW detector"); |
||||
result |= ARCH_X86; |
||||
it = cpu_info.find("flags"); |
||||
if (cpu_info.end() != it) |
||||
{ |
||||
set<string> features = SplitString(it->second, ' '); |
||||
if (features.end() != features.find(CPU_INFO_SSE_STR)) |
||||
{ |
||||
result |= FEATURES_HAS_SSE; |
||||
} |
||||
if (features.end() != features.find(CPU_INFO_SSE2_STR)) |
||||
{ |
||||
result |= FEATURES_HAS_SSE2; |
||||
} |
||||
if (features.end() != features.find(CPU_INFO_SSSE3_STR)) |
||||
{ |
||||
result |= FEATURES_HAS_SSSE3; |
||||
} |
||||
} |
||||
#elif defined(__mips) |
||||
#ifdef __SUPPORT_MIPS |
||||
result |= ARCH_MIPS; |
||||
#else |
||||
result = ARCH_UNKNOWN; |
||||
#endif |
||||
#elif defined(__aarch64__) |
||||
#ifdef __SUPPORT_AARCH64 |
||||
result |= ARCH_AARCH64; |
||||
#else |
||||
result = ARCH_UNKNOWN; |
||||
#endif |
||||
#elif defined(__arm__) |
||||
LOGD("Using ARM HW detector"); |
||||
it = cpu_info.find("Processor"); |
||||
|
||||
if (cpu_info.end() != it) |
||||
{ |
||||
size_t proc_name_pos = it->second.find(CPU_INFO_ARCH_ARMV7_STR); |
||||
if (string::npos != proc_name_pos) |
||||
{ |
||||
result |= ARCH_ARMv7; |
||||
} |
||||
else |
||||
{ |
||||
proc_name_pos = it->second.find(CPU_INFO_ARCH_ARMV6_STR); |
||||
if (string::npos != proc_name_pos) |
||||
{ |
||||
result |= ARCH_ARMv6; |
||||
} |
||||
else |
||||
{ |
||||
proc_name_pos = it->second.find(CPU_INFO_ARCH_ARMV5_STR); |
||||
if (string::npos != proc_name_pos) |
||||
{ |
||||
result |= ARCH_ARMv5; |
||||
} |
||||
else |
||||
{ |
||||
// Treat the arch of current binary. Google Play checks
|
||||
// device hardware before installation. Let's assume that
|
||||
// if the binary works, it's compatible with current hardware
|
||||
#if defined __ARM_ARCH_7A__ |
||||
result |= ARCH_ARMv7; |
||||
result |= FEATURES_HAS_VFPv3d16; |
||||
#else |
||||
result |= ARCH_ARMv5; |
||||
#endif |
||||
} |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// Treat the arch of current binary. Google Play checks
|
||||
// device hardware before installation. Let's assume that
|
||||
// if the binary works, it's compatible with current hardware
|
||||
#if defined __ARM_ARCH_7A__ |
||||
result |= ARCH_ARMv7; |
||||
result |= FEATURES_HAS_VFPv3; |
||||
#else |
||||
result |= ARCH_ARMv5; |
||||
#endif |
||||
} |
||||
|
||||
it = cpu_info.find("Features"); |
||||
if (cpu_info.end() != it) |
||||
{ |
||||
set<string> features = SplitString(it->second, ' '); |
||||
if (features.end() != features.find(CPU_INFO_NEON_STR)) |
||||
{ |
||||
result |= FEATURES_HAS_NEON; |
||||
} |
||||
if (features.end() != features.find(CPU_INFO_NEON2_STR)) |
||||
{ |
||||
result |= FEATURES_HAS_NEON2; |
||||
} |
||||
if (features.end() != features.find(CPU_INFO_VFPV4_STR)) |
||||
{ |
||||
result |= FEATURES_HAS_VFPv4; |
||||
} |
||||
if (features.end() != features.find(CPU_INFO_VFPV3_STR)) |
||||
{ |
||||
if (features.end () != features.find(CPU_INFO_VFPV3D16_STR)) |
||||
{ |
||||
result |= FEATURES_HAS_VFPv3d16; |
||||
} |
||||
else |
||||
{ |
||||
result |= FEATURES_HAS_VFPv3; |
||||
} |
||||
} |
||||
} |
||||
#else |
||||
result = ARCH_UNKNOWN; |
||||
#endif |
||||
|
||||
return result; |
||||
} |
||||
|
||||
string GetPlatformName() |
||||
{ |
||||
map<string, string> cpu_info = GetCpuInfo(); |
||||
string hardware_name = ""; |
||||
map<string, string>::const_iterator hw_iterator = cpu_info.find("Hardware"); |
||||
|
||||
if (cpu_info.end() != hw_iterator) |
||||
{ |
||||
hardware_name = hw_iterator->second; |
||||
} |
||||
|
||||
return hardware_name; |
||||
} |
||||
|
||||
int GetProcessorCount() |
||||
{ |
||||
FILE* cpuPossible = fopen("/sys/devices/system/cpu/possible", "r"); |
||||
if(!cpuPossible) |
||||
return 1; |
||||
|
||||
char buf[2000]; //big enough for 1000 CPUs in worst possible configuration
|
||||
char* pbuf = fgets(buf, sizeof(buf), cpuPossible); |
||||
fclose(cpuPossible); |
||||
if(!pbuf) |
||||
return 1; |
||||
|
||||
//parse string of form "0-1,3,5-7,10,13-15"
|
||||
int cpusAvailable = 0; |
||||
|
||||
while(*pbuf) |
||||
{ |
||||
const char* pos = pbuf; |
||||
bool range = false; |
||||
while(*pbuf && *pbuf != ',') |
||||
{ |
||||
if(*pbuf == '-') range = true; |
||||
++pbuf; |
||||
} |
||||
if(*pbuf) *pbuf++ = 0; |
||||
if(!range) |
||||
++cpusAvailable; |
||||
else |
||||
{ |
||||
int rstart = 0, rend = 0; |
||||
sscanf(pos, "%d-%d", &rstart, &rend); |
||||
cpusAvailable += rend - rstart + 1; |
||||
} |
||||
} |
||||
return cpusAvailable ? cpusAvailable : 1; |
||||
} |
||||
|
||||
int DetectKnownPlatforms() |
||||
{ |
||||
#if defined(__arm__) && defined(USE_TEGRA_HW_DETECTOR) |
||||
int tegra_status = DetectTegra(); |
||||
#else |
||||
int tegra_status = NOT_TEGRA; |
||||
#endif |
||||
// All Tegra platforms since Tegra3
|
||||
if (2 < tegra_status) |
||||
{ |
||||
return PLATFORM_TEGRA + tegra_status - 1; |
||||
} |
||||
else |
||||
{ |
||||
return PLATFORM_UNKNOWN; |
||||
} |
||||
} |
@ -1,41 +0,0 @@ |
||||
#ifndef __HARDWARE_DETECTOR_H__ |
||||
#define __HARDWARE_DETECTOR_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#define ARCH_UNKNOWN 0L |
||||
#define ARCH_X86 16777216L |
||||
#define ARCH_X64 33554432L |
||||
#define ARCH_ARMv5 67108864L |
||||
#define ARCH_ARMv6 134217728L |
||||
#define ARCH_ARMv7 268435456L |
||||
#define ARCH_AARCH64 536870912L |
||||
#define ARCH_MIPS 1073741824L |
||||
|
||||
#define FEATURES_HAS_VFPv3d16 1L |
||||
#define FEATURES_HAS_VFPv3 2L |
||||
#define FEATURES_HAS_VFPv4 4L |
||||
#define FEATURES_HAS_NEON 8L |
||||
#define FEATURES_HAS_NEON2 16L |
||||
|
||||
#define FEATURES_HAS_SSE 1L |
||||
#define FEATURES_HAS_SSE2 2L |
||||
#define FEATURES_HAS_SSSE3 4L |
||||
#define FEATURES_HAS_GPU 65536L |
||||
|
||||
// TODO: Do not forget to add Platrfom name to PackageInfo::PlatformNameMap
|
||||
// in method PackageInfo::InitPlatformNameMap()
|
||||
#define PLATFORM_UNKNOWN 0L |
||||
#define PLATFORM_TEGRA 1L |
||||
#define PLATFORM_TEGRA2 2L |
||||
#define PLATFORM_TEGRA3 3L |
||||
#define PLATFORM_TEGRA4i 4L |
||||
#define PLATFORM_TEGRA4 5L |
||||
#define PLATFORM_TEGRA5 6L |
||||
|
||||
int DetectKnownPlatforms(); |
||||
int GetProcessorCount(); |
||||
std::string GetPlatformName(); |
||||
int GetCpuID(); |
||||
|
||||
#endif |
@ -1,202 +0,0 @@ |
||||
#include "EngineCommon.h" |
||||
#include "OpenCVEngine.h" |
||||
#include "HardwareDetector.h" |
||||
#include "StringUtils.h" |
||||
#include <utils/Log.h> |
||||
#include <assert.h> |
||||
#include <string> |
||||
|
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#include <dirent.h> |
||||
#include <dlfcn.h> |
||||
|
||||
using namespace android; |
||||
|
||||
const int OpenCVEngine::Platform = DetectKnownPlatforms(); |
||||
const int OpenCVEngine::CpuID = GetCpuID(); |
||||
const int OpenCVEngine::KnownVersions[] = {2040000, 2040100, 2040200, 2040300, 2040301, 2040302, 2040400, 2040500, 2040600, 2040700, 2040701, 2040800, 2040900, 2041000, 2041100, 3000000}; |
||||
|
||||
bool OpenCVEngine::ValidateVersion(int version) |
||||
{ |
||||
for (size_t i = 0; i < sizeof(KnownVersions)/sizeof(int); i++) |
||||
if (KnownVersions[i] == version) |
||||
return true; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
int OpenCVEngine::NormalizeVersionString(std::string version) |
||||
{ |
||||
int result = 0; |
||||
|
||||
if (version.empty()) |
||||
{ |
||||
return result; |
||||
} |
||||
|
||||
std::vector<std::string> parts = SplitStringVector(version, '.'); |
||||
|
||||
// Use only 4 digits of the version, i.e. 1.2.3.4.
|
||||
// Other digits will be ignored.
|
||||
if (parts.size() > 4) |
||||
parts.erase(parts.begin()+4, parts.end()); |
||||
|
||||
int multiplyer = 1000000; |
||||
for (std::vector<std::string>::const_iterator it = parts.begin(); it != parts.end(); ++it) |
||||
{ |
||||
int digit = atoi(it->c_str()); |
||||
result += multiplyer*digit; |
||||
multiplyer /= 100; |
||||
} |
||||
|
||||
if (!ValidateVersion(result)) |
||||
result = 0; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
OpenCVEngine::OpenCVEngine(IPackageManager* PkgManager): |
||||
PackageManager(PkgManager) |
||||
{ |
||||
assert(PkgManager); |
||||
} |
||||
|
||||
int32_t OpenCVEngine::GetVersion() |
||||
{ |
||||
return OPEN_CV_ENGINE_VERSION; |
||||
} |
||||
|
||||
String16 OpenCVEngine::GetLibPathByVersion(android::String16 version) |
||||
{ |
||||
std::string std_version(String8(version).string()); |
||||
int norm_version; |
||||
std::string path; |
||||
|
||||
LOGD("OpenCVEngine::GetLibPathByVersion(%s) impl", String8(version).string()); |
||||
|
||||
norm_version = NormalizeVersionString(std_version); |
||||
|
||||
if (0 != norm_version) |
||||
{ |
||||
path = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID); |
||||
if (path.empty()) |
||||
{ |
||||
LOGI("Package OpenCV of version \"%s\" (%d) is not installed. Try to install it :)", String8(version).string(), norm_version); |
||||
} |
||||
else |
||||
{ |
||||
FixPermissions(path); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LOGE("OpenCV version \"%s\" (%d) is not supported", String8(version).string(), norm_version); |
||||
} |
||||
|
||||
return String16(path.c_str()); |
||||
} |
||||
|
||||
android::String16 OpenCVEngine::GetLibraryList(android::String16 version) |
||||
{ |
||||
std::string std_version = String8(version).string(); |
||||
int norm_version; |
||||
String16 result; |
||||
norm_version = NormalizeVersionString(std_version); |
||||
|
||||
if (0 != norm_version) |
||||
{ |
||||
std::string tmp = PackageManager->GetPackagePathByVersion(norm_version, Platform, CpuID); |
||||
if (!tmp.empty()) |
||||
{ |
||||
tmp += (std::string("/") + LIB_OPENCV_INFO_NAME); |
||||
|
||||
LOGD("Trying to load info library \"%s\"", tmp.c_str()); |
||||
|
||||
void* handle; |
||||
InfoFunctionType info_func; |
||||
|
||||
handle = dlopen(tmp.c_str(), RTLD_LAZY); |
||||
if (handle) |
||||
{ |
||||
const char* error; |
||||
|
||||
dlerror(); |
||||
info_func = (InfoFunctionType)dlsym(handle, "GetLibraryList"); |
||||
if ((error = dlerror()) == NULL) |
||||
{ |
||||
result = String16((*info_func)()); |
||||
dlclose(handle); |
||||
} |
||||
else |
||||
{ |
||||
LOGE("Library loading error: \"%s\"", error); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LOGI("Info library not found in package"); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LOGI("Package OpenCV of version \"%s\" (%d) is not installed. Try to install it :)", std_version.c_str(), norm_version); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LOGE("OpenCV version \"%s\" is not supported", std_version.c_str()); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
bool OpenCVEngine::InstallVersion(android::String16 version) |
||||
{ |
||||
std::string std_version = String8(version).string(); |
||||
int norm_version; |
||||
bool result = false; |
||||
|
||||
LOGD("OpenCVEngine::InstallVersion() begin"); |
||||
|
||||
norm_version = NormalizeVersionString(std_version); |
||||
|
||||
if (0 != norm_version) |
||||
{ |
||||
LOGD("PackageManager->InstallVersion call"); |
||||
result = PackageManager->InstallVersion(norm_version, Platform, CpuID); |
||||
} |
||||
else |
||||
{ |
||||
LOGE("OpenCV version \"%s\" (%d) is not supported", std_version.c_str(), norm_version); |
||||
} |
||||
|
||||
LOGD("OpenCVEngine::InstallVersion() end"); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
bool OpenCVEngine::FixPermissions(const std::string& path) |
||||
{ |
||||
LOGD("Fixing permissions for folder: \"%s\"", path.c_str()); |
||||
chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); |
||||
|
||||
DIR* dir = opendir(path.c_str()); |
||||
if (!dir) |
||||
{ |
||||
LOGD("Fixing permissions error"); |
||||
return false; |
||||
} |
||||
|
||||
dirent* files = readdir(dir); |
||||
while (files) |
||||
{ |
||||
LOGD("Fix permissions for \"%s\"", files->d_name); |
||||
chmod((path + std::string("/") + std::string(files->d_name)).c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); |
||||
files = readdir(dir); |
||||
} |
||||
|
||||
closedir(dir); |
||||
|
||||
return true; |
||||
} |
@ -1,37 +0,0 @@ |
||||
#ifndef __OPEN_CV_ENGINE_H__ |
||||
#define __OPEN_CV_ENGINE_H__ |
||||
|
||||
#include "EngineCommon.h" |
||||
#include "IOpenCVEngine.h" |
||||
#include "BnOpenCVEngine.h" |
||||
#include "IPackageManager.h" |
||||
#include <binder/IInterface.h> |
||||
#include <binder/Parcel.h> |
||||
#include <utils/String8.h> |
||||
#include <utils/String16.h> |
||||
#include <string> |
||||
#include <set> |
||||
|
||||
class OpenCVEngine: public BnOpenCVEngine |
||||
{ |
||||
public: |
||||
OpenCVEngine(IPackageManager* PkgManager); |
||||
int32_t GetVersion(); |
||||
android::String16 GetLibPathByVersion(android::String16 version); |
||||
virtual android::String16 GetLibraryList(android::String16 version); |
||||
bool InstallVersion(android::String16 version); |
||||
|
||||
protected: |
||||
IPackageManager* PackageManager; |
||||
static const int KnownVersions[]; |
||||
|
||||
OpenCVEngine(); |
||||
bool ValidateVersion(int version); |
||||
int NormalizeVersionString(std::string version); |
||||
bool FixPermissions(const std::string& path); |
||||
|
||||
static const int Platform; |
||||
static const int CpuID; |
||||
}; |
||||
|
||||
#endif |
@ -1,31 +0,0 @@ |
||||
#include "ProcReader.h" |
||||
#include "StringUtils.h" |
||||
#include <fstream> |
||||
|
||||
using namespace std; |
||||
|
||||
map<string, string> GetCpuInfo() |
||||
{ |
||||
map<string, string> result; |
||||
ifstream f; |
||||
|
||||
f.open("/proc/cpuinfo"); |
||||
if (f.is_open()) |
||||
{ |
||||
while (!f.eof()) |
||||
{ |
||||
string tmp; |
||||
string key; |
||||
string value; |
||||
getline(f, tmp); |
||||
if (ParseString(tmp, key, value)) |
||||
{ |
||||
result[key] = value; |
||||
} |
||||
} |
||||
} |
||||
|
||||
f.close(); |
||||
|
||||
return result; |
||||
} |
@ -1,30 +0,0 @@ |
||||
#ifndef __PROC_READER_H__ |
||||
#define __PROC_READER_H__ |
||||
|
||||
#include <map> |
||||
#include <set> |
||||
#include <string> |
||||
|
||||
#define CPU_INFO_NEON_STR "neon" |
||||
#define CPU_INFO_NEON2_STR "neon2" |
||||
#define CPU_INFO_VFPV3D16_STR "vfpv3d16" |
||||
#define CPU_INFO_VFPV3_STR "vfpv3" |
||||
#define CPU_INFO_VFPV4_STR "vfpv4" |
||||
|
||||
#define CPU_INFO_SSE_STR "sse" |
||||
#define CPU_INFO_SSE2_STR "sse2" |
||||
#define CPU_INFO_SSSE3_STR "ssse3" |
||||
|
||||
#define CPU_INFO_ARCH_ARMV7_STR "(v7l)" |
||||
#define CPU_INFO_ARCH_ARMV6_STR "(v6l)" |
||||
#define CPU_INFO_ARCH_ARMV5_STR "(v5l)" |
||||
|
||||
#define CPU_INFO_ARCH_X86_STR "x86" |
||||
|
||||
#define CPU_INFO_ARCH_MIPS_STR "MIPS" |
||||
|
||||
|
||||
// public part
|
||||
std::map<std::string, std::string> GetCpuInfo(); |
||||
|
||||
#endif |
@ -1,92 +0,0 @@ |
||||
#include "StringUtils.h" |
||||
|
||||
using namespace std; |
||||
|
||||
bool StripString(string& src) |
||||
{ |
||||
size_t pos = 0; |
||||
|
||||
if (src.empty()) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
while ((pos < src.length()) && (' ' == src[pos])) pos++; |
||||
src.erase(0, pos); |
||||
|
||||
pos = 0; |
||||
while ((pos < src.length()) && ('\t' == src[pos])) pos++; |
||||
src.erase(0, pos); |
||||
|
||||
pos = src.length() - 1; |
||||
while (pos && (' ' == src[pos])) pos--; |
||||
src.erase(pos+1); |
||||
|
||||
pos = src.length() - 1; |
||||
while (pos && ('\t' == src[pos])) pos--; |
||||
src.erase(pos+1); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool ParseString(const string& src, string& key, string& value) |
||||
{ |
||||
if (src.empty()) |
||||
return false; |
||||
|
||||
// find separator ":"
|
||||
size_t separator_pos = src.find(":"); |
||||
if (string::npos != separator_pos) |
||||
{ |
||||
key = src.substr(0, separator_pos); |
||||
StripString(key); |
||||
value = src.substr(separator_pos+1); |
||||
StripString(value); |
||||
return true; |
||||
} |
||||
else |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
set<string> SplitString(const string& src, const char separator) |
||||
{ |
||||
set<string> result; |
||||
|
||||
if (!src.empty()) |
||||
{ |
||||
size_t separator_pos; |
||||
size_t prev_pos = 0; |
||||
do |
||||
{ |
||||
separator_pos = src.find(separator, prev_pos); |
||||
result.insert(src.substr(prev_pos, separator_pos - prev_pos)); |
||||
prev_pos = separator_pos + 1; |
||||
} |
||||
while (string::npos != separator_pos); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
vector<string> SplitStringVector(const string& src, const char separator) |
||||
{ |
||||
vector<string> result; |
||||
|
||||
if (!src.empty()) |
||||
{ |
||||
size_t separator_pos; |
||||
size_t prev_pos = 0; |
||||
do |
||||
{ |
||||
separator_pos = src.find(separator, prev_pos); |
||||
string tmp = src.substr(prev_pos, separator_pos - prev_pos); |
||||
result.push_back(tmp); |
||||
prev_pos = separator_pos + 1; |
||||
} |
||||
while (string::npos != separator_pos); |
||||
} |
||||
|
||||
return result; |
||||
} |
@ -1,13 +0,0 @@ |
||||
#ifndef __STRING_UTILS_H__ |
||||
#define __STRING_UTILS_H__ |
||||
|
||||
#include <string> |
||||
#include <set> |
||||
#include <vector> |
||||
|
||||
bool StripString(std::string& src); |
||||
std::set<std::string> SplitString(const std::string& src, const char separator); |
||||
bool ParseString(const std::string& src, std::string& key, std::string& value); |
||||
std::vector<std::string> SplitStringVector(const std::string& src, const char separator); |
||||
|
||||
#endif |
@ -1,14 +0,0 @@ |
||||
#ifndef __TEGRA_DETECTOR_H__ |
||||
#define __TEGRA_DETECTOR_H__ |
||||
|
||||
#define TEGRA_DETECTOR_ERROR -2 |
||||
#define NOT_TEGRA -1 |
||||
#define TEGRA2 2 |
||||
#define TEGRA3 3 |
||||
#define TEGRA4i 4 |
||||
#define TEGRA4 5 |
||||
#define TEGRA5 6 |
||||
|
||||
int DetectTegra(); |
||||
|
||||
#endif |
@ -1,25 +0,0 @@ |
||||
#include "HardwareDetector_jni.h" |
||||
#include "HardwareDetector.h" |
||||
#include <jni.h> |
||||
#include <string> |
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_GetCpuID(JNIEnv* , jclass) |
||||
{ |
||||
return GetCpuID(); |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine3_HardwareDetector_GetPlatformName(JNIEnv* env, jclass) |
||||
{ |
||||
std::string hardware_name = GetPlatformName(); |
||||
return env->NewStringUTF(hardware_name.c_str()); |
||||
} |
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_GetProcessorCount(JNIEnv* , jclass) |
||||
{ |
||||
return GetProcessorCount(); |
||||
} |
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_DetectKnownPlatforms(JNIEnv* , jclass) |
||||
{ |
||||
return DetectKnownPlatforms(); |
||||
} |
@ -1,48 +0,0 @@ |
||||
/* DO NOT EDIT THIS FILE - it is machine generated */ |
||||
#include <jni.h> |
||||
/* Header for class HardwareDetector */ |
||||
|
||||
#ifndef _Included_HardwareDetector |
||||
#define _Included_HardwareDetector |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/*
|
||||
* Class: org_opencv_engine_HardwareDetector |
||||
* Method: GetCpuID |
||||
* Signature: ()I |
||||
*/ |
||||
JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_GetCpuID |
||||
(JNIEnv *, jclass); |
||||
|
||||
/*
|
||||
* Class: org_opencv_engine_HardwareDetector |
||||
* Method: GetPlatformName |
||||
* Signature: ()Ljava/lang/String; |
||||
*/ |
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine3_HardwareDetector_GetPlatformName |
||||
(JNIEnv *, jclass); |
||||
|
||||
/*
|
||||
* Class: org_opencv_engine_HardwareDetector |
||||
* Method: GetProcessorCount |
||||
* Signature: ()I |
||||
*/ |
||||
JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_GetProcessorCount |
||||
(JNIEnv *, jclass); |
||||
|
||||
/*
|
||||
* Class: org_opencv_engine_HardwareDetector |
||||
* Method: DetectKnownPlatforms |
||||
* Signature: ()I |
||||
*/ |
||||
JNIEXPORT jint JNICALL Java_org_opencv_engine3_HardwareDetector_DetectKnownPlatforms |
||||
(JNIEnv *, jclass); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif |
@ -1,202 +0,0 @@ |
||||
#include "JavaBasedPackageManager.h" |
||||
#include <utils/Log.h> |
||||
#include <assert.h> |
||||
|
||||
#undef LOG_TAG |
||||
#define LOG_TAG "JavaBasedPackageManager" |
||||
|
||||
using namespace std; |
||||
|
||||
JavaBasedPackageManager::JavaBasedPackageManager(JavaVM* JavaMashine, jobject MarketConnector): |
||||
JavaContext(JavaMashine), |
||||
JavaPackageManager(MarketConnector) |
||||
{ |
||||
assert(JavaContext); |
||||
assert(JavaPackageManager); |
||||
} |
||||
|
||||
bool JavaBasedPackageManager::InstallPackage(const PackageInfo& package) |
||||
{ |
||||
JNIEnv* jenv; |
||||
bool self_attached; |
||||
LOGD("JavaBasedPackageManager::InstallPackage() begin\n"); |
||||
|
||||
self_attached = (JNI_EDETACHED == JavaContext->GetEnv((void**)&jenv, JNI_VERSION_1_6)); |
||||
if (self_attached) |
||||
{ |
||||
JavaContext->AttachCurrentThread(&jenv, NULL); |
||||
} |
||||
|
||||
LOGD("GetObjectClass call\n"); |
||||
jclass jclazz = jenv->GetObjectClass(JavaPackageManager); |
||||
if (!jclazz) |
||||
{ |
||||
LOGE("MarketConnector class was not found!"); |
||||
return false; |
||||
} |
||||
|
||||
LOGD("GetMethodID call\n"); |
||||
jmethodID jmethod = jenv->GetMethodID(jclazz, "InstallAppFromMarket", "(Ljava/lang/String;)Z"); |
||||
if (!jmethod) |
||||
{ |
||||
LOGE("MarketConnector::GetAppFormMarket method was not found!"); |
||||
jenv->DeleteLocalRef(jclazz); |
||||
return false; |
||||
} |
||||
|
||||
LOGD("Calling java package manager with package name %s\n", package.GetFullName().c_str()); |
||||
jobject jpkgname = jenv->NewStringUTF(package.GetFullName().c_str()); |
||||
bool result = jenv->CallNonvirtualBooleanMethod(JavaPackageManager, jclazz, jmethod, jpkgname); |
||||
|
||||
jenv->DeleteLocalRef(jpkgname); |
||||
jenv->DeleteLocalRef(jclazz); |
||||
|
||||
if (self_attached) |
||||
{ |
||||
JavaContext->DetachCurrentThread(); |
||||
} |
||||
|
||||
LOGD("JavaBasedPackageManager::InstallPackage() end\n"); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
vector<PackageInfo> JavaBasedPackageManager::GetInstalledPackages() |
||||
{ |
||||
vector<PackageInfo> result; |
||||
JNIEnv* jenv; |
||||
bool self_attached; |
||||
|
||||
LOGD("JavaBasedPackageManager::GetInstalledPackages() begin"); |
||||
|
||||
self_attached = (JNI_EDETACHED == JavaContext->GetEnv((void**)&jenv, JNI_VERSION_1_6)); |
||||
if (self_attached) |
||||
{ |
||||
JavaContext->AttachCurrentThread(&jenv, NULL); |
||||
} |
||||
|
||||
jclass jclazz = jenv->GetObjectClass(JavaPackageManager); |
||||
if (!jclazz) |
||||
{ |
||||
LOGE("MarketConnector class was not found!"); |
||||
return result; |
||||
} |
||||
|
||||
jmethodID jmethod = jenv->GetMethodID(jclazz, "GetInstalledOpenCVPackages", "()[Landroid/content/pm/PackageInfo;"); |
||||
if (!jmethod) |
||||
{ |
||||
LOGE("MarketConnector::GetInstalledOpenCVPackages method was not found!"); |
||||
jenv->DeleteLocalRef(jclazz); |
||||
return result; |
||||
} |
||||
|
||||
jobjectArray jpkgs = static_cast<jobjectArray>(jenv->CallNonvirtualObjectMethod(JavaPackageManager, jclazz, jmethod)); |
||||
jsize size = jenv->GetArrayLength(jpkgs); |
||||
|
||||
LOGD("Package info conversion"); |
||||
|
||||
result.reserve(size); |
||||
|
||||
for (jsize i = 0; i < size; i++) |
||||
{ |
||||
jobject jtmp = jenv->GetObjectArrayElement(jpkgs, i); |
||||
PackageInfo tmp = ConvertPackageFromJava(jtmp, jenv); |
||||
|
||||
if (tmp.IsValid()) |
||||
result.push_back(tmp); |
||||
|
||||
jenv->DeleteLocalRef(jtmp); |
||||
} |
||||
|
||||
jenv->DeleteLocalRef(jpkgs); |
||||
jenv->DeleteLocalRef(jclazz); |
||||
|
||||
if (self_attached) |
||||
{ |
||||
JavaContext->DetachCurrentThread(); |
||||
} |
||||
|
||||
LOGD("JavaBasedPackageManager::GetInstalledPackages() end"); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
static jint GetAndroidVersion(JNIEnv* jenv) |
||||
{ |
||||
jclass jclazz = jenv->FindClass("android/os/Build$VERSION"); |
||||
jfieldID jfield = jenv->GetStaticFieldID(jclazz, "SDK_INT", "I"); |
||||
jint api_level = jenv->GetStaticIntField(jclazz, jfield); |
||||
jenv->DeleteLocalRef(jclazz); |
||||
|
||||
return api_level; |
||||
} |
||||
|
||||
// IMPORTANT: This method can be called only if thread is attached to Dalvik
|
||||
PackageInfo JavaBasedPackageManager::ConvertPackageFromJava(jobject package, JNIEnv* jenv) |
||||
{ |
||||
jclass jclazz = jenv->GetObjectClass(package); |
||||
|
||||
jfieldID jfield = jenv->GetFieldID(jclazz, "packageName", "Ljava/lang/String;"); |
||||
jstring jnameobj = static_cast<jstring>(jenv->GetObjectField(package, jfield)); |
||||
const char* jnamestr = jenv->GetStringUTFChars(jnameobj, NULL); |
||||
string name(jnamestr); |
||||
jenv->DeleteLocalRef(jnameobj); |
||||
|
||||
jfield = jenv->GetFieldID(jclazz, "versionName", "Ljava/lang/String;"); |
||||
jstring jversionobj = static_cast<jstring>(jenv->GetObjectField(package, jfield)); |
||||
const char* jversionstr = jenv->GetStringUTFChars(jversionobj, NULL); |
||||
string verison(jversionstr); |
||||
jenv->DeleteLocalRef(jversionobj); |
||||
|
||||
jenv->DeleteLocalRef(jclazz); |
||||
|
||||
static const jint api_level = GetAndroidVersion(jenv); |
||||
string path; |
||||
if (api_level > 8) |
||||
{ |
||||
jclazz = jenv->GetObjectClass(package); |
||||
jfield = jenv->GetFieldID(jclazz, "applicationInfo", "Landroid/content/pm/ApplicationInfo;"); |
||||
jobject japp_info = jenv->GetObjectField(package, jfield); |
||||
jenv->DeleteLocalRef(jclazz); |
||||
|
||||
jclazz = jenv->GetObjectClass(japp_info); |
||||
jfield = jenv->GetFieldID(jclazz, "nativeLibraryDir", "Ljava/lang/String;"); |
||||
jstring jpathobj = static_cast<jstring>(jenv->GetObjectField(japp_info, jfield)); |
||||
const char* jpathstr = jenv->GetStringUTFChars(jpathobj, NULL); |
||||
path = string(jpathstr); |
||||
jenv->ReleaseStringUTFChars(jpathobj, jpathstr); |
||||
|
||||
jenv->DeleteLocalRef(japp_info); |
||||
jenv->DeleteLocalRef(jpathobj); |
||||
jenv->DeleteLocalRef(jclazz); |
||||
} |
||||
else |
||||
{ |
||||
path = "/data/data/" + name + "/lib"; |
||||
} |
||||
|
||||
return PackageInfo(name, path, verison); |
||||
} |
||||
|
||||
JavaBasedPackageManager::~JavaBasedPackageManager() |
||||
{ |
||||
JNIEnv* jenv; |
||||
bool self_attached; |
||||
|
||||
LOGD("JavaBasedPackageManager::~JavaBasedPackageManager() begin"); |
||||
|
||||
JavaContext->GetEnv((void**)&jenv, JNI_VERSION_1_6); |
||||
self_attached = (JNI_EDETACHED == JavaContext->GetEnv((void**)&jenv, JNI_VERSION_1_6)); |
||||
if (self_attached) |
||||
{ |
||||
JavaContext->AttachCurrentThread(&jenv, NULL); |
||||
} |
||||
|
||||
jenv->DeleteGlobalRef(JavaPackageManager); |
||||
|
||||
if (self_attached) |
||||
{ |
||||
JavaContext->DetachCurrentThread(); |
||||
} |
||||
LOGD("JavaBasedPackageManager::~JavaBasedPackageManager() end"); |
||||
} |
@ -1,22 +0,0 @@ |
||||
#include "IPackageManager.h" |
||||
#include "CommonPackageManager.h" |
||||
#include <jni.h> |
||||
#include <vector> |
||||
|
||||
class JavaBasedPackageManager: public CommonPackageManager |
||||
{ |
||||
public: |
||||
JavaBasedPackageManager(JavaVM* JavaMashine, jobject MarketConector); |
||||
virtual ~JavaBasedPackageManager(); |
||||
|
||||
protected: |
||||
virtual bool InstallPackage(const PackageInfo& package); |
||||
virtual std::vector<PackageInfo> GetInstalledPackages(); |
||||
|
||||
private: |
||||
JavaVM* JavaContext; |
||||
jobject JavaPackageManager; |
||||
|
||||
JavaBasedPackageManager(); |
||||
PackageInfo ConvertPackageFromJava(jobject package, JNIEnv* jenv); |
||||
}; |
@ -1,69 +0,0 @@ |
||||
#include "OpenCVEngine_jni.h" |
||||
#include "EngineCommon.h" |
||||
#include "IOpenCVEngine.h" |
||||
#include "OpenCVEngine.h" |
||||
#include "IPackageManager.h" |
||||
#include "JavaBasedPackageManager.h" |
||||
#include <utils/Log.h> |
||||
#include <android_util_Binder.h> |
||||
|
||||
#undef LOG_TAG |
||||
#define LOG_TAG "OpenCVEngine/JNI" |
||||
|
||||
using namespace android; |
||||
|
||||
sp<IBinder> OpenCVEngineBinder = NULL; |
||||
IPackageManager* PackageManager = NULL; |
||||
|
||||
JNIEXPORT jobject JNICALL Java_org_opencv_engine3_BinderConnector_Connect(JNIEnv* env, jobject) |
||||
{ |
||||
LOGI("Creating new component"); |
||||
if (NULL != OpenCVEngineBinder.get()) |
||||
{ |
||||
LOGI("New component created successfully"); |
||||
} |
||||
else |
||||
{ |
||||
LOGE("OpenCV Engine component was not created!"); |
||||
} |
||||
|
||||
return javaObjectForIBinder(env, OpenCVEngineBinder); |
||||
} |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_engine3_BinderConnector_Init(JNIEnv* env, jobject , jobject market) |
||||
{ |
||||
LOGD("Java_org_opencv_engine_BinderConnector_Init"); |
||||
|
||||
if (NULL == PackageManager) |
||||
{ |
||||
JavaVM* jvm; |
||||
env->GetJavaVM(&jvm); |
||||
PackageManager = new JavaBasedPackageManager(jvm, env->NewGlobalRef(market)); |
||||
} |
||||
if (PackageManager) |
||||
{ |
||||
if (!OpenCVEngineBinder.get()) |
||||
{ |
||||
OpenCVEngineBinder = new OpenCVEngine(PackageManager); |
||||
return (NULL != OpenCVEngineBinder.get()); |
||||
} |
||||
else |
||||
{ |
||||
return true; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_engine3_BinderConnector_Final(JNIEnv *, jobject) |
||||
{ |
||||
LOGD("Java_org_opencv_engine_BinderConnector_Final"); |
||||
|
||||
OpenCVEngineBinder = NULL; |
||||
|
||||
delete PackageManager; |
||||
PackageManager = NULL; |
||||
} |
@ -1,37 +0,0 @@ |
||||
/* DO NOT EDIT THIS FILE - it is machine generated */ |
||||
#include <jni.h> |
||||
/* Header for class org_opencv_engine_BinderConnector */ |
||||
|
||||
#ifndef _Included_org_opencv_engine_BinderConnector |
||||
#define _Included_org_opencv_engine_BinderConnector |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
/*
|
||||
* Class: org_opencv_engine_BinderConnector |
||||
* Method: Connect |
||||
* Signature: ()Landroid/os/IBinder; |
||||
*/ |
||||
JNIEXPORT jobject JNICALL Java_org_opencv_engine3_BinderConnector_Connect |
||||
(JNIEnv *, jobject); |
||||
|
||||
/*
|
||||
* Class: org_opencv_engine_BinderConnector |
||||
* Method: Init |
||||
* Signature: (Lorg/opencv/engine/MarketConnector;)Z |
||||
*/ |
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_engine3_BinderConnector_Init |
||||
(JNIEnv *, jobject, jobject); |
||||
|
||||
/*
|
||||
* Class: org_opencv_engine_BinderConnector |
||||
* Method: Final |
||||
* Signature: ()V |
||||
*/ |
||||
JNIEXPORT void JNICALL Java_org_opencv_engine3_BinderConnector_Final |
||||
(JNIEnv *, jobject); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
#endif |
@ -1,88 +0,0 @@ |
||||
#include "OpenCVLibraryInfo.h" |
||||
#include "EngineCommon.h" |
||||
#include <utils/Log.h> |
||||
#include <dlfcn.h> |
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_open |
||||
(JNIEnv * env, jobject, jstring str) |
||||
{ |
||||
const char* infoLibPath = env->GetStringUTFChars(str, NULL); |
||||
if (infoLibPath == NULL) |
||||
return 0; |
||||
|
||||
LOGD("Trying to load info library \"%s\"", infoLibPath); |
||||
|
||||
void* handle; |
||||
|
||||
handle = dlopen(infoLibPath, RTLD_LAZY); |
||||
if (handle == NULL) |
||||
LOGI("Info library not found by path \"%s\"", infoLibPath); |
||||
|
||||
return (jlong)handle; |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getPackageName |
||||
(JNIEnv* env, jobject, jlong handle) |
||||
{ |
||||
InfoFunctionType info_func; |
||||
const char* result; |
||||
const char* error; |
||||
|
||||
dlerror(); |
||||
info_func = (InfoFunctionType)dlsym((void*)handle, "GetPackageName"); |
||||
if ((error = dlerror()) == NULL) |
||||
result = (*info_func)(); |
||||
else |
||||
{ |
||||
LOGE("dlsym error: \"%s\"", error); |
||||
result = "unknown"; |
||||
} |
||||
|
||||
return env->NewStringUTF(result); |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getLibraryList |
||||
(JNIEnv* env, jobject, jlong handle) |
||||
{ |
||||
InfoFunctionType info_func; |
||||
const char* result; |
||||
const char* error; |
||||
|
||||
dlerror(); |
||||
info_func = (InfoFunctionType)dlsym((void*)handle, "GetLibraryList"); |
||||
if ((error = dlerror()) == NULL) |
||||
result = (*info_func)(); |
||||
else |
||||
{ |
||||
LOGE("dlsym error: \"%s\"", error); |
||||
result = "unknown"; |
||||
} |
||||
|
||||
return env->NewStringUTF(result); |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getVersionName |
||||
(JNIEnv* env, jobject, jlong handle) |
||||
{ |
||||
InfoFunctionType info_func; |
||||
const char* result; |
||||
const char* error; |
||||
|
||||
dlerror(); |
||||
info_func = (InfoFunctionType)dlsym((void*)handle, "GetRevision"); |
||||
if ((error = dlerror()) == NULL) |
||||
result = (*info_func)(); |
||||
else |
||||
{ |
||||
LOGE("dlsym error: \"%s\"", error); |
||||
result = "unknown"; |
||||
} |
||||
|
||||
return env->NewStringUTF(result); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_close |
||||
(JNIEnv*, jobject, jlong handle) |
||||
{ |
||||
dlclose((void*)handle); |
||||
} |
@ -1,27 +0,0 @@ |
||||
#include <jni.h> |
||||
|
||||
#ifndef _Included_org_opencv_engine_OpenCVLibraryInfo |
||||
#define _Included_org_opencv_engine_OpenCVLibraryInfo |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_open |
||||
(JNIEnv *, jobject, jstring); |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getPackageName |
||||
(JNIEnv *, jobject, jlong); |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getLibraryList |
||||
(JNIEnv *, jobject, jlong); |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_getVersionName |
||||
(JNIEnv *, jobject, jlong); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_engine3_OpenCVLibraryInfo_close |
||||
(JNIEnv *, jobject, jlong); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
#endif |
@ -1,42 +0,0 @@ |
||||
#include "EngineCommon.h" |
||||
#include "IOpenCVEngine.h" |
||||
|
||||
#include <sys/types.h> |
||||
#include <unistd.h> |
||||
#include <grp.h> |
||||
|
||||
#include <binder/IPCThreadState.h> |
||||
#include <binder/ProcessState.h> |
||||
#include <binder/IServiceManager.h> |
||||
#include <utils/Log.h> |
||||
|
||||
#include <stdio.h> |
||||
|
||||
using namespace android; |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
LOGI("OpenCVEngine client is now starting"); |
||||
|
||||
sp<IServiceManager> ServiceManager = defaultServiceManager(); |
||||
sp<IBinder> EngineService; |
||||
sp<IOpenCVEngine> Engine; |
||||
|
||||
LOGI("Trying to contect to service"); |
||||
|
||||
do { |
||||
EngineService = ServiceManager->getService(IOpenCVEngine::descriptor); |
||||
if (EngineService != 0) break; |
||||
LOGW("OpenCVEngine not published, waiting..."); |
||||
usleep(500000); // 0.5 s
|
||||
} while(true); |
||||
|
||||
LOGI("Connection established"); |
||||
|
||||
Engine = interface_cast<IOpenCVEngine>(EngineService); |
||||
int32_t EngineVersion = Engine->GetVersion(); |
||||
|
||||
printf("OpenCVEngine version %d started", EngineVersion); |
||||
|
||||
return 0; |
||||
} |
@ -1,243 +0,0 @@ |
||||
#include "IOpenCVEngine.h" |
||||
#include "CommonPackageManager.h" |
||||
#include "HardwareDetector.h" |
||||
#include <utils/Log.h> |
||||
#include <algorithm> |
||||
#include <stdio.h> |
||||
#include <assert.h> |
||||
|
||||
#undef LOG_TAG |
||||
#define LOG_TAG "CommonPackageManager" |
||||
|
||||
using namespace std; |
||||
|
||||
vector<int> CommonPackageManager::GetInstalledVersions() |
||||
{ |
||||
vector<int> result; |
||||
vector<PackageInfo> installed_packages = GetInstalledPackages(); |
||||
|
||||
result.resize(installed_packages.size()); |
||||
|
||||
for (size_t i = 0; i < installed_packages.size(); i++) |
||||
{ |
||||
int version = installed_packages[i].GetVersion(); |
||||
assert(version); |
||||
result[i] = version; |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
bool CommonPackageManager::CheckVersionInstalled(int version, int platform, int cpu_id) |
||||
{ |
||||
bool result = false; |
||||
LOGD("CommonPackageManager::CheckVersionInstalled() begin"); |
||||
PackageInfo target_package(version, platform, cpu_id); |
||||
LOGD("GetInstalledPackages() call"); |
||||
vector<PackageInfo> packages = GetInstalledPackages(); |
||||
|
||||
for (vector<PackageInfo>::const_iterator it = packages.begin(); it != packages.end(); ++it) |
||||
{ |
||||
LOGD("Found package: \"%s\"", it->GetFullName().c_str()); |
||||
} |
||||
|
||||
if (!packages.empty()) |
||||
{ |
||||
vector<PackageInfo>::const_iterator it = find(packages.begin(), packages.end(), target_package); |
||||
result = (it != packages.end()); |
||||
} |
||||
LOGD("CommonPackageManager::CheckVersionInstalled() end"); |
||||
return result; |
||||
} |
||||
|
||||
bool CommonPackageManager::InstallVersion(int version, int platform, int cpu_id) |
||||
{ |
||||
LOGD("CommonPackageManager::InstallVersion() begin"); |
||||
PackageInfo package(version, platform, cpu_id); |
||||
return InstallPackage(package); |
||||
} |
||||
|
||||
string CommonPackageManager::GetPackagePathByVersion(int version, int platform, int cpu_id) |
||||
{ |
||||
string result; |
||||
PackageInfo target_package(version, platform, cpu_id); |
||||
vector<PackageInfo> all_packages = GetInstalledPackages(); |
||||
vector<PackageInfo> packages; |
||||
|
||||
for (vector<PackageInfo>::iterator it = all_packages.begin(); it != all_packages.end(); ++it) |
||||
{ |
||||
LOGD("Check version \"%d\" compatibility with \"%d\"\n", version, it->GetVersion()); |
||||
if (IsVersionCompatible(version, it->GetVersion())) |
||||
{ |
||||
LOGD("Compatible"); |
||||
packages.push_back(*it); |
||||
} |
||||
else |
||||
{ |
||||
LOGD("NOT Compatible"); |
||||
} |
||||
} |
||||
|
||||
if (!packages.empty()) |
||||
{ |
||||
int platform_group = 0; |
||||
|
||||
if ((cpu_id & ARCH_X86) || (cpu_id & ARCH_X64)) |
||||
platform_group = 1; |
||||
|
||||
if (cpu_id & ARCH_MIPS) |
||||
platform_group = 2; |
||||
|
||||
int opt_rating = -1; |
||||
int opt_version = 0; |
||||
|
||||
const int hardware_rating = GetHardwareRating(platform, cpu_id, ArchRatings[platform_group]); |
||||
LOGD("Current hardware platform rating %d for (%d,%d)", hardware_rating, platform, cpu_id); |
||||
|
||||
if (-1 == hardware_rating) |
||||
{ |
||||
LOGE("Cannot calculate rating for current hardware platform!"); |
||||
} |
||||
else |
||||
{ |
||||
vector<PackageInfo>::iterator found = packages.end(); |
||||
for (vector<PackageInfo>::iterator it = packages.begin(); it != packages.end(); ++it) |
||||
{ |
||||
int package_group = 0; |
||||
|
||||
if ((it->GetCpuID() & ARCH_X86) || (it->GetCpuID() & ARCH_X64)) |
||||
package_group = 1; |
||||
|
||||
if (it->GetCpuID() & ARCH_MIPS) |
||||
package_group = 2; |
||||
|
||||
if (package_group != platform_group) |
||||
continue; |
||||
|
||||
const int package_rating = GetHardwareRating(it->GetPlatform(), it->GetCpuID(), ArchRatings[package_group]); |
||||
|
||||
LOGD("Package \"%s\" rating %d for (%d,%d)", it->GetFullName().c_str(), package_rating, it->GetPlatform(), it->GetCpuID()); |
||||
if ((package_rating >= 0) && (package_rating <= hardware_rating)) |
||||
{ |
||||
if (((it->GetVersion() >= opt_version) && (package_rating >= opt_rating)) || (it->GetVersion() > opt_version)) |
||||
{ |
||||
opt_rating = package_rating; |
||||
opt_version = it->GetVersion(); |
||||
found = it; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if ((-1 != opt_rating) && (packages.end() != found)) |
||||
{ |
||||
result = found->GetInstalationPath(); |
||||
} |
||||
else |
||||
{ |
||||
LOGI("No compatible packages found!"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
bool CommonPackageManager::IsVersionCompatible(int target_version, int package_version) |
||||
{ |
||||
assert(target_version); |
||||
assert(package_version); |
||||
|
||||
// major version is the same and minor package version is above or the same as target.
|
||||
return ( (package_version/10000 == target_version/10000) && (package_version%10000 >= target_version%10000) ); |
||||
} |
||||
|
||||
int CommonPackageManager::GetHardwareRating(int platform, int cpu_id, const std::vector<std::pair<int, int> >& group) |
||||
{ |
||||
int result = -1; |
||||
|
||||
if ((cpu_id & ARCH_X86) || (cpu_id & ARCH_X64) || (cpu_id & ARCH_MIPS)) |
||||
// Note: No raiting for x86, x64 and MIPS
|
||||
// only one package is used
|
||||
result = 0; |
||||
else |
||||
{ |
||||
// Calculate rating for Arm
|
||||
LOGD("!!! Calculating rating for ARM\n"); |
||||
for (size_t i = 0; i < group.size(); i++) |
||||
{ |
||||
LOGD("Checking (%d, %d) against (%d,%d)\n", group[i].first, group[i].second, platform, cpu_id); |
||||
if (group[i] == std::pair<int, int>(platform, cpu_id)) |
||||
{ |
||||
LOGD("Rating found: %d\n", i); |
||||
result = i; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
std::vector<std::pair<int, int> > CommonPackageManager::InitArmRating() |
||||
{ |
||||
std::vector<std::pair<int, int> > result; |
||||
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv5)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv6)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv6 | FEATURES_HAS_VFPv3d16)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv6 | FEATURES_HAS_VFPv3)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv6 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv3d16)); |
||||
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA2, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16 | FEATURES_HAS_VFPv3)); |
||||
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_NEON)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3d16 | FEATURES_HAS_NEON)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv3d16 | FEATURES_HAS_NEON)); |
||||
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv4 | FEATURES_HAS_NEON)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv4 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_ARMv7 | FEATURES_HAS_VFPv4 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv3d16 | FEATURES_HAS_NEON)); |
||||
|
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA3, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA4i, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv4 | FEATURES_HAS_NEON)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA4, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv4 | FEATURES_HAS_NEON)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_TEGRA5, ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv4 | FEATURES_HAS_NEON)); |
||||
|
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_AARCH64)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_AARCH64 | FEATURES_HAS_VFPv3)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_AARCH64 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv4)); |
||||
result.push_back(std::pair<int, int>(PLATFORM_UNKNOWN, ARCH_AARCH64 | FEATURES_HAS_VFPv3 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON)); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
// Stub for Intel platforms rating initialization. Common package for all Intel based devices is used now
|
||||
std::vector<std::pair<int, int> > CommonPackageManager::InitIntelRating() |
||||
{ |
||||
std::vector<std::pair<int, int> > result; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
// Stub for MIPS platforms rating initialization. Common package for all MIPS based devices is used now
|
||||
std::vector<std::pair<int, int> > CommonPackageManager::InitMipsRating() |
||||
{ |
||||
std::vector<std::pair<int, int> > result; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
const std::vector<std::pair<int, int> > CommonPackageManager::ArchRatings[] = { |
||||
CommonPackageManager::InitArmRating(), |
||||
CommonPackageManager::InitIntelRating(), |
||||
CommonPackageManager::InitMipsRating() |
||||
}; |
||||
|
||||
CommonPackageManager::~CommonPackageManager() |
||||
{ |
||||
} |
@ -1,33 +0,0 @@ |
||||
#ifndef __COMMON_PACKAGE_MANAGER_H__ |
||||
#define __COMMON_PACKAGE_MANAGER_H__ |
||||
|
||||
#include "IPackageManager.h" |
||||
#include "PackageInfo.h" |
||||
#include <vector> |
||||
#include <string> |
||||
|
||||
class CommonPackageManager: public IPackageManager |
||||
{ |
||||
public: |
||||
std::vector<int> GetInstalledVersions(); |
||||
bool CheckVersionInstalled(int version, int platform, int cpu_id); |
||||
bool InstallVersion(int version, int platform, int cpu_id); |
||||
std::string GetPackagePathByVersion(int version, int platform, int cpu_id); |
||||
virtual ~CommonPackageManager(); |
||||
|
||||
protected: |
||||
static const std::vector<std::pair<int, int> > ArchRatings[]; |
||||
|
||||
static std::vector<std::pair<int, int> > InitArmRating(); |
||||
static std::vector<std::pair<int, int> > InitIntelRating(); |
||||
static std::vector<std::pair<int, int> > InitMipsRating(); |
||||
|
||||
bool IsVersionCompatible(int target_version, int package_version); |
||||
int GetHardwareRating(int platform, int cpu_id, const std::vector<std::pair<int, int> >& group); |
||||
|
||||
virtual bool InstallPackage(const PackageInfo& package) = 0; |
||||
virtual std::vector<PackageInfo> GetInstalledPackages() = 0; |
||||
}; |
||||
|
||||
|
||||
#endif |
@ -1,19 +0,0 @@ |
||||
#include "NativePackageManager.h" |
||||
|
||||
using namespace std; |
||||
|
||||
bool NativePackageManager::InstallPackage(const PackageInfo& package) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
vector<PackageInfo> NativePackageManager::GetInstalledPackages() |
||||
{ |
||||
vector<PackageInfo> result; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
NativePackageManager::~NativePackageManager() |
||||
{ |
||||
} |
@ -1,16 +0,0 @@ |
||||
#ifndef __NATIVE_PACKAGE_MANAGER_STUB_H__ |
||||
#define __NATIVE_PACKAGE_MANAGER_STUB_H__ |
||||
|
||||
#include "IPackageManager.h" |
||||
#include "CommonPackageManager.h" |
||||
|
||||
class NativePackageManager: public CommonPackageManager |
||||
{ |
||||
public: |
||||
virtual ~NativePackageManager(); |
||||
protected: |
||||
virtual bool InstallPackage(const PackageInfo& package); |
||||
virtual std::vector<PackageInfo> GetInstalledPackages(); |
||||
}; |
||||
|
||||
#endif |
@ -1,531 +0,0 @@ |
||||
#include "EngineCommon.h" |
||||
#include "PackageInfo.h" |
||||
#include "HardwareDetector.h" |
||||
#include "IOpenCVEngine.h" |
||||
#include "StringUtils.h" |
||||
#include <assert.h> |
||||
#include <vector> |
||||
#include <utils/Log.h> |
||||
#include <dlfcn.h> |
||||
|
||||
using namespace std; |
||||
|
||||
map<int, string> PackageInfo::InitPlatformNameMap() |
||||
{ |
||||
map<int, string> result; |
||||
|
||||
// TODO: Do not forget to add Platrfom constant to HardwareDetector.h
|
||||
result[PLATFORM_TEGRA] = PLATFORM_TEGRA_NAME; |
||||
result[PLATFORM_TEGRA2] = PLATFORM_TEGRA2_NAME; |
||||
result[PLATFORM_TEGRA3] = PLATFORM_TEGRA3_NAME; |
||||
result[PLATFORM_TEGRA4] = PLATFORM_TEGRA4_NAME; |
||||
result[PLATFORM_TEGRA4i] = PLATFORM_TEGRA4_NAME; |
||||
result[PLATFORM_TEGRA5] = PLATFORM_TEGRA5_NAME; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
const map<int, string> PackageInfo::PlatformNameMap = InitPlatformNameMap(); |
||||
const string PackageInfo::BasePackageName = "org.opencv.lib"; |
||||
const string DEFAULT_ENGINE_INSTALL_PATH = "/data/data/org.opencv.engine3"; |
||||
|
||||
inline string JoinARMFeatures(int cpu_id) |
||||
{ |
||||
string result; |
||||
|
||||
if (FEATURES_HAS_NEON2 & cpu_id) |
||||
{ |
||||
if (!((ARCH_ARMv5 & cpu_id) || (ARCH_ARMv6 & cpu_id) ||(ARCH_ARMv7 & cpu_id))) |
||||
result = string(FEATURES_HAS_NEON2_NAME); |
||||
} |
||||
else if (FEATURES_HAS_NEON & cpu_id) |
||||
{ |
||||
if (!((ARCH_ARMv5 & cpu_id) || (ARCH_ARMv6 & cpu_id))) |
||||
result = string(FEATURES_HAS_NEON_NAME); |
||||
} |
||||
else if (FEATURES_HAS_VFPv3 & cpu_id) |
||||
{ |
||||
if ((ARCH_ARMv5 & cpu_id) || (ARCH_ARMv6 & cpu_id)) |
||||
result = string(FEATURES_HAS_VFPv3_NAME); |
||||
} |
||||
else if (FEATURES_HAS_VFPv3d16 & cpu_id) |
||||
{ |
||||
if ((ARCH_ARMv5 & cpu_id) || (ARCH_ARMv6 & cpu_id)) |
||||
result = string(FEATURES_HAS_VFPv3d16_NAME); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
inline int SplitARMFeatures(const vector<string>& features) |
||||
{ |
||||
int result = 0; |
||||
|
||||
for (size_t i = 3; i < features.size(); i++) |
||||
{ |
||||
if (FEATURES_HAS_VFPv3_NAME == features[i]) |
||||
{ |
||||
result |= FEATURES_HAS_VFPv3; |
||||
} |
||||
else if (FEATURES_HAS_VFPv3d16_NAME == features[i]) |
||||
{ |
||||
result |= FEATURES_HAS_VFPv3d16; |
||||
} |
||||
else if (FEATURES_HAS_NEON_NAME == features[i]) |
||||
{ |
||||
result |= FEATURES_HAS_NEON; |
||||
} |
||||
else if (FEATURES_HAS_NEON2_NAME == features[i]) |
||||
{ |
||||
result |= FEATURES_HAS_NEON2; |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
inline string JoinIntelFeatures(int cpu_id) |
||||
{ |
||||
string result; |
||||
|
||||
if (FEATURES_HAS_SSSE3 & cpu_id) |
||||
{ |
||||
result = FEATURES_HAS_SSSE3_NAME; |
||||
} |
||||
else if (FEATURES_HAS_SSE2 & cpu_id) |
||||
{ |
||||
result = FEATURES_HAS_SSE2_NAME; |
||||
} |
||||
else if (FEATURES_HAS_SSE & cpu_id) |
||||
{ |
||||
result = FEATURES_HAS_SSE_NAME; |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
inline int SplitIntelFeatures(const vector<string>& features) |
||||
{ |
||||
int result = 0; |
||||
|
||||
for (size_t i = 3; i < features.size(); i++) |
||||
{ |
||||
if (FEATURES_HAS_SSSE3_NAME == features[i]) |
||||
{ |
||||
result |= FEATURES_HAS_SSSE3; |
||||
} |
||||
else if (FEATURES_HAS_SSE2_NAME == features[i]) |
||||
{ |
||||
result |= FEATURES_HAS_SSE2; |
||||
} |
||||
else if (FEATURES_HAS_SSE_NAME == features[i]) |
||||
{ |
||||
result |= FEATURES_HAS_SSE; |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
inline int SplitVersion(const vector<string>& features, const string& package_version) |
||||
{ |
||||
int result = 0; |
||||
|
||||
if ((features.size() > 1) && ('v' == features[1][0])) |
||||
{ |
||||
// Taking major and minor mart of library version from package name
|
||||
string tmp1 = features[1].substr(1); |
||||
result += atoi(tmp1.substr(0,1).c_str())*1000000 + atoi(tmp1.substr(1,1).c_str())*10000; |
||||
|
||||
// Taking release and build number from package revision
|
||||
vector<string> tmp2 = SplitStringVector(package_version, '.'); |
||||
if (tmp2.size() == 2) |
||||
{ |
||||
// the 2nd digit is revision
|
||||
result += atoi(tmp2[0].c_str())*100 + 00; |
||||
} |
||||
else |
||||
{ |
||||
// the 2nd digit is part of library version
|
||||
// the 3rd digit is revision
|
||||
result += atoi(tmp2[0].c_str())*100 + atoi(tmp2[1].c_str()); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// TODO: Report package name format error
|
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
inline string JoinPlatform(int platform) |
||||
{ |
||||
string result; |
||||
map<int, string>::const_iterator it = PackageInfo::PlatformNameMap.find(platform); |
||||
|
||||
assert(PackageInfo::PlatformNameMap.end() != it); |
||||
result = it->second; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
inline int SplitPlatform(const vector<string>& features) |
||||
{ |
||||
int result = 0; |
||||
|
||||
if (features.size() > 2) |
||||
{ |
||||
string tmp = features[2]; |
||||
if (PLATFORM_TEGRA_NAME == tmp) |
||||
{ |
||||
result = PLATFORM_TEGRA; |
||||
} |
||||
else if (PLATFORM_TEGRA2_NAME == tmp) |
||||
{ |
||||
result = PLATFORM_TEGRA2; |
||||
} |
||||
else if (PLATFORM_TEGRA3_NAME == tmp) |
||||
{ |
||||
result = PLATFORM_TEGRA3; |
||||
} |
||||
else if (PLATFORM_TEGRA4_NAME == tmp) |
||||
{ |
||||
result = PLATFORM_TEGRA4; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// TODO: Report package name format error
|
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
/* Package naming convention
|
||||
* All parts of package name separated by "_" symbol |
||||
* First part is base namespace. |
||||
* Second part is version. Version starts from "v" symbol. After "v" symbol version nomber without dot symbol added. |
||||
* If platform is known third part is platform name |
||||
* If platform is unknown it is defined by hardware capabilities using pattern: <arch>_<floating point and vectorization features>_<other features> |
||||
* Example: armv7_neon |
||||
*/ |
||||
PackageInfo::PackageInfo(int version, int platform, int cpu_id, std::string install_path): |
||||
Version(version), |
||||
Platform(platform), |
||||
CpuID(cpu_id), |
||||
InstallPath("") |
||||
{ |
||||
#ifndef __SUPPORT_TEGRA3 |
||||
Platform = PLATFORM_UNKNOWN; |
||||
#endif |
||||
|
||||
int major_version = version/1000000; |
||||
int minor_version = version/10000 - major_version*100; |
||||
|
||||
char tmp[32]; |
||||
|
||||
sprintf(tmp, "%d%d", major_version, minor_version); |
||||
|
||||
FullName = BasePackageName + std::string("_v") + std::string(tmp); |
||||
if (PLATFORM_UNKNOWN != Platform) |
||||
{ |
||||
FullName += string("_") + JoinPlatform(platform); |
||||
} |
||||
else |
||||
{ |
||||
if (ARCH_UNKNOWN != CpuID) |
||||
{ |
||||
if (ARCH_X86 & CpuID) |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo: package arch x86"); |
||||
FullName += string("_") + ARCH_X86_NAME; |
||||
#ifdef __SUPPORT_INTEL_FEATURES |
||||
string features = JoinIntelFeatures(CpuID); |
||||
if (!features.empty()) |
||||
{ |
||||
FullName += string("_") + features; |
||||
} |
||||
#endif |
||||
} |
||||
else if (ARCH_X64 & CpuID) |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo: package arch x64"); |
||||
#ifdef __SUPPORT_INTEL_x64 |
||||
FullName += string("_") + ARCH_X64_NAME; |
||||
#else |
||||
FullName += string("_") + ARCH_X86_NAME; |
||||
#endif |
||||
#ifdef __SUPPORT_INTEL_FEATURES |
||||
string features = JoinIntelFeatures(CpuID); |
||||
if (!features.empty()) |
||||
{ |
||||
FullName += string("_") + features; |
||||
} |
||||
#endif |
||||
} |
||||
else if (ARCH_ARMv5 & CpuID) |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo: package arch ARMv5"); |
||||
FullName += string("_") + ARCH_ARMv5_NAME; |
||||
#ifdef __SUPPORT_ARMEABI_FEATURES |
||||
string features = JoinARMFeatures(CpuID); |
||||
if (!features.empty()) |
||||
{ |
||||
FullName += string("_") + features; |
||||
} |
||||
#endif |
||||
} |
||||
else if (ARCH_ARMv6 & CpuID) |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo: package arch ARMv6"); |
||||
// NOTE: ARM v5 used instead ARM v6
|
||||
//FullName += string("_") + ARCH_ARMv6_NAME;
|
||||
FullName += string("_") + ARCH_ARMv5_NAME; |
||||
#ifdef __SUPPORT_ARMEABI_FEATURES |
||||
string features = JoinARMFeatures(CpuID); |
||||
if (!features.empty()) |
||||
{ |
||||
FullName += string("_") + features; |
||||
} |
||||
#endif |
||||
} |
||||
else if (ARCH_ARMv7 & CpuID) |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo: package arch ARMv7"); |
||||
FullName += string("_") + ARCH_ARMv7_NAME; |
||||
#ifdef __SUPPORT_ARMEABI_V7A_FEATURES |
||||
string features = JoinARMFeatures(CpuID); |
||||
if (!features.empty()) |
||||
{ |
||||
FullName += string("_") + features; |
||||
} |
||||
#endif |
||||
} |
||||
#ifdef __SUPPORT_AARCH64 |
||||
else if (ARCH_AARCH64 & CpuID) |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo: package arch AARCH64"); |
||||
FullName += string("_") + ARCH_AARCH64_NAME; |
||||
} |
||||
#endif |
||||
#ifdef __SUPPORT_MIPS |
||||
else if (ARCH_MIPS & CpuID) |
||||
{ |
||||
FullName += string("_") + ARCH_MIPS_NAME; |
||||
} |
||||
#endif |
||||
else |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo: package arch unknown"); |
||||
Version = 0; |
||||
CpuID = ARCH_UNKNOWN; |
||||
Platform = PLATFORM_UNKNOWN; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo: package arch unknown"); |
||||
Version = 0; |
||||
CpuID = ARCH_UNKNOWN; |
||||
Platform = PLATFORM_UNKNOWN; |
||||
} |
||||
} |
||||
|
||||
if (!FullName.empty()) |
||||
{ |
||||
InstallPath = install_path + FullName + "/lib"; |
||||
} |
||||
} |
||||
|
||||
PackageInfo::PackageInfo(const string& fullname, const string& install_path, string package_version): |
||||
FullName(fullname), |
||||
InstallPath(install_path) |
||||
{ |
||||
LOGD("PackageInfo::PackageInfo(\"%s\", \"%s\", \"%s\")", fullname.c_str(), install_path.c_str(), package_version.c_str()); |
||||
|
||||
assert(!fullname.empty()); |
||||
assert(!install_path.empty()); |
||||
|
||||
if (OPENCV_ENGINE_PACKAGE == fullname) |
||||
{ |
||||
// Science version 1.7 OpenCV Manager has it's own version of OpenCV inside
|
||||
// Load libopencv_info.so to understand OpenCV version, platform and other features
|
||||
std::string tmp; |
||||
if (install_path.empty()) |
||||
{ |
||||
tmp = std::string(DEFAULT_ENGINE_INSTALL_PATH) + "/" + LIB_OPENCV_INFO_NAME; |
||||
} |
||||
else |
||||
{ |
||||
tmp = install_path + "/" + LIB_OPENCV_INFO_NAME; |
||||
} |
||||
|
||||
LOGD("Trying to load info library \"%s\"", tmp.c_str()); |
||||
|
||||
void* handle; |
||||
InfoFunctionType name_func; |
||||
InfoFunctionType revision_func; |
||||
|
||||
handle = dlopen(tmp.c_str(), RTLD_LAZY); |
||||
if (handle) |
||||
{ |
||||
const char* error; |
||||
|
||||
dlerror(); |
||||
name_func = (InfoFunctionType)dlsym(handle, "GetPackageName"); |
||||
revision_func = (InfoFunctionType)dlsym(handle, "GetRevision"); |
||||
error = dlerror(); |
||||
|
||||
if (!error && revision_func && name_func) |
||||
{ |
||||
FullName = std::string((*name_func)()); |
||||
package_version = std::string((*revision_func)()); |
||||
dlclose(handle); |
||||
LOGI("OpenCV package \"%s\" revision \"%s\" found", FullName.c_str(), package_version.c_str()); |
||||
} |
||||
else |
||||
{ |
||||
LOGE("Library loading error (%p, %p): \"%s\"", name_func, revision_func, error); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LOGI("Info library not found in package"); |
||||
LOGI("OpenCV Manager package does not contain any verison of OpenCV library"); |
||||
Version = 0; |
||||
CpuID = ARCH_UNKNOWN; |
||||
Platform = PLATFORM_UNKNOWN; |
||||
return; |
||||
} |
||||
} |
||||
|
||||
vector<string> features = SplitStringVector(FullName, '_'); |
||||
|
||||
if (!features.empty() && (BasePackageName == features[0])) |
||||
{ |
||||
Version = SplitVersion(features, package_version); |
||||
if (0 == Version) |
||||
{ |
||||
CpuID = ARCH_UNKNOWN; |
||||
Platform = PLATFORM_UNKNOWN; |
||||
return; |
||||
} |
||||
|
||||
Platform = SplitPlatform(features); |
||||
if (PLATFORM_UNKNOWN != Platform) |
||||
{ |
||||
switch (Platform) |
||||
{ |
||||
case PLATFORM_TEGRA2: |
||||
{ |
||||
CpuID = ARCH_ARMv7 | FEATURES_HAS_VFPv3d16; |
||||
} break; |
||||
case PLATFORM_TEGRA3: |
||||
{ |
||||
CpuID = ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON; |
||||
} break; |
||||
case PLATFORM_TEGRA4: |
||||
{ |
||||
CpuID = ARCH_ARMv7 | FEATURES_HAS_VFPv3 | FEATURES_HAS_NEON; |
||||
} break; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if (features.size() < 3) |
||||
{ |
||||
LOGD("It is not OpenCV library package for this platform"); |
||||
Version = 0; |
||||
CpuID = ARCH_UNKNOWN; |
||||
Platform = PLATFORM_UNKNOWN; |
||||
return; |
||||
} |
||||
else if (ARCH_ARMv5_NAME == features[2]) |
||||
{ |
||||
CpuID = ARCH_ARMv5 | SplitARMFeatures(features); |
||||
} |
||||
else if (ARCH_ARMv6_NAME == features[2]) |
||||
{ |
||||
CpuID = ARCH_ARMv6 | SplitARMFeatures(features); |
||||
} |
||||
else if (ARCH_ARMv7_NAME == features[2]) |
||||
{ |
||||
CpuID = ARCH_ARMv7 | SplitARMFeatures(features); |
||||
} |
||||
#ifdef __SUPPORT_AARCH64 |
||||
else if (ARCH_AARCH64_NAME == features[2]) |
||||
{ |
||||
CpuID = ARCH_AARCH64 | SplitARMFeatures(features); |
||||
} |
||||
#endif |
||||
else if (ARCH_X86_NAME == features[2]) |
||||
{ |
||||
CpuID = ARCH_X86 | SplitIntelFeatures(features); |
||||
} |
||||
#ifdef __SUPPORT_INTEL_x64 |
||||
else if (ARCH_X64_NAME == features[2]) |
||||
{ |
||||
CpuID = ARCH_X64 | SplitIntelFeatures(features); |
||||
} |
||||
#endif |
||||
#ifdef __SUPPORT_MIPS |
||||
else if (ARCH_MIPS_NAME == features[2]) |
||||
{ |
||||
CpuID = ARCH_MIPS; |
||||
} |
||||
#endif |
||||
else |
||||
{ |
||||
LOGD("It is not OpenCV library package for this platform"); |
||||
Version = 0; |
||||
CpuID = ARCH_UNKNOWN; |
||||
Platform = PLATFORM_UNKNOWN; |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
LOGD("It is not OpenCV library package for this platform"); |
||||
Version = 0; |
||||
CpuID = ARCH_UNKNOWN; |
||||
Platform = PLATFORM_UNKNOWN; |
||||
return; |
||||
} |
||||
} |
||||
|
||||
bool PackageInfo::IsValid() const |
||||
{ |
||||
return !((0 == Version) && (PLATFORM_UNKNOWN == Platform) && (ARCH_UNKNOWN == CpuID)); |
||||
} |
||||
|
||||
int PackageInfo::GetPlatform() const |
||||
{ |
||||
return Platform; |
||||
} |
||||
|
||||
int PackageInfo::GetCpuID() const |
||||
{ |
||||
return CpuID; |
||||
} |
||||
|
||||
string PackageInfo::GetFullName() const |
||||
{ |
||||
return FullName; |
||||
} |
||||
|
||||
int PackageInfo::GetVersion() const |
||||
{ |
||||
return Version; |
||||
} |
||||
|
||||
string PackageInfo::GetInstalationPath() const |
||||
{ |
||||
return InstallPath; |
||||
} |
||||
|
||||
bool PackageInfo::operator==(const PackageInfo& package) const |
||||
{ |
||||
return (package.FullName == FullName); |
||||
} |
@ -1,55 +0,0 @@ |
||||
#ifndef __PACKAGE_INFO_H__ |
||||
#define __PACKAGE_INFO_H__ |
||||
|
||||
#include <map> |
||||
#include <string> |
||||
|
||||
#define ARCH_X86_NAME "x86" |
||||
#define ARCH_X64_NAME "x64" |
||||
#define ARCH_MIPS_NAME "mips" |
||||
#define ARCH_ARMv5_NAME "armv5" |
||||
#define ARCH_ARMv6_NAME "armv6" |
||||
#define ARCH_ARMv7_NAME "armv7a" |
||||
#define ARCH_AARCH64_NAME "aarch64" |
||||
|
||||
#define FEATURES_HAS_VFPv3d16_NAME "vfpv3d16" |
||||
#define FEATURES_HAS_VFPv3_NAME "vfpv3" |
||||
#define FEATURES_HAS_NEON_NAME "neon" |
||||
#define FEATURES_HAS_NEON2_NAME "neon2" |
||||
#define FEATURES_HAS_SSE_NAME "sse" |
||||
#define FEATURES_HAS_SSE2_NAME "sse2" |
||||
#define FEATURES_HAS_SSSE3_NAME "ssse3" |
||||
#define FEATURES_HAS_GPU_NAME "gpu" |
||||
|
||||
// TODO: Do not forget to update PackageInfo::InitPlatformNameMap() after constant changes
|
||||
#define PLATFORM_TEGRA_NAME "tegra" |
||||
#define PLATFORM_TEGRA2_NAME "tegra2" |
||||
#define PLATFORM_TEGRA3_NAME "tegra3" |
||||
#define PLATFORM_TEGRA4_NAME "tegra4" |
||||
#define PLATFORM_TEGRA5_NAME "tegra5" |
||||
|
||||
class PackageInfo |
||||
{ |
||||
public: |
||||
PackageInfo(int version, int platform, int cpu_id, std::string install_path = "/data/data/"); |
||||
PackageInfo(const std::string& fullname, const std::string& install_path, std::string package_version = "0.0"); |
||||
std::string GetFullName() const; |
||||
int GetVersion() const; |
||||
int GetPlatform() const; |
||||
int GetCpuID() const; |
||||
std::string GetInstalationPath() const; |
||||
bool operator==(const PackageInfo& package) const; |
||||
static const std::map<int, std::string> PlatformNameMap; |
||||
bool IsValid() const; |
||||
|
||||
protected: |
||||
static std::map<int, std::string> InitPlatformNameMap(); |
||||
int Version; |
||||
int Platform; |
||||
int CpuID; |
||||
std::string FullName; |
||||
std::string InstallPath; |
||||
static const std::string BasePackageName; |
||||
}; |
||||
|
||||
#endif |
@ -1,32 +0,0 @@ |
||||
#include "EngineCommon.h" |
||||
#include "IOpenCVEngine.h" |
||||
#include "OpenCVEngine.h" |
||||
#include "IPackageManager.h" |
||||
#include "NativePackageManager.h" |
||||
|
||||
#include <sys/types.h> |
||||
#include <unistd.h> |
||||
#include <grp.h> |
||||
#include <binder/IPCThreadState.h> |
||||
#include <binder/ProcessState.h> |
||||
#include <binder/IServiceManager.h> |
||||
#include <utils/Log.h> |
||||
|
||||
using namespace android; |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
LOGI("OpenCVEngine native service starting"); |
||||
IPackageManager* PackageManager = new NativePackageManager(); |
||||
sp<IBinder> Engine = new OpenCVEngine(PackageManager); |
||||
|
||||
defaultServiceManager()->addService(IOpenCVEngine::descriptor, Engine); |
||||
LOGI("OpenCVEngine native service started successfully"); |
||||
ProcessState::self()->startThreadPool(); |
||||
IPCThreadState::self()->joinThreadPool(); |
||||
LOGI("OpenCVEngine native service finished"); |
||||
|
||||
delete PackageManager; |
||||
|
||||
return 0; |
||||
} |