diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index 8febf6e3..5c867b55 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -1178,6 +1178,7 @@ bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector< params.zoom = mPhotoInfo.zoom; params.zoomRatio = mPhotoInfo.zoomRatio; params.requestTemplate = mPhotoInfo.requestTemplate; + params.wait3ALocked = mPhotoInfo.wait3ALocked; if (params.requestTemplate <= 0 || params.requestTemplate > 5) { params.requestTemplate = 2; @@ -1552,7 +1553,7 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) unsigned int extime = (captureResult.exposureTime >= 1000000) ? ((unsigned int)(captureResult.exposureTime / 1000000)) : ((unsigned int)(captureResult.exposureTime / 1000)); strcpy(extimeunit, (captureResult.exposureTime >= 1000000) ? "ms" : "μs"); char str[128] = { 0 }; - snprintf(str, sizeof(str), "AE=%u EXPS=%u%s(%d) ISO=%d AF=%u LDR=%d(%u) AFS=%u AES=%u SCENE=%d AWB=%u %0.1fx", captureResult.autoExposure, + snprintf(str, sizeof(str), "AE=%u EXPS=%u%s(%d) ISO=%d AF=%u LDR=%d(%u) AFS=%u AES=%u SCENE=%d AWB=%u %0.1fx T=%u", captureResult.autoExposure, extime, extimeunit, captureResult.compensation, captureResult.sensitivity, captureResult.autoFocus, @@ -1561,7 +1562,7 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) (unsigned int)captureResult.afState, (unsigned int)captureResult.aeState, captureResult.sceneMode, - captureResult.awbState, captureResult.zoomRatio); + captureResult.awbState, captureResult.zoomRatio, (uint32_t)captureResult.duration); // cv::putText(mat, str, cv::Point(0, mat.rows - 20), cv::FONT_HERSHEY_COMPLEX, fontScale, scalar, thickness1, cv::LINE_AA); int fs = fontSize * 2 / 3; diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index a00fe148..d8de86fe 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -293,7 +293,7 @@ int NdkCamera::open(const std::string& cameraId) { if (format == AIMAGE_FORMAT_YUV_420_888/* || format == AIMAGE_FORMAT_JPEG*/) { DisplayDimension res(e.data.i32[i + 1], e.data.i32[i + 2]); - XYLOG(XYLOG_SEVERITY_DEBUG, "CameraId=%s CX=%d CY=%d", cameraId.c_str(), res.width(), res.height()); + // XYLOG(XYLOG_SEVERITY_DEBUG, "CameraId=%s CX=%d CY=%d", cameraId.c_str(), res.width(), res.height()); if (!disp.IsSameRatio(res)) { @@ -373,6 +373,26 @@ int NdkCamera::open(const std::string& cameraId) { afSupported = (status == ACAMERA_OK) && !(e.count == 0 || (e.count == 1 && e.data.u8[0] == ACAMERA_CONTROL_AF_MODE_OFF)); } + { + ACameraMetadata_const_entry e = {0}; + status = ACameraMetadata_getConstEntry(camera_metadata,ACAMERA_CONTROL_AWB_AVAILABLE_MODES, &e); + // AASSERT(status == ACAMERA_OK, "ACameraMetadata_getConstEntry::ACAMERA_CONTROL_AF_AVAILABLE_MODES return error, %d", status); + if (status == ACAMERA_OK) + { + for (int idx = 0; idx < e.count; idx++) + { + if (ACAMERA_CONTROL_AWB_MODE_AUTO == e.data.u8[idx]) + { + awbSupported = true; + break; + } + // unsigned int m = e.data.u8[idx]; + // XYLOG(XYLOG_SEVERITY_DEBUG, "Available AWB Mode %u", m); + } + } + // awbSupported = (status == ACAMERA_OK) && !(e.count == 0 || (e.count == 1 && e.data.u8[0] == ACAMERA_CONTROL_AWB_MODE_OFF)); + } + if (!afSupported) { XYLOG(XYLOG_SEVERITY_ERROR, "AF not Supported"); @@ -561,6 +581,9 @@ int NdkCamera::open(const std::string& cameraId) { status = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,2,fpsRange); } + uint8_t flashMode = ACAMERA_FLASH_MODE_OFF; + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_FLASH_MODE, 1, &flashMode); + uint8_t nrMode = ACAMERA_NOISE_REDUCTION_MODE_FAST; status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_NOISE_REDUCTION_MODE, 1, &nrMode); @@ -649,7 +672,7 @@ 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); + // status = ACaptureRequest_setEntry_i32(capture_request, ACAMERA_CONTROL_AE_REGIONS, 5, aeRegions); if (status == ACAMERA_OK) { // m_imagesCaptured = ~0; @@ -689,8 +712,11 @@ int NdkCamera::open(const std::string& cameraId) { // TODO: // m_imagesCaptured = 0; - uint8_t awbMode = ACAMERA_CONTROL_AWB_MODE_AUTO; - status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AWB_MODE, 1, &awbMode); + if (awbSupported) + { + 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; @@ -897,6 +923,8 @@ void NdkCamera::onImageAvailable(AImageReader* reader) return; } + mResult.duration = GetMicroTimeStamp() - m_startTime; + int32_t format; AImage_getFormat(image, &format); @@ -1175,6 +1203,37 @@ 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; + val = { 0 }; + status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AWB_STATE, &val); + mResult.awbState = (status == ACAMERA_OK) ? val.data.u8[0] : ACAMERA_CONTROL_AWB_STATE_INACTIVE; + + val = { 0 }; + status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AF_STATE, &val); + mResult.afState = (status == ACAMERA_OK) ? *(val.data.u8) : ACAMERA_CONTROL_AF_STATE_INACTIVE; + + ALOGW("3ASTATE: ae=%u awb=%u af=%u", (uint32_t)mResult.aeState, (uint32_t)mResult.awbState, (uint32_t)mResult.afState); + + if (awbSupported && awbLockAvailable && mResult.awbState == ACAMERA_CONTROL_AWB_STATE_CONVERGED) + { + uint8_t awbLock = ACAMERA_CONTROL_AWB_LOCK_ON; + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AWB_LOCK, 1, &awbLock); + } + + if (m_params.autoExposure != 0) + { + if (mResult.aeState == ACAMERA_CONTROL_AE_STATE_PRECAPTURE) + { + uint8_t aePrecatureTrigger = ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_START; + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER, 1, &aePrecatureTrigger); + } + + if (aeLockAvailable && (mResult.aeState == ACAMERA_CONTROL_AE_STATE_CONVERGED || mResult.aeState == ACAMERA_CONTROL_AE_STATE_FLASH_REQUIRED)) + { + uint8_t aeLock = ACAMERA_CONTROL_AE_LOCK_ON; + status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_LOCK, 1,&aeLock); + } + } + if (!lightDetected) { val = { 0 }; @@ -1199,30 +1258,44 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque unsigned long long ts = GetMicroTimeStamp(); if (ts - m_startTime >= m_params.focusTimeout * 2) { - XYLOG(XYLOG_SEVERITY_WARNING, "onCaptureCompleted Timeout for AF/AE And will Capture AFS=%u AES=%u Time=%u", (unsigned int)mResult.afState, (unsigned int)mResult.aeState, (unsigned int)(ts - m_startTime)); + XYLOG(XYLOG_SEVERITY_WARNING, "Prepare Capture Timeout for 3A And will Capture AFS=%u AES=%u AWBS=%u Time=%u", + (unsigned int)mResult.afState, (unsigned int)mResult.aeState, (unsigned int)mResult.awbState, (unsigned int)(ts - m_startTime)); m_imagesCaptured = 0; } else { - if (m_params.autoExposure != 0) + if (awbSupported) { - if (mResult.aeState == ACAMERA_CONTROL_AE_STATE_SEARCHING) + if (m_params.wait3ALocked) { - // Waiting - return; + if (mResult.awbState != ACAMERA_CONTROL_AWB_STATE_LOCKED) + { + return; + } } - else if (mResult.aeState == ACAMERA_CONTROL_AE_STATE_PRECAPTURE) + else { - uint8_t aePrecatureTrigger = ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_START; - status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER, 1, &aePrecatureTrigger); - return; + if (mResult.awbState != ACAMERA_CONTROL_AWB_STATE_CONVERGED) + { + return; + } } - else if (mResult.aeState == ACAMERA_CONTROL_AE_STATE_CONVERGED) + } + + if (m_params.autoExposure != 0) + { + if (m_params.wait3ALocked) { - if (aeLockAvailable) + if (mResult.aeState != ACAMERA_CONTROL_AE_STATE_LOCKED) { - uint8_t aeLock = ACAMERA_CONTROL_AE_LOCK_ON; - status = ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_LOCK, 1, &aeLock); + return; + } + } + else + { + if (mResult.aeState != ACAMERA_CONTROL_AE_STATE_CONVERGED && mResult.aeState != ACAMERA_CONTROL_AE_STATE_FLASH_REQUIRED) + { + return; } } } @@ -1271,10 +1344,6 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque // ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity_); mResult.autoExposure = aeMode; - val = { 0 }; - status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AWB_STATE, &val); - mResult.awbState = (status == ACAMERA_OK) ? val.data.u8[0] : 0; - val = { 0 }; float focusDistance = NAN; if (afSupported && (m_params.autoFocus != 0)) diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index 48524cc5..c5c488a6 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -74,14 +74,16 @@ public: unsigned int autoExposure : 1; unsigned int orientation:3; unsigned int focusTimeout : 14; // milli-seconds 65535 / 4 - unsigned int zoom; - unsigned int reserved : 7; + unsigned int zoom : 1; + unsigned int wait3ALocked : 1; + unsigned int reserved : 6; unsigned int exposureTime; // ms unsigned short expsTimeUs; // μs unsigned int sensitivity; int compensation; float zoomRatio; uint8_t requestTemplate; + }; struct CAPTURE_RESULT @@ -98,6 +100,7 @@ public: uint8_t sceneMode; float zoomRatio; uint8_t avgY; + uint64_t duration; }; NdkCamera(int32_t width, int32_t height, const CAMERA_PARAMS& params); diff --git a/app/src/main/java/com/xypower/mpapp/ChannelActivity.java b/app/src/main/java/com/xypower/mpapp/ChannelActivity.java index bfb21938..2ca1bd3a 100644 --- a/app/src/main/java/com/xypower/mpapp/ChannelActivity.java +++ b/app/src/main/java/com/xypower/mpapp/ChannelActivity.java @@ -159,6 +159,7 @@ public class ChannelActivity extends AppCompatActivity { binding.btnUsbCamera.setChecked(jsonObject.optInt("usbCamera", 0) == 1); binding.btnAutoExplosure.setChecked(jsonObject.optInt("autoExposure", 1) == 1); binding.btnAutoFocus.setChecked(jsonObject.optInt("autoFocus", 1) == 1); + binding.btnWait3ALocked.setChecked(jsonObject.optInt("wait3ALocked", 0) != 0); binding.ldrEnabled.setChecked(jsonObject.optInt("ldrEnabled", 0) == 1); // binding.btnHdrMode.setChecked(jsonObject.optInt("hdrMode", 0) == 1); // binding.btnNightMode.setChecked(jsonObject.optInt("nightMode", 0) == 1); @@ -273,6 +274,7 @@ public class ChannelActivity extends AppCompatActivity { jsonObject.put("usbCamera", binding.btnUsbCamera.isChecked() ? 1 : 0); jsonObject.put("autoExposure", binding.btnAutoExplosure.isChecked() ? 1 : 0); jsonObject.put("autoFocus", binding.btnAutoFocus.isChecked() ? 1 : 0); + jsonObject.put("wait3ALocked", binding.btnWait3ALocked.isChecked() ? 1 : 0); jsonObject.put("ldrEnabled", binding.ldrEnabled.isChecked() ? 1 : 0); // jsonObject.put("hdrMode", binding.btnHdrMode.isChecked() ? 1 : 0); // jsonObject.put("nightMode", binding.btnNightMode.isChecked() ? 1 : 0); diff --git a/app/src/main/res/layout/activity_channel.xml b/app/src/main/res/layout/activity_channel.xml index 99c0b58d..eb0d8ed5 100644 --- a/app/src/main/res/layout/activity_channel.xml +++ b/app/src/main/res/layout/activity_channel.xml @@ -142,6 +142,16 @@ app:layout_constraintStart_toEndOf="@+id/btnAutoExplosure" app:layout_constraintTop_toBottomOf="@+id/resolutionCX" /> + + 短视频时长(秒) 曝光补偿 光敏控制 + 等待3A锁定 + Hello blank fragment Record