From 206aa50f86b4d8272d66fd167545d518a7c63835 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 16 Jun 2011 18:00:41 +0000 Subject: [PATCH] Added Android native camera module --- 3rdparty/lib/libnative_camera_r2.2.2.so | Bin 0 -> 126644 bytes 3rdparty/lib/libnative_camera_r2.3.3.so | Bin 0 -> 126708 bytes CMakeLists.txt | 26 +- OpenCVConfig.cmake.in | 20 + android/android.toolchain.cmake | 2 +- modules/CMakeLists.txt | 2 + modules/androidcamera/CMakeLists.txt | 48 +++ .../camera_wrapper/camera_wrapper.cpp | 398 +++++++++++++++++ .../camera_wrapper/camera_wrapper.h | 24 ++ .../androidcamera/include/camera_activity.hpp | 48 +++ .../androidcamera/include/camera_properties.h | 10 + modules/androidcamera/src/camera_activity.cpp | 405 ++++++++++++++++++ modules/highgui/CMakeLists.txt | 11 +- modules/highgui/src/cap_android.cpp | 2 +- 14 files changed, 973 insertions(+), 23 deletions(-) create mode 100644 3rdparty/lib/libnative_camera_r2.2.2.so create mode 100644 3rdparty/lib/libnative_camera_r2.3.3.so create mode 100644 modules/androidcamera/CMakeLists.txt create mode 100644 modules/androidcamera/camera_wrapper/camera_wrapper.cpp create mode 100644 modules/androidcamera/camera_wrapper/camera_wrapper.h create mode 100644 modules/androidcamera/include/camera_activity.hpp create mode 100644 modules/androidcamera/include/camera_properties.h create mode 100644 modules/androidcamera/src/camera_activity.cpp diff --git a/3rdparty/lib/libnative_camera_r2.2.2.so b/3rdparty/lib/libnative_camera_r2.2.2.so new file mode 100644 index 0000000000000000000000000000000000000000..0866e4348ada39fc29a54df65c8d4c66c91278a1 GIT binary patch literal 126644 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 pPrHbhN`=IwX6g>V{t)*k9QBx9l{|~BPaP0s9 literal 0 HcmV?d00001 diff --git a/3rdparty/lib/libnative_camera_r2.3.3.so b/3rdparty/lib/libnative_camera_r2.3.3.so new file mode 100644 index 0000000000000000000000000000000000000000..54e6c09b26bd3f100e2d1a2cede133a5371acdc6 GIT binary patch literal 126708 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 RX>HT8mSaDBMN{H<{~y}rs=xpM literal 0 HcmV?d00001 diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b2647bc8f..282ece7f84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -553,19 +553,6 @@ if(WITH_JASPER AND NOT JASPER_FOUND) set(JASPER_LIBRARIES libjasper) 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}") if(WITH_OPENEXR) @@ -667,7 +654,7 @@ endif() ############################### TBB ################################ if (WITH_TBB) - if (UNIX AND NOT APPLE) + if (UNIX AND NOT APPLE AND NOT ANDROID) PKG_CHECK_MODULES(TBB tbb) message(STATUS "TBB detected: ${TBBLIB_FOUND}") @@ -682,7 +669,7 @@ if (WITH_TBB) endif() 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") if (TBB_INCLUDE_DIR) @@ -692,6 +679,9 @@ if (WITH_TBB) endif() if (APPLE) 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) set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} tbb) elseif (WIN32) @@ -1170,10 +1160,6 @@ set(CMAKE_BASE_INCLUDE_DIRS_CONFIGCMAKE "\"${CMAKE_CURRENT_SOURCE_DIR}\"") 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) # -------------------------------------------------------------------------------------------- @@ -1467,7 +1453,7 @@ message(STATUS " V4L/V4L2: ${HAVE_CAMV4L}/${HAVE_CAMV4L2}") endif() message(STATUS " Xine: ${HAVE_XINE}") if(ANDROID) -message(STATUS " AndroidNativeCamera: ${HAVE_ANDROID_NATIVE_CAMERA}") +message(STATUS " AndroidNativeCamera: build") endif() endif() #if(UNIX AND NOT APPLE) diff --git a/OpenCVConfig.cmake.in b/OpenCVConfig.cmake.in index 5864419afa..cac601b139 100644 --- a/OpenCVConfig.cmake.in +++ b/OpenCVConfig.cmake.in @@ -58,6 +58,9 @@ if(NOT ANDROID) else() #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 ) + IF (NOT @BUILD_SHARED_LIBS@) + set(OPENCV_LIB_COMPONENTS opencv_androidcamera ${OPENCV_LIB_COMPONENTS}) + ENDIF() endif() SET(OpenCV_LIBS "") @@ -114,6 +117,23 @@ IF (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: diff --git a/android/android.toolchain.cmake b/android/android.toolchain.cmake index ba540e1d4f..912c1bf8d8 100644 --- a/android/android.toolchain.cmake +++ b/android/android.toolchain.cmake @@ -321,7 +321,7 @@ set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags" ) #-L${LIBCPP_LINK_DIR} -lstdc++ -lsupc++ #Also, this is *required* to use the following linker flags that routes around #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" ) if( NO_UNDEFINED ) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 87bd90171c..77bb7d1a82 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -3,6 +3,8 @@ if(ANDROID) if(ANDROID_API_LEVEL LESS 8) ADD_DEFINITIONS(-DGTEST_HAS_CLONE=0) endif() + + add_subdirectory(androidcamera) endif() add_subdirectory(calib3d) diff --git a/modules/androidcamera/CMakeLists.txt b/modules/androidcamera/CMakeLists.txt new file mode 100644 index 0000000000..751bbecace --- /dev/null +++ b/modules/androidcamera/CMakeLists.txt @@ -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() \ No newline at end of file diff --git a/modules/androidcamera/camera_wrapper/camera_wrapper.cpp b/modules/androidcamera/camera_wrapper/camera_wrapper.cpp new file mode 100644 index 0000000000..2071d6e327 --- /dev/null +++ b/modules/androidcamera/camera_wrapper/camera_wrapper.cpp @@ -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 +#include "camera_wrapper.h" +#include "../camera_wrapper_connector/camera_properties.h" +#include + +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; + 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& 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& 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& 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 = 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(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 (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 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); +} + +} diff --git a/modules/androidcamera/camera_wrapper/camera_wrapper.h b/modules/androidcamera/camera_wrapper/camera_wrapper.h new file mode 100644 index 0000000000..f1ae6bda62 --- /dev/null +++ b/modules/androidcamera/camera_wrapper/camera_wrapper.h @@ -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); +} + diff --git a/modules/androidcamera/include/camera_activity.hpp b/modules/androidcamera/include/camera_activity.hpp new file mode 100644 index 0000000000..76a63b06ec --- /dev/null +++ b/modules/androidcamera/include/camera_activity.hpp @@ -0,0 +1,48 @@ +#ifndef _CAMERAACTIVITY_H_ +#define _CAMERAACTIVITY_H_ + +#include +//#include + +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 \ No newline at end of file diff --git a/modules/androidcamera/include/camera_properties.h b/modules/androidcamera/include/camera_properties.h new file mode 100644 index 0000000000..42202e3696 --- /dev/null +++ b/modules/androidcamera/include/camera_properties.h @@ -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 diff --git a/modules/androidcamera/src/camera_activity.cpp b/modules/androidcamera/src/camera_activity.cpp new file mode 100644 index 0000000000..ca612b354b --- /dev/null +++ b/modules/androidcamera/src/camera_activity.cpp @@ -0,0 +1,405 @@ +#include +#include +#include +#include +#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 +#include +#include + + +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& 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 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& 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); +} diff --git a/modules/highgui/CMakeLists.txt b/modules/highgui/CMakeLists.txt index cf654953b0..a1469aa93a 100644 --- a/modules/highgui/CMakeLists.txt +++ b/modules/highgui/CMakeLists.txt @@ -211,9 +211,11 @@ if(APPLE) endif() 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) add_definitions(-DHAVE_ANDROID_NATIVE_CAMERA) + set(HIGHGUI_LIBRARIES ${HIGHGUI_LIBRARIES} opencv_androidcamera) endif() if(COMMAND get_module_external_sources) @@ -331,6 +333,10 @@ if(NOT ZLIB_FOUND) add_dependencies(${the_target} zlib) endif() +if(ANDROID) + add_dependencies(${the_target} opencv_androidcamera) +endif() + #message(STATUS "GRFMT: ${GRFMT_LIBS}") #message(STATUS "HIGHGUI_LIBS: ${HIGHGUI_LIBRARIES}") #message(STATUS "OPENCV_LIBS: ${OPENCV_LINKER_LIBS}") @@ -371,6 +377,9 @@ if(BUILD_TESTS) "${CMAKE_CURRENT_BINARY_DIR}") set(test_deps opencv_ts opencv_highgui opencv_imgproc) + if(ANDROID) + set(test_deps ${test_deps} opencv_androidcamera) + endif() foreach(d ${test_deps}) if(${d} MATCHES "opencv_") diff --git a/modules/highgui/src/cap_android.cpp b/modules/highgui/src/cap_android.cpp index 26fe28e919..8aabf67b60 100644 --- a/modules/highgui/src/cap_android.cpp +++ b/modules/highgui/src/cap_android.cpp @@ -46,7 +46,7 @@ #include #include #include -#include "camera_activity.h" +#include #if !defined(LOGD) && !defined(LOGI) && !defined(LOGE) #define LOG_TAG "CV_CAP"