From 1292427410c70d847d97202e72c5ffcc0a42b55b Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 11 Oct 2024 18:42:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=8B=AC=E7=AB=8B=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E5=A4=84=E7=90=86raw=E7=85=A7=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 避免持续内存泄漏 --- app/src/main/cpp/CMakeLists.txt | 12 +- app/src/main/cpp/MicroPhoto.cpp | 9 +- app/src/main/cpp/PhoneDevice.cpp | 151 +++++++----------- app/src/main/cpp/PhoneDevice.h | 4 +- app/src/main/cpp/hdrplus/bin/hdrplus.cpp | 12 +- .../com/xypower/mpapp/MicroPhotoService.java | 59 +++++++ 6 files changed, 139 insertions(+), 108 deletions(-) diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index 3b238683..5be83f4d 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -41,8 +41,8 @@ add_definitions(-DALIGN_HB_TIMER_TO_PHOTO) add_definitions(-DENABLE_3V3_ALWAYS) add_definitions(-DUSING_HDRPLUS) - -# add_definitions(-DUSING_EXEC_HDRP=1) +add_definitions(-DUSING_EXEC_HDRP=1) +set(USING_EXEC_HDRP 1) #add_definitions(-DUSING_N938) @@ -327,6 +327,7 @@ add_library( if(USING_EXEC_HDRP) + message(WARNING "HDRP Compiled") add_executable( libhdrp.so ${HDRPLUS_SOURCES} hdrplus/bin/hdrplus.cpp ) @@ -336,6 +337,9 @@ target_link_libraries( libhdrp.so PUBLIC -fopenmp -static-openmp # ${LIBRAW_LIBRARY} ${HDRPLUS_LIBS} ) +else(USING_EXEC_HDRP) +SET(HDRPLUS_SOURCES_EMBED ${HDRPLUS_SOURCES} ) +SET(HDRPLUS_LIBS_EMBED ${HDRPLUS_LIBS} ) endif() add_library( # Sets the name of the library. @@ -365,7 +369,7 @@ add_library( # Sets the name of the library. # camera2/OpenCVFont.cpp - ${HDRPLUS_SOURCES} + ${HDRPLUS_SOURCES_EMBED} ${CAMERA2_SOURCES} ${IMG_UTILS_SRCS} @@ -441,7 +445,7 @@ target_link_libraries( # Specifies the target library. android camera2ndk mediandk z - ncnn ${OpenCV_LIBS} sqlite3 ${HDRPLUS_LIBS} + ncnn ${OpenCV_LIBS} sqlite3 ${HDRPLUS_LIBS_EMBED} ) diff --git a/app/src/main/cpp/MicroPhoto.cpp b/app/src/main/cpp/MicroPhoto.cpp index ce8b60be..51439600 100644 --- a/app/src/main/cpp/MicroPhoto.cpp +++ b/app/src/main/cpp/MicroPhoto.cpp @@ -333,9 +333,14 @@ Java_com_xypower_mpapp_MicroPhotoService_init( // pTerminal->SetPacketSize(1 * 1024); // 1K #if defined(USING_NRSEC) && !defined(USING_NRSEC_VPN) pTerminal->InitEncryptionInfo(simcardStr, "/dev/spidev0.0", ""); +#endif +#ifdef _DEBUG + ALOGD("Call Startup"); #endif bool res = pTerminal->Startup(device); - +#ifdef _DEBUG + ALOGD("Finish Startup"); +#endif if (appPathStr != NULL) env->ReleaseStringUTFChars(appPath, appPathStr); if (ipStr != NULL) env->ReleaseStringUTFChars(ip, ipStr); if (cmdidStr != NULL) env->ReleaseStringUTFChars(cmdid, cmdidStr); @@ -888,9 +893,11 @@ Java_com_xypower_mpapp_MicroPhotoService_burstCaptureFinished( return; } +#if 0 const char* pathsStr = env->GetStringUTFChars(pathsJoinedByTab, 0); ((CPhoneDevice *)dev)->ProcessRawCapture(result != JNI_FALSE, numberOfCaptures, MakeString(pathsStr), frontCamera != JNI_FALSE, rotation, photoId); env->ReleaseStringUTFChars(pathsJoinedByTab, pathsStr); +#endif } } diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index 23ee728d..d75213a5 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -431,6 +431,8 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPa mEnableGpsMid = env->GetMethodID(classService, "enableGps", "(Z)V"); mRequestPositionMid = env->GetMethodID(classService, "requestPosition", "()Z"); + mExecHdrplusMid = env->GetMethodID(classService, "execHdrplus", "(IILjava/lang/String;Ljava/lang/String;)I"); + env->DeleteLocalRef(classService); } @@ -441,6 +443,7 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPa m_timerUidFeed = time(NULL) * 1000; m_wakelockIdFeed = (unsigned long)m_timerUidFeed; + m_uniqueIdFeed = (unsigned long)m_timerUidFeed; #ifdef USING_NRSEC TurnOnCameraPower(env); @@ -502,7 +505,7 @@ void CPhoneDevice::SetRecognizationCfg(const IDevice::CFG_RECOGNIZATION* pRecogn } else { - XYLOG(XYLOG_SEVERITY_INFO, "AI Enabled"); + XYLOG(XYLOG_SEVERITY_INFO, "AI Enabled and will Init NCNN"); ncnn_init(); mAIInitialized = true; bool res = YoloV5Ncnn_Init(paramFile, binFile); @@ -1836,60 +1839,43 @@ bool CPhoneDevice::onBurstCapture(std::shared_ptr characteristi pThis->TakePhotoCb(1, photoInfo, "", takingTime); #ifdef USING_EXEC_HDRP - // exec() { uint64_t uniqueId = pThis->m_uniqueIdFeed.fetch_add(1); - std::string cmd = pThis->m_nativeLibraryDir; - if (!endsWith(cmd, DIR_SEP_STR)) - { - cmd += DIR_SEP_STR; - } std::string tmpDir = pThis->m_appPath + (APP_DIR_TMP DIR_SEP_STR) + std::to_string(uniqueId) + DIR_SEP_STR; EnsureDirectoryPathExists(tmpDir); - cmd += "libhdrp.so"; std::vector > localFrames; localFrames.swap(pByteArrays.get()->byteArrays); - std::string outputPath = tmpDir + "output.tiff"; + std::string outputPath = tmpDir + "output.bmp"; size_t numberOfFrames = localFrames.size(); - size_t argc = numberOfFrames + 4; - char** argv = new char*[argc]; - argv[argc - 1] = NULL; - argv[0] = MakeArgv(std::to_string(photoInfo.orientation)); - argv[1] = MakeArgv(std::to_string(facing == ACAMERA_LENS_FACING_FRONT ? 1 : 0)); - argv[2] = MakeArgv(outputPath); + std::vector imagePaths; for (int idx = 0; idx < localFrames.size(); idx++) { + std::string imagePath = tmpDir + std::to_string(idx) + ".dng"; std::vector& frame = localFrames[idx]; - writeFile(tmpDir + std::to_string(idx) + ".dng", &frame[0], frame.size()); - argv[3 + idx] = MakeArgv(tmpDir + std::to_string(idx) + ".dng"); + if (writeFile(imagePath, &frame[0], frame.size())) + { + imagePaths.push_back(imagePath); + } } localFrames.clear(); -#if _DEBUG - const char* psz = cmd.c_str(); -#endif - char* szCmd = MakeArgv(cmd); - - int exitcode = execv(szCmd, argv); - for (int idx = 0; idx < numberOfFrames; idx++) - { - std::remove(argv[3 + idx]); - } - delete[] szCmd; - for (int idx = 0; idx < argc; idx++) + int exitCode = pThis->CallExecv(photoInfo.orientation, facing == ACAMERA_LENS_FACING_FRONT ? 1 : 0, outputPath, imagePaths); + for (auto it = imagePaths.cbegin(); it != imagePaths.cend(); ++it) { - if (argv[idx] != NULL) delete[] argv[idx]; + std::remove((*it).c_str()); } - delete[] argv; - if (existsFile(outputPath)) { - + rgb = cv::imread(outputPath); + std::remove(outputPath.c_str()); } + + std::error_code errCode; + fs::remove_all(fs::path(tmpDir), errCode); } #else // USING_EXEC_HDRP XYLOG(XYLOG_SEVERITY_ERROR, "Start HDR CH=%u IMGID=%u", (uint32_t)photoInfo.channel, (uint32_t)photoInfo.photoId); @@ -2000,9 +1986,10 @@ bool CPhoneDevice::onBurstCapture(std::shared_ptr characteristi mCamera = NULL; cv::Mat rgb; - std::vector > rawFiles; media_status_t mstatus; + std::vector > rawFiles; + if (photoInfo.usingRawFormat != 0) { for (int idx = 0; idx < frames.size(); idx++) @@ -2200,10 +2187,12 @@ bool CPhoneDevice::onBurstCapture(std::shared_ptr characteristi if (photoInfo.usingRawFormat != 0) { +#ifndef USING_EXEC_HDRP XYLOG(XYLOG_SEVERITY_ERROR, "Start HDR CH=%u IMGID=%u", (uint32_t)photoInfo.channel, (uint32_t)photoInfo.photoId); hdrplus::hdrplus_pipeline pipeline; pipeline.run_pipeline(rawFiles, 0, rgb); rawFiles.clear(); +#endif XYLOG(XYLOG_SEVERITY_ERROR, "Finish HDR CH=%u IMGID=%u", (uint32_t)photoInfo.channel, (uint32_t)photoInfo.photoId); @@ -2267,6 +2256,38 @@ bool CPhoneDevice::onBurstCapture(std::shared_ptr characteristi return true; } +int CPhoneDevice::CallExecv(int rotation, int frontCamera, const std::string& outputPath, const std::vector& images) +{ + JNIEnv* env = NULL; + bool didAttachThread = false; + bool res = GetJniEnv(m_vm, &env, didAttachThread); + if (!res) + { + ALOGE("Failed to get JNI Env"); + } + + std::string pathsWithSpace; + for (auto it = images.cbegin(); it != images.cend(); ++it) + { + pathsWithSpace.append(*it); + pathsWithSpace.append(" "); + } + pathsWithSpace.pop_back(); + + jstring joutputPath = env->NewStringUTF(outputPath.c_str()); + jstring jpathWithSpace = env->NewStringUTF(pathsWithSpace.c_str()); + jint exitCode = env->CallIntMethod(m_javaService, mExecHdrplusMid, rotation, frontCamera, joutputPath, jpathWithSpace); + env->DeleteLocalRef(jpathWithSpace); + env->DeleteLocalRef(joutputPath); + + if (didAttachThread) + { + m_vm->DetachCurrentThread(); + } + + return exitCode; +} + bool CPhoneDevice::OnImageReady(cv::Mat& mat) { time_t takingTime = time(NULL); @@ -3007,68 +3028,6 @@ void CPhoneDevice::UpdateSimcard(const std::string& simcard) m_simcard = simcard; } -bool CPhoneDevice::ProcessRawCapture(bool result, int numberOfCaptures, const std::string& pathsJoinedByTab, bool frontCamera, int rotation, long photoId) -{ - std::vector paths = split(pathsJoinedByTab, "\t"); - - if (paths.empty()) - { - cv::Mat mat; - OnCaptureReady(true, false, mat, (unsigned long)photoId); - return false; - } - - XYLOG(XYLOG_SEVERITY_ERROR, "Start Processing Raw Capture CH=%u IMGID=%u", (uint32_t)mPhotoInfo.channel, (uint32_t)mPhotoInfo.photoId); - - hdrplus::hdrplus_pipeline pipeline; - cv::Mat mat; - pipeline.run_pipeline(paths, 0, mat); - XYLOG(XYLOG_SEVERITY_ERROR, "Finish HDR CH=%u IMGID=%u", (uint32_t)mPhotoInfo.channel, (uint32_t)mPhotoInfo.photoId); - - mat = convert16bit2_8bit_(mat.clone()); - - if (rotation >= 0) - { - if (rotation == 90) - { - cv::Mat tempPic; - cv::transpose(mat, tempPic); - cv::flip(tempPic, mat, 1); - } - else if (rotation == 180) - { - if (frontCamera) - { - flip(mat, mat, 0); - - } - else - { - cv::flip(mat, mat, -1); - } - } - else if (rotation == 270) - { - cv::Mat tempPic; - cv::transpose(mat, tempPic); - cv::flip(tempPic, mat, 0); - } - - XYLOG(XYLOG_SEVERITY_ERROR, "Finish rotation CH=%u IMGID=%u", (uint32_t)mPhotoInfo.channel, (uint32_t)mPhotoInfo.photoId); - } - cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR); - - XYLOG(XYLOG_SEVERITY_ERROR, "Finish Processing Raw Capture CH=%u IMGID=%u", (uint32_t)mPhotoInfo.channel, (uint32_t)mPhotoInfo.photoId); - -#ifdef _DEBUG - // cv::cvtColor(outputImg, outputImg, cv::COLOR_RGB2BGR); - // cv::imwrite("/sdcard/com.xypower.mpapp/tmp/final.jpg", mat); -#endif - - OnCaptureReady(true, result != JNI_FALSE, mat, (unsigned long)photoId); - return true; -} - int CPhoneDevice::GetIceData(IDevice::ICE_INFO *iceInfo, IDevice::ICE_TAIL *iceTail, SENSOR_PARAM *sensorParam) { Collect_sensor_data(); //15s diff --git a/app/src/main/cpp/PhoneDevice.h b/app/src/main/cpp/PhoneDevice.h index c15651e7..a5b7a3f4 100644 --- a/app/src/main/cpp/PhoneDevice.h +++ b/app/src/main/cpp/PhoneDevice.h @@ -227,7 +227,6 @@ public: void UpdatePosition(double lon, double lat, double radius, time_t ts); bool OnVideoReady(bool photoOrVideo, bool result, const char* path, unsigned int photoId); bool OnCaptureReady(bool photoOrVideo, bool result, cv::Mat& mat, unsigned int photoId); - bool ProcessRawCapture(bool result, int numberOfCaptures, const std::string& pathsJoinedByTab, bool frontCamera, int rotation, long photoId); void UpdateSignalLevel(int signalLevel); void UpdateTfCardPath(const std::string& tfCardPath) @@ -297,6 +296,8 @@ protected: int QueryBatteryVoltage(int retries); + int CallExecv(int rotation, int frontCamera, const std::string& outputPath, const std::vector& images); + protected: std::mutex m_devLocker; @@ -321,6 +322,7 @@ protected: jmethodID mInstallAppMid; jmethodID mEnableGpsMid; jmethodID mRequestPositionMid; + jmethodID mExecHdrplusMid; std::string mPath; IDevice::PHOTO_INFO mPhotoInfo; diff --git a/app/src/main/cpp/hdrplus/bin/hdrplus.cpp b/app/src/main/cpp/hdrplus/bin/hdrplus.cpp index 4536e347..a01d398d 100644 --- a/app/src/main/cpp/hdrplus/bin/hdrplus.cpp +++ b/app/src/main/cpp/hdrplus/bin/hdrplus.cpp @@ -22,21 +22,21 @@ int main( int argc, char** argv ) } mat = hdrplus::convert16bit2_8bit_(mat.clone()); - if (rotation >= 0) + if (rotation > 0) { - if (rotation == 0) + if (rotation == 1) // 0 { cv::Mat tempPic; cv::transpose(mat, tempPic); cv::flip(tempPic, mat, 0); } - else if (rotation == 1) + else if (rotation == 2) // 90 { cv::Mat tempPic; cv::transpose(mat, tempPic); cv::flip(tempPic, mat, 1); } - else if (rotation == 2) + else if (rotation == 3) // 180 { if (frontCamera) { @@ -47,7 +47,7 @@ int main( int argc, char** argv ) cv::flip(mat, mat, -1); } } - else if (rotation == 3) + else if (rotation == 4) // 270 { cv::Mat tempPic; cv::transpose(mat, tempPic); @@ -65,7 +65,7 @@ int main( int argc, char** argv ) bool res = cv::imwrite(argv[3], mat); if (!res) { - printf("Failed to write file %s", argv[3]); + printf("Failed to write file %s err=%d", argv[3], errno); } return 0; diff --git a/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java b/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java index 54c7a6bf..cb597c76 100644 --- a/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java +++ b/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java @@ -66,9 +66,13 @@ import com.xypower.mpapp.utils.DeviceUtil; import com.xypower.mpapp.v2.Camera2VideoActivity; import com.xypower.mpapp.video.RawActivity; +import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.RandomAccessFile; +import java.io.Reader; import java.lang.reflect.Method; import java.net.InetAddress; import java.nio.channels.FileLock; @@ -961,6 +965,7 @@ public class MicroPhotoService extends Service { } }; + Log.d(TAG, "Start Service from MicroPhotoService"); Thread th = new Thread(runnable); th.start(); } @@ -1395,6 +1400,60 @@ public class MicroPhotoService extends Service { SysApi.enableGps(getApplicationContext(), enabled); } + private int execHdrplus(int rotation, int frontCamera, String outputPath, String pathsWithSpace) { + + ApplicationInfo applicationInfo = null; + Context context = getApplicationContext(); + try { + applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_SHARED_LIBRARY_FILES); + } catch (Exception ex) { + + } + + String exeFilePath = applicationInfo.nativeLibraryDir + '/' + "libhdrp.so"; + File hdrpFile = new File(exeFilePath); + if (!hdrpFile.exists()) { + return -1; + } + + String cmd = exeFilePath + " " + Integer.toString(rotation) + " "; + cmd += Integer.toString(frontCamera) + " "; + cmd += outputPath + " " + pathsWithSpace; + + String[] params = new String[]{""}; + File workDir = context.getFilesDir(); + int exitCode = 0; + + try { + Process process = Runtime.getRuntime().exec(cmd, params, workDir.getAbsoluteFile()); + // Intrinsics.checkNotNullExpressionValue(process, "process"); + InputStream inputStream = process.getInputStream(); + BufferedReader reader = new BufferedReader((Reader)(new InputStreamReader(inputStream))); + + // StringBuilder stringBuilder = new StringBuilder(); + while(true) { + String line = reader.readLine(); + if (line == null) { + exitCode = process.exitValue(); + reader.close(); + process.destroy(); + break; + } + + if (line != null) { + // this.outputCallback.invoke(var5); + Log.d("HDRPlus", line); + // stringBuilder.append(line); + // stringBuilder.append("\r\n"); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + return exitCode; + } + /* TelephonyManager telephonyManager = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); // for example value of first element