代码优化
This commit is contained in:
@@ -46,8 +46,8 @@ check_lib() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
all_libs_ok=true
|
all_libs_ok=true
|
||||||
check_lib "libssl.so" || all_libs_ok=false
|
# check_lib "libssl.so" || all_libs_ok=false (Removed in optimization)
|
||||||
check_lib "libcrypto.so" || all_libs_ok=false
|
# check_lib "libcrypto.so" || all_libs_ok=false (Removed in optimization)
|
||||||
check_lib "libcurl.so" || all_libs_ok=false
|
check_lib "libcurl.so" || all_libs_ok=false
|
||||||
check_lib "libasound.so" || all_libs_ok=false
|
check_lib "libasound.so" || all_libs_ok=false
|
||||||
|
|
||||||
|
|||||||
@@ -132,8 +132,8 @@ LDFLAGS += -lcedarxrender -lhwdisplay
|
|||||||
# ALSA 音频库(静态库不存在,且音频播放已禁用)
|
# ALSA 音频库(静态库不存在,且音频播放已禁用)
|
||||||
# LDFLAGS += -lasound
|
# LDFLAGS += -lasound
|
||||||
|
|
||||||
# OpenSSL (用于 WebSocket 握手)
|
# OpenSSL (Removed in Day 26 optimization)
|
||||||
LDFLAGS += -lssl -lcrypto
|
# LDFLAGS += -lssl -lcrypto
|
||||||
|
|
||||||
# 结束静态库组
|
# 结束静态库组
|
||||||
LDFLAGS += -Wl,--end-group
|
LDFLAGS += -Wl,--end-group
|
||||||
|
|||||||
@@ -52,7 +52,11 @@ Camera::Camera()
|
|||||||
, m_fps(0.0f)
|
, m_fps(0.0f)
|
||||||
, m_frame_count(0)
|
, m_frame_count(0)
|
||||||
, m_last_time(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");
|
LOGD("Camera constructor");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,6 +106,14 @@ void Camera::deinit()
|
|||||||
// 退出系统
|
// 退出系统
|
||||||
AW_MPI_SYS_Exit();
|
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_fps = 0.0f;
|
||||||
m_frame_count = 0;
|
m_frame_count = 0;
|
||||||
@@ -113,6 +125,18 @@ void Camera::deinit()
|
|||||||
bool Camera::init()
|
bool Camera::init()
|
||||||
{
|
{
|
||||||
LOGI("Initializing camera: %dx%d @%dfps", m_width, m_height, DEFAULT_FPS);
|
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 系统
|
// 1. 初始化 MPP 系统
|
||||||
MPP_SYS_CONF_S sys_conf;
|
MPP_SYS_CONF_S sys_conf;
|
||||||
@@ -332,16 +356,25 @@ bool Camera::capture_frame(uint8_t** jpeg_data, size_t* jpeg_size)
|
|||||||
return false;
|
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;
|
size_t total_size = stream.mpPack[0].mLen0 + stream.mpPack[0].mLen1 + stream.mpPack[0].mLen2;
|
||||||
if (total_size == 0) {
|
if (total_size == 0) {
|
||||||
LOGE("Empty JPEG frame");
|
LOGE("Empty JPEG frame");
|
||||||
AW_MPI_VENC_ReleaseStream(m_venc_chn, &stream);
|
AW_MPI_VENC_ReleaseStream(m_venc_chn, &stream);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 = new uint8_t[total_size];
|
uint8_t* buffer = m_frame_buffers[m_current_buf_idx];
|
||||||
|
|
||||||
|
// Copy data
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
if (stream.mpPack[0].mLen0 > 0 && stream.mpPack[0].mpAddr0) {
|
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);
|
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 统计
|
// 更新 FPS 统计
|
||||||
update_fps_stats();
|
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)
|
void Camera::release_frame(uint8_t* jpeg_data)
|
||||||
{
|
{
|
||||||
if (jpeg_data) {
|
// No-op for memory pool
|
||||||
delete[] jpeg_data;
|
// Buffer will be overwritten when it's turn comes again
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Camera::set_framesize(const std::string& size)
|
bool Camera::set_framesize(const std::string& size)
|
||||||
|
|||||||
@@ -95,6 +95,11 @@ private:
|
|||||||
bool init_venc(); // Video Encoder
|
bool init_venc(); // Video Encoder
|
||||||
|
|
||||||
void update_fps_stats();
|
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
|
#endif // CAMERA_H
|
||||||
|
|||||||
@@ -12,10 +12,61 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <openssl/sha.h>
|
#include <vector>
|
||||||
#include <openssl/bio.h>
|
#include <string>
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/buffer.h>
|
// 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 魔术字符串(用于握手验证,当前未使用)
|
// WebSocket 魔术字符串(用于握手验证,当前未使用)
|
||||||
// static const char* WS_MAGIC_STRING = "258EAFAA-5914-47DA-95CA-C5AB0DC85B11";
|
// static const char* WS_MAGIC_STRING = "258EAFAA-5914-47DA-95CA-C5AB0DC85B11";
|
||||||
@@ -178,21 +229,11 @@ bool WSClient::perform_handshake() {
|
|||||||
random_bytes[i] = rand() % 256;
|
random_bytes[i] = rand() % 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base64 编码
|
// Day 26: Use custom Base64 implementation instead of OpenSSL
|
||||||
BIO *bio, *b64;
|
std::string ws_key = base64_encode(random_bytes, 16);
|
||||||
BUF_MEM *bufferPtr;
|
|
||||||
|
|
||||||
b64 = BIO_new(BIO_f_base64());
|
// Debug log key (optional)
|
||||||
bio = BIO_new(BIO_s_mem());
|
// LOG_DEBUG("[WS] Generated Sec-WebSocket-Key: %s", ws_key.c_str());
|
||||||
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);
|
|
||||||
|
|
||||||
// 构造 HTTP 升级请求
|
// 构造 HTTP 升级请求
|
||||||
char request[1024];
|
char request[1024];
|
||||||
|
|||||||
Reference in New Issue
Block a user