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