#ifndef __PHONE_DEVICE_H__ #define __PHONE_DEVICE_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "camera2/Camera2Helper.h" #include "camera2/ndkcamera.h" #include #include #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "error", __VA_ARGS__)) #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "debug", __VA_ARGS__)) #if 0 void BitmapToMat2(JNIEnv *env, jobject& bitmap, cv::Mat& mat, jboolean needUnPremultiplyAlpha) { AndroidBitmapInfo info; void *pixels = 0; cv::Mat &dst = mat; // try { ALOGD("nBitmapToMat"); CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0); CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 || info.format == ANDROID_BITMAP_FORMAT_RGB_565); CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0); CV_Assert(pixels); dst.create(info.height, info.width, CV_8UC4); if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) { ALOGD("nBitmapToMat: RGBA_8888 -> CV_8UC4"); cv::Mat tmp(info.height, info.width, CV_8UC4, pixels); if (needUnPremultiplyAlpha) cvtColor(tmp, dst, cv::COLOR_mRGBA2RGBA); else tmp.copyTo(dst); } else { // info.format == ANDROID_BITMAP_FORMAT_RGB_565 ALOGD("nBitmapToMat: RGB_565 -> CV_8UC4"); cv::Mat tmp(info.height, info.width, CV_8UC2, pixels); cvtColor(tmp, dst, cv::COLOR_BGR5652RGBA); } AndroidBitmap_unlockPixels(env, bitmap); return; /* } catch (const cv::Exception &e) { AndroidBitmap_unlockPixels(env, bitmap); LOGE("nBitmapToMat catched cv::Exception: %s", e.what()); jclass je = env->FindClass("org/opencv/core/CvException"); if (!je) je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, e.what()); return; } catch (...) { AndroidBitmap_unlockPixels(env, bitmap); LOGE("nBitmapToMat catched unknown exception (...)"); jclass je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}"); return; } */ } void BitmapToMat(JNIEnv *env, jobject& bitmap, cv::Mat& mat) { BitmapToMat2(env, bitmap, mat, false); } void MatToBitmap2 (JNIEnv *env, cv::Mat& mat, jobject& bitmap, jboolean needPremultiplyAlpha) { AndroidBitmapInfo info; void *pixels = 0; cv::Mat &src = mat; // try { ALOGD("nMatToBitmap"); CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0); CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 || info.format == ANDROID_BITMAP_FORMAT_RGB_565); CV_Assert(src.dims == 2 && info.height == (uint32_t) src.rows && info.width == (uint32_t) src.cols); CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4); CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0); CV_Assert(pixels); if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) { cv::Mat tmp(info.height, info.width, CV_8UC4, pixels); if (src.type() == CV_8UC1) { ALOGD("nMatToBitmap: CV_8UC1 -> RGBA_8888"); cvtColor(src, tmp, cv::COLOR_GRAY2RGBA); } else if (src.type() == CV_8UC3) { ALOGD("nMatToBitmap: CV_8UC3 -> RGBA_8888"); cvtColor(src, tmp, cv::COLOR_RGB2RGBA); } else if (src.type() == CV_8UC4) { ALOGD("nMatToBitmap: CV_8UC4 -> RGBA_8888"); if (needPremultiplyAlpha) cvtColor(src, tmp, cv::COLOR_RGBA2mRGBA); else src.copyTo(tmp); } } else { // info.format == ANDROID_BITMAP_FORMAT_RGB_565 cv::Mat tmp(info.height, info.width, CV_8UC2, pixels); if (src.type() == CV_8UC1) { ALOGD("nMatToBitmap: CV_8UC1 -> RGB_565"); cvtColor(src, tmp, cv::COLOR_GRAY2BGR565); } else if (src.type() == CV_8UC3) { ALOGD("nMatToBitmap: CV_8UC3 -> RGB_565"); cvtColor(src, tmp, cv::COLOR_RGB2BGR565); } else if (src.type() == CV_8UC4) { ALOGD("nMatToBitmap: CV_8UC4 -> RGB_565"); cvtColor(src, tmp, cv::COLOR_RGBA2BGR565); } } AndroidBitmap_unlockPixels(env, bitmap); return; /* } catch (const cv::Exception &e) { AndroidBitmap_unlockPixels(env, bitmap); LOGE("nMatToBitmap catched cv::Exception: %s", e.what()); jclass je = env->FindClass("org/opencv/core/CvException"); if (!je) je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, e.what()); return; } catch (...) { AndroidBitmap_unlockPixels(env, bitmap); LOGE("nMatToBitmap catched unknown exception (...)"); jclass je = env->FindClass("java/lang/Exception"); env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}"); return; }*/ } void MatToBitmap(JNIEnv *env, cv::Mat& mat, jobject& bitmap) { MatToBitmap2(env, mat, bitmap, false); } #endif class CPhoneDevice : public IDevice { public: class CPhoneCamera : public NdkCamera { public: CPhoneCamera(CPhoneDevice* dev, int32_t width, int32_t height, const NdkCamera::CAMERA_PARAMS& params); virtual bool on_image(cv::Mat& rgb); virtual void on_error(const std::string& msg); protected: CPhoneDevice* m_dev; }; CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath); virtual ~CPhoneDevice(); virtual void SetListener(IListener* listener); virtual void SetRecognizationCfg(const CFG_RECOGNIZATION* pRecognizationCfg); virtual bool UpdateTime(time_t ts); virtual bool UpdateSchedules(); virtual bool QuerySystemProperties(map& properties); virtual bool Reboot(int resetType); virtual bool EnableGPS(bool enabled); virtual bool RequestPosition(); virtual timer_uid_t RegisterHeartbeat(unsigned int timerType, unsigned int timeout); virtual bool TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector& osds, const std::string& path); virtual bool CloseCamera(); virtual timer_uid_t RegisterTimer(unsigned int timerType, unsigned int timeout, unsigned long times = 0); virtual bool UnregisterTimer(timer_uid_t uid); virtual unsigned long RequestWakelock(unsigned long timeout); virtual bool ReleaseWakelock(unsigned long wakelock); virtual bool FireTimer(timer_uid_t uid, unsigned long times); bool GetNextScheduleItem(uint32_t tsBasedZero, uint32_t scheduleTime, vector& items); void UpdatePosition(double lon, double lat, time_t ts); protected: std::string GetFileName() const; bool SendBroadcastMessage(std::string action, int value); // bool MatchCaptureSizeRequest(ACameraManager *cameraManager, const char *selectedCameraId, unsigned int width, unsigned int height, uint32_t cameraOrientation_, inline bool TakePhotoCb(bool res, const IDevice::PHOTO_INFO& photoInfo, const string& path, time_t photoTime) const { if (m_listener != NULL) { return m_listener->OnPhotoTaken(res, photoInfo, path, photoTime); } return false; } void QueryPowerInfo(std::map& powerInfo); std::string QueryCpuTemperature(); bool OnImageReady(cv::Mat& mat); void onError(const std::string& msg); static void CloseCamera2(CPhoneCamera* camera); protected: JavaVM* m_vm; jobject m_javaService; std::string m_appPath; jmethodID mRegisterTimerMid; jmethodID mRegisterHeartbeatMid; jmethodID mUnregisterTimerMid; jmethodID mUpdateTimeMid; jmethodID mRequestWakelockMid; jmethodID mReleaseWakelockMid; jmethodID mGetSystemInfoMid; jmethodID mRebootMid; jmethodID mEnableGpsMid; jmethodID mRequestPositionMid; std::string mPath; IDevice::PHOTO_INFO mPhotoInfo; vector mOsds; IListener* m_listener; const CFG_RECOGNIZATION* m_pRecognizationCfg; atomic_ulong m_timerUidFeed; atomic_ulong m_wakelockIdFeed; std::map mTimers; mutable CPhoneCamera* mCamera; time_t mHeartbeatStartTime; unsigned int mHeartbeatDuration; }; #endif // __PHONE_DEVICE_H__