5 #include <android/log.h>
10 #include <opencv2/core/version.hpp>
11 #include "camera_activity.hpp"
12 #include "camera_wrapper.h"
13 #include "EngineCommon.h"
20 #define LOG_TAG "OpenCV::camera"
21 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
22 #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
23 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
28 #include <sys/types.h>
34 class CameraWrapperConnector
37 static CameraActivity::ErrorCode connect(int cameraId, CameraActivity* pCameraActivity, void** camera);
38 static CameraActivity::ErrorCode disconnect(void** camera);
39 static CameraActivity::ErrorCode setProperty(void* camera, int propIdx, double value);
40 static CameraActivity::ErrorCode getProperty(void* camera, int propIdx, double* value);
41 static CameraActivity::ErrorCode applyProperties(void** ppcamera);
43 static void setPathLibFolder(const std::string& path);
46 static std::string pathLibFolder;
47 static bool isConnectedToLib;
49 static std::string getPathLibFolder();
50 static std::string getDefaultPathLibFolder();
51 static CameraActivity::ErrorCode connectToLib();
52 static CameraActivity::ErrorCode getSymbolFromLib(void * libHandle, const char* symbolName, void** ppSymbol);
53 static void fillListWrapperLibs(const string& folderPath, vector<string>& listLibs);
55 static InitCameraConnectC pInitCameraC;
56 static CloseCameraConnectC pCloseCameraC;
57 static GetCameraPropertyC pGetPropertyC;
58 static SetCameraPropertyC pSetPropertyC;
59 static ApplyCameraPropertiesC pApplyPropertiesC;
61 friend bool nextFrame(void* buffer, size_t bufferSize, void* userData);
64 std::string CameraWrapperConnector::pathLibFolder;
66 bool CameraWrapperConnector::isConnectedToLib = false;
67 InitCameraConnectC CameraWrapperConnector::pInitCameraC = 0;
68 CloseCameraConnectC CameraWrapperConnector::pCloseCameraC = 0;
69 GetCameraPropertyC CameraWrapperConnector::pGetPropertyC = 0;
70 SetCameraPropertyC CameraWrapperConnector::pSetPropertyC = 0;
71 ApplyCameraPropertiesC CameraWrapperConnector::pApplyPropertiesC = 0;
73 #define INIT_CAMERA_SYMBOL_NAME "initCameraConnectC"
74 #define CLOSE_CAMERA_SYMBOL_NAME "closeCameraConnectC"
75 #define SET_CAMERA_PROPERTY_SYMBOL_NAME "setCameraPropertyC"
76 #define GET_CAMERA_PROPERTY_SYMBOL_NAME "getCameraPropertyC"
77 #define APPLY_CAMERA_PROPERTIES_SYMBOL_NAME "applyCameraPropertiesC"
78 #define PREFIX_CAMERA_WRAPPER_LIB "libnative_camera"
81 bool nextFrame(void* buffer, size_t bufferSize, void* userData)
86 return ((CameraActivity*)userData)->onFrameBuffer(buffer, bufferSize);
89 CameraActivity::ErrorCode CameraWrapperConnector::connect(int cameraId, CameraActivity* pCameraActivity, void** camera)
91 if (pCameraActivity == NULL)
93 LOGE("CameraWrapperConnector::connect error: wrong pointer to CameraActivity object");
94 return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER;
97 CameraActivity::ErrorCode errcode=connectToLib();
98 if (errcode) return errcode;
100 void* cmr = (*pInitCameraC)((void*)nextFrame, cameraId, (void*)pCameraActivity);
103 LOGE("CameraWrapperConnector::connectWrapper ERROR: the initializing function returned false");
104 return CameraActivity::ERROR_CANNOT_INITIALIZE_CONNECTION;
108 return CameraActivity::NO_ERROR;
111 CameraActivity::ErrorCode CameraWrapperConnector::disconnect(void** camera)
113 if (camera == NULL || *camera == NULL)
115 LOGE("CameraWrapperConnector::disconnect error: wrong pointer to camera object");
116 return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER;
119 CameraActivity::ErrorCode errcode=connectToLib();
120 if (errcode) return errcode;
122 (*pCloseCameraC)(camera);
124 return CameraActivity::NO_ERROR;
127 CameraActivity::ErrorCode CameraWrapperConnector::setProperty(void* camera, int propIdx, double value)
131 LOGE("CameraWrapperConnector::setProperty error: wrong pointer to camera object");
132 return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER;
135 (*pSetPropertyC)(camera, propIdx, value);
137 return CameraActivity::NO_ERROR;
140 CameraActivity::ErrorCode CameraWrapperConnector::getProperty(void* camera, int propIdx, double* value)
144 LOGE("CameraWrapperConnector::getProperty error: wrong pointer to camera object");
145 return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER;
147 LOGE("calling (*pGetPropertyC)(%p, %d)", camera, propIdx);
148 *value = (*pGetPropertyC)(camera, propIdx);
149 return CameraActivity::NO_ERROR;
152 CameraActivity::ErrorCode CameraWrapperConnector::applyProperties(void** ppcamera)
154 if ((ppcamera == NULL) || (*ppcamera == NULL))
156 LOGE("CameraWrapperConnector::applyProperties error: wrong pointer to camera object");
157 return CameraActivity::ERROR_WRONG_POINTER_CAMERA_WRAPPER;
160 (*pApplyPropertiesC)(ppcamera);
161 return CameraActivity::NO_ERROR;
164 CameraActivity::ErrorCode CameraWrapperConnector::connectToLib()
166 if (isConnectedToLib) {
167 return CameraActivity::NO_ERROR;
171 string folderPath = getPathLibFolder();
172 if (folderPath.empty())
174 LOGD("Trying to find native camera in default OpenCV packages");
175 folderPath = getDefaultPathLibFolder();
178 LOGD("CameraWrapperConnector::connectToLib: folderPath=%s", folderPath.c_str());
180 vector<string> listLibs;
181 fillListWrapperLibs(folderPath, listLibs);
182 std::sort(listLibs.begin(), listLibs.end(), std::greater<string>());
186 for(size_t i = 0; i < listLibs.size(); i++) {
187 cur_path=folderPath + listLibs[i];
188 LOGD("try to load library '%s'", listLibs[i].c_str());
189 libHandle=dlopen(cur_path.c_str(), RTLD_LAZY);
191 LOGD("Loaded library '%s'", cur_path.c_str());
194 LOGD("CameraWrapperConnector::connectToLib ERROR: cannot dlopen camera wrapper library %s, dlerror=\"%s\"",
195 cur_path.c_str(), dlerror());
200 LOGE("CameraWrapperConnector::connectToLib ERROR: cannot dlopen camera wrapper library");
201 return CameraActivity::ERROR_CANNOT_OPEN_CAMERA_WRAPPER_LIB;
204 InitCameraConnectC pInit_C;
205 CloseCameraConnectC pClose_C;
206 GetCameraPropertyC pGetProp_C;
207 SetCameraPropertyC pSetProp_C;
208 ApplyCameraPropertiesC pApplyProp_C;
210 CameraActivity::ErrorCode res;
212 res = getSymbolFromLib(libHandle, (const char*)INIT_CAMERA_SYMBOL_NAME, (void**)(&pInit_C));
215 res = getSymbolFromLib(libHandle, CLOSE_CAMERA_SYMBOL_NAME, (void**)(&pClose_C));
218 res = getSymbolFromLib(libHandle, GET_CAMERA_PROPERTY_SYMBOL_NAME, (void**)(&pGetProp_C));
221 res = getSymbolFromLib(libHandle, SET_CAMERA_PROPERTY_SYMBOL_NAME, (void**)(&pSetProp_C));
224 res = getSymbolFromLib(libHandle, APPLY_CAMERA_PROPERTIES_SYMBOL_NAME, (void**)(&pApplyProp_C));
227 pInitCameraC = pInit_C;
228 pCloseCameraC = pClose_C;
229 pGetPropertyC = pGetProp_C;
230 pSetPropertyC = pSetProp_C;
231 pApplyPropertiesC = pApplyProp_C;
232 isConnectedToLib=true;
234 return CameraActivity::NO_ERROR;
237 CameraActivity::ErrorCode CameraWrapperConnector::getSymbolFromLib(void* libHandle, const char* symbolName, void** ppSymbol)
240 *(void **) (ppSymbol)=dlsym(libHandle, symbolName);
242 const char* error_dlsym_init=dlerror();
243 if (error_dlsym_init) {
244 LOGE("CameraWrapperConnector::getSymbolFromLib ERROR: cannot get symbol of the function '%s' from the camera wrapper library, dlerror=\"%s\"",
245 symbolName, error_dlsym_init);
246 return CameraActivity::ERROR_CANNOT_GET_FUNCTION_FROM_CAMERA_WRAPPER_LIB;
248 return CameraActivity::NO_ERROR;
251 void CameraWrapperConnector::fillListWrapperLibs(const string& folderPath, vector<string>& listLibs)
256 dp = opendir (folderPath.c_str());
259 while ((ep = readdir (dp))) {
260 const char* cur_name=ep->d_name;
261 if (strstr(cur_name, PREFIX_CAMERA_WRAPPER_LIB)) {
262 listLibs.push_back(cur_name);
263 LOGE("||%s", cur_name);
266 (void) closedir (dp);
270 std::string CameraWrapperConnector::getDefaultPathLibFolder()
272 #define BIN_PACKAGE_NAME(x) "org.opencv.lib_v" CVAUX_STR(CV_VERSION_EPOCH) CVAUX_STR(CV_VERSION_MAJOR) "_" x
273 const char* const packageList[] = {BIN_PACKAGE_NAME("armv7a"), OPENCV_ENGINE_PACKAGE};
274 for (size_t i = 0; i < sizeof(packageList)/sizeof(packageList[0]); i++)
277 sprintf(path, "/data/data/%s/lib/", packageList[i]);
278 LOGD("Trying package \"%s\" (\"%s\")", packageList[i], path);
280 DIR* dir = opendir(path);
283 LOGD("Package not found");
296 std::string CameraWrapperConnector::getPathLibFolder()
298 if (!pathLibFolder.empty())
299 return pathLibFolder;
302 if(0 != dladdr((void *)nextFrame, &dl_info))
304 LOGD("Library name: %s", dl_info.dli_fname);
305 LOGD("Library base address: %p", dl_info.dli_fbase);
307 const char* libName=dl_info.dli_fname;
308 while( ((*libName)=='/') || ((*libName)=='.') )
312 FILE* file = fopen("/proc/self/smaps", "rt");
316 while (fgets(lineBuf, sizeof lineBuf, file) != NULL)
318 //verify that line ends with library name
319 int lineLength = strlen(lineBuf);
320 int libNameLength = strlen(libName);
323 for(int i = lineLength - 1; i >= 0 && isspace(lineBuf[i]); --i)
329 if (0 != strncmp(lineBuf + lineLength - libNameLength, libName, libNameLength))
331 //the line does not contain the library name
335 //extract path from smaps line
336 char* pathBegin = strchr(lineBuf, '/');
339 LOGE("Strange error: could not find path beginning in lin \"%s\"", lineBuf);
343 char* pathEnd = strrchr(pathBegin, '/');
346 LOGD("Libraries folder found: %s", pathBegin);
352 LOGE("Could not find library path");
356 LOGE("Could not read /proc/self/smaps");
361 LOGE("Could not get library name and base address");
367 void CameraWrapperConnector::setPathLibFolder(const string& path)
373 /////////////////////////////////////////////////////////////////////////////////////////////////
375 CameraActivity::CameraActivity() : camera(0), frameWidth(-1), frameHeight(-1)
379 CameraActivity::~CameraActivity()
385 bool CameraActivity::onFrameBuffer(void* /*buffer*/, int /*bufferSize*/)
387 LOGD("CameraActivity::onFrameBuffer - empty callback");
391 void CameraActivity::disconnect()
393 CameraWrapperConnector::disconnect(&camera);
396 bool CameraActivity::isConnected() const
401 CameraActivity::ErrorCode CameraActivity::connect(int cameraId)
403 ErrorCode rescode = CameraWrapperConnector::connect(cameraId, this, &camera);
404 if (rescode) return rescode;
409 double CameraActivity::getProperty(int propIdx)
412 ErrorCode rescode = CameraWrapperConnector::getProperty(camera, propIdx, &propVal);
413 if (rescode) return -1;
417 void CameraActivity::setProperty(int propIdx, double value)
419 CameraWrapperConnector::setProperty(camera, propIdx, value);
422 void CameraActivity::applyProperties()
426 CameraWrapperConnector::applyProperties(&camera);
427 frameWidth = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEWIDTH);
428 frameHeight = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT);
431 int CameraActivity::getFrameWidth()
434 frameWidth = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEWIDTH);
438 int CameraActivity::getFrameHeight()
440 if (frameHeight <= 0)
441 frameHeight = getProperty(ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT);
445 void CameraActivity::setPathLibFolder(const char* path)
447 CameraWrapperConnector::setPathLibFolder(path);