代码优化
This commit is contained in:
@@ -46,8 +46,8 @@ check_lib() {
|
||||
}
|
||||
|
||||
all_libs_ok=true
|
||||
check_lib "libssl.so" || all_libs_ok=false
|
||||
check_lib "libcrypto.so" || all_libs_ok=false
|
||||
# check_lib "libssl.so" || all_libs_ok=false (Removed in optimization)
|
||||
# check_lib "libcrypto.so" || all_libs_ok=false (Removed in optimization)
|
||||
check_lib "libcurl.so" || all_libs_ok=false
|
||||
check_lib "libasound.so" || all_libs_ok=false
|
||||
|
||||
|
||||
@@ -132,8 +132,8 @@ LDFLAGS += -lcedarxrender -lhwdisplay
|
||||
# ALSA 音频库(静态库不存在,且音频播放已禁用)
|
||||
# LDFLAGS += -lasound
|
||||
|
||||
# OpenSSL (用于 WebSocket 握手)
|
||||
LDFLAGS += -lssl -lcrypto
|
||||
# OpenSSL (Removed in Day 26 optimization)
|
||||
# LDFLAGS += -lssl -lcrypto
|
||||
|
||||
# 结束静态库组
|
||||
LDFLAGS += -Wl,--end-group
|
||||
|
||||
@@ -52,7 +52,11 @@ Camera::Camera()
|
||||
, m_fps(0.0f)
|
||||
, m_frame_count(0)
|
||||
, m_last_time(0)
|
||||
, m_current_buf_idx(0)
|
||||
{
|
||||
// Initialize buffer pointers to nullptr
|
||||
m_frame_buffers[0] = nullptr;
|
||||
m_frame_buffers[1] = nullptr;
|
||||
LOGD("Camera constructor");
|
||||
}
|
||||
|
||||
@@ -102,6 +106,14 @@ void Camera::deinit()
|
||||
// 退出系统
|
||||
AW_MPI_SYS_Exit();
|
||||
|
||||
// Day 26: Free memory pool
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (m_frame_buffers[i]) {
|
||||
delete[] m_frame_buffers[i];
|
||||
m_frame_buffers[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// 重置统计
|
||||
m_fps = 0.0f;
|
||||
m_frame_count = 0;
|
||||
@@ -114,6 +126,18 @@ bool Camera::init()
|
||||
{
|
||||
LOGI("Initializing camera: %dx%d @%dfps", m_width, m_height, DEFAULT_FPS);
|
||||
|
||||
// Day 26: Pre-allocate memory pool
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (!m_frame_buffers[i]) {
|
||||
m_frame_buffers[i] = new uint8_t[MAX_FRAME_SIZE];
|
||||
if (!m_frame_buffers[i]) {
|
||||
LOGE("Failed to allocate frame buffer %d", i);
|
||||
return false;
|
||||
}
|
||||
LOGD("Allocated frame buffer %d (%zu bytes)", i, MAX_FRAME_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 初始化 MPP 系统
|
||||
MPP_SYS_CONF_S sys_conf;
|
||||
memset(&sys_conf, 0, sizeof(MPP_SYS_CONF_S));
|
||||
@@ -332,7 +356,7 @@ bool Camera::capture_frame(uint8_t** jpeg_data, size_t* jpeg_size)
|
||||
return false;
|
||||
}
|
||||
|
||||
// 计算总大小
|
||||
// Day 26: Use Memory Pool instead of dynamic allocation
|
||||
size_t total_size = stream.mpPack[0].mLen0 + stream.mpPack[0].mLen1 + stream.mpPack[0].mLen2;
|
||||
if (total_size == 0) {
|
||||
LOGE("Empty JPEG frame");
|
||||
@@ -340,8 +364,17 @@ bool Camera::capture_frame(uint8_t** jpeg_data, size_t* jpeg_size)
|
||||
return false;
|
||||
}
|
||||
|
||||
// 分配内存并拷贝数据
|
||||
uint8_t* buffer = new uint8_t[total_size];
|
||||
// Safety check for buffer overflow
|
||||
if (total_size > MAX_FRAME_SIZE) {
|
||||
LOGE("Frame size (%zu) exceeds MAX_FRAME_SIZE (%zu), dropping frame", total_size, MAX_FRAME_SIZE);
|
||||
AW_MPI_VENC_ReleaseStream(m_venc_chn, &stream);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get current buffer
|
||||
uint8_t* buffer = m_frame_buffers[m_current_buf_idx];
|
||||
|
||||
// Copy data
|
||||
size_t offset = 0;
|
||||
|
||||
if (stream.mpPack[0].mLen0 > 0 && stream.mpPack[0].mpAddr0) {
|
||||
@@ -360,6 +393,9 @@ bool Camera::capture_frame(uint8_t** jpeg_data, size_t* jpeg_size)
|
||||
// 释放流
|
||||
AW_MPI_VENC_ReleaseStream(m_venc_chn, &stream);
|
||||
|
||||
// Switch buffer index for next frame
|
||||
m_current_buf_idx = (m_current_buf_idx + 1) % 2;
|
||||
|
||||
// 更新 FPS 统计
|
||||
update_fps_stats();
|
||||
|
||||
@@ -373,9 +409,8 @@ bool Camera::capture_frame(uint8_t** jpeg_data, size_t* jpeg_size)
|
||||
|
||||
void Camera::release_frame(uint8_t* jpeg_data)
|
||||
{
|
||||
if (jpeg_data) {
|
||||
delete[] jpeg_data;
|
||||
}
|
||||
// No-op for memory pool
|
||||
// Buffer will be overwritten when it's turn comes again
|
||||
}
|
||||
|
||||
bool Camera::set_framesize(const std::string& size)
|
||||
|
||||
@@ -95,6 +95,11 @@ private:
|
||||
bool init_venc(); // Video Encoder
|
||||
|
||||
void update_fps_stats();
|
||||
|
||||
// Day 26 Optimization: Fixed Memory Pool (Double Buffering)
|
||||
static const size_t MAX_FRAME_SIZE = 512 * 1024; // 512KB (Sufficient for 720p MJPEG)
|
||||
uint8_t* m_frame_buffers[2];
|
||||
int m_current_buf_idx;
|
||||
};
|
||||
|
||||
#endif // CAMERA_H
|
||||
|
||||
@@ -12,10 +12,61 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// Day 26: Remove OpenSSL dependency
|
||||
// #include <openssl/sha.h>
|
||||
// #include <openssl/bio.h>
|
||||
// #include <openssl/evp.h>
|
||||
// #include <openssl/buffer.h>
|
||||
|
||||
// Custom Base64 Encoding Table
|
||||
static const char base64_chars[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
// Custom helper: base64 encode
|
||||
static std::string base64_encode(const unsigned char* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// WebSocket 魔术字符串(用于握手验证,当前未使用)
|
||||
// static const char* WS_MAGIC_STRING = "258EAFAA-5914-47DA-95CA-C5AB0DC85B11";
|
||||
@@ -178,21 +229,11 @@ bool WSClient::perform_handshake() {
|
||||
random_bytes[i] = rand() % 256;
|
||||
}
|
||||
|
||||
// Base64 编码
|
||||
BIO *bio, *b64;
|
||||
BUF_MEM *bufferPtr;
|
||||
// Day 26: Use custom Base64 implementation instead of OpenSSL
|
||||
std::string ws_key = base64_encode(random_bytes, 16);
|
||||
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
bio = BIO_push(b64, bio);
|
||||
|
||||
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
|
||||
BIO_write(bio, random_bytes, 16);
|
||||
BIO_flush(bio);
|
||||
BIO_get_mem_ptr(bio, &bufferPtr);
|
||||
|
||||
std::string ws_key(bufferPtr->data, bufferPtr->length);
|
||||
BIO_free_all(bio);
|
||||
// Debug log key (optional)
|
||||
// LOG_DEBUG("[WS] Generated Sec-WebSocket-Key: %s", ws_key.c_str());
|
||||
|
||||
// 构造 HTTP 升级请求
|
||||
char request[1024];
|
||||
|
||||
Reference in New Issue
Block a user