From a946d454e148ae613657a8c2f4d009ca86830e8c Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 17 Mar 2025 22:40:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=B8=BB=E5=88=86=E6=94=AF?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/cpp/camera2/ndkcamera.cpp | 504 ++++++++++--------------- app/src/main/cpp/camera2/ndkcamera.h | 13 +- 2 files changed, 200 insertions(+), 317 deletions(-) diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index 7e896d36..bb5bda93 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -32,6 +32,7 @@ #ifdef _DEBUG void Auto_AImage_delete(AImage* image) { + XYLOG(XYLOG_SEVERITY_DEBUG,"delete image"); AImage_delete(image); } #else @@ -81,7 +82,7 @@ static void onSessionReady(void* context, ACameraCaptureSession *session) static void onSessionClosed(void* context, ACameraCaptureSession *session) { - XYLOG(XYLOG_SEVERITY_INFO, "onSessionClosed %p", session); + XYLOG(XYLOG_SEVERITY_DEBUG, "onSessionClosed %p", session); } void onCaptureFailed(void* context, ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure) @@ -164,6 +165,7 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA mHeight = height; mCaptureTriggered = false; + mFocusTriggered = false; mCaptureDispatched = false; maxFrameDuration = 0; @@ -214,7 +216,7 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA mResult = { 0 }; mLdr = ~0; mFinalLdr = 0; - mFinalBurstCaptures = m_params.burstRawCapture == 0 ? 1 : m_params.burstCaptures; + mFinalBurstCaptures = m_params.burstRawCapture == 0 ? m_params.burstCaptures : m_params.burstCaptures; if (mFinalBurstCaptures == 0) { mFinalBurstCaptures = 1; @@ -224,6 +226,7 @@ NdkCamera::NdkCamera(int32_t width, int32_t height, const NdkCamera::CAMERA_PARA NdkCamera::~NdkCamera() { + XYLOG(XYLOG_SEVERITY_DEBUG, "NdkCamera::~NdkCamera %s", mCameraId.c_str()); close(); } @@ -733,201 +736,6 @@ int NdkCamera::open(const std::string& cameraId) { CaptureRequest *request = CreateRequest(true); mCaptureRequests.push_back(request); -#if 0 - for (int idx = 0; idx <= burstCaptures; idx++) - { - CaptureRequest *request = new CaptureRequest(); - std::memset(request, 0, sizeof(CaptureRequest)); - - bool isPreviewRequest = (idx == PREVIEW_REQUEST_IDX); - - request->pThis = this; - request->imageReader = isPreviewRequest ? mPreviewImageReader : mImageReader; - request->imageWindow = isPreviewRequest ? mPreviewImageWindow : mImageWindow; - request->imageTarget = isPreviewRequest ? mPreviewOutputTarget : mOutputTarget; - request->templateId = isPreviewRequest ? TEMPLATE_PREVIEW : (ACameraDevice_request_template)m_params.requestTemplate; - - // capture request - status = ACameraDevice_createCaptureRequest(camera_device, request->templateId, &request->request); - ACaptureRequest_setUserContext(request->request, request); - - // uint8_t ctrlMode = sceneModeSupported ? ACAMERA_CONTROL_MODE_USE_SCENE_MODE : ACAMERA_CONTROL_MODE_AUTO; - uint8_t ctrlMode = ACAMERA_CONTROL_MODE_AUTO; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_MODE, 1, &ctrlMode); - - uint8_t captureIntent = isPreviewRequest ? ACAMERA_CONTROL_CAPTURE_INTENT_PREVIEW : GetCaptureIntent(ACameraDevice_request_template)m_params.requestTemplate); - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_CAPTURE_INTENT, 1, &captureIntent); - - uint8_t flashMode = ACAMERA_FLASH_MODE_OFF; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_FLASH_MODE, 1, &flashMode); - - uint8_t nrMode = ACAMERA_NOISE_REDUCTION_MODE_HIGH_QUALITY; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_NOISE_REDUCTION_MODE, 1, &nrMode); - - uint8_t edgeMode = ACAMERA_EDGE_MODE_FAST; - // status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_EDGE_MODE, 1, &edgeMode); - - if (afSupported && m_params.autoFocus) - { - 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(request->request, ACAMERA_CONTROL_AF_REGIONS, 5, afRegions); - if (status == ACAMERA_OK) - { -#ifdef _DEBUG - int aa = 0; -#endif - } - } - - // 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; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_MODE, 1, &afMode); - - // uint8_t trig = ACAMERA_CONTROL_AF_TRIGGER_CANCEL; - // status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); - - // trig = ACAMERA_CONTROL_AF_TRIGGER_START; - // status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); - } - } - else - { - uint8_t trig = ACAMERA_CONTROL_AF_TRIGGER_START; - // status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); - } - - if (m_params.sceneMode != 0) - { - uint8_t sceneMode = m_params.sceneMode; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_SCENE_MODE, 1, &sceneMode); - } - - if (m_params.autoExposure) - { - uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_ON; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AE_MODE, 1, &aeMode); - // ACaptureRequest_setEntry_i32(capture_request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity_); - - if ((aeCompensationRange.min_ != 0 || aeCompensationRange.max_ != 0) && m_params.compensation != 0) - { - int32_t compensation = m_params.compensation; - if (compensation < aeCompensationRange.min_) - { - compensation = aeCompensationRange.min_; - } - if (compensation > aeCompensationRange.max_) - { - compensation = aeCompensationRange.max_; - } - // int32_t aeCompensation = aeCompensationRange.max_; - status = ACaptureRequest_setEntry_i32(request->request, ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION, 1, &compensation); - if (status != ACAMERA_OK) - { - int aa = 0; - } - } - - 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) - { -#ifdef _DEBUG - int aa = 0; -#endif - } - } - - if (isPreviewRequest) - { - if (aeLockAvailable && (m_params.wait3ALocked & WAIT_AE_LOCKED)) - { - uint8_t aeLock = ACAMERA_CONTROL_AE_LOCK_ON; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AE_LOCK, 1, &aeLock); - - XYLOG(XYLOG_SEVERITY_DEBUG, "Try to Lock AE"); - mResult.aeLockSetted = 1; - } - else - { - uint8_t aeLock = ACAMERA_CONTROL_AE_LOCK_OFF; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AE_LOCK, 1, &aeLock); - XYLOG(XYLOG_SEVERITY_DEBUG, "AE_Lock Not Supported"); - } - - uint8_t aePrecatureTrigger = ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_START; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER, 1, &aePrecatureTrigger); - XYLOG(XYLOG_SEVERITY_DEBUG, "Trigger PRECAPTURE status=%d", (int)status); - m_precaptureStartTime = m_startTime; - - // ACaptureRequest_setEntry_u8(capture_request, ACAMERA_CONTROL_AE_LOCK, 1, &aeLockOff); - } - } - else - { - uint8_t aeMode = ACAMERA_CONTROL_AE_MODE_OFF; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AE_MODE, 1, &aeMode); - - if (m_params.sensitivity > 0) - { - int32_t sensitivity = m_params.sensitivity; - status = ACaptureRequest_setEntry_i32(request->request, ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity); - } - if (m_params.exposureTime > 0) - { - int64_t exposureTime = m_params.exposureTime; - status = ACaptureRequest_setEntry_i64(request->request, ACAMERA_SENSOR_EXPOSURE_TIME, 1, &exposureTime); - } - - int64_t frameDuration = maxFrameDuration / 2; - // status = ACaptureRequest_setEntry_i64(request->request, ACAMERA_SENSOR_FRAME_DURATION, 1, &frameDuration); - } - - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AWB_MODE, 1, &awbMode); - if ((awbMode == ACAMERA_CONTROL_AWB_MODE_AUTO) && awbLockAvailable && (m_params.wait3ALocked & WAIT_AWB_LOCKED)) - { - uint8_t awbLock = ACAMERA_CONTROL_AWB_LOCK_ON; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AWB_LOCK, 1, &awbLock); - mResult.awbLockSetted = 1; - - XYLOG(XYLOG_SEVERITY_DEBUG, "Try to Lock AWB AWBS=%u", (unsigned int)mResult.awbState); - } - -#if 0 - uint8_t antiBandingMode = ACAMERA_CONTROL_AE_ANTIBANDING_MODE_60HZ; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AE_ANTIBANDING_MODE, 1, &antiBandingMode); - uint8_t flicker = ACAMERA_STATISTICS_SCENE_FLICKER_60HZ; - status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_STATISTICS_SCENE_FLICKER, 1, &flicker); -#endif - - if (m_params.zoom) - { - float zoomRatio = m_params.zoomRatio; - // uint8_t afMode = ACAMERA_CONTROL_AF_MODE_AUTO; - status = ACaptureRequest_setEntry_float(request->request, ACAMERA_CONTROL_ZOOM_RATIO, 1, &zoomRatio); - if (status != ACAMERA_OK) - { - } - } - - status = ACaptureRequest_addTarget(request->request, request->imageTarget); - - status = ACaptureSessionOutput_create(request->imageWindow, &request->sessionOutput); - status = ACaptureSessionOutputContainer_add(capture_session_output_container, request->sessionOutput); - } -#endif // capture session ACameraCaptureSession_stateCallbacks camera_capture_session_state_callbacks; @@ -1024,11 +832,18 @@ NdkCamera::CaptureRequest* NdkCamera::CreateRequest(bool isPreviewRequest) // uint8_t afMode = ACAMERA_CONTROL_AF_MODE_AUTO; status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_MODE, 1, &afMode); - // uint8_t trig = ACAMERA_CONTROL_AF_TRIGGER_CANCEL; - // status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); +#if 0 + // For ACAMERA_CONTROL_AF_MODE_CONTINUOUS_PICTURE, we SHOULD NOT call ACAMERA_CONTROL_AF_TRIGGER_START + // Refer to: https://source.android.google.cn/docs/core/camera/camera3_3Amodes?hl=zh-cn + if (isPreviewRequest) + { + // uint8_t trig = ACAMERA_CONTROL_AF_TRIGGER_CANCEL; + // status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); - // trig = ACAMERA_CONTROL_AF_TRIGGER_START; - // status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); + // trig = ACAMERA_CONTROL_AF_TRIGGER_START; + // status = ACaptureRequest_setEntry_u8(request->request, ACAMERA_CONTROL_AF_TRIGGER, 1, &trig); + } +#endif } } else @@ -1161,6 +976,11 @@ NdkCamera::CaptureRequest* NdkCamera::CreateRequest(bool isPreviewRequest) return request; } +void NdkCamera::DestroyRequest(CaptureRequest* request) +{ + +} + void NdkCamera::close() { XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::try close %s", mCameraId.c_str()); @@ -1181,6 +1001,8 @@ void NdkCamera::close() } */ + mPreviewResults.reset(); + mCaptureResults.clear(); mCaptureFrames.clear(); mCaptureResultMap.clear(); @@ -1191,9 +1013,9 @@ void NdkCamera::close() if (capture_session) { - // res = ACameraCaptureSession_stopRepeating(capture_session); + res = ACameraCaptureSession_stopRepeating(capture_session); + std::this_thread::sleep_for(std::chrono::milliseconds(512)); ACameraCaptureSession_close(capture_session); - std::this_thread::sleep_for(std::chrono::milliseconds(512)); capture_session = 0; } @@ -1234,12 +1056,24 @@ void NdkCamera::close() if (mPreviewImageReader != NULL) { +#ifdef _DEBUG + ALOGD("Will Free mPreviewImageReader"); +#endif + AImage* image = NULL; + media_status_t mstatus; + while ((mstatus = AImageReader_acquireNextImage(mPreviewImageReader, &image)) == AMEDIA_OK) + { + AImage_delete(image); + image = NULL; + } AImageReader_setImageListener(mPreviewImageReader, NULL); //XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::AImageReader_delete %s", mCameraId.c_str()); AImageReader_delete(mPreviewImageReader); //XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::End AImageReader_delete %s", mCameraId.c_str()); - mPreviewImageReader = 0; +#ifdef _DEBUG + ALOGD("After Free mPreviewImageReader"); +#endif } if (mOutputTarget != NULL) @@ -1256,26 +1090,37 @@ void NdkCamera::close() if (mImageReader != NULL) { +#ifdef _DEBUG + ALOGD("Will Free mImageReader"); +#endif + AImage* image = NULL; + media_status_t mstatus; + while ((mstatus = AImageReader_acquireNextImage(mImageReader, &image)) == AMEDIA_OK) + { + AImage_delete(image); + image = NULL; + } AImageReader_setImageListener(mImageReader, NULL); + //XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::AImageReader_delete %s", mCameraId.c_str()); AImageReader_delete(mImageReader); - //XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::End AImageReader_delete %s", mCameraId.c_str()); + //XYLOG(XYLOG_SEVERITY_DEBUG, "CameraStatus::End AImageReader_delete %s", mCameraId.c_str()); mImageReader = 0; +#ifdef _DEBUG + ALOGD("After Free mImageReader"); +#endif } - if (mOutputTarget2 != NULL) { ACameraOutputTarget_free(mOutputTarget2); mOutputTarget2 = 0; } - if (mImageWindow2 != NULL) { ANativeWindow_release(mImageWindow2); mImageWindow2 = 0; } - if (mImageReader2 != NULL) { AImageReader_setImageListener(mImageReader2, NULL); @@ -1285,7 +1130,6 @@ void NdkCamera::close() mImageReader2 = 0; } - if (mPreviewSessionOutput != NULL) { if (capture_session_output_container) @@ -1373,102 +1217,113 @@ void NdkCamera::onImageAvailable(AImageReader* reader) else { uint32_t burstCaptures = getBurstCaptures(); + uint64_t ts = GetMicroTimeStamp(); + size_t expectedTimes = mCaptureRequests.size() - 1; if (burstCaptures == 0) { burstCaptures = 1; } - if (burstCaptures == 1) + if (m_params.burstRawCapture == 0) { - mstatus = AImageReader_acquireNextImage(reader, &image); - if (mstatus != AMEDIA_OK) + while (1) { - // https://stackoverflow.com/questions/67063562 - if (mstatus != AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) + mstatus = AImageReader_acquireNextImage(reader, &image); + if (mstatus != AMEDIA_OK) { - if (mCaptureFrames.size() < burstCaptures) + // https://stackoverflow.com/questions/67063562 + if (mstatus != AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) { - XYLOG(XYLOG_SEVERITY_ERROR, "Capture AImageReader_acquireNextImage error: %d", mstatus); + if (mCaptureFrames.size() < burstCaptures) + { + XYLOG(XYLOG_SEVERITY_ERROR, "Capture AImageReader_acquireNextImage error: %d", mstatus); + } } + break; } - return; - } - - unsigned long long ts = GetMicroTimeStamp(); - int32_t format; - mstatus = AImage_getFormat(image, &format); + int32_t format; + mstatus = AImage_getFormat(image, &format); - if (format == AIMAGE_FORMAT_YUV_420_888) - { - int32_t width; - int32_t height; - mstatus = AImage_getWidth(image, &width); - mstatus = AImage_getHeight(image, &height); - - int32_t y_pixelStride = 0; - int32_t u_pixelStride = 0; - int32_t v_pixelStride = 0; - AImage_getPlanePixelStride(image, 0, &y_pixelStride); - AImage_getPlanePixelStride(image, 1, &u_pixelStride); - AImage_getPlanePixelStride(image, 2, &v_pixelStride); - - int32_t y_rowStride = 0; - int32_t u_rowStride = 0; - int32_t v_rowStride = 0; - AImage_getPlaneRowStride(image, 0, &y_rowStride); - AImage_getPlaneRowStride(image, 1, &u_rowStride); - AImage_getPlaneRowStride(image, 2, &v_rowStride); - - uint8_t* y_data = 0; - uint8_t* u_data = 0; - uint8_t* v_data = 0; - int y_len = 0; - int u_len = 0; - int v_len = 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 (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) - { - // already nv21 - ConvertYUV21ToMat(y_data, width, height, mWidth, mHeight, camera_orientation, - camera_facing == ACAMERA_LENS_FACING_FRONT, m_params.orientation, mOneFrame); - } - else + cv::Mat frame; + if (format == AIMAGE_FORMAT_YUV_420_888) { - // construct nv21 - uint8_t* nv21 = new uint8_t[width * height + width * height / 2]; + int32_t width; + int32_t height; + mstatus = AImage_getWidth(image, &width); + mstatus = AImage_getHeight(image, &height); + + int32_t y_pixelStride = 0; + int32_t u_pixelStride = 0; + int32_t v_pixelStride = 0; + AImage_getPlanePixelStride(image, 0, &y_pixelStride); + AImage_getPlanePixelStride(image, 1, &u_pixelStride); + AImage_getPlanePixelStride(image, 2, &v_pixelStride); + + int32_t y_rowStride = 0; + int32_t u_rowStride = 0; + int32_t v_rowStride = 0; + AImage_getPlaneRowStride(image, 0, &y_rowStride); + AImage_getPlaneRowStride(image, 1, &u_rowStride); + AImage_getPlaneRowStride(image, 2, &v_rowStride); + + uint8_t* y_data = 0; + uint8_t* u_data = 0; + uint8_t* v_data = 0; + int y_len = 0; + int u_len = 0; + int v_len = 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 (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) + { + // already nv21 + ConvertYUV21ToMat(y_data, width, height, mWidth, mHeight, camera_orientation, + camera_facing == ACAMERA_LENS_FACING_FRONT, m_params.orientation, frame); + } + else { - // Y - uint8_t* yptr = nv21; - for (int y = 0; y < height; y++) + // construct nv21 + uint8_t* nv21 = new uint8_t[width * height + width * height / 2]; { - const uint8_t* y_data_ptr = y_data + y_rowStride * y; - for (int x = 0; x < width; x++) + // Y + uint8_t* yptr = nv21; + for (int y = 0; y < height; y++) { - yptr[0] = y_data_ptr[0]; - yptr++; - y_data_ptr += y_pixelStride; + const uint8_t* y_data_ptr = y_data + y_rowStride * y; + for (int x = 0; x < width; x++) + { + yptr[0] = y_data_ptr[0]; + yptr++; + y_data_ptr += y_pixelStride; + } } - } - // UV - uint8_t* uvptr = nv21 + width * height; - for (int y = 0; y < height / 2; y++) - { - const uint8_t* v_data_ptr = v_data + v_rowStride * y; - const uint8_t* u_data_ptr = u_data + u_rowStride * y; - for (int x = 0; x < width / 2; x++) + // UV + uint8_t* uvptr = nv21 + width * height; + for (int y = 0; y < height / 2; y++) { - uvptr[0] = v_data_ptr[0]; - uvptr[1] = u_data_ptr[0]; - uvptr += 2; - v_data_ptr += v_pixelStride; - u_data_ptr += u_pixelStride; + const uint8_t* v_data_ptr = v_data + v_rowStride * y; + const uint8_t* u_data_ptr = u_data + u_rowStride * y; + for (int x = 0; x < width / 2; x++) + { + uvptr[0] = v_data_ptr[0]; + uvptr[1] = u_data_ptr[0]; + uvptr += 2; + v_data_ptr += v_pixelStride; + u_data_ptr += u_pixelStride; + } } } + + ConvertYUV21ToMat(nv21, width, height,mWidth, mHeight, camera_orientation, + camera_facing == ACAMERA_LENS_FACING_FRONT, m_params.orientation, frame); + + delete[] nv21; } + } + m_photoTaken = true; int64_t frameTs = 0; mstatus = AImage_getTimestamp(image, &frameTs); @@ -1505,27 +1360,14 @@ void NdkCamera::onImageAvailable(AImageReader* reader) } m_locker.unlock(); - AImage_delete(image); - - std::shared_ptr result; - bool captureCompleted = false; - bool captureDispatchable = false; - m_locker.lock(); - if (!mCaptureResults.empty()) - { - captureCompleted = true; - result = mCaptureResults[0]; - } - if (captureCompleted && !mCaptureDispatched) - { - mCaptureDispatched = true; - captureDispatchable = true; - } - m_locker.unlock(); - - if (captureCompleted && captureDispatchable) - { - onOneCapture(mCharacteristics, result, mFinalLdr, ts - m_startTime, mOneFrame); + if (captureCompleted && captureDispatchable) + { + XYLOG(XYLOG_SEVERITY_INFO,"onOneCapture from onImageAvailable"); + camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session); + FireOneCapture(ts); + // onOneCapture(mCharacteristics, result, mFinalLdr, ts - m_startTime, mOneFrame); + break; + } } } else @@ -1557,7 +1399,6 @@ void NdkCamera::onImageAvailable(AImageReader* reader) bool captureCompleted = false; bool captureDispatchable = false; - size_t expectedTimes = mCaptureRequests.size() - 1; m_locker.lock(); captureCompleted = mCaptureResults.size() >= expectedTimes && mCaptureFrames.size() >= expectedTimes; if (captureCompleted && !mCaptureDispatched) @@ -1763,8 +1604,7 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque status = ACameraMetadata_getConstEntry(result, ACAMERA_CONTROL_AF_STATE, &val); afState = (status == ACAMERA_OK) ? *(val.data.u8) : ACAMERA_CONTROL_AF_STATE_INACTIVE; - // ALOGW("Preview State AFS=%u AES=%u AWBS=%u Time=%u", - // (unsigned int)afState, (unsigned int)aeState, (unsigned int)awbState, (unsigned int)(ts - m_startTime)); + // XYLOG(XYLOG_SEVERITY_DEBUG, "Preview State AFS=%u AES=%u AWBS=%u Time=%u", (unsigned int)afState, (unsigned int)aeState, (unsigned int)awbState, (unsigned int)(ts - m_startTime)); // Check if timeout if (ts - m_startTime < m_params.focusTimeout) @@ -1788,8 +1628,8 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque */ if (afState != ACAMERA_CONTROL_AF_STATE_PASSIVE_FOCUSED && - afState != ACAMERA_CONTROL_AF_STATE_FOCUSED_LOCKED && - afState != ACAMERA_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) + afState != ACAMERA_CONTROL_AF_STATE_FOCUSED_LOCKED/* && + afState != ACAMERA_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED*/) // if (afState != ACAMERA_CONTROL_AF_STATE_INACTIVE) { //XYLOG(XYLOG_SEVERITY_DEBUG, "AF Enabled And Focused"); @@ -1806,7 +1646,7 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque aePrecatureTrigger = ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER_START; status = ACaptureRequest_setEntry_u8(request, ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER, 1, &aePrecatureTrigger); - //XYLOG(XYLOG_SEVERITY_DEBUG, "Trigger PRECAPTURE status=%d AES=%u", (int)status, (unsigned int)mResult.aeState); + //XYLOG(XYLOG_SEVERITY_DEBUG, "Trigger PRECAPTURE status=%d AES=%u", (int)status, (unsigned int)aeState); AASSERT(status == ACAMERA_OK, "Failed to call PRECAPTURE_TRIGGER, status=%d", status); readyForCapture = false; @@ -1917,6 +1757,37 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque requests.push_back(request->request); } + if (m_params.customHdr) + { + int32_t hdrStep = m_params.hdrStep; + if (hdrStep == 0) + { + hdrStep = 1; + } + + val = { 0 }; + status = ACameraMetadata_getConstEntry(result, ACAMERA_SENSOR_EXPOSURE_TIME, &val); + int64_t exTime = (status == ACAMERA_OK) ? val.data.i64[0] : -1; + + val = {0}; + status = ACameraMetadata_getConstEntry(result, ACAMERA_SENSOR_SENSITIVITY, &val); + int sensitivity = (status == ACAMERA_OK) ? *(val.data.i32) : 0; + + XYLOG(XYLOG_SEVERITY_INFO, "HDR: Base Exp=%lld ISO=%d", exTime / 1000, sensitivity); + if (exTime != -1 && sensitivity > 0) + { + uint8_t aeModeOff = ACAMERA_CONTROL_AE_MODE_OFF; + for (int idx = 0; idx < burstCaptures; idx++) + { + ACaptureRequest_setEntry_u8(requests[idx], ACAMERA_CONTROL_AE_MODE, 1, &aeModeOff); + int64_t expt = (idx == 0) ? exTime : (exTime * (hdrStep + idx)); + ACaptureRequest_setEntry_i64(requests[idx], ACAMERA_SENSOR_EXPOSURE_TIME, 1, &expt); + ACaptureRequest_setEntry_i32(requests[idx], ACAMERA_SENSOR_SENSITIVITY, 1, &sensitivity); + sensitivity = sensitivityRange.min_; + } + } + } + // ALOGW("Will Stop Repeating Request"); // status = ACameraCaptureSession_stopRepeating(capture_session); // ALOGW("Finished Repeating Request"); @@ -1994,7 +1865,10 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque if (captureCompleted && captureDispatchable) { - onOneCapture(mCharacteristics, captureResult, mFinalLdr, ts - m_startTime, mOneFrame); + XYLOG(XYLOG_SEVERITY_INFO,"onOneCapture from onCaptureCompleted"); + camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session); + + FireOneCapture(ts); } } else @@ -2058,6 +1932,8 @@ void NdkCamera::FireOneCapture(uint64_t ts) void NdkCamera::FireBurstCapture() { + camera_status_t status = ACameraCaptureSession_stopRepeating(capture_session); + unsigned long long ts = GetMicroTimeStamp(); size_t expectedTimes = mCaptureRequests.size() - 1; @@ -2143,9 +2019,11 @@ void NdkCamera::CopyPreviewRequest(ACaptureRequest* request, const ACameraMetada void NdkCamera::onCaptureFailed(ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure) { - XYLOG(XYLOG_SEVERITY_WARNING, "onCaptureFailed session=%p request=%p reason=%d PhotoTaken=%d", session, request, failure->reason, m_photoTaken ? 1 : 0); + bool isPreview = (request == mCaptureRequests[PREVIEW_REQUEST_IDX]->request); + + XYLOG(XYLOG_SEVERITY_WARNING, "onCaptureFailed session=%p request=%p reason=%d CameraId=%s PhotoTaken=%d Preview=%d", session, request, failure->reason, mCameraId.c_str(), m_photoTaken ? 1 : 0, isPreview ? 1 : 0); - if (failure->sequenceId == mCaptureRequests[PREVIEW_REQUEST_IDX]->sessionSequenceId) + if (isPreview) { return; } diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index 7e6a21ba..fe4384eb 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -83,7 +83,9 @@ public: unsigned int zoom : 1; unsigned int wait3ALocked : 3; unsigned int burstRawCapture : 2; - unsigned int reserved : 16; + unsigned int customHdr : 1; + unsigned int hdrStep : 3; + unsigned int reserved : 12; int64_t exposureTime; unsigned int sensitivity; int compensation; @@ -160,6 +162,7 @@ public: void CreateSession(ANativeWindow* previewWindow); CaptureRequest* CreateRequest(bool isPreviewRequest); + void DestroyRequest(CaptureRequest* request); void DestroySession(); @@ -181,6 +184,7 @@ public: void CopyPreviewRequest(ACaptureRequest* request, const ACameraMetadata* previewResult); void FireBurstCapture(); + void FireOneCapture(uint64_t ts); uint32_t GetLdr() const { @@ -234,10 +238,11 @@ protected: int32_t maxRegions[3]; bool mCaptureTriggered; + bool mFocusTriggered; bool mCaptureDispatched; CAPTURE_RESULT mResult; - unsigned long long m_startTime; + uint64_t m_startTime; protected: @@ -266,6 +271,8 @@ protected: std::shared_ptr mCharacteristics; std::vector mCaptureRequests; + ACameraCaptureSession* capture_session; + std::shared_ptr mPreviewResults; std::vector > mCaptureResults; std::map > mCaptureResultMap; @@ -279,8 +286,6 @@ protected: std::vector > mOneFrame; std::vector > mRawFrames; - ACameraCaptureSession* capture_session; - // AImageReader* image_reader; // ANativeWindow* image_reader_surface; // ACameraOutputTarget* image_reader_target;