diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index 39adc479..bb5bda93 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -1004,6 +1004,7 @@ void NdkCamera::close() mPreviewResults.reset(); mCaptureResults.clear(); mCaptureFrames.clear(); + mCaptureResultMap.clear(); if ((ACameraManager *)camera_manager != NULL) { @@ -1324,6 +1325,8 @@ void NdkCamera::onImageAvailable(AImageReader* reader) } m_photoTaken = true; + int64_t frameTs = 0; + mstatus = AImage_getTimestamp(image, &frameTs); AImage_delete(image); bool captureCompleted = false; @@ -1331,13 +1334,26 @@ void NdkCamera::onImageAvailable(AImageReader* reader) m_locker.lock(); if (!frame.empty()) { - mOneFrame.push_back(frame); + mOneFrame.push_back(std::make_pair<>(frameTs, frame)); } - if (mCaptureResults.size() == expectedTimes && mOneFrame.size() == expectedTimes) - { - captureCompleted = true; - } - if (captureCompleted && !mCaptureDispatched) + if (mOneFrame.size() >= expectedTimes) + { + bool allExisted = true; + for (auto itFrame = mOneFrame.cbegin(); itFrame != mOneFrame.cend(); ++itFrame) + { + if (mCaptureResultMap.find(itFrame->first) == mCaptureResultMap.cend()) + { + allExisted = false; + break; + } + } + if (allExisted) + { + captureCompleted = true; + } + } + + if (captureCompleted && !mCaptureDispatched) { mCaptureDispatched = true; captureDispatchable = true; @@ -1814,12 +1830,32 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque bool captureDispatchable = false; size_t expectedTimes = mCaptureRequests.size() - 1; + int64_t resultTimestamp = GetTimestamp(result); std::shared_ptr captureResult(pCopy, ACameraMetadata_free); + if (m_params.burstRawCapture == 0) { m_locker.lock(); mCaptureResults.push_back(captureResult); - captureCompleted = mCaptureFrames.size() >= expectedTimes && mCaptureResults.size() >= expectedTimes; + mCaptureResultMap[resultTimestamp] = captureResult; + + if (mOneFrame.size() >= expectedTimes) + { + bool allExisted = true; + for (auto itFrame = mOneFrame.cbegin(); itFrame != mOneFrame.cend(); ++itFrame) + { + if (mCaptureResultMap.find(itFrame->first) == mCaptureResultMap.cend()) + { + allExisted = false; + break; + } + } + if (allExisted) + { + captureCompleted = true; + } + } + if (captureCompleted && !mCaptureDispatched) { mCaptureDispatched = true; @@ -1856,6 +1892,18 @@ void NdkCamera::onCaptureCompleted(ACameraCaptureSession* session, ACaptureReque } } +int64_t NdkCamera::GetTimestamp(const ACameraMetadata* result) +{ + ACameraMetadata_const_entry entry; + camera_status_t status = ACameraMetadata_getConstEntry(result, ACAMERA_SENSOR_TIMESTAMP, &entry); + + if (status == ACAMERA_OK && entry.count > 0) { + return entry.data.i64[0]; + } + + return 0; +} + void NdkCamera::FireOneCapture(uint64_t ts) { #ifdef OUTPUT_DBG_INFO @@ -1866,7 +1914,6 @@ void NdkCamera::FireOneCapture(uint64_t ts) params.push_back(cv::IMWRITE_JPEG_QUALITY); params.push_back(50); - for (auto it = mOneFrame.cbegin(); it != mOneFrame.cend(); ++it) { std::string fileName = "/sdcard/com.xypower.mpapp/tmp/" + dt; @@ -1876,11 +1923,11 @@ void NdkCamera::FireOneCapture(uint64_t ts) EnumCameraResult(result.get(), captureResult); fileName += "_" + mCameraId + "_" + std::to_string(captureResult.aeState) + "_" + std::to_string(idx) + ".jpg"; - cv::imwrite(fileName, *it, params); + cv::imwrite(fileName, it->second, params); } } #endif - onOneCapture(mCharacteristics, mCaptureResults.back(), mFinalLdr, ts - m_startTime, mOneFrame.back()); + onOneCapture(mCharacteristics, mCaptureResults.back(), mFinalLdr, ts - m_startTime, mOneFrame.back().second); } void NdkCamera::FireBurstCapture() diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index 94dbde8f..fe4384eb 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -23,6 +23,7 @@ #include #include "Camera2Helper.h" #include +#include #include /** @@ -196,6 +197,7 @@ public: } bool IsCameraAvailable(const std::string& cameraId); + int64_t GetTimestamp(const ACameraMetadata* result); static bool convertAImageToNv21(AImage* image, uint8_t** nv21, int32_t& width, int32_t& height); static void EnumCameraResult(ACameraMetadata* result, CAPTURE_RESULT& captureResult); @@ -273,6 +275,7 @@ protected: std::shared_ptr mPreviewResults; std::vector > mCaptureResults; + std::map > mCaptureResultMap; uint32_t mLdr; uint32_t mFinalLdr; uint32_t mFinalBurstCaptures; @@ -280,7 +283,7 @@ protected: std::vector > mCaptureFrames; // cv::Mat mOneFrame; - std::vector mOneFrame; + std::vector > mOneFrame; std::vector > mRawFrames; // AImageReader* image_reader;