Added Android native camera module
This commit is contained in:
parent
5cae924a3d
commit
206aa50f86
BIN
3rdparty/lib/libnative_camera_r2.2.2.so
vendored
Normal file
BIN
3rdparty/lib/libnative_camera_r2.2.2.so
vendored
Normal file
Binary file not shown.
BIN
3rdparty/lib/libnative_camera_r2.3.3.so
vendored
Normal file
BIN
3rdparty/lib/libnative_camera_r2.3.3.so
vendored
Normal file
Binary file not shown.
@ -553,19 +553,6 @@ if(WITH_JASPER AND NOT JASPER_FOUND)
|
|||||||
set(JASPER_LIBRARIES libjasper)
|
set(JASPER_LIBRARIES libjasper)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ANDROID)
|
|
||||||
#android camera support
|
|
||||||
set(NativeCamera_DIR "${OpenCV_SOURCE_DIR}/android/native-camera/build")
|
|
||||||
FIND_PACKAGE(NativeCamera QUIET)
|
|
||||||
if(NativeCamera_FOUND)
|
|
||||||
set(HAVE_ANDROID_NATIVE_CAMERA TRUE)
|
|
||||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${NativeCamera_LIBS})
|
|
||||||
else()
|
|
||||||
set(HAVE_ANDROID_NATIVE_CAMERA FALSE)
|
|
||||||
message(STATUS "Could NOT find NativeCamera for Android")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#message(STATUS "Graphic libraries: ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARIES} ${JASPER_LIBRARIES}")
|
#message(STATUS "Graphic libraries: ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARIES} ${JASPER_LIBRARIES}")
|
||||||
|
|
||||||
if(WITH_OPENEXR)
|
if(WITH_OPENEXR)
|
||||||
@ -667,7 +654,7 @@ endif()
|
|||||||
############################### TBB ################################
|
############################### TBB ################################
|
||||||
|
|
||||||
if (WITH_TBB)
|
if (WITH_TBB)
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE AND NOT ANDROID)
|
||||||
PKG_CHECK_MODULES(TBB tbb)
|
PKG_CHECK_MODULES(TBB tbb)
|
||||||
message(STATUS "TBB detected: ${TBBLIB_FOUND}")
|
message(STATUS "TBB detected: ${TBBLIB_FOUND}")
|
||||||
|
|
||||||
@ -682,7 +669,7 @@ if (WITH_TBB)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT HAVE_TBB)
|
if (NOT HAVE_TBB)
|
||||||
set(TBB_DEFAULT_INCLUDE_DIRS "/opt/intel/tbb" "/usr/local/include" "/usr/include" "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB" "C:/Program Files (x86)/TBB")
|
set(TBB_DEFAULT_INCLUDE_DIRS "/opt/intel/tbb" "/usr/local/include" "/usr/include" "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB" "C:/Program Files (x86)/TBB" "${CMAKE_INSTALL_PREFIX}/include")
|
||||||
|
|
||||||
find_path(TBB_INCLUDE_DIR "tbb/tbb.h" PATHS ${TBB_DEFAULT_INCLUDE_DIRS} DOC "The path to TBB headers")
|
find_path(TBB_INCLUDE_DIR "tbb/tbb.h" PATHS ${TBB_DEFAULT_INCLUDE_DIRS} DOC "The path to TBB headers")
|
||||||
if (TBB_INCLUDE_DIR)
|
if (TBB_INCLUDE_DIR)
|
||||||
@ -692,6 +679,9 @@ if (WITH_TBB)
|
|||||||
endif()
|
endif()
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} libtbb.dylib)
|
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} libtbb.dylib)
|
||||||
|
elseif (ANDROID)
|
||||||
|
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbbmalloc tbb)
|
||||||
|
add_definitions(-DTBB_USE_GCC_BUILTINS)
|
||||||
elseif (UNIX)
|
elseif (UNIX)
|
||||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb)
|
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb)
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
@ -1170,10 +1160,6 @@ set(CMAKE_BASE_INCLUDE_DIRS_CONFIGCMAKE "\"${CMAKE_CURRENT_SOURCE_DIR}\"")
|
|||||||
|
|
||||||
set(CMAKE_LIB_DIRS_CONFIGCMAKE "${LIBRARY_OUTPUT_PATH}")
|
set(CMAKE_LIB_DIRS_CONFIGCMAKE "${LIBRARY_OUTPUT_PATH}")
|
||||||
|
|
||||||
if( HAVE_ANDROID_NATIVE_CAMERA )
|
|
||||||
set(CMAKE_LIB_DIRS_CONFIGCMAKE ${CMAKE_LIB_DIRS_CONFIGCMAKE} ${NativeCamera_LIB_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" IMMEDIATE @ONLY)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/OpenCVConfig.cmake.in" "${CMAKE_BINARY_DIR}/OpenCVConfig.cmake" IMMEDIATE @ONLY)
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------------------
|
||||||
@ -1467,7 +1453,7 @@ message(STATUS " V4L/V4L2: ${HAVE_CAMV4L}/${HAVE_CAMV4L2}")
|
|||||||
endif()
|
endif()
|
||||||
message(STATUS " Xine: ${HAVE_XINE}")
|
message(STATUS " Xine: ${HAVE_XINE}")
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
message(STATUS " AndroidNativeCamera: ${HAVE_ANDROID_NATIVE_CAMERA}")
|
message(STATUS " AndroidNativeCamera: build")
|
||||||
endif()
|
endif()
|
||||||
endif() #if(UNIX AND NOT APPLE)
|
endif() #if(UNIX AND NOT APPLE)
|
||||||
|
|
||||||
|
@ -58,6 +58,9 @@ if(NOT ANDROID)
|
|||||||
else()
|
else()
|
||||||
#libraries order is very important because linker from Android NDK is one-pass linker
|
#libraries order is very important because linker from Android NDK is one-pass linker
|
||||||
set(OPENCV_LIB_COMPONENTS opencv_contrib opencv_calib3d opencv_objdetect opencv_features2d opencv_imgproc opencv_video opencv_highgui opencv_ml opencv_legacy opencv_flann opencv_core )
|
set(OPENCV_LIB_COMPONENTS opencv_contrib opencv_calib3d opencv_objdetect opencv_features2d opencv_imgproc opencv_video opencv_highgui opencv_ml opencv_legacy opencv_flann opencv_core )
|
||||||
|
IF (NOT @BUILD_SHARED_LIBS@)
|
||||||
|
set(OPENCV_LIB_COMPONENTS opencv_androidcamera ${OPENCV_LIB_COMPONENTS})
|
||||||
|
ENDIF()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
SET(OpenCV_LIBS "")
|
SET(OpenCV_LIBS "")
|
||||||
@ -114,6 +117,23 @@ IF (NOT @BUILD_SHARED_LIBS@)
|
|||||||
|
|
||||||
ENDIF(NOT @BUILD_SHARED_LIBS@)
|
ENDIF(NOT @BUILD_SHARED_LIBS@)
|
||||||
|
|
||||||
|
# ======================================================
|
||||||
|
# Android camera helper macro
|
||||||
|
# ======================================================
|
||||||
|
IF (ANDROID)
|
||||||
|
macro( COPY_NATIVE_CAMERA_LIBS target )
|
||||||
|
get_target_property(target_location ${target} LOCATION)
|
||||||
|
get_filename_component(target_location "${target_location}" PATH)
|
||||||
|
file(GLOB camera_wrappers "${OpenCV_LIB_DIR}/libnative_camera_r*.so")
|
||||||
|
foreach(wrapper ${camera_wrappers})
|
||||||
|
ADD_CUSTOM_COMMAND(
|
||||||
|
TARGET ${target}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${target_location}"
|
||||||
|
)
|
||||||
|
endforeach()
|
||||||
|
endmacro()
|
||||||
|
ENDIF(ANDROID)
|
||||||
|
|
||||||
# ======================================================
|
# ======================================================
|
||||||
# Version variables:
|
# Version variables:
|
||||||
|
@ -321,7 +321,7 @@ set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags" )
|
|||||||
#-L${LIBCPP_LINK_DIR} -lstdc++ -lsupc++
|
#-L${LIBCPP_LINK_DIR} -lstdc++ -lsupc++
|
||||||
#Also, this is *required* to use the following linker flags that routes around
|
#Also, this is *required* to use the following linker flags that routes around
|
||||||
#a CPU bug in some Cortex-A8 implementations:
|
#a CPU bug in some Cortex-A8 implementations:
|
||||||
set( LINKER_FLAGS "-Wl,--fix-cortex-a8 -L${STL_LIBRARIES_PATH} -lstdc++ -lsupc++ " )
|
set( LINKER_FLAGS "-Wl,--fix-cortex-a8 -L${STL_LIBRARIES_PATH} -L${CMAKE_INSTALL_PREFIX}/lib -lstdc++ -lsupc++ " )
|
||||||
|
|
||||||
set( NO_UNDEFINED ON CACHE BOOL "Don't all undefined symbols" )
|
set( NO_UNDEFINED ON CACHE BOOL "Don't all undefined symbols" )
|
||||||
if( NO_UNDEFINED )
|
if( NO_UNDEFINED )
|
||||||
|
@ -3,6 +3,8 @@ if(ANDROID)
|
|||||||
if(ANDROID_API_LEVEL LESS 8)
|
if(ANDROID_API_LEVEL LESS 8)
|
||||||
ADD_DEFINITIONS(-DGTEST_HAS_CLONE=0)
|
ADD_DEFINITIONS(-DGTEST_HAS_CLONE=0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(androidcamera)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(calib3d)
|
add_subdirectory(calib3d)
|
||||||
|
48
modules/androidcamera/CMakeLists.txt
Normal file
48
modules/androidcamera/CMakeLists.txt
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
IF(NOT ANDROID)
|
||||||
|
MESSAGE( FATAL_ERROR "This project is for ANDROID only" )
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
if (BUILD_ANDROID_CAMERA_WRAPPER)
|
||||||
|
add_subdirectory(camera_wrapper)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
project(opencv_androidcamera)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/camera_wrapper )
|
||||||
|
SET( LIBRARY_DEPS ${LIBRARY_DEPS} log dl )
|
||||||
|
|
||||||
|
SET( the_target opencv_androidcamera )
|
||||||
|
|
||||||
|
ADD_LIBRARY( ${the_target} STATIC src/camera_activity.cpp )
|
||||||
|
|
||||||
|
if (BUILD_SHARED_LIBS)
|
||||||
|
add_definitions(-DCVAPI_EXPORTS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES( ${the_target} ${LIBRARY_DEPS} )
|
||||||
|
|
||||||
|
SET_TARGET_PROPERTIES(${the_target} PROPERTIES
|
||||||
|
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||||
|
OUTPUT_NAME "${the_target}${OPENCV_DLLVERSION}"
|
||||||
|
DEFINE_SYMBOL "CVAPI_EXPORTS"
|
||||||
|
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||||
|
)
|
||||||
|
|
||||||
|
IF (NOT BUILD_SHARED_LIBS)
|
||||||
|
install(TARGETS ${the_target}
|
||||||
|
RUNTIME DESTINATION bin COMPONENT main
|
||||||
|
ARCHIVE DESTINATION lib COMPONENT main
|
||||||
|
LIBRARY DESTINATION lib COMPONENT main
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
file(GLOB camera_wrappers "${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/lib/libnative_camera_r*.so")
|
||||||
|
|
||||||
|
foreach(wrapper ${camera_wrappers})
|
||||||
|
ADD_CUSTOM_COMMAND(
|
||||||
|
TARGET ${the_target}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${wrapper}" "${LIBRARY_OUTPUT_PATH}"
|
||||||
|
)
|
||||||
|
endforeach()
|
398
modules/androidcamera/camera_wrapper/camera_wrapper.cpp
Normal file
398
modules/androidcamera/camera_wrapper/camera_wrapper.cpp
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
#define USE_RECORDING_INSTEAD_PREVIEW 0
|
||||||
|
|
||||||
|
#if !defined(ANDROID_r2_2_2) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1)
|
||||||
|
#error unsupported version of Android
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <camera/CameraHardwareInterface.h>
|
||||||
|
#include "camera_wrapper.h"
|
||||||
|
#include "../camera_wrapper_connector/camera_properties.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace android;
|
||||||
|
|
||||||
|
void debugShowFPS()
|
||||||
|
{
|
||||||
|
static int mFrameCount = 0;
|
||||||
|
static int mLastFrameCount = 0;
|
||||||
|
static nsecs_t mLastFpsTime = systemTime();;
|
||||||
|
static float mFps = 0;
|
||||||
|
|
||||||
|
mFrameCount++;
|
||||||
|
|
||||||
|
if ( ( mFrameCount % 30 ) == 0 ) {
|
||||||
|
nsecs_t now = systemTime();
|
||||||
|
nsecs_t diff = now - mLastFpsTime;
|
||||||
|
if (diff==0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
|
||||||
|
mLastFpsTime = now;
|
||||||
|
mLastFrameCount = mFrameCount;
|
||||||
|
LOGI("####### [%d] Frames, %f FPS", mFrameCount, mFps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CameraHandler: public CameraListener
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
sp<Camera> camera;
|
||||||
|
CameraCallback cameraCallback;
|
||||||
|
CameraParameters params;
|
||||||
|
void* userData;
|
||||||
|
int cameraId;
|
||||||
|
|
||||||
|
bool isEmptyCameraCallbackReported;
|
||||||
|
virtual void doCall(void* buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
if (cameraCallback == 0)
|
||||||
|
{
|
||||||
|
if (!isEmptyCameraCallbackReported)
|
||||||
|
LOGE("Camera callback is empty!");
|
||||||
|
|
||||||
|
isEmptyCameraCallbackReported = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool res = (*cameraCallback)(buffer, bufferSize, userData);
|
||||||
|
|
||||||
|
if(!res) closeCameraConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void doCall(const sp<IMemory>& dataPtr)
|
||||||
|
{
|
||||||
|
LOGI("doCall started");
|
||||||
|
|
||||||
|
if (dataPtr == NULL)
|
||||||
|
{
|
||||||
|
LOGE("CameraBuffer: dataPtr==NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = dataPtr->size();
|
||||||
|
if (size <= 0)
|
||||||
|
{
|
||||||
|
LOGE("CameraBuffer: IMemory object is of zero size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* buffer = (unsigned char *)dataPtr->pointer();
|
||||||
|
if (!buffer)
|
||||||
|
{
|
||||||
|
LOGE("CameraBuffer: Buffer pointer is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
doCall(buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
CameraHandler(CameraCallback callback = 0, void* _userData = 0):cameraCallback(callback), userData(_userData), cameraId(0), isEmptyCameraCallbackReported(false) {}
|
||||||
|
virtual ~CameraHandler()
|
||||||
|
{
|
||||||
|
LOGW("CameraHandler destructor is called!");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2)
|
||||||
|
{
|
||||||
|
LOGE("Notify cb: %d %d %d\n", msgType, ext1, ext2);
|
||||||
|
#if 0
|
||||||
|
if ( msgType & CAMERA_MSG_FOCUS )
|
||||||
|
LOGE("AutoFocus %s in %llu us\n", (ext1) ? "OK" : "FAIL", timevalDelay(&autofocus_start));
|
||||||
|
|
||||||
|
if ( msgType & CAMERA_MSG_SHUTTER )
|
||||||
|
LOGE("Shutter done in %llu us\n", timeval_delay(&picture_start));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr)
|
||||||
|
{
|
||||||
|
debugShowFPS();
|
||||||
|
|
||||||
|
if ( msgType & CAMERA_MSG_PREVIEW_FRAME )
|
||||||
|
{
|
||||||
|
doCall(dataPtr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msgType != CAMERA_MSG_PREVIEW_FRAME)
|
||||||
|
LOGE("Recieved not CAMERA_MSG_PREVIEW_FRAME message %d", (int) msgType);
|
||||||
|
|
||||||
|
if ( msgType & CAMERA_MSG_RAW_IMAGE )
|
||||||
|
LOGE("Unexpected data format: RAW\n");
|
||||||
|
|
||||||
|
if (msgType & CAMERA_MSG_POSTVIEW_FRAME)
|
||||||
|
LOGE("Unexpected data format: Postview frame\n");
|
||||||
|
|
||||||
|
if (msgType & CAMERA_MSG_COMPRESSED_IMAGE )
|
||||||
|
LOGE("Unexpected data format: JPEG");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
|
||||||
|
{
|
||||||
|
static uint32_t count = 0;
|
||||||
|
count++;
|
||||||
|
|
||||||
|
LOGE("Recording cb: %d %lld %%p Offset:%%d Stride:%%d\n", msgType, timestamp);
|
||||||
|
|
||||||
|
if (dataPtr == NULL)
|
||||||
|
{
|
||||||
|
LOGE("postDataTimestamp: dataPtr IS ZERO -- returning");
|
||||||
|
camera->releaseRecordingFrame(dataPtr);
|
||||||
|
LOGE("postDataTimestamp: camera->releaseRecordingFrame(dataPtr) is done");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *ptr = (uint8_t*) dataPtr->pointer();
|
||||||
|
if (ptr)
|
||||||
|
LOGE("VID_CB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], ptr[8], ptr[9]);
|
||||||
|
else
|
||||||
|
LOGE("postDataTimestamp: Ptr is zero");
|
||||||
|
|
||||||
|
camera->releaseRecordingFrame(dataPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CameraHandler* initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters);
|
||||||
|
void closeCameraConnect();
|
||||||
|
double getProperty(int propIdx);
|
||||||
|
void setProperty(int propIdx, double value);
|
||||||
|
static void applyProperties(CameraHandler** ppcameraHandler);
|
||||||
|
|
||||||
|
std::string cameraPropertySupportedPreviewSizesString;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters)
|
||||||
|
{
|
||||||
|
// if (camera != NULL)
|
||||||
|
// {
|
||||||
|
// LOGE("initCameraConnect: camera have been connected already");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
sp<Camera> camera = 0;
|
||||||
|
|
||||||
|
#ifdef ANDROID_r2_2_2
|
||||||
|
camera = Camera::connect();
|
||||||
|
#endif
|
||||||
|
#ifdef ANDROID_r2_3_3
|
||||||
|
camera = Camera::connect(cameraId);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( NULL == camera.get() )
|
||||||
|
{
|
||||||
|
LOGE("initCameraConnect: Unable to connect to CameraService\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraHandler* handler = new CameraHandler(callback, userData);
|
||||||
|
camera->setListener(handler);
|
||||||
|
|
||||||
|
handler->camera = camera;
|
||||||
|
handler->cameraId=cameraId;
|
||||||
|
#if 1
|
||||||
|
//setting paramers from previous camera handler
|
||||||
|
if (prevCameraParameters != NULL) {
|
||||||
|
camera->setParameters(prevCameraParameters->flatten());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
handler->params.unflatten(camera->getParameters());
|
||||||
|
|
||||||
|
|
||||||
|
LOGD("Supported Cameras: %s", handler->params.get("camera-indexes"));
|
||||||
|
LOGD("Supported Picture Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES));
|
||||||
|
LOGD("Supported Picture Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
|
||||||
|
LOGD("Supported Preview Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES));
|
||||||
|
LOGD("Supported Preview Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS));
|
||||||
|
LOGD("Supported Preview Frame Rates: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
|
||||||
|
LOGD("Supported Thumbnail Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES));
|
||||||
|
LOGD("Supported Whitebalance Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE));
|
||||||
|
LOGD("Supported Effects: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_EFFECTS));
|
||||||
|
LOGD("Supported Scene Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES));
|
||||||
|
LOGD("Supported Focus Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
|
||||||
|
LOGD("Supported Antibanding Options: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING));
|
||||||
|
LOGD("Supported Flash Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES));
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: check if yuv420i format available. Set this format as preview format.
|
||||||
|
|
||||||
|
#if USE_RECORDING_INSTEAD_PREVIEW
|
||||||
|
status_t err = camera->setPreviewDisplay(sp<ISurface>(NULL /*new DummySurface1*/));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////ATTENTION: switching between two versions: with and without copying memory inside Android OS
|
||||||
|
//// see the method CameraService::Client::copyFrameAndPostCopiedFrame and where it is used
|
||||||
|
#if 1
|
||||||
|
camera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK | FRAME_CALLBACK_FLAG_COPY_OUT_MASK);//with copy
|
||||||
|
#else
|
||||||
|
camera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK );//without copy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_RECORDING_INSTEAD_PREVIEW
|
||||||
|
status_t resStart = camera->startRecording();
|
||||||
|
#else
|
||||||
|
status_t resStart = camera->startPreview();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (resStart != 0)
|
||||||
|
{
|
||||||
|
handler->closeCameraConnect();
|
||||||
|
handler = 0;
|
||||||
|
}
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraHandler::closeCameraConnect()
|
||||||
|
{
|
||||||
|
if (camera == NULL)
|
||||||
|
{
|
||||||
|
LOGI("... camera is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: ATTENTION! should we do it ALWAYS???
|
||||||
|
#if USE_RECORDING_INSTEAD_PREVIEW
|
||||||
|
camera->stopRecording();
|
||||||
|
#else
|
||||||
|
camera->stopPreview();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
camera->disconnect();
|
||||||
|
camera.clear();
|
||||||
|
|
||||||
|
camera=NULL;
|
||||||
|
// ATTENTION!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
// When we set
|
||||||
|
// camera=NULL
|
||||||
|
// above, the pointed instance of android::Camera object is destructed,
|
||||||
|
// since this member `camera' has type android::sp<Camera> (android smart pointer template class),
|
||||||
|
// and this is the only pointer to it.
|
||||||
|
//
|
||||||
|
// BUT this instance of CameraHandler is set as a listener for that android::Camera object
|
||||||
|
// (see the function CameraHandler::initCameraConnect above),
|
||||||
|
// so this instance of CameraHandler is pointed from that android::Camera object as
|
||||||
|
// sp<CameraListener> mListener
|
||||||
|
// and there is no other android smart pointers to this.
|
||||||
|
//
|
||||||
|
// It means, when that instance of the android::Camera object is destructed,
|
||||||
|
// it calls destructor for this CameraHandler instance too.
|
||||||
|
//
|
||||||
|
// So, this line `camera=NULL' causes to the call `delete this'
|
||||||
|
// (see destructor of the template class android::sp)
|
||||||
|
//
|
||||||
|
// So, we must not call `delete this' after the line, since it just has been called indeed
|
||||||
|
}
|
||||||
|
|
||||||
|
double CameraHandler::getProperty(int propIdx)
|
||||||
|
{
|
||||||
|
switch (propIdx)
|
||||||
|
{
|
||||||
|
case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
|
||||||
|
{
|
||||||
|
int w,h;
|
||||||
|
params.getPreviewSize(&w,&h);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
|
||||||
|
{
|
||||||
|
int w,h;
|
||||||
|
params.getPreviewSize(&w,&h);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
case ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING:
|
||||||
|
{
|
||||||
|
cameraPropertySupportedPreviewSizesString=params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
|
||||||
|
double res;
|
||||||
|
memset(&res, 0, sizeof(res));
|
||||||
|
(*( (void**)&res ))= (void*)( cameraPropertySupportedPreviewSizesString.c_str() );
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraHandler::setProperty(int propIdx, double value)
|
||||||
|
{
|
||||||
|
switch (propIdx)
|
||||||
|
{
|
||||||
|
case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
|
||||||
|
{
|
||||||
|
int w,h;
|
||||||
|
params.getPreviewSize(&w,&h);
|
||||||
|
w = (int)value;
|
||||||
|
params.setPreviewSize(w,h);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
|
||||||
|
{
|
||||||
|
int w,h;
|
||||||
|
params.getPreviewSize(&w,&h);
|
||||||
|
h = (int)value;
|
||||||
|
params.setPreviewSize(w,h);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
|
||||||
|
{
|
||||||
|
LOGD("CameraHandler::applyProperties()");
|
||||||
|
CameraHandler* previousCameraHandler=*ppcameraHandler;
|
||||||
|
CameraParameters curCameraParameters(previousCameraHandler->params.flatten());
|
||||||
|
|
||||||
|
CameraCallback cameraCallback=previousCameraHandler->cameraCallback;
|
||||||
|
void* userData=previousCameraHandler->userData;
|
||||||
|
int cameraId=previousCameraHandler->cameraId;
|
||||||
|
|
||||||
|
LOGD("CameraHandler::applyProperties(): before previousCameraHandler->closeCameraConnect");
|
||||||
|
previousCameraHandler->closeCameraConnect();
|
||||||
|
LOGD("CameraHandler::applyProperties(): after previousCameraHandler->closeCameraConnect");
|
||||||
|
|
||||||
|
|
||||||
|
LOGD("CameraHandler::applyProperties(): before initCameraConnect");
|
||||||
|
CameraHandler* handler=initCameraConnect(cameraCallback, cameraId, userData, &curCameraParameters);
|
||||||
|
LOGD("CameraHandler::applyProperties(): after initCameraConnect, handler=0x%x", (int)handler);
|
||||||
|
if (handler == NULL) {
|
||||||
|
LOGE("ERROR in applyProperties --- cannot reinit camera");
|
||||||
|
handler=initCameraConnect(cameraCallback, cameraId, userData, NULL);
|
||||||
|
LOGD("CameraHandler::applyProperties(): repeate initCameraConnect after ERROR, handler=0x%x", (int)handler);
|
||||||
|
if (handler == NULL) {
|
||||||
|
LOGE("ERROR in applyProperties --- cannot reinit camera AGAIN --- cannot do anything else");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*ppcameraHandler)=handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void* initCameraConnectC(void* callback, int cameraId, void* userData)
|
||||||
|
{
|
||||||
|
return CameraHandler::initCameraConnect((CameraCallback)callback, cameraId, userData, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void closeCameraConnectC(void** camera)
|
||||||
|
{
|
||||||
|
CameraHandler** cc = (CameraHandler**)camera;
|
||||||
|
(*cc)->closeCameraConnect();
|
||||||
|
*cc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getCameraPropertyC(void* camera, int propIdx)
|
||||||
|
{
|
||||||
|
return ((CameraHandler*)camera)->getProperty(propIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCameraPropertyC(void* camera, int propIdx, double value)
|
||||||
|
{
|
||||||
|
((CameraHandler*)camera)->setProperty(propIdx,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyCameraPropertiesC(void** camera)
|
||||||
|
{
|
||||||
|
CameraHandler::applyProperties((CameraHandler**)camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
modules/androidcamera/camera_wrapper/camera_wrapper.h
Normal file
24
modules/androidcamera/camera_wrapper/camera_wrapper.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
enum CameraWrapperErrorCode {
|
||||||
|
ERROR_NATIVE_CAMERA_WRAPPER_NOERROR = 0,
|
||||||
|
ERROR_NATIVE_CAMERA_WRAPPER_CANNOT_FIND_CLASS = 1,
|
||||||
|
ERROR_NATIVE_CAMERA_WRAPPER_CANNOT_FIND_FIELD = 2,
|
||||||
|
ERROR_NATIVE_CAMERA_WRAPPER_CANNOT_SET_PREVIEW_DISPLAY = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
48
modules/androidcamera/include/camera_activity.hpp
Normal file
48
modules/androidcamera/include/camera_activity.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#ifndef _CAMERAACTIVITY_H_
|
||||||
|
#define _CAMERAACTIVITY_H_
|
||||||
|
|
||||||
|
#include <camera_properties.h>
|
||||||
|
//#include <opencv2/core/core.hpp>
|
||||||
|
|
||||||
|
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
|
10
modules/androidcamera/include/camera_properties.h
Normal file
10
modules/androidcamera/include/camera_properties.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CAMERA_PROPERTIES_H
|
||||||
|
#define CAMERA_PROPERTIES_H
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ANDROID_CAMERA_PROPERTY_FRAMEWIDTH = 0,
|
||||||
|
ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT = 1,
|
||||||
|
ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CAMERA_PROPERTIES_H
|
405
modules/androidcamera/src/camera_activity.cpp
Normal file
405
modules/androidcamera/src/camera_activity.cpp
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
#include <dlfcn.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "camera_activity.hpp"
|
||||||
|
#include "camera_wrapper.h"
|
||||||
|
|
||||||
|
#define LOG_TAG "CAMERA_ACTIVITY"
|
||||||
|
#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__))
|
||||||
|
|
||||||
|
///////
|
||||||
|
// Debug
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
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 std::string& path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string pathLibFolder;
|
||||||
|
static bool isConnectedToLib;
|
||||||
|
|
||||||
|
static std::string getPathLibFolder();
|
||||||
|
static CameraActivity::ErrorCode connectToLib();
|
||||||
|
static CameraActivity::ErrorCode getSymbolFromLib(void * libHandle, const char* symbolName, void** ppSymbol);
|
||||||
|
static void fillListWrapperLibs(const string& folderPath, vector<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);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string CameraWrapperConnector::pathLibFolder;
|
||||||
|
#define DEFAULT_WRAPPER_PACKAGE_NAME "com.NativeCamera"
|
||||||
|
#define DEFAULT_PATH_LIB_FOLDER "/data/data/" DEFAULT_WRAPPER_PACKAGE_NAME "/lib/"
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
*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();
|
||||||
|
string folderPath=getPathLibFolder();
|
||||||
|
LOGD("CameraWrapperConnector::connectToLib: folderPath=%s", folderPath.c_str());
|
||||||
|
|
||||||
|
vector<string> listLibs;
|
||||||
|
fillListWrapperLibs(folderPath, listLibs);
|
||||||
|
|
||||||
|
void * libHandle=0;
|
||||||
|
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 string& folderPath, vector<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::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);
|
||||||
|
|
||||||
|
char addrBuf[18];
|
||||||
|
sprintf(addrBuf, "%x-", dl_info.dli_fbase);
|
||||||
|
int addrLength = strlen(addrBuf);
|
||||||
|
|
||||||
|
char lineBuf[2048];
|
||||||
|
FILE* file = fopen("/proc/self/smaps", "rt");
|
||||||
|
|
||||||
|
if(file)
|
||||||
|
{
|
||||||
|
while (fgets(lineBuf, sizeof lineBuf, file) != NULL)
|
||||||
|
{
|
||||||
|
if(0 == strncmp(lineBuf, addrBuf, addrLength))
|
||||||
|
{
|
||||||
|
//verify that line ends with library name
|
||||||
|
int lineLength = strlen(lineBuf);
|
||||||
|
int libNameLength = strlen(dl_info.dli_fname);
|
||||||
|
|
||||||
|
//trim end
|
||||||
|
for(int i = lineLength - 1; i >= 0 && isspace(lineBuf[i]); --i)
|
||||||
|
{
|
||||||
|
lineBuf[i] = 0;
|
||||||
|
--lineLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != strncmp(lineBuf + lineLength - libNameLength, dl_info.dli_fname, libNameLength))
|
||||||
|
{
|
||||||
|
LOGE("Strange error: line \"%s\" does not ends with library name %s", lineBuf, dl_info.dli_fname);
|
||||||
|
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 DEFAULT_PATH_LIB_FOLDER ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraWrapperConnector::setPathLibFolder(const 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
@ -211,9 +211,11 @@ if(APPLE)
|
|||||||
endif()
|
endif()
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
if(HAVE_ANDROID_NATIVE_CAMERA)
|
if(ANDROID)
|
||||||
|
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../androidcamera/include")
|
||||||
set(highgui_srcs ${highgui_srcs} src/cap_android.cpp)
|
set(highgui_srcs ${highgui_srcs} src/cap_android.cpp)
|
||||||
add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA)
|
add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA)
|
||||||
|
set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} opencv_androidcamera)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(COMMAND get_module_external_sources)
|
if(COMMAND get_module_external_sources)
|
||||||
@ -331,6 +333,10 @@ if(NOT ZLIB_FOUND)
|
|||||||
add_dependencies(${the_target} zlib)
|
add_dependencies(${the_target} zlib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ANDROID)
|
||||||
|
add_dependencies(${the_target} opencv_androidcamera)
|
||||||
|
endif()
|
||||||
|
|
||||||
#message(STATUS "GRFMT: ${GRFMT_LIBS}")
|
#message(STATUS "GRFMT: ${GRFMT_LIBS}")
|
||||||
#message(STATUS "HIGHGUI_LIBS: ${HIGHGUI_LIBRARIES}")
|
#message(STATUS "HIGHGUI_LIBS: ${HIGHGUI_LIBRARIES}")
|
||||||
#message(STATUS "OPENCV_LIBS: ${OPENCV_LINKER_LIBS}")
|
#message(STATUS "OPENCV_LIBS: ${OPENCV_LINKER_LIBS}")
|
||||||
@ -371,6 +377,9 @@ if(BUILD_TESTS)
|
|||||||
"${CMAKE_CURRENT_BINARY_DIR}")
|
"${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
||||||
set(test_deps opencv_ts opencv_highgui opencv_imgproc)
|
set(test_deps opencv_ts opencv_highgui opencv_imgproc)
|
||||||
|
if(ANDROID)
|
||||||
|
set(test_deps ${test_deps} opencv_androidcamera)
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(d ${test_deps})
|
foreach(d ${test_deps})
|
||||||
if(${d} MATCHES "opencv_")
|
if(${d} MATCHES "opencv_")
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#include <opencv2/imgproc/imgproc.hpp>
|
#include <opencv2/imgproc/imgproc.hpp>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include "camera_activity.h"
|
#include <camera_activity.hpp>
|
||||||
|
|
||||||
#if !defined(LOGD) && !defined(LOGI) && !defined(LOGE)
|
#if !defined(LOGD) && !defined(LOGI) && !defined(LOGE)
|
||||||
#define LOG_TAG "CV_CAP"
|
#define LOG_TAG "CV_CAP"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user