Merge pull request #4083 from mshabunin:java-engine

This commit is contained in:
Maksim Shabunin
2015-06-03 17:17:36 +00:00
161 changed files with 521 additions and 38215 deletions

View File

@@ -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()

View File

@@ -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)

View File

@@ -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();

View File

@@ -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;

View File

@@ -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.

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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()

View File

@@ -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>

View File

@@ -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}"

View File

@@ -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]} } } }

View File

@@ -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()
{

View File

@@ -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();

View File

@@ -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);
}
}
}

View File

@@ -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.

View File

@@ -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)

View File

@@ -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,

View File

@@ -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.

View File

@@ -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();
}
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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