From f5e67bd7b60306c4b4548ebb9acb77a5e863e774 Mon Sep 17 00:00:00 2001 From: BlueMatthew Date: Thu, 18 Jan 2024 22:36:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=8D=E7=85=A7=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/cpp/MicroPhoto.cpp | 110 ++++++++++++ app/src/main/cpp/PhoneDevice.cpp | 70 +++++--- app/src/main/cpp/PhoneDevice.h | 2 +- app/src/main/cpp/camera2/ndkcamera.cpp | 163 ++++++++++-------- app/src/main/cpp/camera2/ndkcamera.h | 32 +++- app/src/main/cpp/camera2/utils/native_debug.h | 2 +- 6 files changed, 275 insertions(+), 104 deletions(-) diff --git a/app/src/main/cpp/MicroPhoto.cpp b/app/src/main/cpp/MicroPhoto.cpp index 8ddab27d..3eb9fda3 100644 --- a/app/src/main/cpp/MicroPhoto.cpp +++ b/app/src/main/cpp/MicroPhoto.cpp @@ -49,6 +49,96 @@ static jmethodID mRequestPositionMid = 0; static jmethodID mWriteLogMid = 0; + +void posix_signal_handler(int sig, siginfo_t *siginfo, void *context) +{ + (void)context; + switch(sig) + { + case SIGSEGV: + fputs("Caught SIGSEGV: Segmentation Fault\n", stderr); + break; + case SIGINT: + fputs("Caught SIGINT: Interactive attention signal, (usually ctrl+c)\n", + stderr); + break; + case SIGFPE: + switch(siginfo->si_code) + { + case FPE_INTDIV: + fputs("Caught SIGFPE: (integer divide by zero)\n", stderr); + break; + case FPE_INTOVF: + fputs("Caught SIGFPE: (integer overflow)\n", stderr); + break; + case FPE_FLTDIV: + fputs("Caught SIGFPE: (floating-point divide by zero)\n", stderr); + break; + case FPE_FLTOVF: + fputs("Caught SIGFPE: (floating-point overflow)\n", stderr); + break; + case FPE_FLTUND: + fputs("Caught SIGFPE: (floating-point underflow)\n", stderr); + break; + case FPE_FLTRES: + fputs("Caught SIGFPE: (floating-point inexact result)\n", stderr); + break; + case FPE_FLTINV: + fputs("Caught SIGFPE: (floating-point invalid operation)\n", stderr); + break; + case FPE_FLTSUB: + fputs("Caught SIGFPE: (subscript out of range)\n", stderr); + break; + default: + fputs("Caught SIGFPE: Arithmetic Exception\n", stderr); + break; + } + case SIGILL: + switch(siginfo->si_code) + { + case ILL_ILLOPC: + fputs("Caught SIGILL: (illegal opcode)\n", stderr); + break; + case ILL_ILLOPN: + fputs("Caught SIGILL: (illegal operand)\n", stderr); + break; + case ILL_ILLADR: + fputs("Caught SIGILL: (illegal addressing mode)\n", stderr); + break; + case ILL_ILLTRP: + fputs("Caught SIGILL: (illegal trap)\n", stderr); + break; + case ILL_PRVOPC: + fputs("Caught SIGILL: (privileged opcode)\n", stderr); + break; + case ILL_PRVREG: + fputs("Caught SIGILL: (privileged register)\n", stderr); + break; + case ILL_COPROC: + fputs("Caught SIGILL: (coprocessor error)\n", stderr); + break; + case ILL_BADSTK: + fputs("Caught SIGILL: (internal stack error)\n", stderr); + break; + default: + fputs("Caught SIGILL: Illegal Instruction\n", stderr); + break; + } + break; + case SIGTERM: + fputs("Caught SIGTERM: a termination request was sent to the program\n", + stderr); + break; + case SIGABRT: + fputs("Caught SIGABRT: usually caused by an abort() or assert()\n", stderr); + break; + default: + break; + } + + _Exit(1); +} + class Runner { public: @@ -93,6 +183,26 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) google_breakpad::ExceptionHandler eh(descriptor, NULL, DumpCallback, NULL, true, -1); #endif + + { + struct sigaction sig_action = {}; + sig_action.sa_sigaction = posix_signal_handler; + sigemptyset(&sig_action.sa_mask); + +#ifdef __APPLE__ + /* for some reason we backtrace() doesn't work on osx + when we use an alternate stack */ + sig_action.sa_flags = SA_SIGINFO; +#else + sig_action.sa_flags = SA_SIGINFO | SA_ONSTACK; +#endif + + if (sigaction(SIGSEGV, &sig_action, NULL) != 0) { + // err(1, "sigaction"); + int aa = 0; + } + } + const char* className = "com/xypower/mpapp/MicroPhotoService"; jclass clazz = (env)->FindClass(className); diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index 86adf645..fd37cc12 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -216,12 +216,14 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPa CPhoneDevice::~CPhoneDevice() { + m_devLocker.lock(); for (auto it = mTimers.begin(); it != mTimers.end(); ++it) { timer_delete((timer_t)it->first); delete it->second; } mTimers.clear(); + m_devLocker.unlock(); JNIEnv* env = NULL; bool didAttachThread = false; @@ -647,7 +649,9 @@ IDevice::timer_uid_t CPhoneDevice::RegisterTimer(unsigned int timerType, unsigne return INVALID_TIMER_UID; } + m_devLocker.lock(); mTimers.insert(mTimers.end(), std::pair((IDevice::timer_uid_t)timer, context)); + m_devLocker.unlock(); return (IDevice::timer_uid_t)timer; } @@ -656,14 +660,17 @@ bool CPhoneDevice::UnregisterTimer(IDevice::timer_uid_t uid) timer_t timer = (timer_t)uid; int res = timer_delete(timer); + m_devLocker.lock(); std::map::iterator it = mTimers.find(uid); if (it != mTimers.end()) { delete it->second; mTimers.erase(it); + m_devLocker.unlock(); return true; } + m_devLocker.unlock(); return false; } @@ -761,11 +768,11 @@ bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector< if (mCamera != NULL) { - delete mCamera; + // delete mCamera; mCamera = NULL; } - XYLOG(XYLOG_SEVERITY_INFO, "TAKE_PHOTO: CH=%u PR=%u PHOTOID=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset, photoInfo.photoId); + XYLOG(XYLOG_SEVERITY_INFO, "TAKE_PHOTO: CH=%u PR=%X PHOTOID=%u", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset, photoInfo.photoId); mPhotoInfo = photoInfo; mPath = path; mOsds = osds; @@ -781,20 +788,12 @@ bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector< // GpioControl::EnableGpio(CMD_SET_CAM_3V3_EN_STATE, true); bool res = false; - JNIEnv* env = NULL; - bool didAttachThread = false; - res = GetJniEnv(m_vm, &env, didAttachThread); - if (!res) - { - ALOGE("Failed to get JNI Env"); - return false; - } if (photoInfo.usbCamera) { - TurnOnOtg(env); + TurnOnOtg(NULL); } - TurnOnCameraPower(env); + TurnOnCameraPower(NULL); res = true; if (mPhotoInfo.mediaType == 0) @@ -802,24 +801,39 @@ bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector< mCamera = new CPhoneCamera(this, photoInfo.width, photoInfo.height, params); if (mCamera->open(to_string(mPhotoInfo.cameraId)) == 0) { - XYLOG(XYLOG_SEVERITY_DEBUG, "TP: Succeeded to OpenCamera CH=%u PR=%u PHOTOID=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset, photoInfo.photoId); + XYLOG(XYLOG_SEVERITY_DEBUG, "TP: Succeeded to OpenCamera CH=%u PR=%X PHOTOID=%u", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset, photoInfo.photoId); } else { - XYLOG(XYLOG_SEVERITY_DEBUG, "TP: Failed to OpenCamera CH=%u PR=%u PHOTOID=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset, photoInfo.photoId); + XYLOG(XYLOG_SEVERITY_DEBUG, "TP: Failed to OpenCamera CH=%u PR=%X PHOTOID=%u", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset, photoInfo.photoId); delete mCamera; mCamera = NULL; res = false; + + TurnOffCameraPower(NULL); + if (photoInfo.usbCamera) + { + TurnOffOtg(NULL); + } } } else { + + JNIEnv* env = NULL; + bool didAttachThread = false; + res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + return false; + } env->CallVoidMethod(m_javaService, mStartRecordingMid, mPhotoInfo.cameraId, (unsigned long)mPhotoInfo.photoId, mPhotoInfo.duration, mPhotoInfo.width, mPhotoInfo.height, mPhotoInfo.duration); - } - if (didAttachThread) - { - m_vm->DetachCurrentThread(); + if (didAttachThread) + { + m_vm->DetachCurrentThread(); + } } return res; @@ -1077,6 +1091,10 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) bool turnOffOtg = (mPhotoInfo.usbCamera != 0); std::thread closeThread(&CPhoneDevice::CloseCamera2, this, pCamera, mPhotoInfo.photoId, turnOffOtg); m_threadClose.swap(closeThread); + if (closeThread.joinable()) + { + closeThread.detach(); + } return res; } @@ -1135,18 +1153,18 @@ void CPhoneDevice::UpdatePosition(double lon, double lat, time_t ts) void CPhoneDevice::TurnOnCameraPower(JNIEnv* env) { - mCameraPowerLocker.lock(); + m_devLocker.lock(); if (mCameraPowerCount == 0) { GpioControl::setCam3V3Enable(true); } mCameraPowerCount++; - mCameraPowerLocker.unlock(); + m_devLocker.unlock(); } void CPhoneDevice::TurnOffCameraPower(JNIEnv* env) { - mCameraPowerLocker.lock(); + m_devLocker.lock(); if (mCameraPowerCount > 0) { mCameraPowerCount--; @@ -1155,24 +1173,24 @@ void CPhoneDevice::TurnOffCameraPower(JNIEnv* env) GpioControl::setCam3V3Enable(false); } } - mCameraPowerLocker.unlock(); + m_devLocker.unlock(); } void CPhoneDevice::TurnOnOtg(JNIEnv* env) { - mCameraPowerLocker.lock(); + m_devLocker.lock(); if (mOtgCount == 0) { ALOGD("setOtgState 1"); GpioControl::setOtgState(true); } mOtgCount++; - mCameraPowerLocker.unlock(); + m_devLocker.unlock(); } void CPhoneDevice::TurnOffOtg(JNIEnv* env) { - mCameraPowerLocker.lock(); + m_devLocker.lock(); if (mOtgCount > 0) { mOtgCount--; @@ -1182,5 +1200,5 @@ void CPhoneDevice::TurnOffOtg(JNIEnv* env) GpioControl::setOtgState(false); } } - mCameraPowerLocker.unlock(); + m_devLocker.unlock(); } \ No newline at end of file diff --git a/app/src/main/cpp/PhoneDevice.h b/app/src/main/cpp/PhoneDevice.h index 3ea7fe87..f80bfc49 100644 --- a/app/src/main/cpp/PhoneDevice.h +++ b/app/src/main/cpp/PhoneDevice.h @@ -248,7 +248,7 @@ protected: protected: - std::mutex mCameraPowerLocker; + std::mutex m_devLocker; JavaVM* m_vm; jobject m_javaService; diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index 48d125a0..11c4d393 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -22,7 +22,6 @@ #include "gpu.h" #include "Camera2Helper.h" #include - #include static void onAvailabilityCallback(void* context, const char* cameraId) @@ -132,7 +131,6 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA camera_manager_cb.onCameraAvailable = ::onAvailabilityCallback; camera_manager_cb.onCameraUnavailable = ::onUnavailabilityCallback; - camera_manager = 0; camera_device = 0; image_reader = 0; image_reader_surface = 0; @@ -154,20 +152,23 @@ int NdkCamera::open(const std::string& cameraId) { // camera_facing = _camera_facing; - camera_manager = ACameraManager_create(); + camera_manager.Create(); ACameraManager_registerAvailabilityCallback(camera_manager, &camera_manager_cb); // find camera bool foundIt = false; DisplayDimension disp(mWidth, mHeight); DisplayDimension foundRes = disp; + camera_status_t status = ACAMERA_OK; ALOGD("Start ACameraManager_getCameraIdList"); { ACameraIdList *camera_id_list = 0; for (int retry = 0; retry < 2; retry++) { - ACameraManager_getCameraIdList(camera_manager, &camera_id_list); + status = ACameraManager_getCameraIdList(camera_manager, &camera_id_list); + AASSERT(status == ACAMERA_OK, "ACameraManager_getCameraIdList return error, %d", status); + // ACameraManager_getCameraIdList will fire AvailabilityCallback for (int i = 0; i < camera_id_list->numCameras; ++i) { @@ -207,7 +208,8 @@ int NdkCamera::open(const std::string& cameraId) { mCameraId = cameraId; ACameraMetadata * camera_metadata = 0; - ACameraManager_getCameraCharacteristics(camera_manager, cameraId.c_str(), &camera_metadata); + status = ACameraManager_getCameraCharacteristics(camera_manager, cameraId.c_str(), &camera_metadata); + AASSERT(status == ACAMERA_OK, "ACameraManager_getCameraCharacteristics return error, %d", status); { ACameraMetadata_const_entry e = {0}; @@ -271,8 +273,12 @@ int NdkCamera::open(const std::string& cameraId) { acamera_metadata_enum_android_lens_facing_t facing = ACAMERA_LENS_FACING_FRONT; { ACameraMetadata_const_entry e = {0}; - ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_LENS_FACING, &e); - facing = (acamera_metadata_enum_android_lens_facing_t) e.data.u8[0]; + status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_LENS_FACING, &e); + AASSERT(status == ACAMERA_OK, "ACameraMetadata_getConstEntry::ACAMERA_LENS_FACING return error, %d", status); + if (status == ACAMERA_OK) + { + facing = (acamera_metadata_enum_android_lens_facing_t) e.data.u8[0]; + } } camera_facing = facing; @@ -280,25 +286,31 @@ int NdkCamera::open(const std::string& cameraId) { int orientation = 0; { ACameraMetadata_const_entry e = {0}; - ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_ORIENTATION, &e); - orientation = (int) e.data.i32[0]; + status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_ORIENTATION, &e); + AASSERT(status == ACAMERA_OK, "ACameraMetadata_getConstEntry::ACAMERA_SENSOR_ORIENTATION return error, %d", status); + if (status == ACAMERA_OK) + { + orientation = (int) e.data.i32[0]; + } } camera_orientation = orientation; { ACameraMetadata_const_entry e = {0}; - camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &e); + status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE, &e); } { ACameraMetadata_const_entry e = {0}; - camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_CONTROL_AF_AVAILABLE_MODES, &e); + status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_CONTROL_AF_AVAILABLE_MODES, &e); + // AASSERT(status == ACAMERA_OK, "ACameraMetadata_getConstEntry::ACAMERA_CONTROL_AF_AVAILABLE_MODES return error, %d", status); afSupported = (status == ACAMERA_OK) && !(e.count == 0 || (e.count == 1 && e.data.u8[0] == ACAMERA_CONTROL_AF_MODE_OFF)); } { ACameraMetadata_const_entry val = {0}; - camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE, &val); + status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE, &val); + // AASSERT(status == ACAMERA_OK, "ACameraMetadata_getConstEntry::ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE return error, %d", status); if (status == ACAMERA_OK) { exposureRange.min_ = val.data.i64[0]; @@ -323,7 +335,7 @@ int NdkCamera::open(const std::string& cameraId) { { ACameraMetadata_const_entry val = {0}; - camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_CONTROL_AE_COMPENSATION_RANGE, &val); + status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_CONTROL_AE_COMPENSATION_RANGE, &val); if (status == ACAMERA_OK) { aeCompensationRange.min_ = val.data.i32[0]; @@ -338,7 +350,7 @@ int NdkCamera::open(const std::string& cameraId) { { ACameraMetadata_const_entry val = {0}; - camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE, &val); + status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE, &val); if (status == ACAMERA_OK) { sensitivityRange.min_ = val.data.i32[0]; @@ -353,21 +365,24 @@ int NdkCamera::open(const std::string& cameraId) { { ACameraMetadata_const_entry e = {0}; - camera_status_t status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_CONTROL_AVAILABLE_SCENE_MODES, &e); - for (int i = 0; i < e.count; i++) + status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_CONTROL_AVAILABLE_SCENE_MODES, &e); + if (status == ACAMERA_OK) { - if (ACAMERA_CONTROL_SCENE_MODE_HDR == e.data.u8[i]) + for (int i = 0; i < e.count; i++) { - hdrSupported = true; - break; - } - else if (ACAMERA_CONTROL_SCENE_MODE_NIGHT == e.data.u8[i]) - { - nightModeSupported = true; - } - else if (ACAMERA_CONTROL_SCENE_MODE_NIGHT_PORTRAIT == e.data.u8[i]) - { - nightPortraitModeSupported = true; + if (ACAMERA_CONTROL_SCENE_MODE_HDR == e.data.u8[i]) + { + hdrSupported = true; + break; + } + else if (ACAMERA_CONTROL_SCENE_MODE_NIGHT == e.data.u8[i]) + { + nightModeSupported = true; + } + else if (ACAMERA_CONTROL_SCENE_MODE_NIGHT_PORTRAIT == e.data.u8[i]) + { + nightPortraitModeSupported = true; + } } } } @@ -375,23 +390,7 @@ int NdkCamera::open(const std::string& cameraId) { ACameraMetadata_free(camera_metadata); } - camera_status_t res = ACAMERA_OK; - // setup imagereader and its surface - { - AImageReader_new(foundRes.width(), foundRes.height(), AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader); - - AImageReader_ImageListener listener; - listener.context = this; - listener.onImageAvailable = ::onImageAvailable; - - AImageReader_setImageListener(image_reader, &listener); - - AImageReader_getWindow(image_reader, &image_reader_surface); - // ANativeWindow_setBuffersGeometry(image_reader_surface, width, height,WINDOW_FORMAT_RGBX_8888); - - // ANativeWindow_acquire(image_reader_surface); - } // open camera { @@ -400,43 +399,59 @@ int NdkCamera::open(const std::string& cameraId) { camera_device_state_callbacks.onDisconnected = onDisconnected; camera_device_state_callbacks.onError = onError; - res = ACameraManager_openCamera(camera_manager, cameraId.c_str(), &camera_device_state_callbacks, &camera_device); - if (res != ACAMERA_OK) + status = ACameraManager_openCamera(camera_manager, cameraId.c_str(), &camera_device_state_callbacks, &camera_device); + if (status != ACAMERA_OK) { - XYLOG(XYLOG_SEVERITY_ERROR, "Failed to open camera res=%d", res); + XYLOG(XYLOG_SEVERITY_ERROR, "Failed to open camera %s res=%d", cameraId.c_str(), status); return 1; } } XYLOG(XYLOG_SEVERITY_INFO, "CameraStatus::Open %s %d", cameraId.c_str(), camera_orientation); + // setup imagereader and its surface + { + media_status_t mstatus = AImageReader_new(foundRes.width(), foundRes.height(), AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader); + + if (mstatus == AMEDIA_OK) + { + AImageReader_ImageListener listener; + listener.context = this; + listener.onImageAvailable = ::onImageAvailable; + mstatus = AImageReader_setImageListener(image_reader, &listener); + mstatus = AImageReader_getWindow(image_reader, &image_reader_surface); + // ANativeWindow_setBuffersGeometry(image_reader_surface, width, height,WINDOW_FORMAT_RGBX_8888); + // ANativeWindow_acquire(image_reader_surface); + } + } + // std::this_thread::sleep_for(std::chrono::milliseconds(128)); // capture request { // res = ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_PREVIEW, &capture_request); - res = ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_STILL_CAPTURE, &capture_request); + status = ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_STILL_CAPTURE, &capture_request); int32_t fpsRange[2] = {10,30}; - res = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,2,fpsRange); + status = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,2,fpsRange); if (m_params.autoExposure) { uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON; - res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_MODE, 1, &aeMode); + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_MODE, 1, &aeMode); // ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity_); uint8_t aeLockOff = ACAMERA_CONTROL_AE_LOCK_OFF; // ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_LOCK, 1, &aeLockOff); } else { uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF; - res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_MODE, 1, &aeMode); + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_MODE, 1, &aeMode); if (m_params.sensibility > 0) { int32_t sensitivity = m_params.sensibility; - res = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity); + status = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity); } if (m_params.exposureTime > 0) { int64_t exposureTime = m_params.exposureTime * 1000000; - res = ACaptureRequest_setEntry_i64(capture_request, ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime); + status = ACaptureRequest_setEntry_i64(capture_request, ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime); } } @@ -444,17 +459,17 @@ int NdkCamera::open(const std::string& cameraId) { // uint8_t afMode = ACAMERA_CONTROL_AF_MODE_CONTINUOUS_VIDEO; // uint8_t afMode = ACAMERA_CONTROL_AF_MODE_CONTINUOUS_PICTURE; uint8_t afMode = ACAMERA_CONTROL_AF_MODE_AUTO; - res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AF_MODE, 1, &afMode); + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AF_MODE, 1, &afMode); uint8_t trig = ACAMERA_CONTROL_AF_TRIGGER_START; - res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); - m_imagesCaptured = (res == ACAMERA_OK) ? ~0 : 0; + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); + m_imagesCaptured = (status == ACAMERA_OK) ? ~0 : 0; } else { uint8_t trig = ACAMERA_CONTROL_AF_TRIGGER_START; - res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); - m_imagesCaptured = (res == ACAMERA_OK) ? ~0 : 0; + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); + m_imagesCaptured = (status == ACAMERA_OK) ? ~0 : 0; // m_imagesCaptured = 0; } @@ -463,13 +478,13 @@ int NdkCamera::open(const std::string& cameraId) { if (hdrSupported && m_params.hdrMode) { uint8_t hdrMode = ACAMERA_CONTROL_SCENE_MODE_HDR; - res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE, 1,&hdrMode); + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE, 1,&hdrMode); } if (m_params.nightMode) { if (nightModeSupported) { uint8_t sceneMode = ACAMERA_CONTROL_SCENE_MODE_NIGHT; - res = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE, 1, &sceneMode); + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_SCENE_MODE, 1, &sceneMode); } if (nightPortraitModeSupported) { uint8_t modeEnabled = 1; // ACAMERA_CONTROL_SCENE_MODE_HDR @@ -477,8 +492,8 @@ int NdkCamera::open(const std::string& cameraId) { } } - res = ACameraOutputTarget_create(image_reader_surface, &image_reader_target); - res = ACaptureRequest_addTarget(capture_request, image_reader_target); + status = ACameraOutputTarget_create(image_reader_surface, &image_reader_target); + status = ACaptureRequest_addTarget(capture_request, image_reader_target); } // capture session @@ -489,13 +504,13 @@ int NdkCamera::open(const std::string& cameraId) { camera_capture_session_state_callbacks.onReady = onSessionReady; camera_capture_session_state_callbacks.onClosed = onSessionClosed; - res = ACaptureSessionOutputContainer_create(&capture_session_output_container); + status = ACaptureSessionOutputContainer_create(&capture_session_output_container); - res = ACaptureSessionOutput_create(image_reader_surface, &capture_session_output); + status = ACaptureSessionOutput_create(image_reader_surface, &capture_session_output); - res = ACaptureSessionOutputContainer_add(capture_session_output_container, capture_session_output); + status = ACaptureSessionOutputContainer_add(capture_session_output_container, capture_session_output); - res = ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session); + status = ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session); ACameraCaptureSession_captureCallbacks camera_capture_session_capture_callbacks; camera_capture_session_capture_callbacks.context = this; @@ -507,17 +522,22 @@ int NdkCamera::open(const std::string& cameraId) { camera_capture_session_capture_callbacks.onCaptureSequenceAborted = onCaptureSequenceAborted; camera_capture_session_capture_callbacks.onCaptureBufferLost = 0; - res = ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, &captureSequenceId); + status = ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, &captureSequenceId); // ACameraCaptureSession_capture(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, &captureSequenceId); } - return 0; + return status == ACAMERA_OK ? 0 : 1; } void NdkCamera::close() { camera_status_t res = ACAMERA_OK; + if ((ACameraManager *)camera_manager != NULL) + { + res = ACameraManager_unregisterAvailabilityCallback(camera_manager, &camera_manager_cb); + } + if (capture_session) { res = ACameraCaptureSession_stopRepeating(capture_session); @@ -570,19 +590,12 @@ void NdkCamera::close() image_reader_surface = 0; } - if (image_reader) + if (image_reader != NULL) { AImageReader_setImageListener(image_reader, NULL); AImageReader_delete(image_reader); image_reader = 0; } - - if (camera_manager) - { - ACameraManager_unregisterAvailabilityCallback(camera_manager, &camera_manager_cb); - ACameraManager_delete(camera_manager); - camera_manager = 0; - } } void NdkCamera::onImageAvailable(AImageReader* reader) diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index 10d0dcde..840234d7 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -34,6 +34,35 @@ static const uint64_t kMinExposureTime = static_cast(1000000); static const uint64_t kMaxExposureTime = static_cast(250000000); +class CameraManager +{ +public: + CameraManager() + { + camera_manager = NULL; + } + + void Create() + { + camera_manager = ACameraManager_create(); + } + + operator ACameraManager* () + { + return camera_manager; + } + ~CameraManager() + { + if (camera_manager != NULL) + { + ACameraManager_delete(camera_manager); + camera_manager = NULL; + } + } + +private: + ACameraManager* camera_manager; +}; class NdkCamera { @@ -116,7 +145,8 @@ protected: protected: ACameraManager_AvailabilityCallbacks camera_manager_cb; - ACameraManager* camera_manager; + + CameraManager camera_manager; ACameraDevice* camera_device; AImageReader* image_reader; ANativeWindow* image_reader_surface; diff --git a/app/src/main/cpp/camera2/utils/native_debug.h b/app/src/main/cpp/camera2/utils/native_debug.h index 047e5720..d62b3464 100644 --- a/app/src/main/cpp/camera2/utils/native_debug.h +++ b/app/src/main/cpp/camera2/utils/native_debug.h @@ -1,6 +1,6 @@ #include -#define LOG_TAG "CAMERA-SAMPLE" +#define LOG_TAG "MPLOG" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)