From 4cc84c2b5a89c5b7c80769a7761999e12d0124f8 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 12 May 2024 00:25:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9B=9D=E5=85=89=E5=8C=BA?= =?UTF-8?q?=E5=9F=9F=E5=92=8C=E5=AF=B9=E7=84=A6=E5=8C=BA=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/cpp/camera2/ndkcamera.cpp | 140 +++++++++++++++++++++++-- app/src/main/cpp/camera2/ndkcamera.h | 4 + 2 files changed, 137 insertions(+), 7 deletions(-) diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index e9c0d7f1..236fd4c8 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -123,6 +123,13 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA sceneModeSupported = false; + activeArraySize[0] = 0; + activeArraySize[1] = 0; + + maxRegions[0] = 0; + maxRegions[1] = 0; + maxRegions[2] = 0; + camera_manager_cb.context = this; camera_manager_cb.onCameraAvailable = ::onAvailabilityCallback; camera_manager_cb.onCameraUnavailable = ::onUnavailabilityCallback; @@ -137,6 +144,8 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA capture_session = 0; captureSequenceId = 0; + lightDetected = false; + mResult = { 0 }; } @@ -394,6 +403,27 @@ int NdkCamera::open(const std::string& cameraId) { } } + { + ACameraMetadata_const_entry val = {0}; + status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE, &val); + if (status == ACAMERA_OK) + { + activeArraySize[0] = val.data.i32[2]; + activeArraySize[1] = val.data.i32[3]; + } + } + + { + ACameraMetadata_const_entry val = {0}; + status = ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_CONTROL_MAX_REGIONS, &val); + if (status == ACAMERA_OK) + { + maxRegions[0] = val.data.i32[0]; + maxRegions[1] = val.data.i32[1]; + maxRegions[2] = val.data.i32[2]; + } + } + { ACameraMetadata_const_entry e = {0}; status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_CONTROL_AVAILABLE_SCENE_MODES, &e); @@ -456,7 +486,7 @@ int NdkCamera::open(const std::string& cameraId) { : TEMPLATE_STILL_CAPTURE; status = ACameraDevice_createCaptureRequest(camera_device, templateId, &capture_request); - int32_t fpsRange[2] = {1,1}; + int32_t fpsRange[2] = {1,10}; status = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,2,fpsRange); } @@ -468,6 +498,24 @@ int NdkCamera::open(const std::string& cameraId) { if (!m_params.zoom) { + if (maxRegions[2] > 0) + { + int32_t centerX = activeArraySize[0] >> 1; + int32_t centerY = activeArraySize[1] >> 1; + + int32_t sizeX = activeArraySize[0] >> 4; + int32_t sizeY = activeArraySize[1] >> 4; + + int32_t afRegions[] = {centerX - sizeX, centerY - sizeY, centerX + sizeX, centerY + sizeY, 1000}; + status = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_CONTROL_AF_REGIONS, 5, afRegions); + if (status == ACAMERA_OK) + { + // m_imagesCaptured = ~0; +#ifdef _DEBUG + int aa = 0; +#endif + } + } uint8_t trig = ACAMERA_CONTROL_AF_TRIGGER_CANCEL; // status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); @@ -520,6 +568,19 @@ int NdkCamera::open(const std::string& cameraId) { } } + if (maxRegions[0] > 0) + { + int32_t aeRegions[] = {0, 0, activeArraySize[0] - 1, activeArraySize[1] - 1, 1000}; + status = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_CONTROL_AE_REGIONS, 5, aeRegions); + if (status == ACAMERA_OK) + { + // m_imagesCaptured = ~0; +#ifdef _DEBUG + int aa = 0; +#endif + } + } + uint8_t aePrecatureTrigger = ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_START; status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER, 1, &aePrecatureTrigger); if (status == ACAMERA_OK) @@ -552,6 +613,14 @@ int NdkCamera::open(const std::string& cameraId) { uint8_t awbMode = ACAMERA_CONTROL_AWB_MODE_AUTO; status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AWB_MODE, 1, &awbMode); +#if 0 + uint8_t antiBandingMode = ACAMERA_CONTROL_AE_ANTIBANDING_MODE_60HZ; + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_ANTIBANDING_MODE, 1, &antiBandingMode); + + uint8_t flicker = ACAMERA_STATISTICS_SCENE_FLICKER_60HZ; + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_STATISTICS_SCENE_FLICKER, 1, &flicker); +#endif + status = ACameraOutputTarget_create(image_reader_surface, &image_reader_target); status = ACaptureRequest_addTarget(capture_request, image_reader_target); } @@ -688,15 +757,55 @@ void NdkCamera::onImageAvailable(AImageReader* reader) ALOGD("onImageAvailable %p", reader); AImage* image = 0; - media_status_t status = AImageReader_acquireLatestImage(reader, &image); + media_status_t mstatus = AImageReader_acquireLatestImage(reader, &image); - if (status != AMEDIA_OK) + if (mstatus != AMEDIA_OK) { // error - XYLOG(XYLOG_SEVERITY_ERROR, "AImageReader_acquireLatestImage error: %d", status); + XYLOG(XYLOG_SEVERITY_ERROR, "AImageReader_acquireLatestImage error: %d", mstatus); return; } + uint8_t* y_data = 0; + int y_len = 0; +#if 0 + if (!lightDetected) + { + AImage_getPlaneData(image, 0, &y_data, &y_len); + + lightDetected = true; + +#if __cplusplus >= 201703L + uint64_t avgY = std::reduce(y_data, y_data + y_len, 0); +#else + uint64_t avgY = std::accumulate(y_data, y_data + y_len, 0); +#endif + avgY = avgY / (uint64_t)y_len; + mResult.avgY = avgY; +#if 1 + if (avgY < 50) + { + if (m_params.autoExposure) + { + uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF; + camera_status_t status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_MODE, 1, &aeMode); + + int32_t sensitivity = (avgY < 5) ? 2000 : (mResult.sensitibity * 60.0 / avgY); + status = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity); + + int64_t exposureTime = (avgY < 5) ? 200 * 1000000 : (mResult.exposureTime * 120.0 / avgY); + status = ACaptureRequest_setEntry_i64(capture_request, ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime); + + XYLOG(XYLOG_SEVERITY_WARNING, "YUV Light: %u EXPO:%lld => %lld ISO: %u => %u", (uint32_t)avgY, + mResult.exposureTime, exposureTime, mResult.sensitibity, sensitivity); + } + AImage_delete(image); + return; + } +#endif + } +#endif + if (m_imagesCaptured == ~0 || m_imagesCaptured >= 1) { // XYLOG(XYLOG_SEVERITY_DEBUG, "m_imagesCaptured=%u wait for next image", m_imagesCaptured); @@ -729,22 +838,27 @@ void NdkCamera::onImageAvailable(AImageReader* reader) AImage_getPlaneRowStride(image, 1, &u_rowStride); AImage_getPlaneRowStride(image, 2, &v_rowStride); - uint8_t* y_data = 0; + // uint8_t* y_data = 0; uint8_t* u_data = 0; uint8_t* v_data = 0; - int y_len = 0; + // int y_len = 0; int u_len = 0; int v_len = 0; - AImage_getPlaneData(image, 0, &y_data, &y_len); + if (y_data == 0) + { + AImage_getPlaneData(image, 0, &y_data, &y_len); + } AImage_getPlaneData(image, 1, &u_data, &u_len); AImage_getPlaneData(image, 2, &v_data, &v_len); +#if 0 #if __cplusplus >= 201703L uint64_t avgy = std::reduce(y_data, y_data + y_len, 0); #else uint64_t avgy = std::accumulate(y_data, y_data + y_len, 0); #endif mResult.avgY = avgy / y_len; +#endif if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width) { @@ -974,6 +1088,18 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AE_STATE, &val); mResult.aeState = (status == ACAMERA_OK) ? *(val.data.u8) : ACAMERA_CONTROL_AE_STATE_INACTIVE; + if (!lightDetected) + { + val = { 0 }; + status = ACameraMetadata_getConstEntry(result, ACAMERA_SENSOR_EXPOSURE_TIME, &val); + int64_t exTime = (status == ACAMERA_OK) ? val.data.i64[0] : -1; + mResult.exposureTime = exTime; + + val = {0}; + status = ACameraMetadata_getConstEntry(result, ACAMERA_SENSOR_SENSITIVITY, &val); + mResult.sensitibity = *(val.data.i32); + } + if (afSupported && (m_params.autoFocus != 0)) { val = { 0 }; diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index 10533858..e9a343c9 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -143,12 +143,16 @@ protected: bool aeLockAvailable; bool awbLockAvailable; + bool lightDetected; + // int64_t exposureTime_; RangeValue exposureRange; // int32_t sensitivity_; RangeValue sensitivityRange; RangeValue aeCompensationRange; ACameraMetadata_rational aeCompensationStep; + int32_t activeArraySize[2]; + int32_t maxRegions[3]; unsigned int m_imagesCaptured;