Merge pull request #4083 from mshabunin:java-engine
This commit is contained in:
@@ -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) {
|
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
@@ -174,8 +174,8 @@ endforeach()
|
||||
file(REMOVE_RECURSE "${probe_dir}")
|
||||
|
||||
if(NOT ANDROID)
|
||||
ocv_list_filterout(handwritten_java_sources "/(engine3|android)\\\\+")
|
||||
ocv_list_filterout(handwritten_aidl_sources "/(engine3|android)\\\\+")
|
||||
ocv_list_filterout(handwritten_java_sources "/(engine|android)\\\\+")
|
||||
ocv_list_filterout(handwritten_aidl_sources "/(engine|android)\\\\+")
|
||||
else()
|
||||
file(GLOB_RECURSE handwrittren_lib_project_files_rel RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/android_lib/" "${CMAKE_CURRENT_SOURCE_DIR}/android_lib/*")
|
||||
list(REMOVE_ITEM handwrittren_lib_project_files_rel "${ANDROID_MANIFEST_FILE}")
|
||||
@@ -277,7 +277,7 @@ endif(ANDROID AND ANDROID_EXECUTABLE)
|
||||
set(step3_depends ${step2_depends} ${step3_input_files} ${copied_files})
|
||||
|
||||
if(ANDROID)
|
||||
set(LIB_NAME_SUFIX "")
|
||||
set(LIB_NAME_SUFIX "${OPENCV_VERSION_MAJOR}")
|
||||
else()
|
||||
set(LIB_NAME_SUFIX "${OPENCV_VERSION_MAJOR}${OPENCV_VERSION_MINOR}${OPENCV_VERSION_PATCH}")
|
||||
endif()
|
||||
@@ -357,6 +357,16 @@ else()
|
||||
ocv_target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS})
|
||||
endif()
|
||||
|
||||
# Additional target properties
|
||||
set_target_properties(${the_module} PROPERTIES
|
||||
OUTPUT_NAME "${the_module}${LIB_NAME_SUFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
INSTALL_NAME_DIR ${OPENCV_LIB_INSTALL_PATH}
|
||||
LINK_INTERFACE_LIBRARIES ""
|
||||
)
|
||||
|
||||
if(ANDROID)
|
||||
ocv_target_link_libraries(${the_module} jnigraphics) # for Mat <=> Bitmap converters
|
||||
|
||||
@@ -369,16 +379,6 @@ if(ANDROID)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Additional target properties
|
||||
set_target_properties(${the_module} PROPERTIES
|
||||
OUTPUT_NAME "${the_module}${LIB_NAME_SUFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
LIBRARY_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
INSTALL_NAME_DIR ${OPENCV_LIB_INSTALL_PATH}
|
||||
LINK_INTERFACE_LIBRARIES ""
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(${the_module} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
||||
endif()
|
||||
|
@@ -25,4 +25,4 @@
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
@@ -43,10 +43,13 @@ add_custom_command(
|
||||
|
||||
list(APPEND opencv_test_java_file_deps ${android_proj_target_files})
|
||||
|
||||
get_target_property(java_location opencv_java LOCATION)
|
||||
get_filename_component(java_name "${java_location}" NAME)
|
||||
|
||||
# build java part
|
||||
add_custom_command(
|
||||
OUTPUT "${opencv_test_java_bin_dir}/bin/OpenCVTest-debug.apk"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${OpenCV_BINARY_DIR}/lib/${ANDROID_NDK_ABI_NAME}/libopencv_java.so" "${opencv_test_java_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/libopencv_java.so"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${java_location}" "${opencv_test_java_bin_dir}/libs/${ANDROID_NDK_ABI_NAME}/${java_name}"
|
||||
COMMAND ${ANT_EXECUTABLE} -q -noinput -k debug
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${opencv_test_java_bin_dir}/bin/OpenCVTest-debug.apk" # needed because ant does not update the timestamp of updated apk
|
||||
WORKING_DIRECTORY "${opencv_test_java_bin_dir}"
|
||||
|
@@ -507,55 +507,6 @@ JNIEXPORT jdoubleArray JNICALL Java_org_opencv_core_Core_n_1minMaxLocManual
|
||||
"moveWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' },
|
||||
"resizeWindow" : {'j_code' : '', 'jn_code' : '', 'cpp_code' : '' },
|
||||
}, # Highgui
|
||||
|
||||
'VideoCapture' :
|
||||
{
|
||||
"getSupportedPreviewSizes" :
|
||||
{
|
||||
'j_code' :
|
||||
"""
|
||||
public java.util.List<org.opencv.core.Size> getSupportedPreviewSizes()
|
||||
{
|
||||
String[] sizes_str = getSupportedPreviewSizes_0(nativeObj).split(",");
|
||||
java.util.List<org.opencv.core.Size> sizes = new java.util.ArrayList<org.opencv.core.Size>(sizes_str.length);
|
||||
|
||||
for (String str : sizes_str) {
|
||||
String[] wh = str.split("x");
|
||||
sizes.add(new org.opencv.core.Size(Double.parseDouble(wh[0]), Double.parseDouble(wh[1])));
|
||||
}
|
||||
|
||||
return sizes;
|
||||
}
|
||||
|
||||
""",
|
||||
'jn_code' :
|
||||
"""\n private static native String getSupportedPreviewSizes_0(long nativeObj);\n""",
|
||||
'cpp_code' :
|
||||
"""
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_videoio_VideoCapture_getSupportedPreviewSizes_10
|
||||
(JNIEnv *env, jclass, jlong self);
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_videoio_VideoCapture_getSupportedPreviewSizes_10
|
||||
(JNIEnv *env, jclass, jlong self)
|
||||
{
|
||||
static const char method_name[] = "videoio::VideoCapture_getSupportedPreviewSizes_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
VideoCapture* me = (VideoCapture*) self; //TODO: check for NULL
|
||||
union {double prop; const char* name;} u;
|
||||
u.prop = me->get(CAP_PROP_ANDROID_PREVIEW_SIZES_STRING);
|
||||
return env->NewStringUTF(u.name);
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return env->NewStringUTF("");
|
||||
}
|
||||
|
||||
""",
|
||||
}, # getSupportedPreviewSizes
|
||||
}, # VideoCapture
|
||||
}
|
||||
|
||||
# { class : { func : { arg_name : {"ctype" : ctype, "attrib" : [attrib]} } } }
|
||||
|
@@ -4,7 +4,7 @@ import java.io.File;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.engine3.OpenCVEngineInterface;
|
||||
import org.opencv.engine.OpenCVEngineInterface;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -21,8 +21,8 @@ class AsyncServiceHelper
|
||||
final LoaderCallbackInterface Callback)
|
||||
{
|
||||
AsyncServiceHelper helper = new AsyncServiceHelper(Version, AppContext, Callback);
|
||||
Intent intent = new Intent("org.opencv.engine3.BIND");
|
||||
intent.setPackage("org.opencv.engine3");
|
||||
Intent intent = new Intent("org.opencv.engine.BIND");
|
||||
intent.setPackage("org.opencv.engine");
|
||||
if (AppContext.bindService(intent, helper.mServiceConnection, Context.BIND_AUTO_CREATE))
|
||||
{
|
||||
return true;
|
||||
@@ -77,7 +77,7 @@ class AsyncServiceHelper
|
||||
private LoaderCallbackInterface mUserAppCallback = Callback;
|
||||
public String getPackageName()
|
||||
{
|
||||
return "OpenCV3 Manager";
|
||||
return "OpenCV Manager";
|
||||
}
|
||||
public void install() {
|
||||
Log.d(TAG, "Trying to install OpenCV Manager via Google Play");
|
||||
@@ -123,7 +123,7 @@ class AsyncServiceHelper
|
||||
private LoaderCallbackInterface mUserAppCallback = Callback;
|
||||
public String getPackageName()
|
||||
{
|
||||
return "OpenCV3 Manager";
|
||||
return "OpenCV Manager";
|
||||
}
|
||||
public void install()
|
||||
{
|
||||
@@ -151,7 +151,7 @@ class AsyncServiceHelper
|
||||
/**
|
||||
* URL of OpenCV Manager page on Google Play Market.
|
||||
*/
|
||||
protected static final String OPEN_CV_SERVICE_URL = "market://details?id=org.opencv.engine3";
|
||||
protected static final String OPEN_CV_SERVICE_URL = "market://details?id=org.opencv.engine";
|
||||
|
||||
protected ServiceConnection mServiceConnection = new ServiceConnection()
|
||||
{
|
||||
|
@@ -46,7 +46,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
||||
protected int mMaxHeight;
|
||||
protected int mMaxWidth;
|
||||
protected float mScale = 0;
|
||||
protected int mPreviewFormat = Videoio.CV_CAP_ANDROID_COLOR_FRAME_RGBA;
|
||||
protected int mPreviewFormat = RGBA;
|
||||
protected int mCameraIndex = CAMERA_ID_ANY;
|
||||
protected boolean mEnabled;
|
||||
protected FpsMeter mFpsMeter = null;
|
||||
@@ -54,6 +54,8 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
||||
public static final int CAMERA_ID_ANY = -1;
|
||||
public static final int CAMERA_ID_BACK = 99;
|
||||
public static final int CAMERA_ID_FRONT = 98;
|
||||
public static final int RGBA = 1;
|
||||
public static final int GRAY = 2;
|
||||
|
||||
public CameraBridgeViewBase(Context context, int cameraId) {
|
||||
super(context);
|
||||
@@ -151,10 +153,10 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
||||
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
|
||||
Mat result = null;
|
||||
switch (mPreviewFormat) {
|
||||
case Videoio.CV_CAP_ANDROID_COLOR_FRAME_RGBA:
|
||||
case RGBA:
|
||||
result = mOldStyleListener.onCameraFrame(inputFrame.rgba());
|
||||
break;
|
||||
case Videoio.CV_CAP_ANDROID_GREY_FRAME:
|
||||
case GRAY:
|
||||
result = mOldStyleListener.onCameraFrame(inputFrame.gray());
|
||||
break;
|
||||
default:
|
||||
@@ -168,7 +170,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
||||
mPreviewFormat = format;
|
||||
}
|
||||
|
||||
private int mPreviewFormat = Videoio.CV_CAP_ANDROID_COLOR_FRAME_RGBA;
|
||||
private int mPreviewFormat = RGBA;
|
||||
private CvCameraViewListener mOldStyleListener;
|
||||
};
|
||||
|
||||
@@ -296,6 +298,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
||||
* Called when mSyncObject lock is held
|
||||
*/
|
||||
private void checkCurrentState() {
|
||||
Log.d(TAG, "call checkCurrentState");
|
||||
int targetState;
|
||||
|
||||
if (mEnabled && mSurfaceExist && getVisibility() == VISIBLE) {
|
||||
@@ -313,6 +316,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
||||
}
|
||||
|
||||
private void processEnterState(int state) {
|
||||
Log.d(TAG, "call processEnterState: " + state);
|
||||
switch(state) {
|
||||
case STARTED:
|
||||
onEnterStartedState();
|
||||
@@ -330,6 +334,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
||||
}
|
||||
|
||||
private void processExitState(int state) {
|
||||
Log.d(TAG, "call processExitState: " + state);
|
||||
switch(state) {
|
||||
case STARTED:
|
||||
onExitStartedState();
|
||||
@@ -351,6 +356,7 @@ public abstract class CameraBridgeViewBase extends SurfaceView implements Surfac
|
||||
// NOTE: The order of bitmap constructor and camera connection is important for android 4.1.x
|
||||
// Bitmap must be constructed before surface
|
||||
private void onEnterStartedState() {
|
||||
Log.d(TAG, "call onEnterStartedState");
|
||||
/* Connect camera */
|
||||
if (!connectCamera(getWidth(), getHeight())) {
|
||||
AlertDialog ad = new AlertDialog.Builder(getContext()).create();
|
||||
|
@@ -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,5 +1,5 @@
|
||||
set(the_description "Media I/O")
|
||||
ocv_add_module(videoio opencv_imgproc opencv_imgcodecs OPTIONAL opencv_androidcamera WRAP java python)
|
||||
ocv_add_module(videoio opencv_imgproc opencv_imgcodecs WRAP java python)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# CMake file for videoio. See root CMakeLists.txt
|
||||
@@ -118,11 +118,6 @@ if(HAVE_OPENNI2)
|
||||
list(APPEND VIDEOIO_LIBRARIES ${OPENNI2_LIBRARY})
|
||||
endif(HAVE_OPENNI2)
|
||||
|
||||
if(HAVE_opencv_androidcamera)
|
||||
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_android.cpp)
|
||||
add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA)#TODO: remove this line
|
||||
endif(HAVE_opencv_androidcamera)
|
||||
|
||||
if(HAVE_XIMEA)
|
||||
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_ximea.cpp)
|
||||
if(XIMEA_PATH)
|
||||
|
@@ -81,7 +81,7 @@ enum { CAP_ANY = 0, // autodetect
|
||||
CAP_PVAPI = 800, // PvAPI, Prosilica GigE SDK
|
||||
CAP_OPENNI = 900, // OpenNI (for Kinect)
|
||||
CAP_OPENNI_ASUS = 910, // OpenNI (for Asus Xtion)
|
||||
CAP_ANDROID = 1000, // Android
|
||||
CAP_ANDROID = 1000, // Android - not used
|
||||
CAP_XIAPI = 1100, // XIMEA Camera API
|
||||
CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API)
|
||||
CAP_GIGANETIX = 1300, // Smartek Giganetix GigEVisionSDK
|
||||
@@ -273,72 +273,6 @@ enum { CAP_PROP_XI_DOWNSAMPLING = 400, // Change image resolution by binning or
|
||||
CAP_PROP_XI_TIMEOUT = 420 // Image capture timeout in milliseconds
|
||||
};
|
||||
|
||||
|
||||
// Properties for Android cameras
|
||||
enum { CAP_PROP_ANDROID_AUTOGRAB = 1024,
|
||||
CAP_PROP_ANDROID_PREVIEW_SIZES_STRING = 1025, // readonly, tricky property, returns const char* indeed
|
||||
CAP_PROP_ANDROID_PREVIEW_FORMAT = 1026, // readonly, tricky property, returns const char* indeed
|
||||
CAP_PROP_ANDROID_FLASH_MODE = 8001,
|
||||
CAP_PROP_ANDROID_FOCUS_MODE = 8002,
|
||||
CAP_PROP_ANDROID_WHITE_BALANCE = 8003,
|
||||
CAP_PROP_ANDROID_ANTIBANDING = 8004,
|
||||
CAP_PROP_ANDROID_FOCAL_LENGTH = 8005,
|
||||
CAP_PROP_ANDROID_FOCUS_DISTANCE_NEAR = 8006,
|
||||
CAP_PROP_ANDROID_FOCUS_DISTANCE_OPTIMAL = 8007,
|
||||
CAP_PROP_ANDROID_FOCUS_DISTANCE_FAR = 8008
|
||||
};
|
||||
|
||||
|
||||
// Android camera output formats
|
||||
enum { CAP_ANDROID_COLOR_FRAME_BGR = 0, //BGR
|
||||
CAP_ANDROID_COLOR_FRAME = CAP_ANDROID_COLOR_FRAME_BGR,
|
||||
CAP_ANDROID_GREY_FRAME = 1, //Y
|
||||
CAP_ANDROID_GRAY_FRAME = CAP_ANDROID_GREY_FRAME,
|
||||
CAP_ANDROID_COLOR_FRAME_RGB = 2,
|
||||
CAP_ANDROID_COLOR_FRAME_BGRA = 3,
|
||||
CAP_ANDROID_COLOR_FRAME_RGBA = 4
|
||||
};
|
||||
|
||||
|
||||
// Android camera flash modes
|
||||
enum { CAP_ANDROID_FLASH_MODE_AUTO = 0,
|
||||
CAP_ANDROID_FLASH_MODE_OFF = 1,
|
||||
CAP_ANDROID_FLASH_MODE_ON = 2,
|
||||
CAP_ANDROID_FLASH_MODE_RED_EYE = 3,
|
||||
CAP_ANDROID_FLASH_MODE_TORCH = 4
|
||||
};
|
||||
|
||||
|
||||
// Android camera focus modes
|
||||
enum { CAP_ANDROID_FOCUS_MODE_AUTO = 0,
|
||||
CAP_ANDROID_FOCUS_MODE_CONTINUOUS_VIDEO = 1,
|
||||
CAP_ANDROID_FOCUS_MODE_EDOF = 2,
|
||||
CAP_ANDROID_FOCUS_MODE_FIXED = 3,
|
||||
CAP_ANDROID_FOCUS_MODE_INFINITY = 4,
|
||||
CAP_ANDROID_FOCUS_MODE_MACRO = 5
|
||||
};
|
||||
|
||||
|
||||
// Android camera white balance modes
|
||||
enum { CAP_ANDROID_WHITE_BALANCE_AUTO = 0,
|
||||
CAP_ANDROID_WHITE_BALANCE_CLOUDY_DAYLIGHT = 1,
|
||||
CAP_ANDROID_WHITE_BALANCE_DAYLIGHT = 2,
|
||||
CAP_ANDROID_WHITE_BALANCE_FLUORESCENT = 3,
|
||||
CAP_ANDROID_WHITE_BALANCE_INCANDESCENT = 4,
|
||||
CAP_ANDROID_WHITE_BALANCE_SHADE = 5,
|
||||
CAP_ANDROID_WHITE_BALANCE_TWILIGHT = 6,
|
||||
CAP_ANDROID_WHITE_BALANCE_WARM_FLUORESCENT = 7
|
||||
};
|
||||
|
||||
|
||||
// Android camera antibanding modes
|
||||
enum { CAP_ANDROID_ANTIBANDING_50HZ = 0,
|
||||
CAP_ANDROID_ANTIBANDING_60HZ = 1,
|
||||
CAP_ANDROID_ANTIBANDING_AUTO = 2,
|
||||
CAP_ANDROID_ANTIBANDING_OFF = 3
|
||||
};
|
||||
|
||||
|
||||
// Properties of cameras available through AVFOUNDATION interface
|
||||
enum { CAP_PROP_IOS_DEVICE_FOCUS = 9001,
|
||||
CAP_PROP_IOS_DEVICE_EXPOSURE = 9002,
|
||||
|
@@ -98,9 +98,9 @@ enum
|
||||
CV_CAP_OPENNI =900, // OpenNI (for Kinect)
|
||||
CV_CAP_OPENNI_ASUS =910, // OpenNI (for Asus Xtion)
|
||||
|
||||
CV_CAP_ANDROID =1000, // Android
|
||||
CV_CAP_ANDROID_BACK =CV_CAP_ANDROID+99, // Android back camera
|
||||
CV_CAP_ANDROID_FRONT =CV_CAP_ANDROID+98, // Android front camera
|
||||
CV_CAP_ANDROID =1000, // Android - not used
|
||||
CV_CAP_ANDROID_BACK =CV_CAP_ANDROID+99, // Android back camera - not used
|
||||
CV_CAP_ANDROID_FRONT =CV_CAP_ANDROID+98, // Android front camera - not used
|
||||
|
||||
CV_CAP_XIAPI =1100, // XIMEA Camera API
|
||||
|
||||
@@ -330,62 +330,6 @@ enum
|
||||
CV_CAP_OPENNI_QVGA_60HZ = 4
|
||||
};
|
||||
|
||||
//supported by Android camera output formats
|
||||
enum
|
||||
{
|
||||
CV_CAP_ANDROID_COLOR_FRAME_BGR = 0, //BGR
|
||||
CV_CAP_ANDROID_COLOR_FRAME = CV_CAP_ANDROID_COLOR_FRAME_BGR,
|
||||
CV_CAP_ANDROID_GREY_FRAME = 1, //Y
|
||||
CV_CAP_ANDROID_GRAY_FRAME = CV_CAP_ANDROID_GREY_FRAME,
|
||||
CV_CAP_ANDROID_COLOR_FRAME_RGB = 2,
|
||||
CV_CAP_ANDROID_COLOR_FRAME_BGRA = 3,
|
||||
CV_CAP_ANDROID_COLOR_FRAME_RGBA = 4
|
||||
};
|
||||
|
||||
// supported Android camera flash modes
|
||||
enum
|
||||
{
|
||||
CV_CAP_ANDROID_FLASH_MODE_AUTO = 0,
|
||||
CV_CAP_ANDROID_FLASH_MODE_OFF,
|
||||
CV_CAP_ANDROID_FLASH_MODE_ON,
|
||||
CV_CAP_ANDROID_FLASH_MODE_RED_EYE,
|
||||
CV_CAP_ANDROID_FLASH_MODE_TORCH
|
||||
};
|
||||
|
||||
// supported Android camera focus modes
|
||||
enum
|
||||
{
|
||||
CV_CAP_ANDROID_FOCUS_MODE_AUTO = 0,
|
||||
CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_PICTURE,
|
||||
CV_CAP_ANDROID_FOCUS_MODE_CONTINUOUS_VIDEO,
|
||||
CV_CAP_ANDROID_FOCUS_MODE_EDOF,
|
||||
CV_CAP_ANDROID_FOCUS_MODE_FIXED,
|
||||
CV_CAP_ANDROID_FOCUS_MODE_INFINITY,
|
||||
CV_CAP_ANDROID_FOCUS_MODE_MACRO
|
||||
};
|
||||
|
||||
// supported Android camera white balance modes
|
||||
enum
|
||||
{
|
||||
CV_CAP_ANDROID_WHITE_BALANCE_AUTO = 0,
|
||||
CV_CAP_ANDROID_WHITE_BALANCE_CLOUDY_DAYLIGHT,
|
||||
CV_CAP_ANDROID_WHITE_BALANCE_DAYLIGHT,
|
||||
CV_CAP_ANDROID_WHITE_BALANCE_FLUORESCENT,
|
||||
CV_CAP_ANDROID_WHITE_BALANCE_INCANDESCENT,
|
||||
CV_CAP_ANDROID_WHITE_BALANCE_SHADE,
|
||||
CV_CAP_ANDROID_WHITE_BALANCE_TWILIGHT,
|
||||
CV_CAP_ANDROID_WHITE_BALANCE_WARM_FLUORESCENT
|
||||
};
|
||||
|
||||
// supported Android camera antibanding modes
|
||||
enum
|
||||
{
|
||||
CV_CAP_ANDROID_ANTIBANDING_50HZ = 0,
|
||||
CV_CAP_ANDROID_ANTIBANDING_60HZ,
|
||||
CV_CAP_ANDROID_ANTIBANDING_AUTO,
|
||||
CV_CAP_ANDROID_ANTIBANDING_OFF
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CV_CAP_INTELPERC_DEPTH_MAP = 0, // Each pixel is a 16-bit integer. The value indicates the distance from an object to the camera's XY plane or the Cartesian depth.
|
||||
|
@@ -24,145 +24,21 @@ public class VideoCaptureTest extends OpenCVTestCase {
|
||||
isOpened = false;
|
||||
}
|
||||
|
||||
public void testGet() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
double frameWidth = capture.get(Videoio.CV_CAP_PROP_FRAME_WIDTH);
|
||||
assertTrue(0 != frameWidth);
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetSupportedPreviewSizes() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
List<Size> sizes = capture.getSupportedPreviewSizes();
|
||||
assertNotNull(sizes);
|
||||
assertFalse(sizes.isEmpty());
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testGrab() {
|
||||
capture = new VideoCapture();
|
||||
isSucceed = capture.grab();
|
||||
assertFalse(isSucceed);
|
||||
}
|
||||
|
||||
public void testGrabFromRealCamera() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
isSucceed = capture.grab();
|
||||
assertTrue(isSucceed);
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testIsOpened() {
|
||||
capture = new VideoCapture();
|
||||
assertFalse(capture.isOpened());
|
||||
}
|
||||
|
||||
public void testIsOpenedRealCamera() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
isOpened = capture.isOpened();
|
||||
assertTrue(isOpened);
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testOpen() {
|
||||
try {
|
||||
capture = new VideoCapture();
|
||||
capture.open(Videoio.CV_CAP_ANDROID);
|
||||
isOpened = capture.isOpened();
|
||||
assertTrue(isOpened);
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testRead() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
isSucceed = capture.read(dst);
|
||||
assertTrue(isSucceed);
|
||||
assertFalse(dst.empty());
|
||||
assertEquals(3, dst.channels());
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testRelease() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
capture.release();
|
||||
assertFalse(capture.isOpened());
|
||||
capture = null;
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testRetrieveMat() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
capture.grab();
|
||||
isSucceed = capture.retrieve(dst);
|
||||
assertTrue(isSucceed);
|
||||
assertFalse(dst.empty());
|
||||
assertEquals(3, dst.channels());
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testRetrieveMatInt() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
capture.grab();
|
||||
isSucceed = capture.retrieve(dst, Videoio.CV_CAP_ANDROID_GREY_FRAME);
|
||||
assertTrue(isSucceed);
|
||||
assertFalse(dst.empty());
|
||||
assertEquals(1, dst.channels());
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testSet() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
capture.set(Videoio.CV_CAP_PROP_FRAME_WIDTH, 640);
|
||||
capture.set(Videoio.CV_CAP_PROP_FRAME_HEIGHT, 480);
|
||||
double frameWidth = capture.get(Videoio.CV_CAP_PROP_FRAME_WIDTH);
|
||||
capture.read(dst);
|
||||
assertEquals(640.0, frameWidth);
|
||||
assertEquals(640, dst.cols());
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
|
||||
public void testVideoCapture() {
|
||||
capture = new VideoCapture();
|
||||
assertNotNull(capture);
|
||||
assertFalse(capture.isOpened());
|
||||
}
|
||||
|
||||
public void testVideoCaptureInt() {
|
||||
try {
|
||||
capture = new VideoCapture(Videoio.CV_CAP_ANDROID);
|
||||
assertNotNull(capture);
|
||||
assertTrue(capture.isOpened());
|
||||
} finally {
|
||||
if (capture != null) capture.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -158,9 +158,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
|
||||
#ifdef HAVE_OPENNI2
|
||||
CV_CAP_OPENNI2,
|
||||
#endif
|
||||
#ifdef HAVE_ANDROID_NATIVE_CAMERA
|
||||
CV_CAP_ANDROID,
|
||||
#endif
|
||||
#ifdef HAVE_XIMEA
|
||||
CV_CAP_XIAPI,
|
||||
#endif
|
||||
@@ -208,7 +205,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
|
||||
defined(HAVE_OPENNI2) || \
|
||||
defined(HAVE_XIMEA) || \
|
||||
defined(HAVE_AVFOUNDATION) || \
|
||||
defined(HAVE_ANDROID_NATIVE_CAMERA) || \
|
||||
defined(HAVE_GIGE_API) || \
|
||||
defined(HAVE_INTELPERC) || \
|
||||
(0)
|
||||
@@ -329,14 +325,6 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ANDROID_NATIVE_CAMERA
|
||||
case CV_CAP_ANDROID:
|
||||
capture = cvCreateCameraCapture_Android (index);
|
||||
if (capture)
|
||||
return capture;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XIMEA
|
||||
case CV_CAP_XIAPI:
|
||||
capture = cvCreateCameraCapture_XIMEA (index);
|
||||
|
@@ -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
|
@@ -39,7 +39,6 @@
|
||||
defined(HAVE_INTELPERC) || \
|
||||
defined(HAVE_GPHOTO2) || \
|
||||
(0)
|
||||
//defined(HAVE_ANDROID_NATIVE_CAMERA) || - enable after #1193
|
||||
# define BUILD_WITH_CAMERA_SUPPORT 1
|
||||
#else
|
||||
# define BUILD_WITH_CAMERA_SUPPORT 0
|
||||
|
Reference in New Issue
Block a user