延时优化完成
This commit is contained in:
@@ -70,38 +70,14 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L
|
||||
|
||||
|
||||
imageAnalyzer.setAnalyzer(backgroundExecutor, new ImageAnalysis.Analyzer() {
|
||||
private long lastCaptureTime = 0;
|
||||
private int frameCount = 0;
|
||||
|
||||
@Override
|
||||
public void analyze(@NonNull ImageProxy image) {
|
||||
frameCount++;
|
||||
long currentTime = System.currentTimeMillis();
|
||||
try {
|
||||
long captureTimeNs = image.getImageInfo().getTimestamp();
|
||||
long analyzeTime = System.currentTimeMillis();
|
||||
|
||||
// 简单直接的计算方法
|
||||
long captureTimeMs = TimeUnit.NANOSECONDS.toMillis(captureTimeNs);
|
||||
long latency = analyzeTime - captureTimeMs;
|
||||
|
||||
// 帧率计算
|
||||
if (lastCaptureTime > 0) {
|
||||
long frameInterval = captureTimeMs - lastCaptureTime;
|
||||
double fps = 1000.0 / frameInterval;
|
||||
|
||||
if (frameCount % 10 == 0) { // 每30帧打印一次
|
||||
Log.i("TimeLatency", String.format(
|
||||
"Frame %d - Latency: %d ms, FPS: %.1f",
|
||||
frameCount, latency, fps
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
lastCaptureTime = captureTimeMs;
|
||||
|
||||
processImageForVulkan(image);
|
||||
if(frameCount %2 == 0)
|
||||
if(frameCount %3 == 0)
|
||||
{
|
||||
detectFace(image);
|
||||
}
|
||||
@@ -186,7 +162,6 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L
|
||||
0.5f,
|
||||
0.5f,
|
||||
1,
|
||||
0,
|
||||
RunningMode.LIVE_STREAM,
|
||||
FaceActivity.this,
|
||||
FaceActivity.this
|
||||
|
||||
@@ -20,8 +20,7 @@ class FaceLandmarkerHelper(
|
||||
var minFaceTrackingConfidence: Float = DEFAULT_FACE_TRACKING_CONFIDENCE,
|
||||
var minFacePresenceConfidence: Float = DEFAULT_FACE_PRESENCE_CONFIDENCE,
|
||||
var maxNumFaces: Int = DEFAULT_NUM_FACES,
|
||||
var currentDelegate: Int = DELEGATE_CPU,
|
||||
var runningMode: RunningMode = RunningMode.IMAGE,
|
||||
var runningMode: RunningMode = RunningMode.LIVE_STREAM,
|
||||
val context: Context,
|
||||
// this listener is only used when running in RunningMode.LIVE_STREAM
|
||||
val faceLandmarkerHelperListener: LandmarkerListener? = null
|
||||
@@ -50,14 +49,7 @@ class FaceLandmarkerHelper(
|
||||
val baseOptionBuilder = BaseOptions.builder()
|
||||
|
||||
// Use the specified hardware for running the model. Default to CPU
|
||||
when (currentDelegate) {
|
||||
DELEGATE_CPU -> {
|
||||
baseOptionBuilder.setDelegate(Delegate.CPU)
|
||||
}
|
||||
DELEGATE_GPU -> {
|
||||
baseOptionBuilder.setDelegate(Delegate.GPU)
|
||||
}
|
||||
}
|
||||
baseOptionBuilder.setDelegate(Delegate.GPU)
|
||||
|
||||
baseOptionBuilder.setModelAssetPath(MP_FACE_LANDMARKER_TASK)
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ import android.os.Bundle;
|
||||
import com.hmwl.face_sdk.FaceActivity;
|
||||
public class MainActivity extends FaceActivity{
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState){
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
SetInitArg("{\"action_fps\":3,\"motion\":{\"png_name\":\"demo\",\"png_num\":1,\"show_type\":\"direction\",\"step\":\"press2\",\"technique\":\"base_makeup\",\"type\":\"bottom_makeup\"},\"zoom\":1.5}");
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//这个是设置接口的参数,采用json传递,可以保证接口灵活性
|
||||
|
||||
+104
-23
@@ -1,6 +1,9 @@
|
||||
#include "FaceApp.h"
|
||||
#include "hardcode_data.h"
|
||||
#include <sstream>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
|
||||
@@ -24,15 +27,89 @@ void ReceiveFacePoint(float* pos, int pointCount, int width, int height)
|
||||
}
|
||||
}
|
||||
|
||||
// 定义帧数据结构
|
||||
struct FrameData {
|
||||
uint8_t* data;
|
||||
int width;
|
||||
int height;
|
||||
int rowStride;
|
||||
size_t dataSize;
|
||||
|
||||
FrameData(uint8_t* d, int w, int h, int rs, size_t ds)
|
||||
: data(nullptr), width(w), height(h), rowStride(rs), dataSize(ds) {
|
||||
// 深拷贝数据
|
||||
if (d && ds > 0) {
|
||||
data = new uint8_t[dataSize];
|
||||
memcpy(data, d, dataSize);
|
||||
}
|
||||
}
|
||||
|
||||
~FrameData() {
|
||||
if (data) {
|
||||
delete[] data;
|
||||
data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// 禁止拷贝构造和赋值(使用移动语义)
|
||||
FrameData(const FrameData&) = delete;
|
||||
FrameData& operator=(const FrameData&) = delete;
|
||||
|
||||
// 移动构造
|
||||
FrameData(FrameData&& other) noexcept
|
||||
: data(other.data), width(other.width), height(other.height),
|
||||
rowStride(other.rowStride), dataSize(other.dataSize) {
|
||||
other.data = nullptr;
|
||||
}
|
||||
|
||||
// 移动赋值
|
||||
FrameData& operator=(FrameData&& other) noexcept {
|
||||
if (this != &other) {
|
||||
if (data) delete[] data;
|
||||
data = other.data;
|
||||
width = other.width;
|
||||
height = other.height;
|
||||
rowStride = other.rowStride;
|
||||
dataSize = other.dataSize;
|
||||
other.data = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// 全局队列和互斥锁
|
||||
std::queue<FrameData> frameQueue;
|
||||
std::mutex queueMutex;
|
||||
const int MAX_QUEUE_SIZE = 4;
|
||||
|
||||
void TextureLoadProcessWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize)
|
||||
{
|
||||
if(FaceApp::Get()->isInited())
|
||||
{
|
||||
Texture& tex_bg = FaceApp::Get()->tex_bg;
|
||||
FaceApp::Get()->processWithVulkan(data, width, height, rowStride, dataSize, tex_bg, false);
|
||||
}
|
||||
if (!FaceApp::Get()->isInited()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(queueMutex);
|
||||
|
||||
// 添加新帧数据到队列
|
||||
frameQueue.emplace(data, width, height, rowStride, dataSize);
|
||||
|
||||
// 如果队列大小达到阈值,开始处理最旧的一帧
|
||||
if (frameQueue.size() >= MAX_QUEUE_SIZE) {
|
||||
Texture& tex_bg = FaceApp::Get()->tex_bg;
|
||||
FrameData& oldestFrame = frameQueue.front();
|
||||
|
||||
FaceApp::Get()->processWithVulkan(
|
||||
oldestFrame.data,
|
||||
oldestFrame.width,
|
||||
oldestFrame.height,
|
||||
oldestFrame.rowStride,
|
||||
oldestFrame.dataSize,
|
||||
tex_bg,
|
||||
false
|
||||
);
|
||||
|
||||
frameQueue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
bool FaceApp::LoadOBJ(const std::string& filename,
|
||||
@@ -370,27 +447,31 @@ void FaceApp::create_face_pipelines()
|
||||
|
||||
void FaceApp::setup_descriptor_pool()
|
||||
{
|
||||
VkDescriptorPoolSize descriptor_pool_size{};
|
||||
descriptor_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
descriptor_pool_size.descriptorCount = 2;
|
||||
// 保守估计:假设每个描述符集可能有多个绑定
|
||||
const uint32_t setsCount = kMaxTexture;
|
||||
const uint32_t multiplier = 3; // 安全系数
|
||||
|
||||
VkDescriptorPoolSize descriptor_pool_image_size{};
|
||||
descriptor_pool_image_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptor_pool_image_size.descriptorCount = kMaxTexture + 4;
|
||||
std::vector<VkDescriptorPoolSize> pool_sizes = {
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = setsCount * multiplier
|
||||
},
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
.descriptorCount = setsCount * multiplier
|
||||
},
|
||||
// 如果需要其他类型的描述符,在这里添加
|
||||
};
|
||||
|
||||
VkDescriptorPoolCreateInfo descriptor_pool_info{};
|
||||
descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
descriptor_pool_info.poolSizeCount = static_cast<uint32_t>(pool_sizes.size());
|
||||
descriptor_pool_info.pPoolSizes = pool_sizes.data();
|
||||
descriptor_pool_info.maxSets = setsCount * 2; // 额外预留一些集合
|
||||
descriptor_pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||
|
||||
std::vector<VkDescriptorPoolSize> pool_sizes;
|
||||
pool_sizes.push_back(descriptor_pool_size);
|
||||
pool_sizes.push_back(descriptor_pool_image_size);
|
||||
VK_CHECK(vkCreateDescriptorPool(device, &descriptor_pool_info, nullptr, &descriptor_pool));
|
||||
|
||||
|
||||
VkDescriptorPoolCreateInfo descriptor_pool_info{};
|
||||
descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
descriptor_pool_info.poolSizeCount = pool_sizes.size();
|
||||
descriptor_pool_info.pPoolSizes = pool_sizes.data();
|
||||
descriptor_pool_info.maxSets = kMaxTexture + 4 + 2;
|
||||
|
||||
VK_CHECK(vkCreateDescriptorPool(device, &descriptor_pool_info, nullptr, &descriptor_pool));
|
||||
}
|
||||
|
||||
|
||||
@@ -1024,7 +1105,7 @@ void FaceApp::changeMotion(Motion& motion)
|
||||
loadTextureExample(path_name_ex, m_texs_ex[i], true);
|
||||
#else
|
||||
loadTexture(path_name, m_texs[i], true);
|
||||
loadTexture(path_name, path_name_ex[i], true);
|
||||
loadTexture(path_name, m_texs_ex[i], true);
|
||||
#endif // _WIN32
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user