延时优化完成

This commit is contained in:
xsl
2025-10-26 22:42:05 +08:00
parent 57b7c40835
commit 300340bb19
4 changed files with 110 additions and 60 deletions
@@ -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
View File
@@ -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