This commit is contained in:
2026-04-11 17:20:52 +08:00
5 changed files with 81 additions and 37 deletions

0
.codex Normal file
View File

View File

@@ -3,7 +3,12 @@
#include <stdint.h>
uint64_t get_latest_gps_for_video(void);
typedef struct gps_video_sample {
double latitude;
double longitude;
} gps_video_sample_t;
gps_video_sample_t get_latest_gps_for_video(void);
int gps_buffer_init(const char* host);

View File

@@ -14,9 +14,14 @@ extern "C" {
typedef struct video_pipeline_packet_metadata {
uint64_t timestamp_ms;
uint64_t gps_data;
double latitude;
double longitude;
} video_pipeline_packet_metadata_t;
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
_Static_assert(sizeof(video_pipeline_packet_metadata_t) == 24, "video trailer metadata must be 24 bytes");
#endif
typedef struct video_pipeline_config {
const char *camera_device;
const char *server_addr;

View File

@@ -10,25 +10,55 @@
#include <errno.h> // 确保包含 errno
// 全局共享变量
static volatile uint64_t g_current_gps_data = 0;
static gps_video_sample_t g_current_gps_data = {0.0, 0.0};
static volatile int g_running = 0;
static pthread_t g_gps_thread;
static pthread_mutex_t g_gps_mutex = PTHREAD_MUTEX_INITIALIZER;
// 将经纬度打包进 uint64_t
static uint64_t pack_gps(double latitude, double longitude) {
static double normalize_coordinate(double coordinate) {
return round(coordinate * 1000000.0) / 1000000.0;
}
static void store_gps(double latitude, double longitude) {
pthread_mutex_lock(&g_gps_mutex);
g_current_gps_data.latitude = normalize_coordinate(latitude);
g_current_gps_data.longitude = normalize_coordinate(longitude);
pthread_mutex_unlock(&g_gps_mutex);
}
static void clear_gps(void) {
pthread_mutex_lock(&g_gps_mutex);
g_current_gps_data.latitude = 0.0;
g_current_gps_data.longitude = 0.0;
pthread_mutex_unlock(&g_gps_mutex);
}
static gps_video_sample_t load_gps(void) {
gps_video_sample_t sample;
pthread_mutex_lock(&g_gps_mutex);
sample = g_current_gps_data;
pthread_mutex_unlock(&g_gps_mutex);
return sample;
}
// 将经纬度规范化为 float保留 6 位小数。
static int normalize_gps(float latitude, float longitude, gps_video_sample_t* sample) {
if (!isfinite(latitude) || !isfinite(longitude)) {
return 0;
return -1;
}
// 过滤掉 0,0 这种无效坐标
if (fabs(latitude) < 1e-6 && fabs(longitude) < 1e-6) {
return 0;
return -1;
}
// 转换为整数微度 (micro-degrees)
int32_t lat_i = (int32_t)(latitude * 1000000.0);
int32_t lon_i = (int32_t)(longitude * 1000000.0);
if (sample == NULL) {
return -1;
}
return ((uint64_t)(uint32_t)lat_i << 32) | (uint64_t)(uint32_t)lon_i;
sample->latitude = normalize_coordinate(latitude);
sample->longitude = normalize_coordinate(longitude);
return 0;
}
// =================================================================
@@ -76,13 +106,8 @@ static int json_extract_double(const char* json, const char* key, double* value)
return 0; // 键不存在
}
// 处理负号
if (*position == '-') {
position++;
}
// 确保当前位置是数字
if (!(*position >= '0' && *position <= '9')) {
// 确保当前位置是数字或负号
if (*position != '-' && !(*position >= '0' && *position <= '9')) {
return 0;
}
@@ -209,8 +234,12 @@ void* gps_update_thread(void* arg) {
int got_lon = json_extract_double(start, "lon", &lon);
if (got_lat && got_lon) {
// 4. 更新全局共享变量 (原子操作)
g_current_gps_data = pack_gps(lat, lon);
gps_video_sample_t sample;
// 4. 更新全局共享变量,使用 double 直接携带经纬度。
if (normalize_gps(lat, lon, &sample) == 0) {
store_gps(sample.latitude, sample.longitude);
}
// 调试:取消注释可查看实时经纬度
// printf("更新GPS: lat=%.6f, lon=%.6f\n", lat, lon);
}
@@ -246,20 +275,20 @@ void* gps_update_thread(void* arg) {
// =================================================================
// 接口函数实现
// =================================================================
uint64_t get_latest_gps_for_video(void) {
return g_current_gps_data;
gps_video_sample_t get_latest_gps_for_video(void) {
return load_gps();
}
int gps_buffer_init(const char* host) {
if (g_running) return 0;
g_running = 1;
g_current_gps_data = 0;
clear_gps();
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// 创建后台线程
if (pthread_create(&g_gps_thread, NULL, gps_update_thread, (void*)host) != 0) {
if (pthread_create(&g_gps_thread, &attr, gps_update_thread, (void*)host) != 0) {
g_running = 0;
pthread_attr_destroy(&attr); // 清理属性
perror("无法创建 GPS 线程");

View File

@@ -930,8 +930,13 @@ int video_pipeline_run(const video_pipeline_config_t *config, video_pipeline_sta
send_start_ms = encode_end_ms;
}
{
gps_video_sample_t gps_sample = get_latest_gps_for_video();
packet_metadata.timestamp_ms = (uint64_t) get_realtime_ms();
packet_metadata.gps_data = get_latest_gps_for_video();
packet_metadata.latitude = gps_sample.latitude;
packet_metadata.longitude = gps_sample.longitude;
}
kcp_client_runtime_stats_snapshot(sender.client, &transport_stats);
if (video_sender_hard_backpressure_active(config, &transport_stats)) {