实现独立进程执行HDR的方式

TempBranch
Matthew 8 months ago
parent 3fcdc8b7d7
commit 2bbb51184a

@ -36,7 +36,7 @@ android {
externalNativeBuild {
cmake {
// cppFlags '-std=c++17 -frtti -fexceptions -Wno-error=format-security'
cppFlags '-std=c++17 -fexceptions -Wno-error=format-security'
cppFlags '-std=c++17 -fexceptions -Wno-error=format-security -fopenmp'
// cppFlags '-std=c++17 -Wno-error=format-security'
// arguments "-DANDROID_STL=c++_shared"
arguments "-DNCNN_DISABLE_EXCEPTION=OFF", "-DTERM_CORE_ROOT=" + coreroot, "-DOpenCV_DIR=" + opencvsdk + "/sdk/native/jni", "-DHDRPLUS_ROOT=" + hdrplusroot, "-DNCNN_ROOT=" + ncnnroot

@ -42,6 +42,8 @@ add_definitions(-DENABLE_3V3_ALWAYS)
add_definitions(-DUSING_HDRPLUS)
# add_definitions(-DUSING_EXEC_HDRP=1)
#add_definitions(-DUSING_N938)
# include_directories(${OpenCV_DIR}/include)
@ -323,6 +325,19 @@ add_library(
${FREETYPE_SRC_FILES}
)
if(USING_EXEC_HDRP)
add_executable( libhdrp.so
${HDRPLUS_SOURCES}
hdrplus/bin/hdrplus.cpp )
target_link_libraries( libhdrp.so PUBLIC -fopenmp -static-openmp
android z
${OpenCV_LIBS}
# ${LIBRAW_LIBRARY}
${HDRPLUS_LIBS}
)
endif()
add_library( # Sets the name of the library.
microphoto

@ -281,7 +281,7 @@ Java_com_xypower_mpapp_MicroPhotoService_init(
jobject pThis, jstring appPath,
jstring ip, jint port, jstring cmdid, jint protocol,
jint networkProtocol, jint encryptData, jlong netHandle, jint signalLevel,
jint versionCode, jlong buildTime, jstring simcard, jstring tfCardPath) {
jint versionCode, jlong buildTime, jstring simcard, jstring tfCardPath, jstring nativeLibraryDir) {
/*
google_breakpad::MinidumpDescriptor descriptor(".");
@ -311,6 +311,7 @@ Java_com_xypower_mpapp_MicroPhotoService_init(
const char *cmdidStr = cmdid == NULL ? NULL : env->GetStringUTFChars(cmdid, 0);
const char *simcardStr = simcard == NULL ? NULL : env->GetStringUTFChars(simcard, 0);
const char *tfCardPathStr = tfCardPath == NULL ? NULL : env->GetStringUTFChars(tfCardPath, 0);
const char *nativeLibraryDirStr = nativeLibraryDir == NULL ? NULL : env->GetStringUTFChars(nativeLibraryDir, 0);
JavaVM* vm = NULL;
jint ret = env->GetJavaVM(&vm);
@ -321,7 +322,7 @@ Java_com_xypower_mpapp_MicroPhotoService_init(
CTerminal* pTerminal = NewTerminal(protocol);
CPhoneDevice* device = new CPhoneDevice(vm, pThis, MakeString(appPathStr), NETID_UNSET, versionCode);
CPhoneDevice* device = new CPhoneDevice(vm, pThis, MakeString(appPathStr), NETID_UNSET, versionCode, MakeString(nativeLibraryDirStr));
device->SetListener(pTerminal);
device->UpdateSignalLevel(signalLevel);
device->SetBuildTime(buildTime / 1000);
@ -340,6 +341,7 @@ Java_com_xypower_mpapp_MicroPhotoService_init(
if (cmdidStr != NULL) env->ReleaseStringUTFChars(cmdid, cmdidStr);
if (simcardStr != NULL) env->ReleaseStringUTFChars(simcard, simcardStr);
if (tfCardPathStr != NULL) env->ReleaseStringUTFChars(tfCardPath, tfCardPathStr);
if (nativeLibraryDirStr != NULL) env->ReleaseStringUTFChars(nativeLibraryDir, nativeLibraryDirStr);
if (!res)
{
@ -393,7 +395,7 @@ Java_com_xypower_mpapp_MicroPhotoService_takePhoto(
CTerminal::LoadChannelConfig(channel, configFilePathStr, cfg);
CTerminal::ConvertChannelConfigToPhotoInfo(cfg, photoOrVideo != JNI_FALSE, photoInfo);
CPhoneDevice* device = new CPhoneDevice(vm, NULL, "", NETID_UNSET, 0);
CPhoneDevice* device = new CPhoneDevice(vm, NULL, "", NETID_UNSET, 0, std::string(""));
// device->SetListener(pTerminal);
if (photoInfo.usbCamera)
@ -1329,8 +1331,7 @@ Java_com_xypower_mpapp_MicroPhotoService_exportPrivateFile(
#ifdef USING_NRSEC
if (env->GetStringUTFLength(outputPath) <= 0)
{
if (env->GetStringUTFLength(outputPath) <= 0) {
return JNI_FALSE;
}
@ -1341,8 +1342,7 @@ Java_com_xypower_mpapp_MicroPhotoService_exportPrivateFile(
GpioControl::setSpiPower(true);
NrsecPort nrsec;
if (!nrsec.Open(path))
{
if (!nrsec.Open(path)) {
return JNI_FALSE;
}
@ -1355,9 +1355,8 @@ Java_com_xypower_mpapp_MicroPhotoService_exportPrivateFile(
GpioControl::setSpiPower(false);
CPhoneDevice::TurnOffCameraPower(NULL);
if (res)
{
const char* outputPathStr = env->GetStringUTFChars(outputPath, 0);
if (res) {
const char *outputPathStr = env->GetStringUTFChars(outputPath, 0);
res = writeFile(outputPathStr, &data[0], len);
env->ReleaseStringUTFChars(outputPath, outputPathStr);
}

@ -32,6 +32,7 @@
#include <fcntl.h>
#include <filesystem>
#include <cstdio>
#include <unistd.h>
namespace fs = std::filesystem;
#define CMD_SET_485_EN_STATE 131
@ -91,7 +92,13 @@ cv::Mat convert16bit2_8bit_(cv::Mat ans){
return ans;
}
char* MakeArgv(const std::string v)
{
char* argv = new char[v.size() + 1];
memset(argv, 0, v.size() + 1);
strcpy(argv, v.c_str());
return argv;
}
static long getFreeMemoryImpl(const char* const sums[], const size_t sumsLen[], size_t num)
{
@ -378,7 +385,7 @@ std::mutex CPhoneDevice::m_powerLocker;
long CPhoneDevice::mCameraPowerCount = 0;
long CPhoneDevice::mOtgCount = 0;
CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath, unsigned int netId, unsigned int versionCode) : mVersionCode(versionCode)
CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath, unsigned int netId, unsigned int versionCode, const std::string& nativeLibDir) : mVersionCode(versionCode), m_nativeLibraryDir(nativeLibDir)
{
mCamera = NULL;
m_listener = NULL;
@ -1828,6 +1835,63 @@ bool CPhoneDevice::onBurstCapture(std::shared_ptr<ACameraMetadata> characteristi
// Notify to take next photo
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<std::vector<uint8_t> > localFrames;
localFrames.swap(pByteArrays.get()->byteArrays);
std::string outputPath = tmpDir + "output.tiff";
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);
for (int idx = 0; idx < localFrames.size(); idx++)
{
std::vector<uint8_t>& frame = localFrames[idx];
writeFile(tmpDir + std::to_string(idx) + ".dng", &frame[0], frame.size());
argv[3 + idx] = MakeArgv(tmpDir + std::to_string(idx) + ".dng");
}
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++)
{
if (argv[idx] != NULL) delete[] argv[idx];
}
delete[] argv;
if (existsFile(outputPath))
{
}
}
#else // 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;
std::vector<std::vector<uint8_t> > localFrames;
@ -1868,7 +1932,7 @@ bool CPhoneDevice::onBurstCapture(std::shared_ptr<ACameraMetadata> characteristi
cv::flip(rgb, rgb, -1);
}
}
else if (photoInfo.orientation == 4)
else if ((photoInfo.orientation % 4) == 0)
{
cv::Mat tempPic;
cv::transpose(rgb, tempPic);
@ -1878,7 +1942,7 @@ bool CPhoneDevice::onBurstCapture(std::shared_ptr<ACameraMetadata> characteristi
XYLOG(XYLOG_SEVERITY_ERROR, "Finish rotation CH=%u IMGID=%u", (uint32_t)photoInfo.channel, (uint32_t)photoInfo.photoId);
}
cv::cvtColor(rgb, rgb, cv::COLOR_RGB2BGR);
#endif // USING_EXEC_HDRP
bool res = pThis->PostProcessPhoto(photoInfo, osds, path, cameraInfo, rgb);
if (res)
{

@ -194,7 +194,7 @@ public:
unsigned long uid;
};
CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath, unsigned int netId, unsigned int versionCode);
CPhoneDevice(JavaVM* vm, jobject service, const std::string& appPath, unsigned int netId, unsigned int versionCode, const std::string& nativeLibDir);
virtual ~CPhoneDevice();
virtual void SetListener(IListener* listener);
@ -305,6 +305,7 @@ protected:
jobject m_javaService;
std::string m_appPath;
std::string m_tfCardPath;
std::string m_nativeLibraryDir;
jmethodID mRegisterHeartbeatMid;
jmethodID mUpdateCaptureScheduleMid;
@ -333,6 +334,7 @@ protected:
atomic_ulong m_timerUidFeed;
atomic_ulong m_wakelockIdFeed;
atomic_ulong m_uniqueIdFeed;
std::map<IDevice::timer_uid_t, TIMER_CONTEXT*> mTimers;
mutable CPhoneCamera* mCamera;

@ -0,0 +1,72 @@
#include "hdrplus/hdrplus_pipeline.h"
int main( int argc, char** argv )
{
int rotation = atoi(argv[1]);
bool frontCamera = atoi(argv[2]) != 0;
std::vector<std::string> paths;
for (int idx = 4; idx < argc; idx++)
{
paths.push_back(argv[idx]);
}
cv::Mat mat;
hdrplus::hdrplus_pipeline pipeline;
pipeline.run_pipeline( paths, 0, mat);
if (mat.empty())
{
printf("run_pipeline return empty mat");
}
mat = hdrplus::convert16bit2_8bit_(mat.clone());
if (rotation >= 0)
{
if (rotation == 0)
{
cv::Mat tempPic;
cv::transpose(mat, tempPic);
cv::flip(tempPic, mat, 0);
}
else if (rotation == 1)
{
cv::Mat tempPic;
cv::transpose(mat, tempPic);
cv::flip(tempPic, mat, 1);
}
else if (rotation == 2)
{
if (frontCamera)
{
cv::flip(mat, mat, 0);
}
else
{
cv::flip(mat, mat, -1);
}
}
else if (rotation == 3)
{
cv::Mat tempPic;
cv::transpose(mat, tempPic);
cv::flip(tempPic, mat, 0);
}
}
cv::cvtColor(mat, mat, cv::COLOR_RGB2BGR);
if (mat.empty())
{
printf("mat is empty before save");
}
bool res = cv::imwrite(argv[3], mat);
if (!res)
{
printf("Failed to write file %s", argv[3]);
}
return 0;
}

@ -10,7 +10,31 @@
namespace hdrplus
{
class hdrplus_pipeline
inline cv::Mat convert16bit2_8bit_(cv::Mat ans) {
if(ans.type()==CV_16UC3){
cv::MatIterator_<cv::Vec3w> it, end;
for( it = ans.begin<cv::Vec3w>(), end = ans.end<cv::Vec3w>(); it != end; ++it)
{
// std::cout<<sizeof (*it)[0] <<std::endl;
(*it)[0] *=(255.0/USHRT_MAX);
(*it)[1] *=(255.0/USHRT_MAX);
(*it)[2] *=(255.0/USHRT_MAX);
}
ans.convertTo(ans, CV_8UC3);
}else if(ans.type()==CV_16UC1){
u_int16_t* ptr = (u_int16_t*)ans.data;
int end = ans.rows*ans.cols;
for(int i=0;i<end;i++){
*(ptr+i) *=(255.0/USHRT_MAX);
}
ans.convertTo(ans, CV_8UC1);
}else{
// std::cout<<"Unsupported Data Type"<<std::endl;
}
return ans;
}
class hdrplus_pipeline
{
private:
hdrplus::align align_module;

@ -107,7 +107,7 @@ static void build_per_grayimg_pyramid( \
break;
default:
#ifdef __ANDROID__
break;
#else
throw std::runtime_error("inv scale factor " + std::to_string( inv_scale_factors[ i ]) + "invalid" );
#endif

@ -11,7 +11,7 @@
#include <fstream>
#ifdef __ANDROID__
#include <AndroidHelper.h>
// #include <AndroidHelper.h>
#endif
namespace hdrplus
@ -46,25 +46,25 @@ bool hdrplus_pipeline::run_pipeline( \
burst burst_images( burst_paths, reference_image_index );
std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments;
#ifdef __ANDROID__
ALOGI("Finish loading images");
// ALOGI("Finish loading images");
#endif
// Run align
align_module.process( burst_images, alignments );
#ifdef __ANDROID__
ALOGI("Finish align");
// ALOGI("Finish align");
#endif
// Run merging
merge_module.process( burst_images, alignments );
#ifdef __ANDROID__
ALOGI("Finish merging");
// ALOGI("Finish merging");
#endif
// Run finishing
finish_module.process( burst_images, finalImg);
#ifdef __ANDROID__
ALOGI("Finish process");
// ALOGI("Finish process");
#endif
return true;
@ -78,25 +78,25 @@ bool hdrplus_pipeline::run_pipeline( \
burst burst_images( burst_contents, reference_image_index );
std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments;
#ifdef __ANDROID__
ALOGI("Finish loading images");
// ALOGI("Finish loading images");
#endif
// Run align
align_module.process( burst_images, alignments );
#ifdef __ANDROID__
ALOGI("Finish align");
// ALOGI("Finish align");
#endif
// Run merging
merge_module.process( burst_images, alignments );
#ifdef __ANDROID__
ALOGI("Finish merging");
// ALOGI("Finish merging");
#endif
// Run finishing
finish_module.process( burst_images, finalImg);
#ifdef __ANDROID__
ALOGI("Finish process");
// ALOGI("Finish process");
#endif
return true;
@ -111,25 +111,25 @@ bool hdrplus_pipeline::run_pipeline( \
burst burst_images( burst_files, reference_image_index );
std::vector<std::vector<std::vector<std::pair<int, int>>>> alignments;
#ifdef __ANDROID__
ALOGI("Finish loading images");
// ALOGI("Finish loading images");
#endif
// Run align
align_module.process( burst_images, alignments );
#ifdef __ANDROID__
ALOGI("Finish align");
// ALOGI("Finish align");
#endif
// Run merging
merge_module.process( burst_images, alignments );
#ifdef __ANDROID__
ALOGI("Finish merging");
// ALOGI("Finish merging");
#endif
// Run finishing
finish_module.process( burst_images, finalImg);
#ifdef __ANDROID__
ALOGI("Finish process");
// ALOGI("Finish process");
#endif
return true;

@ -5,6 +5,8 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.UriMatcher;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
@ -18,7 +20,13 @@ import com.xypower.common.MicroPhotoContext;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
public class BridgeProvider extends ContentProvider {
@ -34,6 +42,8 @@ public class BridgeProvider extends ContentProvider {
private final static String PATH_TAKE_PHOTO = "/takePhoto";
private final static String PATH_TAKE_VIDEO = "/takeVideo";
private final static String PATH_HDRPLUS = "/hdrplus";
private final static String PATH_RECOG_PIC = "/recogPic";
public BridgeProvider() {
@ -106,6 +116,7 @@ public class BridgeProvider extends ContentProvider {
matcher.addURI(AUTHORITY, PATH_GEN_CERT_REQ, 4);
matcher.addURI(AUTHORITY, PATH_TAKE_PHOTO, 5);
matcher.addURI(AUTHORITY, PATH_TAKE_VIDEO, 6);
matcher.addURI(AUTHORITY, PATH_HDRPLUS, 7);
int res = 0;
int matched = matcher.match(uri);
@ -128,6 +139,9 @@ public class BridgeProvider extends ContentProvider {
case 6:
res = takeVideo(uri, values);
break;
case 7:
res = hdrPlus(uri, values);
break;
default:
break;
}
@ -416,4 +430,73 @@ public class BridgeProvider extends ContentProvider {
return 1;
}
private int hdrPlus(Uri uri, ContentValues values) {
int rotation = values.containsKey("rotation") ? values.getAsInteger("rotation").intValue() : -1;
int frontCamera = values.containsKey("front") ? values.getAsInteger("front").intValue() : 0;
String outputPath = values.containsKey("output") ? values.getAsString("output") : null;
int numberOfCaptures = values.containsKey("captures") ? values.getAsInteger("captures").intValue() : 0;
List<String> paths = new ArrayList<>();
for (int idx = 0; idx < numberOfCaptures; idx++) {
String key = "path" + Integer.toString(idx + 1);
String path = values.containsKey(key) ? values.getAsString(key) : null;
if (!TextUtils.isEmpty(path)) {
paths.add(path);
}
}
ApplicationInfo applicationInfo = null;
Context context = getContext();
try {
applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_SHARED_LIBRARY_FILES);
} catch (Exception ex) {
}
Log.d(TAG, "nativeLibraryDir= " + applicationInfo.nativeLibraryDir);
String exeFilePath = applicationInfo.nativeLibraryDir + '/' + "libhdrp.so";
File hdrpFile = new File(exeFilePath);
if (!hdrpFile.exists()) {
return 0;
}
String cmd = exeFilePath + " " + Integer.toString(rotation) + " ";
cmd += Integer.toString(frontCamera) + " ";
cmd += outputPath + " " + TextUtils.join(" ", paths);
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 1;
}
}

@ -14,6 +14,8 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageDecoder;
@ -918,9 +920,18 @@ public class MicroPhotoService extends Service {
}
String tfCardPath = MicroPhotoContext.getSecondaryStoragePath(context);
String nativeLibraryDir = null;
ApplicationInfo applicationInfo = null;
try {
applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_SHARED_LIBRARY_FILES);
nativeLibraryDir = applicationInfo.nativeLibraryDir;
} catch (Exception ex) {
ex.printStackTrace();
}
service.mNativeHandle = init(appPath, server, port, cmdid, protocol, networkProtocol,
encryptData, 0, service.getSignalLevel(), versionCode,
BuildConfig.BUILD_TIMESTAMP, simcard, tfCardPath);
BuildConfig.BUILD_TIMESTAMP, simcard, tfCardPath, nativeLibraryDir);
if (service.mNativeHandle != 0) {
isRunning = true;
@ -1394,7 +1405,7 @@ cellSignalStrengthGsm.getDbm();
protected native long init(String appPath, String ip, int port, String cmdid, int protocol,
int networkProtocl, int encryptData, long netHandle, int signalLevel,
int versionCode, long buildTime, String simcard, String tfCardPath);
int versionCode, long buildTime, String simcard, String tfCardPath, String nativeLibraryDir);
protected native long getHeartbeatDuration(long handler);
protected native long[] getPhotoTimeData(long handler, long startTime);
protected native long[] getPhotoTimeData2(long handler);

Loading…
Cancel
Save