1 #if !defined(ANDROID_r2_2_0) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1) && \
2 !defined(ANDROID_r4_0_0) && !defined(ANDROID_r4_0_3) && !defined(ANDROID_r4_1_1) && \
3 !defined(ANDROID_r4_2_0) && !defined(ANDROID_r4_3_0)
4 # error Building camera wrapper for your version of Android is not supported by OpenCV.\
5 You need to modify OpenCV sources in order to compile camera wrapper for your version of Android.
8 #include <camera/Camera.h>
9 #include <camera/CameraParameters.h>
11 #if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
12 # include <system/camera.h>
13 #endif //defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
15 #include "camera_wrapper.h"
16 #include "../include/camera_properties.h"
18 #if defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1)
19 //Include SurfaceTexture.h file with the SurfaceTexture class
20 # include <gui/SurfaceTexture.h>
21 # define MAGIC_OPENCV_TEXTURE_ID (0x10)
22 #elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0)
23 # include <gui/ISurface.h>
24 # include <gui/BufferQueue.h>
25 #elif defined(ANDROID_r4_3_0)
26 # include <gui/IGraphicBufferProducer.h>
27 # include <gui/BufferQueue.h>
29 # include <surfaceflinger/ISurface.h>
35 //undef logging macro from /system/core/libcutils/loghack.h
53 #include <android/log.h>
54 #define CAMERA_LOG_TAG "OpenCV_NativeCamera"
55 #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, CAMERA_LOG_TAG, __VA_ARGS__))
56 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, CAMERA_LOG_TAG, __VA_ARGS__))
57 #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, CAMERA_LOG_TAG, __VA_ARGS__))
58 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, CAMERA_LOG_TAG, __VA_ARGS__))
62 using namespace android;
66 #if defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
67 class ConsumerListenerStub: public BufferQueue::ConsumerListener
70 virtual void onFrameAvailable()
73 virtual void onBuffersReleased()
79 std::string getProcessName()
84 f.open("/proc/self/cmdline");
88 std::getline(f, fullPath, '\0');
89 if (!fullPath.empty())
91 int i = fullPath.size()-1;
92 while ((i >= 0) && (fullPath[i] != '/')) i--;
93 result = fullPath.substr(i+1, std::string::npos);
104 static int mFrameCount = 0;
105 static int mLastFrameCount = 0;
106 static nsecs_t mLastFpsTime = systemTime();
107 static float mFps = 0;
111 if (( mFrameCount % 30 ) != 0)
114 nsecs_t now = systemTime();
115 nsecs_t diff = now - mLastFpsTime;
120 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
122 mLastFrameCount = mFrameCount;
123 LOGI("### Camera FPS ### [%d] Frames, %.2f FPS", mFrameCount, mFps);
126 class CameraHandler: public CameraListener
131 CameraParameters params;
132 CameraCallback cameraCallback;
135 int emptyCameraCallbackReported;
137 static const char* flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM];
138 static const char* focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM];
139 static const char* whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM];
140 static const char* antibandingModesNames[ANDROID_CAMERA_ANTIBANDING_MODES_NUM];
142 void doCall(void* buffer, size_t bufferSize)
144 if (cameraCallback == 0)
146 if (!emptyCameraCallbackReported)
147 LOGE("CameraHandler::doCall(void*, size_t): Camera callback is empty!");
149 emptyCameraCallbackReported++;
153 bool res = (*cameraCallback)(buffer, bufferSize, userData);
157 LOGE("CameraHandler::doCall(void*, size_t): cameraCallback returns false (camera connection will be closed)");
158 closeCameraConnect();
163 void doCall(const sp<IMemory>& dataPtr)
167 LOGE("CameraHandler::doCall(const sp<IMemory>&): dataPtr==NULL (no frame to handle)");
171 size_t size = dataPtr->size();
174 LOGE("CameraHandler::doCall(const sp<IMemory>&): IMemory object is of zero size");
178 void* buffer = (void *)dataPtr->pointer();
181 LOGE("CameraHandler::doCall(const sp<IMemory>&): Buffer pointer is NULL");
185 doCall(buffer, size);
188 virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
190 static uint32_t count = 0;
193 LOGE("Recording cb: %d %lld %%p Offset:%%d Stride:%%d\n", msgType, timestamp);
197 LOGE("postDataTimestamp: dataPtr IS ZERO -- returning");
198 camera->releaseRecordingFrame(dataPtr);
199 LOGE("postDataTimestamp: camera->releaseRecordingFrame(dataPtr) is done");
203 uint8_t *ptr = (uint8_t*) dataPtr->pointer();
205 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]);
207 LOGE("postDataTimestamp: Ptr is zero");
209 camera->releaseRecordingFrame(dataPtr);
212 // Split list of floats, returns number of floats found
213 static int split_float(const char *str, float* out, char delim, int max_elem_num,
214 char **endptr = NULL)
216 // Find the first float.
217 char *end = const_cast<char*>(str);
219 for(; elem_num < max_elem_num; elem_num++ ){
221 out[elem_num] = (float)strtof(end, &curr_end);
222 // No other numbers found, finish the loop
226 if (*curr_end != delim) {
227 // When end of string, finish the loop
233 LOGE("Cannot find delimeter (%c) in str=%s", delim, str);
237 // Skip the delimiter character
245 int is_supported(const char* supp_modes_key, const char* mode)
247 const char* supported_modes = params.get(supp_modes_key);
248 return (supported_modes && mode && (strstr(supported_modes, mode) > 0));
251 float getFocusDistance(int focus_distance_type)
253 #if !defined(ANDROID_r2_2_0)
254 if (focus_distance_type >= 0 && focus_distance_type < 3)
256 float focus_distances[3];
257 const char* output = params.get(CameraParameters::KEY_FOCUS_DISTANCES);
258 int val_num = CameraHandler::split_float(output, focus_distances, ',', 3);
261 return focus_distances[focus_distance_type];
265 LOGE("Invalid focus distances.");
272 static int getModeNum(const char** modes, const int modes_num, const char* mode_name)
274 for (int i = 0; i < modes_num; i++){
275 if(!strcmp(modes[i],mode_name))
282 CameraHandler(CameraCallback callback = 0, void* _userData = 0):
284 cameraCallback(callback),
286 emptyCameraCallbackReported(0)
288 LOGD("Instantiated new CameraHandler (%p, %p)", callback, _userData);
291 virtual ~CameraHandler()
293 LOGD("CameraHandler destructor is called");
296 virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2)
298 LOGE("CameraHandler::Notify: msgType=%d ext1=%d ext2=%d\n", msgType, ext1, ext2);
300 if ( msgType & CAMERA_MSG_FOCUS )
301 LOGE("CameraHandler::Notify AutoFocus %s in %llu us\n", (ext1) ? "OK" : "FAIL", timevalDelay(&autofocus_start));
303 if ( msgType & CAMERA_MSG_SHUTTER )
304 LOGE("CameraHandler::Notify Shutter done in %llu us\n", timeval_delay(&picture_start));
308 virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr
309 #if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
310 ,camera_frame_metadata_t*
316 if ( msgType & CAMERA_MSG_PREVIEW_FRAME )
322 //if (msgType != CAMERA_MSG_PREVIEW_FRAME)
323 //LOGE("CameraHandler::postData Recieved message %d is not equal to CAMERA_MSG_PREVIEW_FRAME (%d)", (int) msgType, CAMERA_MSG_PREVIEW_FRAME);
325 if ( msgType & CAMERA_MSG_RAW_IMAGE )
326 LOGE("CameraHandler::postData Unexpected data format: RAW\n");
328 if (msgType & CAMERA_MSG_POSTVIEW_FRAME)
329 LOGE("CameraHandler::postData Unexpected data format: Postview frame\n");
331 if (msgType & CAMERA_MSG_COMPRESSED_IMAGE )
332 LOGE("CameraHandler::postData Unexpected data format: JPEG");
335 static CameraHandler* initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters);
336 void closeCameraConnect();
337 double getProperty(int propIdx);
338 void setProperty(int propIdx, double value);
339 static void applyProperties(CameraHandler** ppcameraHandler);
341 std::string cameraPropertySupportedPreviewSizesString;
342 std::string cameraPropertyPreviewFormatString;
345 const char* CameraHandler::flashModesNames[ANDROID_CAMERA_FLASH_MODES_NUM] =
347 CameraParameters::FLASH_MODE_AUTO,
348 CameraParameters::FLASH_MODE_OFF,
349 CameraParameters::FLASH_MODE_ON,
350 CameraParameters::FLASH_MODE_RED_EYE,
351 CameraParameters::FLASH_MODE_TORCH
354 const char* CameraHandler::focusModesNames[ANDROID_CAMERA_FOCUS_MODES_NUM] =
356 CameraParameters::FOCUS_MODE_AUTO,
357 #if !defined(ANDROID_r2_2_0)
358 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO,
360 CameraParameters::FOCUS_MODE_EDOF,
361 CameraParameters::FOCUS_MODE_FIXED,
362 CameraParameters::FOCUS_MODE_INFINITY
365 const char* CameraHandler::whiteBalanceModesNames[ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM] =
367 CameraParameters::WHITE_BALANCE_AUTO,
368 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT,
369 CameraParameters::WHITE_BALANCE_DAYLIGHT,
370 CameraParameters::WHITE_BALANCE_FLUORESCENT,
371 CameraParameters::WHITE_BALANCE_INCANDESCENT,
372 CameraParameters::WHITE_BALANCE_SHADE,
373 CameraParameters::WHITE_BALANCE_TWILIGHT
376 const char* CameraHandler::antibandingModesNames[ANDROID_CAMERA_ANTIBANDING_MODES_NUM] =
378 CameraParameters::ANTIBANDING_50HZ,
379 CameraParameters::ANTIBANDING_60HZ,
380 CameraParameters::ANTIBANDING_AUTO
384 CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, int cameraId, void* userData, CameraParameters* prevCameraParameters)
387 typedef sp<Camera> (*Android22ConnectFuncType)();
388 typedef sp<Camera> (*Android23ConnectFuncType)(int);
389 typedef sp<Camera> (*Android3DConnectFuncType)(int, int);
390 typedef sp<Camera> (*Android43ConnectFuncType)(int, const String16&, int);
392 const int ANY_CAMERA_INDEX = -1;
393 const int BACK_CAMERA_INDEX = 99;
394 const int FRONT_CAMERA_INDEX = 98;
397 CAMERA_SUPPORT_MODE_2D = 0x01, /* Camera Sensor supports 2D mode. */
398 CAMERA_SUPPORT_MODE_3D = 0x02, /* Camera Sensor supports 3D mode. */
399 CAMERA_SUPPORT_MODE_NONZSL = 0x04, /* Camera Sensor in NON-ZSL mode. */
400 CAMERA_SUPPORT_MODE_ZSL = 0x08 /* Camera Sensor supports ZSL mode. */
403 // used for Android 4.3
408 const char Android22ConnectName[] = "_ZN7android6Camera7connectEv";
409 const char Android23ConnectName[] = "_ZN7android6Camera7connectEi";
410 const char Android3DConnectName[] = "_ZN7android6Camera7connectEii";
411 const char Android43ConnectName[] = "_ZN7android6Camera7connectEiRKNS_8String16Ei";
413 int localCameraIndex = cameraId;
415 if (cameraId == ANY_CAMERA_INDEX)
417 localCameraIndex = 0;
419 #if !defined(ANDROID_r2_2_0)
420 else if (cameraId == BACK_CAMERA_INDEX)
422 LOGD("Back camera selected");
423 for (int i = 0; i < Camera::getNumberOfCameras(); i++)
426 Camera::getCameraInfo(i, &info);
427 if (info.facing == CAMERA_FACING_BACK)
429 localCameraIndex = i;
434 else if (cameraId == FRONT_CAMERA_INDEX)
436 LOGD("Front camera selected");
437 for (int i = 0; i < Camera::getNumberOfCameras(); i++)
440 Camera::getCameraInfo(i, &info);
441 if (info.facing == CAMERA_FACING_FRONT)
443 localCameraIndex = i;
449 if (localCameraIndex == BACK_CAMERA_INDEX)
451 LOGE("Back camera not found!");
454 else if (localCameraIndex == FRONT_CAMERA_INDEX)
456 LOGE("Front camera not found!");
461 LOGD("CameraHandler::initCameraConnect(%p, %d, %p, %p)", callback, localCameraIndex, userData, prevCameraParameters);
463 sp<Camera> camera = 0;
465 void* CameraHALHandle = dlopen("libcamera_client.so", RTLD_LAZY);
467 if (!CameraHALHandle)
469 LOGE("Cannot link to \"libcamera_client.so\"");
476 if (Android22ConnectFuncType Android22Connect = (Android22ConnectFuncType)dlsym(CameraHALHandle, Android22ConnectName))
478 LOGD("Connecting to CameraService v 2.2");
479 camera = Android22Connect();
481 else if (Android23ConnectFuncType Android23Connect = (Android23ConnectFuncType)dlsym(CameraHALHandle, Android23ConnectName))
483 LOGD("Connecting to CameraService v 2.3");
484 camera = Android23Connect(localCameraIndex);
486 else if (Android3DConnectFuncType Android3DConnect = (Android3DConnectFuncType)dlsym(CameraHALHandle, Android3DConnectName))
488 LOGD("Connecting to CameraService v 3D");
489 camera = Android3DConnect(localCameraIndex, CAMERA_SUPPORT_MODE_2D);
491 else if (Android43ConnectFuncType Android43Connect = (Android43ConnectFuncType)dlsym(CameraHALHandle, Android43ConnectName))
493 std::string currentProcName = getProcessName();
494 LOGD("Current process name for camera init: %s", currentProcName.c_str());
495 camera = Android43Connect(localCameraIndex, String16(currentProcName.c_str()), USE_CALLING_UID);
499 dlclose(CameraHALHandle);
500 LOGE("Cannot connect to CameraService. Connect method was not found!");
504 dlclose(CameraHALHandle);
506 if ( 0 == camera.get() )
508 LOGE("initCameraConnect: Unable to connect to CameraService\n");
512 CameraHandler* handler = new CameraHandler(callback, userData);
513 camera->setListener(handler);
515 handler->camera = camera;
516 handler->cameraId = localCameraIndex;
518 if (prevCameraParameters != NULL)
520 LOGI("initCameraConnect: Setting paramers from previous camera handler");
521 camera->setParameters(prevCameraParameters->flatten());
522 handler->params.unflatten(prevCameraParameters->flatten());
526 android::String8 params_str = camera->getParameters();
527 LOGI("initCameraConnect: [%s]", params_str.string());
529 handler->params.unflatten(params_str);
531 LOGD("Supported Cameras: %s", handler->params.get("camera-indexes"));
532 LOGD("Supported Picture Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES));
533 LOGD("Supported Picture Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS));
534 LOGD("Supported Preview Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES));
535 LOGD("Supported Preview Formats: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS));
536 LOGD("Supported Preview Frame Rates: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES));
537 LOGD("Supported Thumbnail Sizes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES));
538 LOGD("Supported Whitebalance Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE));
539 LOGD("Supported Effects: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_EFFECTS));
540 LOGD("Supported Scene Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_SCENE_MODES));
541 LOGD("Supported Focus Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES));
542 LOGD("Supported Antibanding Options: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_ANTIBANDING));
543 LOGD("Supported Flash Modes: %s", handler->params.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES));
545 #if !defined(ANDROID_r2_2_0)
546 // Set focus mode to continuous-video if supported
547 const char* available_focus_modes = handler->params.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
548 if (available_focus_modes != 0)
550 if (strstr(available_focus_modes, "continuous-video") != NULL)
552 handler->params.set(CameraParameters::KEY_FOCUS_MODE, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO);
554 status_t resParams = handler->camera->setParameters(handler->params.flatten());
558 LOGE("initCameraConnect: failed to set autofocus mode to \"continuous-video\"");
562 LOGD("initCameraConnect: autofocus is set to mode \"continuous-video\"");
568 //check if yuv420sp format available. Set this format as preview format.
569 const char* available_formats = handler->params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS);
570 if (available_formats != 0)
572 const char* format_to_set = 0;
573 const char* pos = available_formats;
574 const char* ptr = pos;
577 while(*ptr != 0 && *ptr != ',') ++ptr;
580 if (0 == strncmp(pos, "yuv420sp", ptr - pos))
582 format_to_set = "yuv420sp";
585 if (0 == strncmp(pos, "yvu420sp", ptr - pos))
586 format_to_set = "yvu420sp";
593 if (0 != format_to_set)
595 handler->params.setPreviewFormat(format_to_set);
597 status_t resParams = handler->camera->setParameters(handler->params.flatten());
600 LOGE("initCameraConnect: failed to set preview format to %s", format_to_set);
602 LOGD("initCameraConnect: preview format is set to %s", format_to_set);
607 status_t bufferStatus;
608 #if defined(ANDROID_r2_2_0)
609 bufferStatus = camera->setPreviewDisplay(sp<ISurface>(0 /*new DummySurface*/));
610 if (bufferStatus != 0)
611 LOGE("initCameraConnect: failed setPreviewDisplay(0) call (status %d); camera might not work correctly on some devices", bufferStatus);
612 #elif defined(ANDROID_r2_3_3)
613 /* Do nothing in case of 2.3 for now */
614 #elif defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
615 sp<SurfaceTexture> surfaceTexture = new SurfaceTexture(MAGIC_OPENCV_TEXTURE_ID);
616 bufferStatus = camera->setPreviewTexture(surfaceTexture);
617 if (bufferStatus != 0)
618 LOGE("initCameraConnect: failed setPreviewTexture call (status %d); camera might not work correctly", bufferStatus);
619 #elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
620 sp<BufferQueue> bufferQueue = new BufferQueue();
621 sp<BufferQueue::ConsumerListener> queueListener = new ConsumerListenerStub();
622 bufferQueue->consumerConnect(queueListener);
623 bufferStatus = camera->setPreviewTexture(bufferQueue);
624 if (bufferStatus != 0)
625 LOGE("initCameraConnect: failed setPreviewTexture call; camera might not work correctly");
628 #if (defined(ANDROID_r2_2_0) || defined(ANDROID_r2_3_3) || defined(ANDROID_r3_0_1))
630 ////ATTENTION: switching between two versions: with and without copying memory inside Android OS
631 //// see the method CameraService::Client::copyFrameAndPostCopiedFrame and where it is used
632 camera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK | FRAME_CALLBACK_FLAG_COPY_OUT_MASK);//with copy
634 camera->setPreviewCallbackFlags( FRAME_CALLBACK_FLAG_ENABLE_MASK );//without copy
637 camera->setPreviewCallbackFlags( CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK | CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK);//with copy
638 #endif //!(defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3))
640 LOGD("Starting preview");
641 status_t previewStatus = camera->startPreview();
643 if (previewStatus != 0)
645 LOGE("initCameraConnect: startPreview() fails. Closing camera connection...");
646 handler->closeCameraConnect();
651 LOGD("Preview started successfully");
657 void CameraHandler::closeCameraConnect()
661 LOGI("... camera is already NULL");
665 camera->stopPreview();
666 #if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
667 camera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP);
669 camera->disconnect();
672 // ATTENTION!!!!!!!!!!!!!!!!!!!!!!!!!!
675 // above, the pointed instance of android::Camera object is destructed,
676 // since this member `camera' has type android::sp<Camera> (android smart pointer template class),
677 // and this is the only pointer to it.
679 // BUT this instance of CameraHandler is set as a listener for that android::Camera object
680 // (see the function CameraHandler::initCameraConnect above),
681 // so this instance of CameraHandler is pointed from that android::Camera object as
682 // sp<CameraListener> mListener
683 // and there is no other android smart pointers to this.
685 // It means, when that instance of the android::Camera object is destructed,
686 // it calls destructor for this CameraHandler instance too.
688 // So, this line `camera=NULL' causes to the call `delete this'
689 // (see destructor of the template class android::sp)
691 // So, we must not call `delete this' after the line, since it just has been called indeed
694 double CameraHandler::getProperty(int propIdx)
696 LOGD("CameraHandler::getProperty(%d)", propIdx);
700 case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
703 params.getPreviewSize(&w, &h);
706 case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
709 params.getPreviewSize(&w, &h);
712 case ANDROID_CAMERA_PROPERTY_SUPPORTED_PREVIEW_SIZES_STRING:
714 cameraPropertySupportedPreviewSizesString = params.get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
715 union {const char* str;double res;} u;
716 memset(&u.res, 0, sizeof(u.res));
717 u.str = cameraPropertySupportedPreviewSizesString.c_str();
720 case ANDROID_CAMERA_PROPERTY_PREVIEW_FORMAT_STRING:
722 const char* fmt = params.get(CameraParameters::KEY_PREVIEW_FORMAT);
723 if (fmt == CameraParameters::PIXEL_FORMAT_YUV422SP)
725 else if (fmt == CameraParameters::PIXEL_FORMAT_YUV420SP)
727 else if (fmt == CameraParameters::PIXEL_FORMAT_YUV422I)
729 else if (fmt == CameraParameters::PIXEL_FORMAT_RGB565)
731 else if (fmt == CameraParameters::PIXEL_FORMAT_JPEG)
733 cameraPropertyPreviewFormatString = fmt;
735 union {const char* str;double res;} u;
736 memset(&u.res, 0, sizeof(u.res));
737 u.str = cameraPropertyPreviewFormatString.c_str();
740 case ANDROID_CAMERA_PROPERTY_EXPOSURE:
742 int exposure = params.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
745 case ANDROID_CAMERA_PROPERTY_FPS:
747 return params.getPreviewFrameRate();
749 case ANDROID_CAMERA_PROPERTY_FLASH_MODE:
751 int flash_mode = getModeNum(CameraHandler::flashModesNames,
752 ANDROID_CAMERA_FLASH_MODES_NUM,
753 params.get(CameraParameters::KEY_FLASH_MODE));
756 case ANDROID_CAMERA_PROPERTY_FOCUS_MODE:
758 int focus_mode = getModeNum(CameraHandler::focusModesNames,
759 ANDROID_CAMERA_FOCUS_MODES_NUM,
760 params.get(CameraParameters::KEY_FOCUS_MODE));
763 case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE:
765 int white_balance = getModeNum(CameraHandler::whiteBalanceModesNames,
766 ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM,
767 params.get(CameraParameters::KEY_WHITE_BALANCE));
768 return white_balance;
770 case ANDROID_CAMERA_PROPERTY_ANTIBANDING:
772 int antibanding = getModeNum(CameraHandler::antibandingModesNames,
773 ANDROID_CAMERA_ANTIBANDING_MODES_NUM,
774 params.get(CameraParameters::KEY_ANTIBANDING));
777 case ANDROID_CAMERA_PROPERTY_FOCAL_LENGTH:
779 float focal_length = params.getFloat(CameraParameters::KEY_FOCAL_LENGTH);
782 case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_NEAR:
784 return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_NEAR_INDEX);
786 case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_OPTIMAL:
788 return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_OPTIMAL_INDEX);
790 case ANDROID_CAMERA_PROPERTY_FOCUS_DISTANCE_FAR:
792 return getFocusDistance(ANDROID_CAMERA_FOCUS_DISTANCE_FAR_INDEX);
795 LOGW("CameraHandler::getProperty - Unsupported property.");
800 void CameraHandler::setProperty(int propIdx, double value)
802 LOGD("CameraHandler::setProperty(%d, %f)", propIdx, value);
806 case ANDROID_CAMERA_PROPERTY_FRAMEWIDTH:
809 params.getPreviewSize(&w, &h);
811 params.setPreviewSize(w, h);
814 case ANDROID_CAMERA_PROPERTY_FRAMEHEIGHT:
817 params.getPreviewSize(&w, &h);
819 params.setPreviewSize(w, h);
822 case ANDROID_CAMERA_PROPERTY_EXPOSURE:
824 int max_exposure = params.getInt("max-exposure-compensation");
825 int min_exposure = params.getInt("min-exposure-compensation");
826 if(max_exposure && min_exposure){
827 int exposure = (int)value;
828 if(exposure >= min_exposure && exposure <= max_exposure){
829 params.set("exposure-compensation", exposure);
831 LOGE("Exposure compensation not in valid range (%i,%i).", min_exposure, max_exposure);
834 LOGE("Exposure compensation adjust is not supported.");
838 case ANDROID_CAMERA_PROPERTY_FLASH_MODE:
840 int new_val = (int)value;
841 if(new_val >= 0 && new_val < ANDROID_CAMERA_FLASH_MODES_NUM){
842 const char* mode_name = flashModesNames[new_val];
843 if(is_supported(CameraParameters::KEY_SUPPORTED_FLASH_MODES, mode_name))
844 params.set(CameraParameters::KEY_FLASH_MODE, mode_name);
846 LOGE("Flash mode %s is not supported.", mode_name);
848 LOGE("Flash mode value not in valid range.");
852 case ANDROID_CAMERA_PROPERTY_FOCUS_MODE:
854 int new_val = (int)value;
855 if(new_val >= 0 && new_val < ANDROID_CAMERA_FOCUS_MODES_NUM){
856 const char* mode_name = focusModesNames[new_val];
857 if(is_supported(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, mode_name))
858 params.set(CameraParameters::KEY_FOCUS_MODE, mode_name);
860 LOGE("Focus mode %s is not supported.", mode_name);
862 LOGE("Focus mode value not in valid range.");
866 case ANDROID_CAMERA_PROPERTY_WHITE_BALANCE:
868 int new_val = (int)value;
869 if(new_val >= 0 && new_val < ANDROID_CAMERA_WHITE_BALANCE_MODES_NUM){
870 const char* mode_name = whiteBalanceModesNames[new_val];
871 if(is_supported(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, mode_name))
872 params.set(CameraParameters::KEY_WHITE_BALANCE, mode_name);
874 LOGE("White balance mode %s is not supported.", mode_name);
876 LOGE("White balance mode value not in valid range.");
880 case ANDROID_CAMERA_PROPERTY_ANTIBANDING:
882 int new_val = (int)value;
883 if(new_val >= 0 && new_val < ANDROID_CAMERA_ANTIBANDING_MODES_NUM){
884 const char* mode_name = antibandingModesNames[new_val];
885 if(is_supported(CameraParameters::KEY_SUPPORTED_ANTIBANDING, mode_name))
886 params.set(CameraParameters::KEY_ANTIBANDING, mode_name);
888 LOGE("Antibanding mode %s is not supported.", mode_name);
890 LOGE("Antibanding mode value not in valid range.");
895 LOGW("CameraHandler::setProperty - Unsupported property.");
899 void CameraHandler::applyProperties(CameraHandler** ppcameraHandler)
901 LOGD("CameraHandler::applyProperties()");
903 if (ppcameraHandler == 0)
905 LOGE("applyProperties: Passed NULL ppcameraHandler");
909 if (*ppcameraHandler == 0)
911 LOGE("applyProperties: Passed NULL *ppcameraHandler");
915 CameraParameters curCameraParameters((*ppcameraHandler)->params.flatten());
917 #if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
918 CameraHandler* handler=*ppcameraHandler;
920 handler->camera->stopPreview();
921 handler->camera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP);
923 status_t reconnectStatus = handler->camera->reconnect();
924 if (reconnectStatus != 0)
926 LOGE("applyProperties: failed to reconnect camera (status %d)", reconnectStatus);
930 handler->camera->setParameters(curCameraParameters.flatten());
931 handler->params.unflatten(curCameraParameters.flatten());
933 status_t bufferStatus;
934 # if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)
935 sp<SurfaceTexture> surfaceTexture = new SurfaceTexture(MAGIC_OPENCV_TEXTURE_ID);
936 bufferStatus = handler->camera->setPreviewTexture(surfaceTexture);
937 if (bufferStatus != 0)
938 LOGE("applyProperties: failed setPreviewTexture call (status %d); camera might not work correctly", bufferStatus);
939 # elif defined(ANDROID_r4_1_1) || defined(ANDROID_r4_2_0) || defined(ANDROID_r4_3_0)
940 sp<BufferQueue> bufferQueue = new BufferQueue();
941 sp<BufferQueue::ConsumerListener> queueListener = new ConsumerListenerStub();
942 bufferQueue->consumerConnect(queueListener);
943 bufferStatus = handler->camera->setPreviewTexture(bufferQueue);
944 if (bufferStatus != 0)
945 LOGE("applyProperties: failed setPreviewTexture call; camera might not work correctly");
948 handler->camera->setPreviewCallbackFlags( CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK | CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK);//with copy
950 LOGD("Starting preview");
951 status_t previewStatus = handler->camera->startPreview();
953 if (previewStatus != 0)
955 LOGE("initCameraConnect: startPreview() fails. Closing camera connection...");
956 handler->closeCameraConnect();
961 LOGD("Preview started successfully");
964 CameraHandler* previousCameraHandler=*ppcameraHandler;
965 CameraCallback cameraCallback=previousCameraHandler->cameraCallback;
966 void* userData=previousCameraHandler->userData;
967 int cameraId=previousCameraHandler->cameraId;
969 LOGD("CameraHandler::applyProperties(): before previousCameraHandler->closeCameraConnect");
970 previousCameraHandler->closeCameraConnect();
971 LOGD("CameraHandler::applyProperties(): after previousCameraHandler->closeCameraConnect");
973 LOGD("CameraHandler::applyProperties(): before initCameraConnect");
974 CameraHandler* handler=initCameraConnect(cameraCallback, cameraId, userData, &curCameraParameters);
975 LOGD("CameraHandler::applyProperties(): after initCameraConnect, handler=0x%x", (int)handler);
976 if (handler == NULL) {
977 LOGE("ERROR in applyProperties --- cannot reinit camera");
978 handler=initCameraConnect(cameraCallback, cameraId, userData, NULL);
979 LOGD("CameraHandler::applyProperties(): repeate initCameraConnect after ERROR, handler=0x%x", (int)handler);
980 if (handler == NULL) {
981 LOGE("ERROR in applyProperties --- cannot reinit camera AGAIN --- cannot do anything else");
984 (*ppcameraHandler)=handler;
991 void* initCameraConnectC(void* callback, int cameraId, void* userData)
993 return CameraHandler::initCameraConnect((CameraCallback)callback, cameraId, userData, NULL);
996 void closeCameraConnectC(void** camera)
998 CameraHandler** cc = (CameraHandler**)camera;
999 (*cc)->closeCameraConnect();
1003 double getCameraPropertyC(void* camera, int propIdx)
1005 return ((CameraHandler*)camera)->getProperty(propIdx);
1008 void setCameraPropertyC(void* camera, int propIdx, double value)
1010 ((CameraHandler*)camera)->setProperty(propIdx,value);
1013 void applyCameraPropertiesC(void** camera)
1015 CameraHandler::applyProperties((CameraHandler**)camera);