Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
404 lines
12 KiB
404 lines
12 KiB
#include <dlfcn.h> |
|
#include <android/log.h> |
|
#include <string> |
|
#include <vector> |
|
#include <algorithm> |
|
#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; |
|
} |
|
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(); |
|
string folderPath=getPathLibFolder(); |
|
LOGD("CameraWrapperConnector::connectToLib: folderPath=%s", folderPath.c_str()); |
|
|
|
vector<string> listLibs; |
|
fillListWrapperLibs(folderPath, listLibs); |
|
std::sort(listLibs.begin(), listLibs.end(), std::greater<string>()); |
|
|
|
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); |
|
|
|
const char* libName=dl_info.dli_fname; |
|
while( ((*libName)=='/') || ((*libName)=='.') ) |
|
libName++; |
|
|
|
char lineBuf[2048]; |
|
FILE* file = fopen("/proc/self/smaps", "rt"); |
|
|
|
if(file) |
|
{ |
|
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 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); |
|
}
|
|
|