From 7ca136870d633cb973be0e4b037fa19d1a7dd6f9 Mon Sep 17 00:00:00 2001 From: nnbcccscdscdsc <2709767634@qq.com> Date: Sat, 11 Apr 2026 13:56:33 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E6=9B=B4=E6=96=B0gps=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .codex | 0 include/gps_buffer.h | 27 +++++++++------ include/video_pipeline.h | 7 +++- src/gps_buffer.c | 75 ++++++++++++++++++++++++++++------------ src/video_pipeline.c | 9 +++-- 5 files changed, 81 insertions(+), 37 deletions(-) create mode 100644 .codex diff --git a/.codex b/.codex new file mode 100644 index 0000000..e69de29 diff --git a/include/gps_buffer.h b/include/gps_buffer.h index 13c8363..f38db88 100644 --- a/include/gps_buffer.h +++ b/include/gps_buffer.h @@ -1,11 +1,16 @@ -#ifndef GPS_BUFFER_H -#define GPS_BUFFER_H - -#include - -uint64_t get_latest_gps_for_video(void); - - -int gps_buffer_init(const char* host); -void gps_buffer_cleanup(void); -#endif \ No newline at end of file +#ifndef GPS_BUFFER_H +#define GPS_BUFFER_H + +#include + +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); +void gps_buffer_cleanup(void); +#endif diff --git a/include/video_pipeline.h b/include/video_pipeline.h index 06ee388..c8f4aa9 100644 --- a/include/video_pipeline.h +++ b/include/video_pipeline.h @@ -14,9 +14,14 @@ extern "C" { typedef struct video_pipeline_packet_metadata { uint64_t timestamp_ms; - uint64_t gps_data; + float latitude; + float 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; diff --git a/src/gps_buffer.c b/src/gps_buffer.c index 6193dcb..af36d77 100644 --- a/src/gps_buffer.c +++ b/src/gps_buffer.c @@ -10,25 +10,55 @@ #include // 确保包含 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 线程"); @@ -277,4 +306,4 @@ void gps_buffer_cleanup(void) { } -//gcc main.c video_pipeline_run.c gps_buffer.c -lpthread -lm -o my_app 请确保在编译命令中链接 pthread 和 m (math) 库 \ No newline at end of file +//gcc main.c video_pipeline_run.c gps_buffer.c -lpthread -lm -o my_app 请确保在编译命令中链接 pthread 和 m (math) 库 diff --git a/src/video_pipeline.c b/src/video_pipeline.c index d7ed569..1bd6bc2 100644 --- a/src/video_pipeline.c +++ b/src/video_pipeline.c @@ -930,8 +930,13 @@ int video_pipeline_run(const video_pipeline_config_t *config, video_pipeline_sta send_start_ms = encode_end_ms; } - packet_metadata.timestamp_ms = (uint64_t) get_realtime_ms(); - packet_metadata.gps_data = get_latest_gps_for_video(); + { + gps_video_sample_t gps_sample = get_latest_gps_for_video(); + + packet_metadata.timestamp_ms = (uint64_t) get_realtime_ms(); + 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)) {