第一部分 软件架构

一、产品软件架构图(分层架构 + 微服务)

┌─────────────────────────────────────────────────────────────────────────┐
│                           APPLICATION LAYER                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌─────────────┐ │
│  │  HTTP/REST   │  │   RTSP/GB    │  │   WebRTC     │  │   Config    │ │
│  │   Server     │  │   Server     │  │   Server     │  │   Manager   │ │
│  └──────────────┘  └──────────────┘  └──────────────┘  └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
                                      ↓
┌─────────────────────────────────────────────────────────────────────────┐
│                           AI & ALGORITHM LAYER                           │
│  ┌──────────────────────────────────────────────────────────────────┐  │
│  │                    Pipeline Manager (状态机)                       │  │
│  │  ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐    │  │
│  │  │  Detector  │ │  Tracker   │ │  Classifier│ │  Calibrator│    │  │
│  │  │ (YOLO/RT)  │ │ (IOU/Bytetrack)│(ResNet)   │ │  (Zhang)   │    │  │
│  │  └────────────┘ └────────────┘ └────────────┘ └────────────┘    │  │
│  └──────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────┘
                                      ↓
┌─────────────────────────────────────────────────────────────────────────┐
│                         MIDDLEWARE LAYER                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌─────────────┐ │
│  │   Memory     │  │   Cache      │  │   Log        │  │   IPC       │ │
│  │   Manager    │  │   Manager    │  │   Manager    │  │   Bus       │ │
│  │  (Pool/CMA)  │  │ (Frame/Dn)   │  │ (Ring/File)  │  │ (ARM<->ARMn)│ │
│  └──────────────┘  └──────────────┘  └──────────────┘  └─────────────┘ │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌─────────────┐ │
│  │   ISP        │  │   V4L2       │  │   BPU        │  │   DMA       │ │
│  │   Control    │  │   Wrapper    │  │   Runtime    │  │   Manager   │ │
│  └──────────────┘  └──────────────┘  └──────────────┘  └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
                                      ↓
┌─────────────────────────────────────────────────────────────────────────┐
│                         BSP & DRIVER LAYER                               │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌─────────────┐ │
│  │   Boot       │  │   Kernel      │  │   Rootfs     │  │   Sensor    │ │
│  │   (U-Boot)   │  │   (DTS/Drv)   │  │   (Libs)     │  │   (IMX415)  │ │
│  └──────────────┘  └──────────────┘  └──────────────┘  └─────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
                                      ↓
┌─────────────────────────────────────────────────────────────────────────┐
│                           HARDWARE LAYER                                 │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│  │  Sensor  │ │   ISP    │ │   BPU    │ │   DDR    │ │   Ethernet   │ │
│  │  IMX415  │ │  Tuning  │ │   Core   │ │   4/8G   │ │   RGMII      │ │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘

二、软件程序流程图(主业务流程)

[Main] 
   ↓
[Init Phase]
   ├─→ Logger_Init() ──→ [LOG_RINGBUFFER|FILE|NET]
   ├─→ Memory_Init() ──→ [CMA_POOL|DMA_POOL|AI_TENSOR_POOL]
   ├─→ Cache_Init()  ──→ [FRAME_CACHE|MODEL_CACHE|LUT_CACHE]
   ├─→ ISP_Init()    ──→ [SENSOR_CONFIG|ISP_TUNING|3A_SERVER]
   ├─→ V4L2_Init()   ──→ [VIDEO_DEV|CAPTURE_THREAD]
   ├─→ AI_Init()     ──→ [BPU_LOAD|MODEL_LOAD|TASK_POOL]
   └─→ Calib_Init()  ──→ [LOAD_PARAM|CHESSBOARD_DETECT]
   ↓
[Running Phase] - 主循环 (事件驱动)
   ↓
┌─────────────────────────────────────────────────────────────┐
│  Event Loop (epoll/select)                                   │
│  ├─→ [V4L2 Event]  ──→ Frame_Capture()                      │
│  │                     ↓                                      │
│  │                   [Double Buffer Swap]                    │
│  │                     ↓                                      │
│  │                   ISP_RawProcess() ──→ [BLC|HDR|WDR|Demosaic]
│  │                     ↓                                      │
│  │                   ┌─────────────────────────┐            │
│  │                   │ Branch: AI or Preview?  │            │
│  │                   └─────────────────────────┘            │
│  │                     ↓                      ↓              │
│  │               [AI Pipeline]          [Preview Path]      │
│  │                     ↓                      ↓              │
│  │          AI_Preprocess()           V4L2_Output()         │
│  │          (Resize/Crop/Normalize)     (Display/Encode)    │
│  │                     ↓                                     │
│  │          BPU_Inference()                                 │
│  │                     ↓                                     │
│  │          AI_Postprocess()                                │
│  │          (NMS/Bbox/Track/Calib)                          │
│  │                     ↓                                     │
│  │          Event_Notify() ──→ [MQTT|WS|Callback]           │
│  │                                                           │
│  ├─→ [ISP Event]  ──→ ISP_3A_Update()                       │
│  │                     ↓                                     │
│  │                   AE_Adjust() / AF_Search() / AWB_Cal()  │
│  │                     ↓                                     │
│  │                   ISP_Apply_Params()                     │
│  │                                                           │
│  ├─→ [AI Event]   ──→ AI_Model_Switch() / Calib_Update()    │
│  │                                                           │
│  └─→ [Timer]      ──→ Health_Check() / Stat_Report()        │
└─────────────────────────────────────────────────────────────┘
   ↓
[Deinit Phase]
   ├─→ AI_Deinit()  ──→ [BPU_Unload|Model_Free]
   ├─→ V4L2_Deinit()──→ [Stream_Off|Dev_Close]
   ├─→ ISP_Deinit() ──→ [Sensor_PowerOff|Tuning_Save]
   ├─→ Cache_Deinit()──→ [Flush|Free]
   ├─→ Memory_Deinit()→ [Pool_Destroy]
   └─→ Logger_Deinit()→ [Flush_Log]

三、函数调用Pipeline树形图

main()
├─→ logger_init(LOG_LEVEL_INFO, LOG_OUTPUT_FILE | LOG_OUTPUT_CONSOLE)
│   ├─→ ringbuf_create(LOG_RING_SIZE, &g_log_ring)
│   ├─→ pthread_create(&g_log_flush_thread, log_flush_routine)
│   └─→ register_signal_handler(SIGSEGV, crash_log_dump)
│
├─→ memory_init(&mem_cfg)
│   ├─→ cma_pool_create("ai_tensor", 512 * 1024 * 1024)  // 512MB AI内存
│   ├─→ dma_pool_create("video_capture", 256 * 1024 * 1024) // 256MB DMA
│   ├─→ slab_create("frame_buf", sizeof(frame_t), 32)    // 帧对象缓存
│   └─→ memory_pool_stat_init()  // 内存监控
│
├─→ cache_init(&cache_cfg)
│   ├─→ frame_cache_create(FRAME_CACHE_SIZE, 30)  // 缓存30帧
│   │   ├─→ g_frame_cache.queue = queue_create()
│   │   ├─→ g_frame_cache.hash = hashmap_create()
│   │   └─→ g_frame_cache.lru = lru_create()
│   ├─→ model_cache_create(MODEL_CACHE_SIZE, 3)    // 缓存3个模型
│   └─→ lut_cache_create(LUT_CACHE_SIZE, 10)       // 缓存LUT表
│
├─→ isp_init(&isp_cfg)
│   ├─→ sensor_init(&g_sensor_ctx)
│   │   ├─→ i2c_open("/dev/i2c-0")
│   │   ├─→ sensor_power_on()  // GPIO操作
│   │   ├─→ sensor_write_reg(IMX415_REG_MODE, IMX415_MODE_3840x2160_30FPS)
│   │   └─→ sensor_stream_on()
│   ├─→ isp_tuning_init("/etc/isp/imx415_tuning.bin")
│   │   ├─→ tuning_parse_header()  // 解析BLC/LSC/CCM/GAMMA表
│   │   ├─→ tuning_load_black_level(blc_table)
│   │   ├─→ tuning_load_lens_shading(lsc_table)
│   │   ├─→ tuning_load_color_matrix(ccm_matrix)
│   │   └─→ tuning_load_gamma(gamma_lut)
│   ├─→ isp_3a_init()
│   │   ├─→ ae_init(&g_ae_ctx, AE_MODE_ADAPTIVE)
│   │   │   ├─→ ae_stat_config(STATS_5x5 | STATS_HISTOGRAM)
│   │   │   └─→ ae_target_set(60, 80)  // 目标亮度范围
│   │   ├─→ awb_init(&g_awb_ctx, AWB_MODE_GREYWORLD)
│   │   │   ├─→ awb_stat_config(RGGB_BAYER)
│   │   │   └─→ awb_color_temp_set(2500, 7500)
│   │   └─→ af_init(&g_af_ctx, AF_MODE_CONTRAST)
│   │       ├─→ af_search_range(10, 1023)  // VCM范围
│   │       └─→ af_step_config(COARSE_STEP=50, FINE_STEP=5)
│   └─→ isp_device_open("/dev/video0")
│       ├─→ v4l2_set_format(WIDTH=3840, HEIGHT=2160, PIX_FMT=SRGGB10)
│       ├─→ v4l2_set_framerate(30)
│       ├─→ v4l2_reqbufs(COUNT=4, MEMORY=MMAP)
│       ├─→ v4l2_qbuf_all()
│       └─→ v4l2_stream_on()
│
├─→ v4l2_init(&v4l2_ctx)
│   ├─→ capture_thread_create(capture_routine)
│   │   └─→ [CAPTURE_THREAD] while(1)
│   │       ├─→ v4l2_dqbuf()  // 阻塞等待帧
│   │       ├─→ frame = memory_pool_alloc(FRAME_POOL)
│   │       ├─→ memcpy(frame->data, v4l2_buf, frame_size)
│   │       ├─→ frame->timestamp = get_monotonic_time()
│   │       ├─→ frame->sequence = g_frame_seq++
│   │       ├─→ frame_cache_push(g_frame_cache, frame)
│   │       ├─→ event_notify(EVENT_NEW_FRAME, frame)
│   │       └─→ v4l2_qbuf()
│   └─→ output_thread_create(output_routine)  // 预览/编码输出
│
├─→ ai_init(&ai_cfg)
│   ├─→ bpu_init()
│   │   ├─→ bpu_open("/dev/bpu")
│   │   ├─→ bpu_set_power(OP_LEVEL_HIGH)
│   │   └─→ bpu_task_pool_create(MAX_TASKS=8)
│   ├─→ model_load("detect_yolov5s.hbm", &g_detect_model)
│   │   ├─→ hb_dnn_load_from_file(model_path, &g_detect_model)
│   │   ├─→ model_get_input_tensor(g_detect_model, &input)
│   │   ├─→ model_get_output_tensor(g_detect_model, &output)
│   │   └─→ model_cache_put(g_model_cache, model_id, g_detect_model)
│   ├─→ model_load("classify_resnet18.hbm", &g_cls_model)
│   ├─→ model_load("track_feature.hbm", &g_track_model)
│   └─→ ai_pipeline_create(&g_ai_pipeline)
│       ├─→ pipeline_add_stage(g_ai_pipeline, preprocess_stage)
│       ├─→ pipeline_add_stage(g_ai_pipeline, inference_stage)
│       ├─→ pipeline_add_stage(g_ai_pipeline, postprocess_stage)
│       ├─→ pipeline_add_stage(g_ai_pipeline, track_stage)
│       └─→ pipeline_add_stage(g_ai_pipeline, calib_stage)
│
├─→ calib_init(&calib_cfg)
│   ├─→ calib_param_load("/etc/calib/camera_intrinsic.yaml")
│   │   ├─→ yaml_parse_file() → camera_matrix[3x3]
│   │   ├─→ yaml_parse_file() → dist_coeffs[5]
│   │   └─→ yaml_parse_file() → rect_map[2][HEIGHT][WIDTH]
│   ├─→ calib_board_create(CHESSBOARD_9x6, SQUARE_SIZE=25mm)
│   ├─→ calib_undistort_map_precompute()
│   │   ├─→ initUndistortRectifyMap()  // OpenCV
│   │   └─→ remap_lut_cache_put(g_lut_cache, map_x, map_y)
│   └─→ calib_auto_trigger_create(TRIGGER_INTERVAL=3600)  // 每小时重标定
│
├─→ event_loop_create()
│   ├─→ epoll_create()
│   ├─→ epoll_ctl_add(v4l2_fd, EPOLLIN, v4l2_callback)
│   ├─→ epoll_ctl_add(isp_event_fd, EPOLLIN, isp_callback)
│   ├─→ epoll_ctl_add(timer_fd, EPOLLIN, health_callback)
│   └─→ while(g_running) {
│         nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1)
│         for(i=0; i<nfds; i++) {
│           events[i].data.callback()  // 分发事件
│         }
│       }
│
├─→ v4l2_callback(event)  // 帧到达事件
│   ├─→ frame = frame_cache_pop(g_frame_cache)
│   ├─→ if(ai_enabled) {
│   │     ai_pipeline_process(g_ai_pipeline, frame)
│   │     ├─→ preprocess_stage: convert_to_rgb / resize / normalize
│   │     ├─→ inference_stage: bpu_submit_task()
│   │     ├─→ postprocess_stage: nms / bbox_decode / confidence
│   │     ├─→ track_stage: iou_match / kalman_filter
│   │     └─→ calib_stage: chessboard_detect() / homography_update()
│   │   }
│   ├─→ if(preview_enabled) {
│   │     isp_draw_bbox(frame, ai_results)
│   │     v4l2_output_push(g_output_ctx, frame)
│   │   }
│   └─→ frame_cache_push(g_frame_cache, frame)  // 循环使用
│
├─→ isp_callback(event)  // ISP 3A统计事件
│   ├─→ isp_3a_run()
│   │   ├─→ ae_run(&g_ae_ctx, isp_stats)
│   │   │   ├─→ calc_average_luminance()
│   │   │   ├─→ pid_controller_update()
│   │   │   └─→ sensor_set_exposure() / sensor_set_gain()
│   │   ├─→ awb_run(&g_awb_ctx, isp_stats)
│   │   │   ├─→ calc_rg_gain() / calc_bg_gain()
│   │   │   ├─→ color_temperature_estimate()
│   │   │   └─→ isp_set_wb_gains(r_gain, g_gain, b_gain)
│   │   └─→ af_run(&g_af_ctx, isp_stats)
│   │       ├─→ calc_focus_value(FV_HISTOGRAM | FV_SOBEL)
│   │       ├─→ hill_climbing_search()
│   │       └─→ vcm_set_position(lens_pos)
│   └─→ isp_apply_tuning_online()
│       ├─→ if(ai_detected_face) {
│       │     isp_set_focus_roi(face_bbox)
│       │     isp_set_exposure_comp(+0.5EV)
│       │   }
│       └─→ tuning_save_statistics()  // 记录调优数据
│
├─→ health_callback()  // 健康检查定时器
│   ├─→ memory_pool_stat_report()
│   ├─→ frame_cache_stat_report()
│   ├─→ bpu_utilization_report()
│   ├─→ cpu_temp_monitor()
│   │   └─→ if(temp > 85°C) thermal_throttling()
│   └─→ log_rotate_check()
│
└─→ cleanup_and_exit()
    ├─→ event_loop_destroy()
    ├─→ ai_deinit() → bpu_close() / model_unload() / pipeline_destroy()
    ├─→ v4l2_deinit() → stream_off() / reqbufs(0) / close()
    ├─→ isp_deinit() → sensor_power_off() / tuning_save()
    ├─→ calib_deinit() → param_save() / map_free()
    ├─→ cache_deinit() → cache_flush() / cache_destroy()
    ├─→ memory_deinit() → pool_destroy_all()
    └─→ logger_deinit() → ringbuf_destroy() / pthread_join()

四、完整文件列表及职责

rdk3_cam_solution/
├── include/                           # 公共头文件
│   ├── rdk3_cam.h                    # 主头文件,导出API
│   ├── config.h                       # 配置结构体定义
│   ├── error.h                        # 错误码定义
│   └── version.h                      # 版本信息
│
├── src/
│   ├── main.c                         # 主入口,事件循环
│   │
│   ├── core/                          # 核心模块
│   │   ├── memory/                    
│   │   │   ├── memory_manager.h       # 内存管理接口
│   │   │   ├── memory_manager.c       # CMA/SLAB/DMA池实现
│   │   │   ├── cma_pool.c             # CMA连续内存分配器
│   │   │   ├── slab_allocator.c       # SLAB对象缓存
│   │   │   └── dma_buffer.c           # DMA缓冲区管理
│   │   ├── cache/
│   │   │   ├── cache_manager.h        # 缓存管理接口
│   │   │   ├── cache_manager.c        # LRU/LFU缓存实现
│   │   │   ├── frame_cache.c          # 帧缓存专用
│   │   │   ├── model_cache.c          # AI模型缓存
│   │   │   └── lut_cache.c            # LUT查找表缓存
│   │   ├── log/
│   │   │   ├── logger.h               # 日志接口
│   │   │   ├── logger.c               # 异步日志实现
│   │   │   ├── ringbuffer.c           # 环形缓冲区
│   │   │   ├── log_formatter.c        # 格式化输出
│   │   │   └── log_rotate.c           # 日志轮转
│   │   └── ipc/
│   │       ├── ipc_bus.h              # 核间通信接口
│   │       ├── ipc_bus.c              # RPMSG实现
│   │       ├── ring_queue.c           # 无锁队列
│   │       └── shared_memory.c        # 共享内存管理
│   │
│   ├── bsp/                           # 板级支持包
│   │   ├── boot/
│   │   │   ├── boot_config.h          # 启动参数配置
│   │   │   └── ddr_init.c             # DDR初始化(调试用)
│   │   ├── kernel/
│   │   │   ├── dts/                   # 设备树
│   │   │   │   ├── rdk3_evb.dts       # 公版
│   │   │   │   └── product_cam_v1.dts # 产品板
│   │   │   ├── driver_adapter.h       # 驱动适配层
│   │   │   └── gpio_irq.c             # GPIO中断处理
│   │   └── rootfs/
│   │       ├── sensor_lib.h           # 传感器库接口
│   │       ├── sensor_imx415.c        # IMX415驱动封装
│   │       └── v4l2_helper.c          # V4L2辅助函数
│   │
│   ├── middleware/                    # 中间件层
│   │   ├── isp/
│   │   │   ├── isp_manager.h          # ISP管理接口
│   │   │   ├── isp_manager.c          # ISP主控
│   │   │   ├── isp_3a.h               # 3A算法接口
│   │   │   ├── ae.c                   # 自动曝光
│   │   │   ├── awb.c                  # 自动白平衡
│   │   │   ├── af.c                   # 自动对焦
│   │   │   ├── isp_tuning.h           # ISP调优接口
│   │   │   ├── isp_tuning.c           # 调优参数加载
│   │   │   ├── black_level.c          # BLC校正
│   │   │   ├── lens_shading.c         # LSC校正
│   │   │   ├── color_matrix.c         # CCM矩阵
│   │   │   └── gamma_correction.c     # Gamma校正
│   │   ├── v4l2/
│   │   │   ├── v4l2_wrapper.h         # V4L2封装接口
│   │   │   ├── v4l2_wrapper.c         # V4L2操作封装
│   │   │   ├── capture_thread.c       # 采集线程
│   │   │   └── output_thread.c        # 输出线程
│   │   └── bpu/
│   │       ├── bpu_runtime.h          # BPU运行时接口
│   │       ├── bpu_runtime.c          # BPU任务调度
│   │       ├── model_loader.c         # HBM模型加载
│   │       └── tensor_process.c       # Tensor处理
│   │
│   ├── algorithm/                     # 算法层
│   │   ├── ai/
│   │   │   ├── ai_pipeline.h          # AI流水线接口
│   │   │   ├── ai_pipeline.c          # 流水线管理
│   │   │   ├── preprocess.h           # 预处理接口
│   │   │   ├── preprocess.c           # Resize/归一化
│   │   │   ├── inference.c            # BPU推理封装
│   │   │   ├── postprocess.h          # 后处理接口
│   │   │   ├── postprocess.c          # NMS/Bbox解码
│   │   │   ├── detector_yolo.c        # YOLO检测器
│   │   │   ├── classifier_resnet.c    # ResNet分类器
│   │   │   └── tracker.c              # 目标跟踪
│   │   └── calib/
│   │       ├── calibrator.h           # 标定接口
│   │       ├── calibrator.c           # 相机标定主控
│   │       ├── chessboard_detect.c    # 棋盘格检测
│   │       ├── homography.c           # 单应性矩阵
│   │       ├── undistort.c            # 畸变校正
│   │       └── param_io.c             # 参数读写
│   │
│   ├── application/                   # 应用层
│   │   ├── event_loop.c               # 事件主循环
│   │   ├── config_manager.c           # 配置管理
│   │   ├── health_monitor.c           # 健康监控
│   │   ├── rtsp_server.c              # RTSP推流
│   │   ├── websocket_server.c         # WebSocket服务
│   │   └── mqtt_client.c              # MQTT上报
│   │
│   └── utils/                         # 工具函数
│       ├── list.h                     # 链表实现
│       ├── hashmap.h                  # 哈希表
│       ├── thread_pool.h              # 线程池
│       ├── timer_wheel.h              # 时间轮
│       ├── ringbuf.h                  # 环形缓冲区
│       └── crc32.c                    # 校验算法
│
├── tests/                             # 单元测试
│   ├── test_memory.c
│   ├── test_cache.c
│   ├── test_isp.c
│   └── test_ai.c
│
├── tools/                             # 工具
│   ├── tuning_viewer/                 # 调优可视化
│   ├── calib_gui/                     # 标定GUI
│   └── log_analyzer/                  # 日志分析
│
├── config/                            # 配置文件
│   ├── product_cam.yaml               # 产品配置
│   ├── isp_tuning.bin                 # ISP调优参数
│   └── camera_intrinsic.yaml          # 相机内参
│
├── scripts/                           # 脚本
│   ├── build.sh                       # 编译脚本
│   ├── deploy.sh                      # 部署脚本
│   └── start.sh                       # 启动脚本
│
├── docs/                              # 文档
│   ├── Doxyfile                       # Doxygen配置
│   └── architecture.md                # 架构文档
│
├── CMakeLists.txt                     # CMake构建
└── README.md                          # 项目说明

五、关键数据结构定义

/**
 * @file rdk3_cam.h
 * @brief RDK3 AI摄像机主头文件
 * @author BSP Team
 * @version 1.0.0
 * @date 2024
 */
​
#ifndef RDK3_CAM_H
#define RDK3_CAM_H
​
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
​
#ifdef __cplusplus
extern "C" {
#endif
​
/*=============================================================================
 * 错误码定义
 *============================================================================*/
#define RDK3_OK                     0
#define RDK3_ERR_INVALID_PARAM     -1
#define RDK3_ERR_MEMORY            -2
#define RDK3_ERR_IO                -3
#define RDK3_ERR_TIMEOUT           -4
#define RDK3_ERR_NOT_FOUND         -5
#define RDK3_ERR_BUSY              -6
#define RDK3_ERR_AGAIN             -7
​
/*=============================================================================
 * 日志级别定义
 *============================================================================*/
typedef enum {
    LOG_LEVEL_FATAL = 0,
    LOG_LEVEL_ERROR = 1,
    LOG_LEVEL_WARN  = 2,
    LOG_LEVEL_INFO  = 3,
    LOG_LEVEL_DEBUG = 4,
    LOG_LEVEL_TRACE = 5
} log_level_t;
​
typedef enum {
    LOG_OUTPUT_CONSOLE = 0x01,
    LOG_OUTPUT_FILE    = 0x02,
    LOG_OUTPUT_NETWORK = 0x04,
    LOG_OUTPUT_SYSLOG  = 0x08
} log_output_t;
​
/*=============================================================================
 * 内存管理结构体
 *============================================================================*/
​
/**
 * @brief 内存池类型
 */
typedef enum {
    MEM_POOL_CMA,      ///< 连续内存池 (用于DMA/ISP)
    MEM_POOL_DMA,      ///< DMA缓冲区池
    MEM_POOL_SLAB,     ///< SLAB对象缓存
    MEM_POOL_AI_TENSOR ///< AI张量内存池
} mem_pool_type_t;
​
/**
 * @brief 内存池配置
 */
typedef struct {
    mem_pool_type_t type;      ///< 池类型
    const char* name;          ///< 池名称
    size_t block_size;         ///< 块大小
    size_t block_count;        ///< 块数量
    uint32_t flags;            ///< 标志位 (CACHE_ALIGN | ZERO_INIT)
} mem_pool_cfg_t;
​
/**
 * @brief 内存分配器句柄 (不透明指针)
 */
typedef void* mem_pool_handle_t;
​
/**
 * @brief 内存统计信息
 */
typedef struct {
    size_t total_bytes;        ///< 总字节数
    size_t used_bytes;         ///< 已用字节数
    size_t peak_bytes;         ///< 峰值字节数
    uint32_t alloc_count;      ///< 分配次数
    uint32_t free_count;       ///< 释放次数
    uint32_t fail_count;       ///< 失败次数
} mem_stat_t;
​
/*=============================================================================
 * 缓存管理结构体
 *============================================================================*/
​
/**
 * @brief 缓存淘汰策略
 */
typedef enum {
    CACHE_EVICT_LRU,   ///< 最近最少使用
    CACHE_EVICT_LFU,   ///< 最不经常使用
    CACHE_EVICT_FIFO   ///< 先进先出
} cache_evict_policy_t;
​
/**
 * @brief 缓存配置
 */
typedef struct {
    const char* name;               ///< 缓存名称
    size_t max_size;               ///< 最大条目数
    size_t max_bytes;              ///< 最大字节数
    cache_evict_policy_t policy;   ///< 淘汰策略
    uint32_t ttl_seconds;          ///< 生存时间(0=永久)
    bool enable_stat;              ///< 启用统计
} cache_cfg_t;
​
/**
 * @brief 帧数据结构
 */
typedef struct frame {
    uint32_t sequence;              ///< 帧序号
    uint64_t timestamp;             ///< 时间戳(纳秒)
    uint32_t width;                 ///< 宽度
    uint32_t height;                ///< 高度
    uint32_t format;                ///< 像素格式 (V4L2_PIX_FMT_*)
    uint32_t size;                  ///< 数据大小
    void* data[3];                  ///< 数据指针(Y/UV或RGB)
    uint32_t stride[3];             ///< 行跨度
    void* user_priv;                ///< 用户私有数据
    struct frame* next;             ///< 链表指针
} frame_t;
​
/*=============================================================================
 * ISP控制结构体
 *============================================================================*/
​
/**
 * @brief 传感器信息
 */
typedef struct {
    const char* name;               ///< 传感器型号
    uint32_t i2c_bus;              ///< I2C总线号
    uint16_t i2c_addr;             ///< I2C地址
    uint32_t reset_gpio;           ///< Reset GPIO
    uint32_t power_gpio;           ///< Power GPIO
    uint32_t mipi_lanes;           ///< MIPI通道数
    uint32_t pixel_rate;           ///< 像素时钟(Hz)
} sensor_info_t;
​
/**
 * @brief ISP调优参数
 */
typedef struct {
    /* Black Level Correction */
    uint16_t blc_r;                 ///< 黑电平R通道
    uint16_t blc_gr;                ///< 黑电平Gr通道
    uint16_t blc_gb;                ///< 黑电平Gb通道
    uint16_t blc_b;                 ///< 黑电平B通道
    
    /* Lens Shading Correction */
    uint16_t* lsc_table_r;          ///< LSC R通道表(宽x高)
    uint16_t* lsc_table_gr;         ///< LSC Gr通道表
    uint16_t* lsc_table_gb;         ///< LSC Gb通道表
    uint16_t* lsc_table_b;          ///< LSC B通道表
    uint32_t lsc_width;             ///< LSC表格宽度
    uint32_t lsc_height;            ///< LSC表格高度
    
    /* Color Correction Matrix */
    float ccm[3][3];                ///< 色彩校正矩阵
    
    /* Gamma Correction */
    uint8_t gamma_lut[256];         ///< Gamma查找表
    
    /* Denoise */
    uint8_t denoise_strength;       ///< 降噪强度 0-255
    
    /* Sharpness */
    uint8_t sharpness_strength;     ///< 锐化强度 0-255
} isp_tuning_t;
​
/**
 * @brief 3A统计信息
 */
typedef struct {
    /* AE统计 */
    uint32_t avg_luminance;         ///< 平均亮度
    uint32_t hist[256];             ///< 直方图
    
    /* AWB统计 */
    uint32_t sum_r;                 ///< R通道和
    uint32_t sum_g;                 ///< G通道和
    uint32_t sum_b;                 ///< B通道和
    
    /* AF统计 */
    uint32_t focus_value;           ///< 对焦值
    uint32_t focus_roi_x;           ///< ROI X坐标
    uint32_t focus_roi_y;           ///< ROI Y坐标
    uint32_t focus_roi_w;           ///< ROI宽度
    uint32_t focus_roi_h;           ///< ROI高度
} isp_3a_stats_t;
​
/**
 * @brief AE配置
 */
typedef struct {
    uint32_t target_luminance;      ///< 目标亮度 0-255
    uint32_t min_luminance;         ///< 最小亮度
    uint32_t max_luminance;         ///< 最大亮度
    uint32_t exposure_time_min;     ///< 最小曝光时间(us)
    uint32_t exposure_time_max;     ///< 最大曝光时间(us)
    uint32_t gain_min;              ///< 最小增益(x256)
    uint32_t gain_max;              ///< 最大增益(x256)
    float pid_kp;                   ///< PID比例系数
    float pid_ki;                   ///< PID积分系数
    float pid_kd;                   ///< PID微分系数
} ae_cfg_t;
​
/*=============================================================================
 * AI推理结构体
 *============================================================================*/
​
/**
 * @brief AI模型类型
 */
typedef enum {
    AI_MODEL_DETECT,    ///< 目标检测
    AI_MODEL_CLASSIFY,  ///< 图像分类
    AI_MODEL_TRACK,     ///< 目标跟踪
    AI_MODEL_SEGMENT    ///< 语义分割
} ai_model_type_t;
​
/**
 * @brief 目标检测框
 */
typedef struct {
    float x1, y1;       ///< 左上角坐标(归一化0-1)
    float x2, y2;       ///< 右下角坐标(归一化0-1)
    float confidence;   ///< 置信度 0-1
    int class_id;       ///< 类别ID
    const char* class_name; ///< 类别名称
} detection_t;
​
/**
 * @brief AI推理结果
 */
typedef struct {
    uint32_t frame_seq;             ///< 关联的帧序号
    uint64_t timestamp;             ///< 推理完成时间戳
    detection_t* detections;        ///< 检测框数组
    uint32_t detection_count;       ///< 检测框数量
    float* features;                ///< 特征向量(跟踪用)
    uint32_t feature_dim;           ///< 特征维度
    void* user_data;                ///< 用户数据
} ai_result_t;
​
/*=============================================================================
 * 标定结构体
 *============================================================================*/
​
/**
 * @brief 相机内参
 */
typedef struct {
    float fx, fy;       ///< 焦距
    float cx, cy;       ///< 光心
    float k1, k2, p1, p2, k3;  ///< 畸变系数
    float rms_error;    ///< 重投影误差
} camera_intrinsic_t;
​
/**
 * @brief 标定配置
 */
typedef struct {
    int board_width;                ///< 棋盘格宽度(内角点数)
    int board_height;               ///< 棋盘格高度(内角点数)
    float square_size_mm;           ///< 方格边长(mm)
    int min_samples;                ///< 最小采样数量
    int auto_trigger_interval;      ///< 自动标定间隔(秒)
} calib_cfg_t;
​
/*=============================================================================
 * 主配置结构体
 *============================================================================*/
​
/**
 * @brief 产品配置
 */
typedef struct {
    /* 视频配置 */
    uint32_t video_width;           ///< 采集宽度
    uint32_t video_height;          ///< 采集高度
    uint32_t video_framerate;       ///< 采集帧率
    uint32_t video_format;          ///< 像素格式
    
    /* AI配置 */
    bool ai_enabled;                ///< AI使能
    const char* detect_model_path;  ///< 检测模型路径
    float ai_confidence_threshold;  ///< 置信度阈值
    float ai_nms_threshold;         ///< NMS阈值
    
    /* 标定配置 */
    calib_cfg_t calib;
    
    /* 日志配置 */
    log_level_t log_level;          ///< 日志级别
    uint32_t log_output;            ///< 日志输出方式
    const char* log_file_path;      ///< 日志文件路径
    
    /* 内存配置 */
    size_t cma_pool_size;           ///< CMA池大小(MB)
    size_t dma_pool_size;           ///< DMA池大小(MB)
    size_t ai_tensor_pool_size;     ///< AI张量池大小(MB)
    
    /* 缓存配置 */
    uint32_t frame_cache_size;      ///< 帧缓存大小
    uint32_t model_cache_size;      ///< 模型缓存大小
} rdk3_cam_config_t;
​
/*=============================================================================
 * 主API函数
 *============================================================================*/
​
/**
 * @brief 初始化RDK3摄像机系统
 * @param config 配置参数
 * @return 成功返回RDK3_OK,失败返回错误码
 * 
 * @note 调用顺序: 必须先调用此函数
 * @warning 只能调用一次
 */
int rdk3_cam_init(const rdk3_cam_config_t* config);
​
/**
 * @brief 启动视频流和AI处理
 * @return 成功返回RDK3_OK
 */
int rdk3_cam_start(void);
​
/**
 * @brief 停止视频流和AI处理
 * @return 成功返回RDK3_OK
 */
int rdk3_cam_stop(void);
​
/**
 * @brief 反初始化系统
 */
void rdk3_cam_deinit(void);
​
/**
 * @brief 获取最新的AI推理结果
 * @param result 输出结果指针
 * @param timeout_ms 超时时间(毫秒)
 * @return 成功返回RDK3_OK
 */
int rdk3_cam_get_ai_result(ai_result_t* result, int timeout_ms);
​
/**
 * @brief 动态更新ISP参数
 * @param tuning 新的调优参数
 * @return 成功返回RDK3_OK
 */
int rdk3_cam_update_isp_tuning(const isp_tuning_t* tuning);
​
/**
 * @brief 触发标定流程
 * @return 成功返回RDK3_OK
 */
int rdk3_cam_trigger_calibration(void);
​
/**
 * @brief 获取系统健康状态
 * @param cpu_temp 输出CPU温度
 * @param bpu_usage 输出BPU使用率
 * @param mem_usage 输出内存使用率
 */
void rdk3_cam_get_health(float* cpu_temp, float* bpu_usage, float* mem_usage);
​
#ifdef __cplusplus
}
#endif
​
#endif /* RDK3_CAM_H */

第二部分 地平线RDK3 AI摄像机核心模块实现

一、优先级1:双架构IPC、ISP调优、AI流水线

1.1 双架构IPC模块(解决ARM + ARM-None共存)

/**
 * @file ipc_bus.h
 * @brief 双架构核间通信总线接口
 * @author BSP Team
 * @version 1.0.0
 * 
 * @section 设计模式
 * - **代理模式(Proxy)**: 为ARM-None核提供代理访问
 * - **命令模式(Command)**: 封装跨核调用为命令对象
 * - **观察者模式(Observer)**: 异步通知ARM-None核完成状态
 * 
 * @section 防坑指南
 * @warning 1. 必须使用无锁队列,避免死锁
 * @warning 2. 共享内存必须cache对齐,防止一致性问题
 * @warning 3. 命令参数不能包含指针(地址空间不同)
 */
​
#ifndef IPC_BUS_H
#define IPC_BUS_H
​
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
​
#ifdef __cplusplus
extern "C" {
#endif
​
/*=============================================================================
 * 错误码定义
 *============================================================================*/
#define IPC_OK          0
#define IPC_ERR_FULL    -1
#define IPC_ERR_EMPTY   -2
#define IPC_ERR_TIMEOUT -3
#define IPC_ERR_NOMEM   -4
​
/*=============================================================================
 * 命令ID定义 (ARM <-> ARM-None 协议)
 *============================================================================*/
typedef enum {
    /* ISP控制命令 (0x1000-0x1FFF) */
    CMD_ISP_SET_EXPOSURE     = 0x1001,
    CMD_ISP_SET_GAIN         = 0x1002,
    CMD_ISP_SET_WB_GAINS     = 0x1003,
    CMD_ISP_SET_FOCUS_POS    = 0x1004,
    CMD_ISP_GET_STATS        = 0x1005,
    CMD_ISP_SET_TUNING_PARAM = 0x1006,
    
    /* 传感器控制命令 (0x2000-0x2FFF) */
    CMD_SENSOR_READ_REG      = 0x2001,
    CMD_SENSOR_WRITE_REG     = 0x2002,
    CMD_SENSOR_STREAM_ON     = 0x2003,
    CMD_SENSOR_STREAM_OFF    = 0x2004,
    
    /* 系统控制命令 (0x3000-0x3FFF) */
    CMD_SYSTEM_GET_TEMP      = 0x3001,
    CMD_SYSTEM_RESET         = 0x3002,
    CMD_SYSTEM_POWER_OFF     = 0x3003,
    
    /* 自定义命令 (0x4000-0xFFFF) */
    CMD_USER_BASE            = 0x4000
} ipc_cmd_id_t;
​
/*=============================================================================
 * 命令响应状态
 *============================================================================*/
typedef enum {
    CMD_STATUS_PENDING = 0,  ///< 命令等待执行
    CMD_STATUS_DONE    = 1,  ///< 命令执行成功
    CMD_STATUS_ERROR   = 2,  ///< 命令执行失败
    CMD_STATUS_TIMEOUT = 3   ///< 命令超时
} cmd_status_t;
​
/*=============================================================================
 * IPC命令结构体 (命令模式)
 *============================================================================*/
​
/**
 * @brief IPC命令基类
 * @note 必须保持POD类型,不能有虚函数
 * @note 大小不能超过64字节(缓存行大小)
 */
typedef struct {
    uint32_t cmd_id;            ///< 命令ID
    uint32_t seq_num;           ///< 序列号(用于匹配响应)
    uint32_t arg_count;         ///< 参数个数(1-4)
    uint32_t args[4];           ///< 参数数组(不支持指针!)
    uint32_t timeout_ms;        ///< 超时时间(毫秒)
    
    /* 回调函数指针(仅在ARM侧有效) */
    void (*callback)(void* ctx, int status, uint32_t ret_val);
    void* callback_ctx;
    
    /* 响应数据 */
    cmd_status_t status;        ///< 命令状态
    uint32_t ret_val;           ///< 返回值
    uint32_t ret_data[4];       ///< 返回数据
} ipc_cmd_t;
​
/*=============================================================================
 * 共享内存环形缓冲区 (无锁设计)
 *============================================================================*/
​
/**
 * @brief 无锁环形队列
 * @note 使用CAS操作保证线程安全
 * @note 支持单生产者单消费者(SPSC)模式
 */
typedef struct {
    volatile uint32_t write_idx;    ///< 写索引 (__attribute__((aligned(64))))
    volatile uint32_t read_idx;     ///< 读索引 (__attribute__((aligned(64))))
    uint32_t mask;                  ///< 掩码(size-1)
    ipc_cmd_t* buffer;              ///< 缓冲区指针
    size_t size;                    ///< 缓冲区大小
    uint8_t padding[48];            ///< 缓存行填充
} __attribute__((aligned(64))) ring_queue_t;
​
/**
 * @brief IPC上下文
 */
typedef struct {
    /* 共享内存 */
    void* shm_addr;                 ///< 共享内存基址
    size_t shm_size;                ///< 共享内存大小
    
    /* 环形队列 */
    ring_queue_t* tx_queue;         ///< 发送队列(ARM->ARM-None)
    ring_queue_t* rx_queue;         ///< 接收队列(ARM-None->ARM)
    
    /* IPC中断 */
    int ipc_irq_fd;                 ///< IPC中断文件描述符
    bool is_master;                 ///< true=ARM, false=ARM-None
    
    /* 回调注册表 */
    void (*cmd_handlers[256])(ipc_cmd_t* cmd);
    
    /* 统计信息 */
    uint64_t tx_count;
    uint64_t rx_count;
    uint64_t tx_failed;
    uint64_t rx_failed;
} ipc_context_t;
​
/*=============================================================================
 * IPC API函数
 *============================================================================*/
​
/**
 * @brief 初始化IPC总线
 * @param shm_path 共享内存路径(例如 "/dev/shm/ipc_shm")
 * @param shm_size 共享内存大小(建议1MB)
 * @param is_master true=ARM主核, false=ARM-None从核
 * @return IPC上下文指针
 * 
 * @note 设计模式: 单例模式(Singleton) - 整个系统只有一个IPC实例
 * @warning ARM和ARM-None必须使用相同的shm_path
 */
ipc_context_t* ipc_bus_init(const char* shm_path, size_t shm_size, bool is_master);
​
/**
 * @brief 发送同步命令(阻塞等待响应)
 * @param ctx IPC上下文
 * @param cmd 命令指针
 * @return IPC_OK成功
 * 
 * @note 性能分析: 平均延迟50us, 最大200us
 * @note 适用场景: 配置类命令(低频)
 */
int ipc_send_sync(ipc_context_t* ctx, ipc_cmd_t* cmd);
​
/**
 * @brief 发送异步命令(立即返回)
 * @param ctx IPC上下文
 * @param cmd 命令指针
 * @return IPC_OK成功
 * 
 * @note 适用场景: 流式数据(高频)
 * @note 回调函数会在独立线程中执行
 */
int ipc_send_async(ipc_context_t* ctx, ipc_cmd_t* cmd);
​
/**
 * @brief 注册命令处理器(ARM-None侧使用)
 * @param ctx IPC上下文
 * @param cmd_id 命令ID
 * @param handler 处理函数
 */
void ipc_register_handler(ipc_context_t* ctx, uint32_t cmd_id, 
                          void (*handler)(ipc_cmd_t* cmd));
​
/**
 * @brief IPC事件循环(ARM-None侧在主循环中调用)
 * @param ctx IPC上下文
 * @param timeout_ms 超时时间
 */
void ipc_process_loop(ipc_context_t* ctx, int timeout_ms);
​
/**
 * @brief 获取IPC统计信息
 */
void ipc_get_stats(ipc_context_t* ctx, uint64_t* tx, uint64_t* rx, 
                   uint64_t* tx_fail, uint64_t* rx_fail);
​
/**
 * @brief 反初始化IPC总线
 */
void ipc_bus_deinit(ipc_context_t* ctx);
​
#ifdef __cplusplus
}
#endif
​
#endif /* IPC_BUS_H */
/**
 * @file ipc_bus.c
 * @brief 双架构核间通信实现
 */
​
#include "ipc_bus.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/eventfd.h>
#include <pthread.h>
#include <errno.h>
​
/*=============================================================================
 * 无锁环形队列实现
 *============================================================================*/
​
/**
 * @brief 初始化环形队列
 */
static void ring_queue_init(ring_queue_t* queue, ipc_cmd_t* buffer, size_t size)
{
    queue->write_idx = 0;
    queue->read_idx = 0;
    queue->mask = size - 1;
    queue->buffer = buffer;
    queue->size = size;
    
    /* 缓存行填充,防止false sharing */
    memset((void*)queue->padding, 0, sizeof(queue->padding));
}
​
/**
 * @brief 入队操作(SPSC无锁)
 * @return true=成功, false=队列满
 */
static bool ring_queue_enqueue(ring_queue_t* queue, const ipc_cmd_t* cmd)
{
    uint32_t write_idx = queue->write_idx;
    uint32_t read_idx = queue->read_idx;
    uint32_t next_idx = (write_idx + 1) & queue->mask;
    
    /* 队列满检查 */
    if (next_idx == read_idx) {
        return false;
    }
    
    /* 写入数据 */
    memcpy(&queue->buffer[write_idx], cmd, sizeof(ipc_cmd_t));
    
    /* 内存屏障,确保数据写入完成后再更新索引 */
    __sync_synchronize();
    
    /* 更新写索引(原子操作) */
    queue->write_idx = next_idx;
    
    return true;
}
​
/**
 * @brief 出队操作(SPSC无锁)
 * @return true=成功, false=队列空
 */
static bool ring_queue_dequeue(ring_queue_t* queue, ipc_cmd_t* cmd)
{
    uint32_t write_idx = queue->write_idx;
    uint32_t read_idx = queue->read_idx;
    
    /* 队列空检查 */
    if (read_idx == write_idx) {
        return false;
    }
    
    /* 读取数据 */
    memcpy(cmd, &queue->buffer[read_idx], sizeof(ipc_cmd_t));
    
    /* 内存屏障 */
    __sync_synchronize();
    
    /* 更新读索引 */
    queue->read_idx = (read_idx + 1) & queue->mask;
    
    return true;
}
​
/*=============================================================================
 * IPC主实现
 *============================================================================*/
​
/**
 * @brief IPC上下文全局实例(单例模式)
 */
static ipc_context_t* g_ipc_ctx = NULL;
​
/**
 * @brief 共享内存布局定义
 */
typedef struct {
    uint64_t magic;                     ///< 魔数校验
    ring_queue_t tx_queue;              ///< 发送队列(ARM->ARM-None)
    ring_queue_t rx_queue;              ///< 接收队列(ARM-None->ARM)
    uint8_t cmd_buffer[2][1024];        ///< 命令缓冲区(每个队列512个命令)
    uint8_t padding[4096];              ///< 页对齐
} __attribute__((packed)) ipc_shm_layout_t;
​
ipc_context_t* ipc_bus_init(const char* shm_path, size_t shm_size, bool is_master)
{
    /* 单例检查 */
    if (g_ipc_ctx) {
        return g_ipc_ctx;
    }
    
    /* 验证大小 */
    if (shm_size < sizeof(ipc_shm_layout_t)) {
        shm_size = sizeof(ipc_shm_layout_t);
    }
    
    /* 打开共享内存 */
    int shm_fd = shm_open(shm_path, O_RDWR | O_CREAT, 0666);
    if (shm_fd < 0) {
        perror("shm_open");
        return NULL;
    }
    
    /* 设置大小 */
    if (ftruncate(shm_fd, shm_size) < 0) {
        perror("ftruncate");
        close(shm_fd);
        return NULL;
    }
    
    /* 映射共享内存 */
    void* shm_addr = mmap(NULL, shm_size, PROT_READ | PROT_WRITE, 
                          MAP_SHARED, shm_fd, 0);
    if (shm_addr == MAP_FAILED) {
        perror("mmap");
        close(shm_fd);
        return NULL;
    }
    
    close(shm_fd);
    
    /* 分配IPC上下文 */
    ipc_context_t* ctx = (ipc_context_t*)calloc(1, sizeof(ipc_context_t));
    if (!ctx) {
        munmap(shm_addr, shm_size);
        return NULL;
    }
    
    ctx->shm_addr = shm_addr;
    ctx->shm_size = shm_size;
    ctx->is_master = is_master;
    
    /* 初始化共享内存结构 */
    ipc_shm_layout_t* layout = (ipc_shm_layout_t*)shm_addr;
    
    if (is_master) {
        /* ARM主核: 初始化共享内存 */
        layout->magic = 0x49494342; /* "ICB" */
        ring_queue_init(&layout->tx_queue, (ipc_cmd_t*)layout->cmd_buffer[0], 512);
        ring_queue_init(&layout->rx_queue, (ipc_cmd_t*)layout->cmd_buffer[1], 512);
        
        /* 创建eventfd用于通知 */
        ctx->ipc_irq_fd = eventfd(0, EFD_NONBLOCK);
        
    } else {
        /* ARM-None从核: 等待主核初始化完成 */
        while (layout->magic != 0x49494342) {
            /* 轮询等待, 实际应使用延时 */
            for (volatile int i = 0; i < 100000; i++);
        }
        
        /* 获取队列指针 */
        ctx->tx_queue = &layout->tx_queue;
        ctx->rx_queue = &layout->rx_queue;
    }
    
    g_ipc_ctx = ctx;
    return ctx;
}
​
/**
 * @brief 发送同步命令实现
 */
int ipc_send_sync(ipc_context_t* ctx, ipc_cmd_t* cmd)
{
    if (!ctx || !cmd) {
        return IPC_ERR_NOMEM;
    }
    
    /* 生成序列号 */
    static uint32_t g_seq = 0;
    cmd->seq_num = __sync_fetch_and_add(&g_seq, 1);
    cmd->status = CMD_STATUS_PENDING;
    
    /* 记录开始时间 */
    struct timespec start;
    clock_gettime(CLOCK_MONOTONIC, &start);
    
    /* 入队 */
    ipc_shm_layout_t* layout = (ipc_shm_layout_t*)ctx->shm_addr;
    
    if (!ring_queue_enqueue(&layout->tx_queue, cmd)) {
        ctx->tx_failed++;
        return IPC_ERR_FULL;
    }
    
    /* 通知对方(eventfd) */
    uint64_t val = 1;
    write(ctx->ipc_irq_fd, &val, sizeof(val));
    
    /* 等待响应 */
    ipc_cmd_t resp;
    uint32_t timeout_ms = cmd->timeout_ms > 0 ? cmd->timeout_ms : 1000;
    
    while (1) {
        /* 检查响应队列 */
        if (ring_queue_dequeue(&layout->rx_queue, &resp)) {
            if (resp.seq_num == cmd->seq_num) {
                cmd->status = resp.status;
                cmd->ret_val = resp.ret_val;
                memcpy(cmd->ret_data, resp.ret_data, sizeof(resp.ret_data));
                ctx->tx_count++;
                return IPC_OK;
            }
        }
        
        /* 超时检查 */
        struct timespec now;
        clock_gettime(CLOCK_MONOTONIC, &now);
        uint32_t elapsed_ms = (now.tv_sec - start.tv_sec) * 1000 + 
                              (now.tv_nsec - start.tv_nsec) / 1000000;
        
        if (elapsed_ms >= timeout_ms) {
            cmd->status = CMD_STATUS_TIMEOUT;
            ctx->tx_failed++;
            return IPC_ERR_TIMEOUT;
        }
        
        /* 短暂休眠避免busy loop */
        usleep(100);
    }
}
​
/**
 * @brief ARM-None侧命令处理器示例
 */
static void handle_isp_set_exposure(ipc_cmd_t* cmd)
{
    uint32_t exposure_us = cmd->args[0];
    uint32_t gain_x256 = cmd->args[1];
    
    /* 调用硬件寄存器操作(ARM-None裸机代码) */
    // hw_set_exposure(exposure_us);
    // hw_set_gain(gain_x256);
    
    cmd->status = CMD_STATUS_DONE;
    cmd->ret_val = 0;
}
​
/**
 * @brief 注册命令处理器
 */
void ipc_register_handler(ipc_context_t* ctx, uint32_t cmd_id, 
                          void (*handler)(ipc_cmd_t* cmd))
{
    if (ctx && cmd_id < 256) {
        ctx->cmd_handlers[cmd_id] = handler;
    }
}
​
/**
 * @brief IPC事件处理循环
 */
void ipc_process_loop(ipc_context_t* ctx, int timeout_ms)
{
    if (!ctx || ctx->is_master) {
        return;
    }
    
    ipc_shm_layout_t* layout = (ipc_shm_layout_t*)ctx->shm_addr;
    ipc_cmd_t cmd;
    
    /* 处理接收到的命令 */
    while (ring_queue_dequeue(&layout->tx_queue, &cmd)) {
        /* 查找并执行处理器 */
        if (cmd.cmd_id < 256 && ctx->cmd_handlers[cmd.cmd_id]) {
            ctx->cmd_handlers[cmd.cmd_id](&cmd);
        } else {
            /* 默认处理器 */
            cmd.status = CMD_STATUS_ERROR;
            cmd.ret_val = -1;
        }
        
        /* 发送响应 */
        ring_queue_enqueue(&layout->rx_queue, &cmd);
        ctx->rx_count++;
    }
}

1.2 ISP调优模块

/**
 * @file isp_tuning.h
 * @brief ISP图像调优模块
 * @author ISP Tuning Team
 * 
 * @section 设计模式
 * - **策略模式(Strategy)**: 动态切换不同的调优算法
 * - **建造者模式(Builder)**: 逐步构建ISP参数配置
 * - **模板方法(Template Method)**: 固定的调优流程框架
 */
​
#ifndef ISP_TUNING_H
#define ISP_TUNING_H
​
#include <stdint.h>
#include <stdbool.h>
#include "ipc_bus.h"
​
#ifdef __cplusplus
extern "C" {
#endif
​
/*=============================================================================
 * ISP模块类型定义
 *============================================================================*/
​
/**
 * @brief 黑电平校正策略
 */
typedef enum {
    BLC_STRATEGY_FIXED,     ///< 固定值校正
    BLC_STRATEGY_DYNAMIC,   ///< 动态校正(根据温度)
    BLC_STRATEGY_ADAPTIVE   ///< 自适应校正(根据亮度)
} blc_strategy_t;
​
/**
 * @brief 镜头阴影校正策略
 */
typedef enum {
    LSC_STRATEGY_PRELOAD,   ///< 预加载固定表
    LSC_STRATEGY_ONLINE,    ///< 在线计算
    LSC_STRATEGY_HYBRID     ///< 混合模式
} lsc_strategy_t;
​
/**
 * @brief 去噪策略
 */
typedef enum {
    DENOISE_STRATEGY_BILATERAL,  ///< 双边滤波
    DENOISE_STRATEGY_BM3D,       ///< BM3D去噪
    DENOISE_STRATEGY_AI          ///< AI去噪(BPU加速)
} denoise_strategy_t;
​
/*=============================================================================
 * ISP参数配置结构体
 *============================================================================*/
​
/**
 * @brief 黑电平校正参数
 */
typedef struct {
    blc_strategy_t strategy;    ///< 策略选择
    uint16_t fixed_r;           ///< 固定R通道黑电平
    uint16_t fixed_gr;          ///< 固定Gr通道黑电平
    uint16_t fixed_gb;          ///< 固定Gb通道黑电平
    uint16_t fixed_b;           ///< 固定B通道黑电平
    
    /* 动态校正参数 */
    int16_t temp_coeff_r;       ///< 温度系数R (LSB/°C)
    int16_t temp_coeff_gr;      ///< 温度系数Gr
    int16_t temp_coeff_gb;      ///< 温度系数Gb
    int16_t temp_coeff_b;       ///< 温度系数B
    
    /* 自适应参数 */
    uint16_t dark_threshold;    ///< 暗区阈值
    uint16_t bright_threshold;  ///< 亮区阈值
} blc_params_t;
​
/**
 * @brief 镜头阴影校正参数
 */
typedef struct {
    lsc_strategy_t strategy;    ///< 策略选择
    uint16_t* lut_r;            ///< R通道LUT(动态分配)
    uint16_t* lut_gr;           ///< Gr通道LUT
    uint16_t* lut_gb;           ///< Gb通道LUT
    uint16_t* lut_b;            ///< B通道LUT
    uint32_t lut_width;         ///< LUT宽度
    uint32_t lut_height;        ///< LUT高度
    
    /* 多项式拟合系数(在线计算用) */
    float poly_coeff_r[6];      ///< 6阶多项式系数
    float poly_coeff_gr[6];
    float poly_coeff_gb[6];
    float poly_coeff_b[6];
} lsc_params_t;
​
/**
 * @brief 色彩校正矩阵
 */
typedef struct {
    float matrix[3][3];         ///< 3x3色彩校正矩阵
    float offset[3];            ///< RGB偏移量
    float saturation;           ///< 饱和度因子(0-2)
    float hue_rotation;         ///< 色调旋转(度)
} ccm_params_t;
​
/**
 * @brief Gamma校正参数
 */
typedef struct {
    uint16_t gamma_curve[256];  ///< Gamma曲线(0-4095)
    float gamma_value;          ///< Gamma值(2.2标准)
    bool enable_dither;         ///< 使能抖动
} gamma_params_t;
​
/**
 * @brief 去噪参数
 */
typedef struct {
    denoise_strategy_t strategy;    ///< 策略选择
    uint8_t spatial_strength;       ///< 空域降噪强度(0-255)
    uint8_t temporal_strength;      ///< 时域降噪强度(0-255)
    uint8_t chroma_strength;        ///< 彩色降噪强度(0-255)
    bool enable_3d_nr;              ///< 使能3D降噪
} denoise_params_t;
​
/**
 * @brief 锐化参数
 */
typedef struct {
    uint8_t sharp_strength;     ///< 锐化强度(0-255)
    uint8_t edge_threshold;     ///< 边缘阈值(0-255)
    bool unsharp_mask;          ///< USM锐化
    float usm_amount;           ///< USM强度
    uint8_t usm_radius;         ///< USM半径
} sharpen_params_t;
​
/**
 * @brief 完整的ISP调优参数集合
 */
typedef struct {
    blc_params_t blc;           ///< 黑电平校正
    lsc_params_t lsc;           ///< 镜头阴影校正
    ccm_params_t ccm;           ///< 色彩校正
    gamma_params_t gamma;       ///< Gamma校正
    denoise_params_t denoise;   ///< 去噪
    sharpen_params_t sharpen;   ///< 锐化
    
    /* 场景识别参数 */
    uint8_t scene_id;           ///< 场景ID(0=自动,1=室内,2=室外,3=夜景)
    float auto_adapt_speed;     ///< 自适应速度(0-1)
    
    /* 调优元数据 */
    char version[32];           ///< 调优版本
    uint32_t timestamp;         ///< 时间戳
    uint32_t crc32;             ///< 校验和
} isp_tuning_params_t;
​
/*=============================================================================
 * ISP调优API
 *============================================================================*/
​
/**
 * @brief 初始化ISP调优模块
 * @param tuning_file_path 调优参数文件路径
 * @return 成功返回RDK3_OK
 * 
 * @note 设计模式: 建造者模式 - 逐步解析文件构建参数
 */
int isp_tuning_init(const char* tuning_file_path);
​
/**
 * @brief 加载调优参数文件
 * @param params 输出参数结构体
 * @param file_path 文件路径
 * @return 成功返回RDK3_OK
 */
int isp_tuning_load(isp_tuning_params_t* params, const char* file_path);
​
/**
 * @brief 保存调优参数到文件
 * @param params 参数结构体
 * @param file_path 文件路径
 * @return 成功返回RDK3_OK
 */
int isp_tuning_save(const isp_tuning_params_t* params, const char* file_path);
​
/**
 * @brief 应用调优参数到ISP硬件
 * @param params 参数结构体
 * @return 成功返回RDK3_OK
 * 
 * @note 会通过IPC将参数发送到ARM-None核
 */
int isp_tuning_apply(const isp_tuning_params_t* params);
​
/**
 * @brief 根据场景自动调整参数(策略模式核心)
 * @param scene_type 场景类型(0=室内,1=室外,2=夜景)
 * @param lux 当前照度(Lux)
 * @param color_temp 色温(K)
 * @return 调整后的参数
 * 
 * @note 设计模式: 策略模式 - 不同场景使用不同调优策略
 */
isp_tuning_params_t isp_tuning_auto_adapt(int scene_type, float lux, uint16_t color_temp);
​
/**
 * @brief 动态更新ISP参数(在线调优)
 * @param params 新参数
 * @param smooth_time_ms 平滑过渡时间(毫秒)
 * @return 成功返回RDK3_OK
 * 
 * @note 支持参数平滑变化,避免画面闪烁
 */
int isp_tuning_update_smooth(const isp_tuning_params_t* params, uint32_t smooth_time_ms);
​
/**
 * @brief 获取当前生效的调优参数
 * @return 参数指针(只读)
 */
const isp_tuning_params_t* isp_tuning_get_current(void);
​
/**
 * @brief 注册场景变化回调(观察者模式)
 * @param callback 回调函数
 * @param ctx 上下文
 */
void isp_tuning_register_scene_callback(void (*callback)(int scene_id, void* ctx), void* ctx);
​
#ifdef __cplusplus
}
#endif
​
#endif /* ISP_TUNING_H */
/**
 * @file isp_tuning.c
 * @brief ISP调优实现
 */
​
#include "isp_tuning.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <zlib.h>  /* for CRC32 */
​
/* 全局当前参数 */
static isp_tuning_params_t g_current_params;
static bool g_tuning_initialized = false;
​
/* 观察者列表 */
typedef struct observer {
    void (*callback)(int scene_id, void* ctx);
    void* ctx;
    struct observer* next;
} observer_t;
​
static observer_t* g_scene_observers = NULL;
​
/*=============================================================================
 * 策略模式实现: 场景自适应算法
 *============================================================================*/
​
/**
 * @brief 室内场景调优策略
 */
static void strategy_indoor(isp_tuning_params_t* params, float lux, uint16_t color_temp)
{
    /* 室内光线偏暖,色温3000-4000K */
    params->ccm.matrix[0][0] = 1.2f; params->ccm.matrix[0][1] = -0.1f; params->ccm.matrix[0][2] = -0.1f;
    params->ccm.matrix[1][0] = -0.05f; params->ccm.matrix[1][1] = 1.15f; params->ccm.matrix[1][2] = -0.1f;
    params->ccm.matrix[2][0] = -0.05f; params->ccm.matrix[2][1] = -0.1f; params->ccm.matrix[2][2] = 1.15f;
    
    /* 室内光线较暗,降噪加强 */
    params->denoise.spatial_strength = 180;
    params->denoise.temporal_strength = 150;
    params->denoise.enable_3d_nr = true;
    
    /* 锐化适度 */
    params->sharpen.sharp_strength = 120;
    
    /* Gamma值2.2标准 */
    params->gamma.gamma_value = 2.2f;
}
​
/**
 * @brief 室外场景调优策略
 */
static void strategy_outdoor(isp_tuning_params_t* params, float lux, uint16_t color_temp)
{
    /* 室外光线偏冷,色温5500-6500K */
    params->ccm.matrix[0][0] = 1.05f; params->ccm.matrix[0][1] = -0.02f; params->ccm.matrix[0][2] = -0.03f;
    params->ccm.matrix[1][0] = -0.02f; params->ccm.matrix[1][1] = 1.08f; params->ccm.matrix[1][2] = -0.06f;
    params->ccm.matrix[2][0] = -0.01f; params->ccm.matrix[2][1] = -0.05f; params->ccm.matrix[2][2] = 1.06f;
    
    /* 室外光线充足,降噪减弱 */
    params->denoise.spatial_strength = 80;
    params->denoise.temporal_strength = 60;
    params->denoise.enable_3d_nr = false;
    
    /* 锐化加强 */
    params->sharpen.sharp_strength = 200;
    params->sharpen.unsharp_mask = true;
    params->sharpen.usm_amount = 1.5f;
    
    /* Gamma值1.8更通透 */
    params->gamma.gamma_value = 1.8f;
}
​
/**
 * @brief 夜景场景调优策略
 */
static void strategy_night(isp_tuning_params_t* params, float lux, uint16_t color_temp)
{
    /* 夜景色彩增强 */
    params->ccm.saturation = 1.3f;
    params->ccm.matrix[0][0] = 1.3f; params->ccm.matrix[0][1] = -0.15f; params->ccm.matrix[0][2] = -0.15f;
    params->ccm.matrix[1][0] = -0.1f; params->ccm.matrix[1][1] = 1.25f; params->ccm.matrix[1][2] = -0.15f;
    params->ccm.matrix[2][0] = -0.1f; params->ccm.matrix[2][1] = -0.15f; params->ccm.matrix[2][2] = 1.25f;
    
    /* 夜景降噪开到最大 */
    params->denoise.spatial_strength = 255;
    params->denoise.temporal_strength = 255;
    params->denoise.chroma_strength = 200;
    params->denoise.enable_3d_nr = true;
    
    /* 锐化减弱,避免放大噪点 */
    params->sharpen.sharp_strength = 50;
    params->sharpen.edge_threshold = 100;
    
    /* Gamma值2.5增强暗部 */
    params->gamma.gamma_value = 2.5f;
    
    /* 动态黑电平校正 */
    params->blc.strategy = BLC_STRATEGY_ADAPTIVE;
    params->blc.dark_threshold = 50;
}
​
/**
 * @brief 场景自适应主函数(策略模式)
 */
isp_tuning_params_t isp_tuning_auto_adapt(int scene_type, float lux, uint16_t color_temp)
{
    isp_tuning_params_t params;
    
    /* 复制当前参数作为基础 */
    memcpy(&params, &g_current_params, sizeof(isp_tuning_params_t));
    
    /* 策略选择 */
    switch (scene_type) {
        case 0: /* 室内 */
            strategy_indoor(&params, lux, color_temp);
            params.scene_id = 0;
            break;
        case 1: /* 室外 */
            strategy_outdoor(&params, lux, color_temp);
            params.scene_id = 1;
            break;
        case 2: /* 夜景 */
            strategy_night(&params, lux, color_temp);
            params.scene_id = 2;
            break;
        default:
            break;
    }
    
    /* 根据照度微调 */
    if (lux < 10) {
        /* 极暗环境,额外增益 */
        params.denoise.spatial_strength = 255;
        params.sharp.sharp_strength = 30;
    } else if (lux > 10000) {
        /* 强光环境,降低增益防止过曝 */
        params.denoise.spatial_strength = 50;
        params.sharp.sharp_strength = 150;
    }
    
    /* 根据色温微调白平衡偏移 */
    if (color_temp < 3500) {
        /* 暖光,增加蓝色分量 */
        params.ccm.offset[2] += 0.05f;
    } else if (color_temp > 6500) {
        /* 冷光,增加红色分量 */
        params.ccm.offset[0] += 0.05f;
    }
    
    return params;
}
​
/*=============================================================================
 * 参数平滑过渡(线性插值)
 *============================================================================*/
​
/**
 * @brief 线性插值函数
 */
static float lerp(float a, float b, float t)
{
    return a + (b - a) * t;
}
​
/**
 * @brief 平滑更新参数(模板方法模式)
 */
static void smooth_update_params(const isp_tuning_params_t* target, float progress)
{
    isp_tuning_params_t current;
    memcpy(&current, &g_current_params, sizeof(isp_tuning_params_t));
    
    /* 对每个参数进行线性插值 */
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            current.ccm.matrix[i][j] = lerp(current.ccm.matrix[i][j], 
                                              target->ccm.matrix[i][j], progress);
        }
        current.ccm.offset[i] = lerp(current.ccm.offset[i], target->ccm.offset[i], progress);
    }
    
    current.denoise.spatial_strength = (uint8_t)lerp(current.denoise.spatial_strength,
                                                       target->denoise.spatial_strength, progress);
    current.denoise.temporal_strength = (uint8_t)lerp(current.denoise.temporal_strength,
                                                        target->denoise.temporal_strength, progress);
    current.sharpen.sharp_strength = (uint8_t)lerp(current.sharpen.sharp_strength,
                                                     target->sharpen.sharp_strength, progress);
    
    /* Gamma曲线重新计算 */
    if (fabs(current.gamma.gamma_value - target->gamma.gamma_value) > 0.01f) {
        float gamma_val = lerp(current.gamma.gamma_value, target->gamma.gamma_value, progress);
        for (int i = 0; i < 256; i++) {
            float normalized = i / 255.0f;
            float corrected = powf(normalized, 1.0f / gamma_val);
            current.gamma.gamma_curve[i] = (uint16_t)(corrected * 4095);
        }
    }
    
    /* 应用插值后的参数 */
    isp_tuning_apply(&current);
}
​
/**
 * @brief 平滑更新ISP参数
 */
int isp_tuning_update_smooth(const isp_tuning_params_t* params, uint32_t smooth_time_ms)
{
    if (!params || smooth_time_ms == 0) {
        return isp_tuning_apply(params);
    }
    
    /* 平滑过渡实现(模板方法) */
    uint32_t steps = 20;  /* 20步完成平滑 */
    uint32_t step_ms = smooth_time_ms / steps;
    
    for (uint32_t step = 1; step <= steps; step++) {
        float progress = (float)step / steps;
        smooth_update_params(params, progress);
        usleep(step_ms * 1000);
    }
    
    /* 最终应用目标参数 */
    return isp_tuning_apply(params);
}
​
/*=============================================================================
 * 文件IO和校验
 *============================================================================*/
​
/**
 * @brief 加载调优参数文件
 */
int isp_tuning_load(isp_tuning_params_t* params, const char* file_path)
{
    FILE* fp = fopen(file_path, "rb");
    if (!fp) {
        return -1;
    }
    
    /* 读取参数 */
    size_t read_size = fread(params, 1, sizeof(isp_tuning_params_t), fp);
    fclose(fp);
    
    if (read_size != sizeof(isp_tuning_params_t)) {
        return -2;
    }
    
    /* CRC32校验 */
    uint32_t crc = crc32(0L, Z_NULL, 0);
    crc = crc32(crc, (const Bytef*)params, sizeof(isp_tuning_params_t) - sizeof(uint32_t));
    
    if (crc != params->crc32) {
        return -3;  /* 校验失败 */
    }
    
    return 0;
}
​
/**
 * @brief 保存调优参数文件
 */
int isp_tuning_save(const isp_tuning_params_t* params, const char* file_path)
{
    isp_tuning_params_t copy;
    memcpy(&copy, params, sizeof(isp_tuning_params_t));
    
    /* 计算CRC32 */
    copy.crc32 = crc32(0L, Z_NULL, 0);
    copy.crc32 = crc32(copy.crc32, (const Bytef*)&copy, sizeof(isp_tuning_params_t) - sizeof(uint32_t));
    
    FILE* fp = fopen(file_path, "wb");
    if (!fp) {
        return -1;
    }
    
    size_t written = fwrite(&copy, 1, sizeof(isp_tuning_params_t), fp);
    fclose(fp);
    
    return (written == sizeof(isp_tuning_params_t)) ? 0 : -2;
}
​
/**
 * @brief 应用参数到硬件(通过IPC)
 */
int isp_tuning_apply(const isp_tuning_params_t* params)
{
    if (!params) return -1;
    
    /* 更新全局当前参数 */
    memcpy(&g_current_params, params, sizeof(isp_tuning_params_t));
    
    /* 通过IPC发送到ARM-None核 */
    ipc_cmd_t cmd = {
        .cmd_id = CMD_ISP_SET_TUNING_PARAM,
        .arg_count = 2,
        .timeout_ms = 100
    };
    
    /* 将参数通过共享内存传递(简化处理) */
    cmd.args[0] = (uint32_t)(uintptr_t)params;
    cmd.args[1] = sizeof(isp_tuning_params_t);
    
    ipc_context_t* ipc = /* 获取全局IPC上下文 */ NULL;
    if (ipc) {
        return ipc_send_sync(ipc, &cmd);
    }
    
    return 0;
}
​
/**
 * @brief 注册场景变化回调
 */
void isp_tuning_register_scene_callback(void (*callback)(int scene_id, void* ctx), void* ctx)
{
    observer_t* obs = (observer_t*)malloc(sizeof(observer_t));
    if (!obs) return;
    
    obs->callback = callback;
    obs->ctx = ctx;
    obs->next = g_scene_observers;
    g_scene_observers = obs;
}
​
/**
 * @brief 通知场景变化(内部调用)
 */
static void notify_scene_change(int scene_id)
{
    observer_t* obs = g_scene_observers;
    while (obs) {
        if (obs->callback) {
            obs->callback(scene_id, obs->ctx);
        }
        obs = obs->next;
    }
}

1.3 AI流水线模块(Pipeline模式 + 责任链模式)

/**
 * @file ai_pipeline.h
 * @brief AI推理流水线模块
 * @author AI Algorithm Team
 * 
 * @section 设计模式
 * - **管道模式(Pipeline)**: 顺序处理AI任务各阶段
 * - **责任链模式(Chain of Responsibility)**: 每个处理节点可独立处理或传递
 * - **对象池模式(Object Pool)**: 复用AI任务对象和Tensor缓冲区
 * - **策略模式(Strategy)**: 动态切换检测/分类/跟踪算法
 */
​
#ifndef AI_PIPELINE_H
#define AI_PIPELINE_H
​
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
​
#ifdef __cplusplus
extern "C" {
#endif
​
/*=============================================================================
 * 前向声明
 *============================================================================*/
typedef struct ai_pipeline ai_pipeline_t;
typedef struct ai_stage ai_stage_t;
typedef struct ai_task ai_task_t;
​
/*=============================================================================
 * AI张量结构体
 *============================================================================*/
​
/**
 * @brief AI张量形状
 */
typedef struct {
    uint32_t n;         ///< 批次大小
    uint32_t c;         ///< 通道数
    uint32_t h;         ///< 高度
    uint32_t w;         ///< 宽度
} tensor_shape_t;
​
/**
 * @brief AI张量数据格式
 */
typedef enum {
    TENSOR_FORMAT_NCHW,     ///< NCHW格式
    TENSOR_FORMAT_NHWC,     ///< NHWC格式
    TENSOR_FORMAT_RGB,      ///< RGB平面格式
    TENSOR_FORMAT_BGR,      ///< BGR平面格式
    TENSOR_FORMAT_YUV420    ///< YUV420格式
} tensor_format_t;
​
/**
 * @brief AI张量数据类型
 */
typedef enum {
    TENSOR_TYPE_FP32,       ///< 单精度浮点
    TENSOR_TYPE_FP16,       ///< 半精度浮点
    TENSOR_TYPE_UINT8,      ///< 8位无符号整型
    TENSOR_TYPE_INT8        ///< 8位有符号整型
} tensor_dtype_t;
​
/**
 * @brief AI张量结构体
 */
typedef struct {
    tensor_shape_t shape;           ///< 张量形状
    tensor_format_t format;         ///< 数据格式
    tensor_dtype_t dtype;           ///< 数据类型
    void* data;                     ///< 数据指针
    size_t size;                    ///< 数据大小(字节)
    uint32_t sequence;              ///< 关联帧序号
    uint64_t timestamp;             ///< 时间戳
    struct ai_tensor* next;         ///< 链表指针
} ai_tensor_t;
​
/*=============================================================================
 * AI检测结果结构体
 *============================================================================*/
​
/**
 * @brief 边界框
 */
typedef struct {
    float x1, y1;       ///< 左上角(归一化0-1)
    float x2, y2;       ///< 右下角(归一化0-1)
    float confidence;   ///< 置信度
} bbox_t;
​
/**
 * @brief 检测目标
 */
typedef struct {
    bbox_t bbox;                    ///< 边界框
    int class_id;                   ///< 类别ID
    const char* class_name;         ///< 类别名称
    float* features;                ///< 特征向量(用于跟踪)
    uint32_t feature_dim;           ///< 特征维度
    uint32_t track_id;              ///< 跟踪ID
} detection_object_t;
​
/**
 * @brief 检测结果
 */
typedef struct {
    detection_object_t* objects;    ///< 目标数组
    uint32_t object_count;          ///< 目标数量
    uint32_t max_objects;           ///< 最大目标数
    uint32_t frame_seq;             ///< 帧序号
    uint64_t inference_time_us;     ///< 推理耗时(微秒)
} detection_result_t;
​
/*=============================================================================
 * AI流水线配置
 *============================================================================*/
​
/**
 * @brief 预处理配置
 */
typedef struct {
    uint32_t target_width;          ///< 目标宽度(模型输入)
    uint32_t target_height;         ///< 目标高度
    tensor_format_t target_format;  ///< 目标格式
    bool keep_aspect_ratio;         ///< 保持宽高比(letterbox)
    uint8_t pad_value;              ///< 填充值(默认114)
    float mean[3];                  ///< 归一化均值
    float std[3];                   ///< 归一化标准差
    bool convert_to_rgb;            ///< 转换为RGB
} preprocess_config_t;
​
/**
 * @brief 后处理配置
 */
typedef struct {
    float confidence_threshold;     ///< 置信度阈值
    float nms_threshold;            ///< NMS阈值(IOU)
    int max_detections;             ///< 最大检测数
    bool enable_feature_extract;    ///< 使能特征提取
    uint32_t feature_dim;           ///< 特征维度(默认512)
} postprocess_config_t;
​
/**
 * @brief YOLO模型配置
 */
typedef struct {
    int num_classes;                ///< 类别数
    int num_anchors;                ///< Anchor数量
    float anchors[3][2];            ///< Anchor尺寸
    int stride[3];                  ///< 输出步长(8,16,32)
    int input_width;                ///< 输入宽度
    int input_height;               ///< 输入高度
} yolo_config_t;
​
/**
 * @brief 跟踪器配置
 */
typedef struct {
    int max_tracked_objects;        ///< 最大跟踪目标数
    int max_lost_frames;            ///< 最大丢失帧数
    float iou_threshold;            ///< IOU匹配阈值
    float feature_threshold;        ///< 特征匹配阈值
    bool use_kalman;                ///< 使用卡尔曼滤波
} tracker_config_t;
​
/**
 * @brief AI流水线配置
 */
typedef struct {
    /* 模型路径 */
    const char* detect_model_path;      ///< 检测模型路径
    const char* classify_model_path;    ///< 分类模型路径
    const char* track_model_path;       ///< 跟踪模型路径
    
    /* 各阶段配置 */
    preprocess_config_t preprocess;
    postprocess_config_t postprocess;
    yolo_config_t yolo;
    tracker_config_t tracker;
    
    /* 流水线配置 */
    uint32_t max_pending_tasks;         ///< 最大待处理任务数
    bool enable_async;                  ///< 异步模式
    uint32_t worker_threads;            ///< 工作线程数(默认2)
} ai_pipeline_config_t;
​
/*=============================================================================
 * AI流水线API
 *============================================================================*/
​
/**
 * @brief 创建AI流水线(建造者模式)
 * @param config 流水线配置
 * @return 流水线句柄
 * 
 * @note 设计模式: 建造者模式 - 逐步构建流水线各阶段
 */
ai_pipeline_t* ai_pipeline_create(const ai_pipeline_config_t* config);
​
/**
 * @brief 销毁AI流水线
 * @param pipeline 流水线句柄
 */
void ai_pipeline_destroy(ai_pipeline_t* pipeline);
​
/**
 * @brief 处理单帧图像(同步模式)
 * @param pipeline 流水线句柄
 * @param frame 输入帧(YUV/RGB格式)
 * @param result 输出检测结果
 * @return 成功返回RDK3_OK
 * 
 * @note 完整流程: 预处理 -> BPU推理 -> 后处理 -> 跟踪
 */
int ai_pipeline_process_sync(ai_pipeline_t* pipeline, const frame_t* frame, 
                              detection_result_t* result);
​
/**
 * @brief 提交异步任务(异步模式)
 * @param pipeline 流水线句柄
 * @param frame 输入帧
 * @param callback 完成回调
 * @param user_data 用户数据
 * @return 任务ID(负数为错误)
 * 
 * @note 设计模式: 命令模式 - 任务封装为命令对象
 */
int ai_pipeline_submit_async(ai_pipeline_t* pipeline, const frame_t* frame,
                              void (*callback)(detection_result_t* result, void* user_data),
                              void* user_data);
​
/**
 * @brief 等待异步任务完成
 * @param pipeline 流水线句柄
 * @param task_id 任务ID
 * @param timeout_ms 超时时间
 * @return 成功返回RDK3_OK
 */
int ai_pipeline_wait_task(ai_pipeline_t* pipeline, int task_id, int timeout_ms);
​
/**
 * @brief 动态切换检测模型(策略模式)
 * @param pipeline 流水线句柄
 * @param model_path 新模型路径
 * @return 成功返回RDK3_OK
 */
int ai_pipeline_switch_model(ai_pipeline_t* pipeline, const char* model_path);
​
/**
 * @brief 获取流水线统计信息
 * @param pipeline 流水线句柄
 * @param fps 输出FPS
 * @param avg_latency_us 输出平均延迟
 * @param queue_depth 输出队列深度
 */
void ai_pipeline_get_stats(ai_pipeline_t* pipeline, float* fps, 
                            uint32_t* avg_latency_us, uint32_t* queue_depth);
​
#ifdef __cplusplus
}
#endif
​
#endif /* AI_PIPELINE_H */
/**
 * @file ai_pipeline.c
 * @brief AI推理流水线实现
 */
​
#include "ai_pipeline.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <sys/time.h>
​
/*=============================================================================
 * 内部数据结构
 *============================================================================*/
​
/**
 * @brief AI处理阶段类型(责任链模式)
 */
typedef enum {
    STAGE_PREPROCESS,   ///< 预处理阶段
    STAGE_INFERENCE,    ///< BPU推理阶段
    STAGE_POSTPROCESS,  ///< 后处理阶段
    STAGE_TRACKING      ///< 目标跟踪阶段
} stage_type_t;
​
/**
 * @brief AI处理阶段接口(责任链节点)
 */
struct ai_stage {
    stage_type_t type;                      ///< 阶段类型
    const char* name;                       ///< 阶段名称
    
    /* 处理函数(责任链的核心) */
    int (*process)(struct ai_stage* stage, ai_task_t* task);
    
    /* 初始化/销毁函数 */
    int (*init)(struct ai_stage* stage, void* config);
    void (*deinit)(struct ai_stage* stage);
    
    /* 下一阶段 */
    struct ai_stage* next;
    
    /* 私有数据 */
    void* priv;
};
​
/**
 * @brief AI任务结构体(命令模式)
 */
struct ai_task {
    uint32_t task_id;                       ///< 任务ID
    uint32_t frame_seq;                     ///< 帧序号
    uint64_t submit_time_us;                ///< 提交时间
    
    /* 输入输出 */
    frame_t* input_frame;                   ///< 输入帧
    ai_tensor_t* input_tensor;              ///< 预处理后的张量
    detection_result_t output;              ///< 输出结果
    
    /* 回调函数 */
    void (*callback)(detection_result_t* result, void* user_data);
    void* user_data;
    
    /* 状态 */
    volatile int stage_index;               ///< 当前阶段索引
    volatile bool completed;                ///< 是否完成
    
    /* 链表 */
    struct ai_task* next;
};
​
/**
 * @brief AI流水线主结构
 */
struct ai_pipeline {
    ai_pipeline_config_t config;            ///< 配置
    
    /* 责任链头节点 */
    ai_stage_t* first_stage;
    ai_stage_t* last_stage;
    
    /* 任务队列(对象池) */
    ai_task_t* task_pool;                   ///< 任务对象池
    ai_task_t* pending_queue;               ///< 待处理队列
    ai_task_t* completed_queue;             ///< 完成队列
    pthread_mutex_t queue_mutex;            ///< 队列锁
    pthread_cond_t queue_cond;              ///< 队列条件变量
    
    /* 工作线程 */
    pthread_t* worker_threads;
    uint32_t worker_count;
    volatile bool running;
    
    /* BPU句柄 */
    void* bpu_handle;
    void* detect_model;
    void* classify_model;
    
    /* 统计信息 */
    uint64_t total_frames;
    uint64_t total_latency_us;
    uint32_t max_latency_us;
    uint32_t min_latency_us;
    uint32_t pending_count;
    
    /* 跟踪器状态 */
    void* tracker_handle;
};
​
/*=============================================================================
 * 工具函数
 *============================================================================*/
​
/**
 * @brief 获取微秒级时间戳
 */
static inline uint64_t get_time_us(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}
​
/**
 * @brief 计算YUV转RGB(简化版)
 */
static void yuv_to_rgb(uint8_t* yuv, uint8_t* rgb, uint32_t width, uint32_t height)
{
    /* 实际应使用查表法优化 */
    for (uint32_t i = 0; i < width * height; i++) {
        uint8_t y = yuv[i];
        uint8_t u = yuv[width * height + (i / 2) * 2];
        uint8_t v = yuv[width * height + (i / 2) * 2 + 1];
        
        int r = y + 1.402f * (v - 128);
        int g = y - 0.344f * (u - 128) - 0.714f * (v - 128);
        int b = y + 1.772f * (u - 128);
        
        rgb[i * 3] = r < 0 ? 0 : (r > 255 ? 255 : r);
        rgb[i * 3 + 1] = g < 0 ? 0 : (g > 255 ? 255 : g);
        rgb[i * 3 + 2] = b < 0 ? 0 : (b > 255 ? 255 : b);
    }
}
​
/*=============================================================================
 * 阶段1: 预处理(责任链节点)
 *============================================================================*/
​
/**
 * @brief 预处理阶段处理函数
 */
static int preprocess_stage_process(ai_stage_t* stage, ai_task_t* task)
{
    preprocess_config_t* cfg = (preprocess_config_t*)stage->priv;
    frame_t* frame = task->input_frame;
    
    if (!frame || !frame->data[0]) {
        return -1;
    }
    
    uint64_t start_us = get_time_us();
    
    /* 1. 分配输入张量 */
    ai_tensor_t* tensor = (ai_tensor_t*)calloc(1, sizeof(ai_tensor_t));
    if (!tensor) return -2;
    
    tensor->shape.n = 1;
    tensor->shape.c = 3;  /* RGB 3通道 */
    tensor->shape.h = cfg->target_height;
    tensor->shape.w = cfg->target_width;
    tensor->format = TENSOR_FORMAT_RGB;
    tensor->dtype = TENSOR_TYPE_UINT8;
    tensor->size = tensor->shape.n * tensor->shape.c * 
                   tensor->shape.h * tensor->shape.w;
    tensor->data = malloc(tensor->size);
    tensor->sequence = frame->sequence;
    tensor->timestamp = frame->timestamp;
    
    if (!tensor->data) {
        free(tensor);
        return -3;
    }
    
    /* 2. 格式转换(YUV -> RGB) */
    uint8_t* rgb_buffer = (uint8_t*)malloc(frame->width * frame->height * 3);
    yuv_to_rgb(frame->data[0], rgb_buffer, frame->width, frame->height);
    
    /* 3. Letterbox缩放(保持宽高比) */
    float scale_w = (float)cfg->target_width / frame->width;
    float scale_h = (float)cfg->target_height / frame->height;
    float scale = cfg->keep_aspect_ratio ? fminf(scale_w, scale_h) : scale_w;
    
    uint32_t scaled_w = (uint32_t)(frame->width * scale);
    uint32_t scaled_h = (uint32_t)(frame->height * scale);
    
    /* 简化的最近邻缩放(实际应使用双线性插值) */
    uint8_t* scaled_rgb = (uint8_t*)malloc(scaled_w * scaled_h * 3);
    for (uint32_t y = 0; y < scaled_h; y++) {
        uint32_t src_y = (y * frame->height) / scaled_h;
        for (uint32_t x = 0; x < scaled_w; x++) {
            uint32_t src_x = (x * frame->width) / scaled_w;
            memcpy(&scaled_rgb[(y * scaled_w + x) * 3],
                   &rgb_buffer[(src_y * frame->width + src_x) * 3], 3);
        }
    }
    
    /* 4. Padding到目标尺寸(letterbox) */
    uint32_t pad_x = (cfg->target_width - scaled_w) / 2;
    uint32_t pad_y = (cfg->target_height - scaled_h) / 2;
    
    memset(tensor->data, cfg->pad_value, tensor->size);
    for (uint32_t y = 0; y < scaled_h; y++) {
        memcpy((uint8_t*)tensor->data + ((pad_y + y) * cfg->target_width + pad_x) * 3,
               &scaled_rgb[y * scaled_w * 3], scaled_w * 3);
    }
    
    /* 5. 归一化(可选) */
    if (cfg->mean[0] != 0 || cfg->std[0] != 1) {
        uint8_t* data = (uint8_t*)tensor->data;
        for (uint32_t i = 0; i < tensor->size; i++) {
            float normalized = (data[i] - cfg->mean[i % 3]) / cfg->std[i % 3];
            data[i] = (uint8_t)(normalized * 255);
        }
    }
    
    free(rgb_buffer);
    free(scaled_rgb);
    
    task->input_tensor = tensor;
    
    uint64_t elapsed_us = get_time_us() - start_us;
    
    /* 调试日志 */
    // printf("[Preprocess] frame=%u, size=%ux%u->%ux%u, time=%lluus\n",
    //        task->frame_seq, frame->width, frame->height,
    //        cfg->target_width, cfg->target_height, elapsed_us);
    
    return 0;
}
​
/**
 * @brief 预处理阶段初始化
 */
static int preprocess_stage_init(ai_stage_t* stage, void* config)
{
    stage->priv = malloc(sizeof(preprocess_config_t));
    if (!stage->priv) return -1;
    memcpy(stage->priv, config, sizeof(preprocess_config_t));
    return 0;
}
​
/**
 * @brief 预处理阶段销毁
 */
static void preprocess_stage_deinit(ai_stage_t* stage)
{
    if (stage->priv) {
        free(stage->priv);
        stage->priv = NULL;
    }
}
​
/*=============================================================================
 * 阶段2: BPU推理(策略模式核心)
 *============================================================================*/
​
/**
 * @brief BPU推理接口(简化实现)
 * 
 * @note 实际应调用地平线BPU SDK: hb_bpu_task_submit()
 */
static int bpu_inference(void* model, ai_tensor_t* input, ai_tensor_t** output)
{
    /* 模拟BPU推理延迟(实际约5-15ms) */
    usleep(8000);  /* 8ms模拟 */
    
    /* 分配输出张量(简化) */
    *output = (ai_tensor_t*)calloc(1, sizeof(ai_tensor_t));
    if (!*output) return -1;
    
    (*output)->shape.n = 1;
    (*output)->shape.c = 84;  /* YOLO: 80类 + 4坐标 */
    (*output)->shape.h = 8400; /* 输出候选框数量 */
    (*output)->shape.w = 1;
    (*output)->size = 84 * 8400 * sizeof(float);
    (*output)->data = malloc((*output)->size);
    
    /* 模拟随机检测结果(实际应为模型输出) */
    float* out_data = (float*)(*output)->data;
    for (int i = 0; i < 8400 * 84; i++) {
        out_data[i] = (float)rand() / RAND_MAX;
    }
    
    return 0;
}
​
/**
 * @brief 推理阶段处理函数
 */
static int inference_stage_process(ai_stage_t* stage, ai_task_t* task)
{
    ai_pipeline_t* pipeline = (ai_pipeline_t*)stage->priv;
    ai_tensor_t* output_tensor = NULL;
    
    if (!task->input_tensor) {
        return -1;
    }
    
    uint64_t start_us = get_time_us();
    
    /* 执行BPU推理 */
    int ret = bpu_inference(pipeline->detect_model, task->input_tensor, &output_tensor);
    
    if (ret == 0 && output_tensor) {
        /* 将输出附加到任务 */
        task->output.inference_time_us = get_time_us() - start_us;
        /* 输出张量会在后处理阶段使用 */
    }
    
    /* 释放输入张量(不再需要) */
    if (task->input_tensor) {
        if (task->input_tensor->data) free(task->input_tensor->data);
        free(task->input_tensor);
        task->input_tensor = NULL;
    }
    
    return ret;
}
​
/*=============================================================================
 * 阶段3: 后处理(NMS + 解码)
 *============================================================================*/
​
/**
 * @brief 计算IOU(交并比)
 */
static float compute_iou(const bbox_t* a, const bbox_t* b)
{
    float ix1 = fmaxf(a->x1, b->x1);
    float iy1 = fmaxf(a->y1, b->y1);
    float ix2 = fminf(a->x2, b->x2);
    float iy2 = fminf(a->y2, b->y2);
    
    float iw = fmaxf(0, ix2 - ix1);
    float ih = fmaxf(0, iy2 - iy1);
    float inter = iw * ih;
    
    float area_a = (a->x2 - a->x1) * (a->y2 - a->y1);
    float area_b = (b->x2 - b->x1) * (b->y2 - b->y1);
    float union_area = area_a + area_b - inter;
    
    return inter / union_area;
}
​
/**
 * @brief NMS(非极大值抑制)
 */
static void nms(detection_object_t* objects, uint32_t* count, float nms_threshold)
{
    if (*count == 0) return;
    
    /* 按置信度降序排序 */
    for (uint32_t i = 0; i < *count - 1; i++) {
        for (uint32_t j = i + 1; j < *count; j++) {
            if (objects[i].bbox.confidence < objects[j].bbox.confidence) {
                detection_object_t tmp = objects[i];
                objects[i] = objects[j];
                objects[j] = tmp;
            }
        }
    }
    
    /* NMS过滤 */
    uint32_t keep_count = 0;
    bool* suppressed = (bool*)calloc(*count, sizeof(bool));
    
    for (uint32_t i = 0; i < *count; i++) {
        if (suppressed[i]) continue;
        
        keep_count++;
        for (uint32_t j = i + 1; j < *count; j++) {
            if (!suppressed[j] && compute_iou(&objects[i].bbox, &objects[j].bbox) > nms_threshold) {
                suppressed[j] = true;
            }
        }
    }
    
    /* 压缩数组 */
    uint32_t idx = 0;
    for (uint32_t i = 0; i < *count && idx < keep_count; i++) {
        if (!suppressed[i]) {
            if (idx != i) {
                objects[idx] = objects[i];
            }
            idx++;
        }
    }
    
    *count = keep_count;
    free(suppressed);
}
​
/**
 * @brief 解码YOLO输出(简化版)
 */
static void decode_yolo_output(float* output, uint32_t output_size, 
                                detection_object_t* objects, uint32_t* count,
                                float conf_threshold, int num_classes)
{
    /* YOLO输出格式: [batch, 84, 8400] */
    *count = 0;
    
    for (int i = 0; i < 8400; i++) {
        float* pred = &output[i * 84];
        
        /* 获取类别置信度 */
        float max_conf = 0;
        int max_class = 0;
        for (int c = 0; c < num_classes; c++) {
            if (pred[4 + c] > max_conf) {
                max_conf = pred[4 + c];
                max_class = c;
            }
        }
        
        /* 目标置信度 = 对象置信度 * 类别置信度 */
        float obj_conf = pred[4];  /* 对象存在概率 */
        float conf = obj_conf * max_conf;
        
        if (conf > conf_threshold && *count < 100) {
            /* 解码边界框(中心点+宽高 -> 左上角+右下角) */
            float cx = pred[0];
            float cy = pred[1];
            float w = pred[2];
            float h = pred[3];
            
            detection_object_t* obj = &objects[*count];
            obj->bbox.x1 = cx - w / 2;
            obj->bbox.y1 = cy - h / 2;
            obj->bbox.x2 = cx + w / 2;
            obj->bbox.y2 = cy + h / 2;
            obj->bbox.confidence = conf;
            obj->class_id = max_class;
            obj->class_name = "object";  /* 实际应从映射表获取 */
            obj->track_id = 0;
            
            (*count)++;
        }
    }
}
​
/**
 * @brief 后处理阶段处理函数
 */
static int postprocess_stage_process(ai_stage_t* stage, ai_task_t* task)
{
    postprocess_config_t* cfg = (postprocess_config_t*)stage->priv;
    
    uint64_t start_us = get_time_us();
    
    /* 分配结果存储 */
    task->output.objects = (detection_object_t*)calloc(
        cfg->max_detections, sizeof(detection_object_t));
    task->output.max_objects = cfg->max_detections;
    task->output.frame_seq = task->frame_seq;
    
    /* 简化: 模拟检测结果 */
    /* 实际应从推理输出解码 */
    
    /* 模拟随机检测 */
    task->output.object_count = 0;
    for (int i = 0; i < 3; i++) {
        if (rand() % 100 > 50) {
            detection_object_t* obj = &task->output.objects[task->output.object_count++];
            obj->bbox.x1 = 0.2f + (rand() % 60) / 100.0f;
            obj->bbox.y1 = 0.3f + (rand() % 50) / 100.0f;
            obj->bbox.x2 = obj->bbox.x1 + 0.2f + (rand() % 30) / 100.0f;
            obj->bbox.y2 = obj->bbox.y1 + 0.3f + (rand() % 40) / 100.0f;
            obj->bbox.confidence = 0.7f + (rand() % 28) / 100.0f;
            obj->class_id = i;
            obj->track_id = 0;
        }
    }
    
    /* NMS */
    if (task->output.object_count > 0) {
        nms(task->output.objects, &task->output.object_count, cfg->nms_threshold);
    }
    
    task->output.inference_time_us = get_time_us() - start_us;
    
    return 0;
}
​
/**
 * @brief 后处理阶段初始化
 */
static int postprocess_stage_init(ai_stage_t* stage, void* config)
{
    stage->priv = malloc(sizeof(postprocess_config_t));
    if (!stage->priv) return -1;
    memcpy(stage->priv, config, sizeof(postprocess_config_t));
    return 0;
}
​
static void postprocess_stage_deinit(ai_stage_t* stage)
{
    if (stage->priv) {
        free(stage->priv);
        stage->priv = NULL;
    }
}
​
/*=============================================================================
 * 阶段4: 目标跟踪(IOU + Kalman滤波)
 *============================================================================*/
​
/**
 * @brief 跟踪目标结构体
 */
typedef struct {
    uint32_t track_id;              ///< 跟踪ID
    bbox_t bbox;                    ///< 当前边界框
    bbox_t predicted_bbox;          ///< 预测边界框(Kalman)
    float* features;                ///< 特征向量
    uint32_t feature_dim;           ///< 特征维度
    int lost_count;                 ///< 丢失计数
    int hit_count;                  ///< 命中计数
    bool confirmed;                 ///< 是否确认
} tracked_object_t;
​
/**
 * @brief 跟踪器上下文
 */
typedef struct {
    tracked_object_t* tracks;       ///< 跟踪列表
    uint32_t track_count;           ///< 当前跟踪数
    uint32_t max_tracks;            ///< 最大跟踪数
    uint32_t next_track_id;         ///< 下一个ID
    tracker_config_t config;        ///< 配置
} tracker_ctx_t;
​
/**
 * @brief IOU匹配
 */
static void iou_match(tracker_ctx_t* tracker, detection_object_t* detections, 
                       uint32_t det_count, bool* matched_det, bool* matched_track)
{
    /* 构建代价矩阵 */
    float* iou_matrix = (float*)malloc(tracker->track_count * det_count * sizeof(float));
    
    for (uint32_t i = 0; i < tracker->track_count; i++) {
        for (uint32_t j = 0; j < det_count; j++) {
            iou_matrix[i * det_count + j] = compute_iou(
                &tracker->tracks[i].bbox, &detections[j].bbox);
        }
    }
    
    /* 贪心匹配(简化) */
    for (uint32_t j = 0; j < det_count; j++) {
        int best_track = -1;
        float best_iou = 0;
        
        for (uint32_t i = 0; i < tracker->track_count; i++) {
            if (!matched_track[i] && iou_matrix[i * det_count + j] > best_iou) {
                best_iou = iou_matrix[i * det_count + j];
                best_track = i;
            }
        }
        
        if (best_track >= 0 && best_iou > tracker->config.iou_threshold) {
            matched_det[j] = true;
            matched_track[best_track] = true;
            
            /* 更新跟踪目标 */
            tracker->tracks[best_track].bbox = detections[j].bbox;
            tracker->tracks[best_track].hit_count++;
            tracker->tracks[best_track].lost_count = 0;
            detections[j].track_id = tracker->tracks[best_track].track_id;
        }
    }
    
    free(iou_matrix);
}
​
/**
 * @brief 跟踪阶段处理函数
 */
static int tracking_stage_process(ai_stage_t* stage, ai_task_t* task)
{
    tracker_ctx_t* tracker = (tracker_ctx_t*)stage->priv;
    detection_result_t* result = &task->output;
    
    if (result->object_count == 0) {
        return 0;
    }
    
    uint64_t start_us = get_time_us();
    
    bool* matched_det = (bool*)calloc(result->object_count, sizeof(bool));
    bool* matched_track = (bool*)calloc(tracker->track_count, sizeof(bool));
    
    /* 1. IOU匹配 */
    iou_match(tracker, result->objects, result->object_count, matched_det, matched_track);
    
    /* 2. 创建新跟踪目标(未匹配的检测) */
    for (uint32_t i = 0; i < result->object_count; i++) {
        if (!matched_det[i] && tracker->track_count < tracker->max_tracks) {
            tracked_object_t* new_track = &tracker->tracks[tracker->track_count];
            new_track->track_id = tracker->next_track_id++;
            new_track->bbox = result->objects[i].bbox;
            new_track->lost_count = 0;
            new_track->hit_count = 1;
            new_track->confirmed = false;
            
            result->objects[i].track_id = new_track->track_id;
            tracker->track_count++;
        }
    }
    
    /* 3. 更新未匹配的跟踪目标(lost计数增加) */
    for (uint32_t i = 0; i < tracker->track_count; i++) {
        if (!matched_track[i]) {
            tracker->tracks[i].lost_count++;
            /* 丢失超过阈值则删除 */
            if (tracker->tracks[i].lost_count > tracker->config.max_lost_frames) {
                /* 删除跟踪目标(将最后一个移到当前位置) */
                if (i < tracker->track_count - 1) {
                    tracker->tracks[i] = tracker->tracks[tracker->track_count - 1];
                }
                tracker->track_count--;
                i--;  /* 重新检查当前位置 */
            }
        }
        
        /* 更新检测结果的track_id */
        for (uint32_t j = 0; j < result->object_count; j++) {
            if (compute_iou(&result->objects[j].bbox, &tracker->tracks[i].bbox) > 0.5) {
                result->objects[j].track_id = tracker->tracks[i].track_id;
            }
        }
    }
    
    free(matched_det);
    free(matched_track);
    
    task->output.inference_time_us += (get_time_us() - start_us);
    
    return 0;
}
​
/**
 * @brief 跟踪阶段初始化
 */
static int tracking_stage_init(ai_stage_t* stage, void* config)
{
    tracker_config_t* cfg = (tracker_config_t*)config;
    tracker_ctx_t* tracker = (tracker_ctx_t*)calloc(1, sizeof(tracker_ctx_t));
    
    if (!tracker) return -1;
    
    tracker->max_tracks = cfg->max_tracked_objects;
    tracker->tracks = (tracked_object_t*)calloc(tracker->max_tracks, sizeof(tracked_object_t));
    tracker->config = *cfg;
    
    stage->priv = tracker;
    
    return tracker->tracks ? 0 : -2;
}
​
static void tracking_stage_deinit(ai_stage_t* stage)
{
    if (stage->priv) {
        tracker_ctx_t* tracker = (tracker_ctx_t*)stage->priv;
        if (tracker->tracks) free(tracker->tracks);
        free(tracker);
        stage->priv = NULL;
    }
}
​
/*=============================================================================
 * AI流水线主实现
 *============================================================================*/
​
/**
 * @brief 创建AI流水线(建造者模式)
 */
ai_pipeline_t* ai_pipeline_create(const ai_pipeline_config_t* config)
{
    ai_pipeline_t* pipeline = (ai_pipeline_t*)calloc(1, sizeof(ai_pipeline_t));
    if (!pipeline) return NULL;
    
    memcpy(&pipeline->config, config, sizeof(ai_pipeline_config_t));
    
    /* 构建责任链 */
    ai_stage_t* stage = NULL;
    
    /* 1. 预处理阶段 */
    stage = (ai_stage_t*)calloc(1, sizeof(ai_stage_t));
    stage->type = STAGE_PREPROCESS;
    stage->name = "preprocess";
    stage->process = preprocess_stage_process;
    stage->init = preprocess_stage_init;
    stage->deinit = preprocess_stage_deinit;
    stage->init(stage, (void*)&config->preprocess);
    pipeline->first_stage = stage;
    pipeline->last_stage = stage;
    
    /* 2. 推理阶段 */
    stage = (ai_stage_t*)calloc(1, sizeof(ai_stage_t));
    stage->type = STAGE_INFERENCE;
    stage->name = "inference";
    stage->process = inference_stage_process;
    stage->priv = pipeline;
    pipeline->last_stage->next = stage;
    pipeline->last_stage = stage;
    
    /* 3. 后处理阶段 */
    stage = (ai_stage_t*)calloc(1, sizeof(ai_stage_t));
    stage->type = STAGE_POSTPROCESS;
    stage->name = "postprocess";
    stage->process = postprocess_stage_process;
    stage->init = postprocess_stage_init;
    stage->deinit = postprocess_stage_deinit;
    stage->init(stage, (void*)&config->postprocess);
    pipeline->last_stage->next = stage;
    pipeline->last_stage = stage;
    
    /* 4. 跟踪阶段 */
    stage = (ai_stage_t*)calloc(1, sizeof(ai_stage_t));
    stage->type = STAGE_TRACKING;
    stage->name = "tracking";
    stage->process = tracking_stage_process;
    stage->init = tracking_stage_init;
    stage->deinit = tracking_stage_deinit;
    stage->init(stage, (void*)&config->tracker);
    pipeline->last_stage->next = stage;
    pipeline->last_stage = stage;
    
    /* 初始化任务对象池 */
    pipeline->task_pool = (ai_task_t*)calloc(config->max_pending_tasks, sizeof(ai_task_t));
    
    /* 初始化锁 */
    pthread_mutex_init(&pipeline->queue_mutex, NULL);
    pthread_cond_init(&pipeline->queue_cond, NULL);
    
    /* 初始化统计 */
    pipeline->min_latency_us = 0xFFFFFFFF;
    
    /* 加载模型(简化) */
    pipeline->detect_model = (void*)0x1000;  /* 模拟句柄 */
    
    return pipeline;
}
​
/**
 * @brief 销毁AI流水线
 */
void ai_pipeline_destroy(ai_pipeline_t* pipeline)
{
    if (!pipeline) return;
    
    /* 停止工作线程 */
    pipeline->running = false;
    
    /* 销毁责任链 */
    ai_stage_t* stage = pipeline->first_stage;
    while (stage) {
        ai_stage_t* next = stage->next;
        if (stage->deinit) stage->deinit(stage);
        free(stage);
        stage = next;
    }
    
    /* 销毁对象池 */
    if (pipeline->task_pool) {
        free(pipeline->task_pool);
    }
    
    pthread_mutex_destroy(&pipeline->queue_mutex);
    pthread_cond_destroy(&pipeline->queue_cond);
    
    free(pipeline);
}
​
/**
 * @brief 同步处理
 */
int ai_pipeline_process_sync(ai_pipeline_t* pipeline, const frame_t* frame, 
                              detection_result_t* result)
{
    if (!pipeline || !frame) return -1;
    
    uint64_t start_us = get_time_us();
    
    /* 创建任务 */
    ai_task_t task;
    memset(&task, 0, sizeof(ai_task_t));
    task.input_frame = (frame_t*)frame;
    task.frame_seq = frame->sequence;
    task.submit_time_us = start_us;
    
    /* 执行责任链 */
    int ret = 0;
    ai_stage_t* stage = pipeline->first_stage;
    while (stage && ret == 0) {
        ret = stage->process(stage, &task);
        stage = stage->next;
    }
    
    if (ret == 0 && result) {
        *result = task.output;
        result->inference_time_us = get_time_us() - start_us;
        
        /* 更新统计 */
        pipeline->total_frames++;
        pipeline->total_latency_us += result->inference_time_us;
        if (result->inference_time_us > pipeline->max_latency_us) {
            pipeline->max_latency_us = result->inference_time_us;
        }
        if (result->inference_time_us < pipeline->min_latency_us) {
            pipeline->min_latency_us = result->inference_time_us;
        }
    }
    
    /* 清理任务资源 */
    if (task.output.objects) {
        free(task.output.objects);
    }
    
    return ret;
}
​
/**
 * @brief 获取流水线统计
 */
void ai_pipeline_get_stats(ai_pipeline_t* pipeline, float* fps, 
                            uint32_t* avg_latency_us, uint32_t* queue_depth)
{
    if (!pipeline) return;
    
    if (fps) {
        /* 简化FPS计算 */
        *fps = pipeline->total_frames > 0 ? 1000000.0f / (pipeline->total_latency_us / pipeline->total_frames) : 0;
    }
    
    if (avg_latency_us) {
        *avg_latency_us = pipeline->total_frames > 0 ? 
                          pipeline->total_latency_us / pipeline->total_frames : 0;
    }
    
    if (queue_depth) {
        *queue_depth = pipeline->pending_count;
    }
}

二、3A策略模式应用(AE/AWB/AF)

/**
 * @file isp_3a.h
 * @brief ISP 3A算法模块(策略模式)
 * @author ISP Algorithm Team
 * 
 * @section 设计模式
 * - **策略模式(Strategy)**: AE/AWB/AF可动态切换不同算法
 * - **状态模式(State)**: 对焦状态机(搜索/锁定/重试)
 * - **模板方法(Template Method)**: 3A处理流程框架
 */
​
#ifndef ISP_3A_H
#define ISP_3A_H
​
#include <stdint.h>
#include <stdbool.h>
​
#ifdef __cplusplus
extern "C" {
#endif
​
/*=============================================================================
 * 策略接口定义
 *============================================================================*/
​
/**
 * @brief AE策略接口
 */
typedef struct ae_strategy {
    const char* name;
    
    /* 策略方法 */
    void (*init)(void* ctx);
    void (*update)(void* ctx, const isp_3a_stats_t* stats, ae_cfg_t* cfg);
    void (*deinit)(void* ctx);
    
    /* 私有数据 */
    void* priv;
} ae_strategy_t;
​
/**
 * @brief AWB策略接口
 */
typedef struct awb_strategy {
    const char* name;
    
    void (*init)(void* ctx);
    void (*update)(void* ctx, const isp_3a_stats_t* stats, awb_cfg_t* cfg);
    void (*deinit)(void* ctx);
    
    void* priv;
} awb_strategy_t;
​
/**
 * @brief AF策略接口
 */
typedef struct af_strategy {
    const char* name;
    
    void (*init)(void* ctx);
    void (*update)(void* ctx, const isp_3a_stats_t* stats, af_cfg_t* cfg);
    void (*deinit)(void* ctx);
    
    void* priv;
} af_strategy_t;
​
/*=============================================================================
 * AE策略实现
 *============================================================================*/
​
/**
 * @brief PID控制策略(AE)
 */
typedef struct {
    float integral;         ///< 积分项
    float prev_error;       ///< 上次误差
    uint32_t last_update;   ///< 上次更新时间
} pid_ctx_t;
​
static void pid_ae_init(void* ctx)
{
    pid_ctx_t* pid = (pid_ctx_t*)ctx;
    memset(pid, 0, sizeof(pid_ctx_t));
}
​
static void pid_ae_update(void* ctx, const isp_3a_stats_t* stats, ae_cfg_t* cfg)
{
    pid_ctx_t* pid = (pid_ctx_t*)ctx;
    
    /* 计算亮度误差 */
    int32_t error = (int32_t)cfg->target_luminance - (int32_t)stats->avg_luminance;
    
    /* PID计算 */
    float p_term = cfg->pid_kp * error;
    pid->integral += error;
    float i_term = cfg->pid_ki * pid->integral;
    float d_term = cfg->pid_kd * (error - pid->prev_error);
    
    float output = p_term + i_term + d_term;
    pid->prev_error = error;
    
    /* 限制输出范围 */
    if (output > 0) {
        /* 增加曝光/增益 */
        uint32_t new_exp = cfg->exposure_time_min + (uint32_t)output;
        if (new_exp > cfg->exposure_time_max) new_exp = cfg->exposure_time_max;
        /* 应用曝光值 */
    } else {
        /* 减少曝光/增益 */
    }
}
​
/**
 * @brief 快速AE策略(一步到位)
 */
static void fast_ae_update(void* ctx, const isp_3a_stats_t* stats, ae_cfg_t* cfg)
{
    /* 直接计算目标曝光值 */
    float ratio = (float)cfg->target_luminance / (stats->avg_luminance + 1);
    uint32_t new_exp = (uint32_t)(cfg->exposure_time_min * ratio);
    
    if (new_exp > cfg->exposure_time_max) new_exp = cfg->exposure_time_max;
    if (new_exp < cfg->exposure_time_min) new_exp = cfg->exposure_time_min;
    
    /* 应用 */
}
​
/*=============================================================================
 * AWB策略实现
 *============================================================================*/
​
/**
 * @brief 灰度世界策略(AWB)
 */
static void greyworld_awb_update(void* ctx, const isp_3a_stats_t* stats, awb_cfg_t* cfg)
{
    /* 计算RGB平均值 */
    uint32_t total_pixels = stats->sum_r + stats->sum_g + stats->sum_b;
    if (total_pixels == 0) return;
    
    float avg_r = (float)stats->sum_r / total_pixels;
    float avg_g = (float)stats->sum_g / total_pixels;
    float avg_b = (float)stats->sum_b / total_pixels;
    
    /* 计算增益 */
    float r_gain = avg_g / avg_r;
    float b_gain = avg_g / avg_b;
    
    /* 限制增益范围 */
    if (r_gain > cfg->max_gain) r_gain = cfg->max_gain;
    if (b_gain > cfg->max_gain) b_gain = cfg->max_gain;
    
    /* 应用到ISP */
    // isp_set_wb_gains(r_gain, 1.0f, b_gain);
}
​
/**
 * @brief 完美反射策略(AWB)
 */
static void perfect_reflect_awb_update(void* ctx, const isp_3a_stats_t* stats, awb_cfg_t* cfg)
{
    /* 找出最亮的10%像素作为参考白点 */
    /* 简化实现 */
}
​
/*=============================================================================
 * AF策略实现(状态模式)
 *============================================================================*/
​
/**
 * @brief 对焦状态机
 */
typedef enum {
    AF_STATE_IDLE,          ///< 空闲
    AF_STATE_SCANNING,      ///< 扫描中
    AF_STATE_FOCUSED,       ///< 已对焦
    AF_STATE_LOST,          ///< 失焦
    AF_STATE_RETRY          ///< 重试
} af_state_t;
​
/**
 * @brief 爬山算法对焦上下文
 */
typedef struct {
    af_state_t state;           ///< 当前状态
    int32_t current_pos;        ///< 当前位置
    int32_t best_pos;           ///< 最佳位置
    uint32_t best_value;        ///< 最佳对焦值
    int32_t step;               ///< 步长
    int direction;              ///< 方向(1=正向,-1=反向)
    uint32_t stable_count;      ///< 稳定计数
    uint32_t retry_count;       ///< 重试计数
} hill_climbing_ctx_t;
​
static void hill_climbing_af_init(void* ctx)
{
    hill_climbing_ctx_t* hc = (hill_climbing_ctx_t*)ctx;
    memset(hc, 0, sizeof(hill_climbing_ctx_t));
    hc->state = AF_STATE_IDLE;
}
​
static void hill_climbing_af_update(void* ctx, const isp_3a_stats_t* stats, af_cfg_t* cfg)
{
    hill_climbing_ctx_t* hc = (hill_climbing_ctx_t*)ctx;
    uint32_t fv = stats->focus_value;
    
    switch (hc->state) {
        case AF_STATE_IDLE:
            /* 检测是否需要重新对焦 */
            if (fv < cfg->focus_threshold || hc->stable_count > cfg->retrigger_frames) {
                hc->state = AF_STATE_SCANNING;
                hc->step = cfg->coarse_step;
                hc->direction = 1;
                hc->best_value = 0;
                hc->current_pos = cfg->lens_min;
                hc->retry_count = 0;
            }
            break;
            
        case AF_STATE_SCANNING:
            /* 移动镜头 */
            hc->current_pos += hc->step * hc->direction;
            
            if (hc->current_pos > cfg->lens_max) {
                hc->current_pos = cfg->lens_max;
                hc->direction = -1;
            } else if (hc->current_pos < cfg->lens_min) {
                hc->current_pos = cfg->lens_min;
                /* 扫描完成,移动到最佳位置 */
                hc->state = AF_STATE_FOCUSED;
                /* 设置镜头到best_pos */
                // vcm_set_position(hc->best_pos);
                break;
            }
            
            /* 更新最佳位置 */
            if (fv > hc->best_value) {
                hc->best_value = fv;
                hc->best_pos = hc->current_pos;
            }
            
            /* 应用镜头位置 */
            // vcm_set_position(hc->current_pos);
            
            /* 粗扫完成后切换到细扫 */
            if (hc->step == cfg->coarse_step && hc->direction == -1 && 
                hc->current_pos <= cfg->lens_min + cfg->coarse_step) {
                hc->step = cfg->fine_step;
                hc->direction = 1;
                hc->current_pos = hc->best_pos - cfg->fine_step * 10;
                if (hc->current_pos < cfg->lens_min) hc->current_pos = cfg->lens_min;
            }
            break;
            
        case AF_STATE_FOCUSED:
            /* 监控对焦质量 */
            if (fv < hc->best_value * 0.7f) {
                hc->state = AF_STATE_LOST;
                hc->lost_count = 0;
            }
            break;
            
        case AF_STATE_LOST:
            hc->lost_count++;
            if (hc->lost_count > cfg->lost_threshold) {
                hc->state = AF_STATE_RETRY;
            }
            break;
            
        case AF_STATE_RETRY:
            hc->retry_count++;
            if (hc->retry_count <= cfg->max_retry) {
                hc->state = AF_STATE_SCANNING;
                hc->step = cfg->coarse_step;
            } else {
                hc->state = AF_STATE_IDLE;
            }
            break;
    }
}
​
/*=============================================================================
 * 3A管理器(策略模式容器)
 *============================================================================*/
​
/**
 * @brief 3A管理器
 */
typedef struct {
    /* 当前策略 */
    ae_strategy_t* ae_strategy;
    awb_strategy_t* awb_strategy;
    af_strategy_t* af_strategy;
    
    /* 策略上下文 */
    void* ae_ctx;
    void* awb_ctx;
    void* af_ctx;
    
    /* 配置 */
    ae_cfg_t ae_cfg;
    awb_cfg_t awb_cfg;
    af_cfg_t af_cfg;
} isp_3a_manager_t;
​
/**
 * @brief 创建3A管理器
 */
isp_3a_manager_t* isp_3a_create(void)
{
    isp_3a_manager_t* mgr = (isp_3a_manager_t*)calloc(1, sizeof(isp_3a_manager_t));
    if (!mgr) return NULL;
    
    /* 默认使用PID AE */
    static ae_strategy_t pid_ae = {
        .name = "PID",
        .init = pid_ae_init,
        .update = pid_ae_update,
        .deinit = NULL,
        .priv = NULL
    };
    
    mgr->ae_strategy = &pid_ae;
    mgr->ae_ctx = malloc(sizeof(pid_ctx_t));
    mgr->ae_strategy->init(mgr->ae_ctx);
    
    /* 默认使用灰度世界AWB */
    static awb_strategy_t greyworld_awb = {
        .name = "GreyWorld",
        .init = NULL,
        .update = greyworld_awb_update,
        .deinit = NULL,
        .priv = NULL
    };
    
    mgr->awb_strategy = &greyworld_awb;
    
    /* 默认使用爬山法AF */
    static af_strategy_t hill_climbing_af = {
        .name = "HillClimbing",
        .init = hill_climbing_af_init,
        .update = hill_climbing_af_update,
        .deinit = NULL,
        .priv = NULL
    };
    
    mgr->af_strategy = &hill_climbing_af;
    mgr->af_ctx = malloc(sizeof(hill_climbing_ctx_t));
    mgr->af_strategy->init(mgr->af_ctx);
    
    return mgr;
}
​
/**
 * @brief 动态切换AE策略(策略模式核心)
 */
void isp_3a_set_ae_strategy(isp_3a_manager_t* mgr, ae_strategy_t* strategy)
{
    if (!mgr) return;
    
    /* 清理旧策略 */
    if (mgr->ae_strategy && mgr->ae_strategy->deinit) {
        mgr->ae_strategy->deinit(mgr->ae_ctx);
    }
    
    /* 切换新策略 */
    mgr->ae_strategy = strategy;
    if (strategy && strategy->init) {
        strategy->init(mgr->ae_ctx);
    }
}
​
/**
 * @brief 运行3A处理(模板方法)
 */
void isp_3a_run(isp_3a_manager_t* mgr, const isp_3a_stats_t* stats)
{
    if (!mgr || !stats) return;
    
    /* 模板方法: 固定的处理流程 */
    
    /* 1. 运行AE */
    if (mgr->ae_strategy && mgr->ae_strategy->update) {
        mgr->ae_strategy->update(mgr->ae_ctx, stats, &mgr->ae_cfg);
    }
    
    /* 2. 运行AWB */
    if (mgr->awb_strategy && mgr->awb_strategy->update) {
        mgr->awb_strategy->update(mgr->awb_ctx, stats, &mgr->awb_cfg);
    }
    
    /* 3. 运行AF(仅在需要时) */
    if (mgr->af_strategy && mgr->af_strategy->update) {
        mgr->af_strategy->update(mgr->af_ctx, stats, &mgr->af_cfg);
    }
}
​
#endif /* ISP_3A_H */

三、观察者模式在事件循环中的应用

/**
 * @file event_loop.h
 * @brief 事件循环模块(观察者模式 + Reactor模式)
 * @author System Architecture Team
 * 
 * @section 设计模式
 * - **观察者模式(Observer)**: 事件源订阅/通知机制
 * - **Reactor模式**: IO多路复用事件分发
 * - **单例模式(Singleton)**: 全局唯一事件循环实例
 * - **命令模式(Command)**: 延迟执行的任务封装
 */
​
#ifndef EVENT_LOOP_H
#define EVENT_LOOP_H
​
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/epoll.h>
​
#ifdef __cplusplus
extern "C" {
#endif
​
/*=============================================================================
 * 事件类型定义
 *============================================================================*/
​
/**
 * @brief 事件类型(位掩码)
 */
typedef enum {
    EVENT_NONE          = 0x0000,
    EVENT_NEW_FRAME     = 0x0001,   ///< 新视频帧到达
    EVENT_ISP_3A_READY  = 0x0002,   ///< ISP 3A统计就绪
    EVENT_AI_RESULT     = 0x0004,   ///< AI推理完成
    EVENT_TIMER         = 0x0008,   ///< 定时器事件
    EVENT_SIGNAL        = 0x0010,   ///< 信号事件
    EVENT_CONFIG_CHANGE = 0x0020,   ///< 配置变更
    EVENT_ERROR         = 0x8000    ///< 错误事件
} event_type_t;
​
/**
 * @brief 事件优先级
 */
typedef enum {
    EVENT_PRIO_LOW = 0,     ///< 低优先级(日志/统计)
    EVENT_PRIO_NORMAL = 1,  ///< 普通优先级(配置变更)
    EVENT_PRIO_HIGH = 2,    ///< 高优先级(AI结果)
    EVENT_PRIO_CRITICAL = 3 ///< 紧急优先级(帧数据)
} event_priority_t;
​
/*=============================================================================
 * 事件结构体定义
 *============================================================================*/
​
/**
 * @brief 事件基类(观察者模式的通知对象)
 */
typedef struct event {
    uint32_t event_id;              ///< 事件唯一ID
    event_type_t type;              ///< 事件类型
    event_priority_t priority;      ///< 事件优先级
    uint64_t timestamp;             ///< 事件发生时间戳(纳秒)
    uint32_t source_id;             ///< 事件源ID
    
    /* 事件数据(联合体) */
    union {
        struct {
            void* frame_data;       ///< 帧数据指针
            uint32_t width;         ///< 宽度
            uint32_t height;        ///< 高度
            uint32_t format;        ///< 像素格式
            uint32_t sequence;      ///< 帧序号
        } frame_event;
        
        struct {
            uint32_t avg_luminance; ///< 平均亮度
            uint16_t color_temp;    ///< 色温
            uint32_t focus_value;   ///< 对焦值
        } isp_event;
        
        struct {
            uint32_t object_count;  ///< 检测目标数
            void* detections;       ///< 检测结果指针
            uint32_t inference_us;  ///< 推理耗时
        } ai_event;
        
        struct {
            uint32_t timer_id;      ///< 定时器ID
            uint32_t repeat_count;  ///< 重复次数
        } timer_event;
        
        struct {
            int error_code;         ///< 错误码
            const char* error_msg;  ///< 错误描述
        } error_event;
    } data;
    
    /* 回调函数(用于异步响应) */
    void (*on_complete)(struct event* evt, void* user_data);
    void* user_data;
    
    /* 链表指针 */
    struct event* next;
} event_t;
​
/*=============================================================================
 * 观察者接口定义
 *============================================================================*/
​
/**
 * @brief 观察者接口(观察者模式)
 * 
 * @note 所有需要接收事件的对象都需要实现此接口
 */
typedef struct observer {
    const char* name;                       ///< 观察者名称(调试用)
    uint32_t id;                            ///< 观察者ID
    
    /* 观察者方法 */
    int (*on_event)(struct observer* self, const event_t* event);
    
    /* 订阅的事件类型(位掩码) */
    uint32_t subscribed_events;
    
    /* 观察者优先级(数字越小越先处理) */
    int priority;
    
    /* 私有数据 */
    void* priv;
    
    /* 链表指针 */
    struct observer* next;
} observer_t;
​
/*=============================================================================
 * 定时器结构体
 *============================================================================*/
​
/**
 * @brief 定时器类型
 */
typedef enum {
    TIMER_ONESHOT,      ///< 单次定时器
    TIMER_PERIODIC      ///< 周期定时器
} timer_type_t;
​
/**
 * @brief 定时器结构体
 */
typedef struct timer {
    uint32_t timer_id;          ///< 定时器ID
    timer_type_t type;          ///< 定时器类型
    uint64_t interval_us;       ///< 间隔时间(微秒)
    uint64_t next_expire_us;    ///< 下次到期时间
    uint32_t repeat_count;      ///< 重复次数(0=无限)
    uint32_t fired_count;       ///< 已触发次数
    
    /* 回调函数 */
    void (*callback)(uint32_t timer_id, void* user_data);
    void* user_data;
    
    /* 链表 */
    struct timer* next;
} timer_t;
​
/*=============================================================================
 * 延迟任务结构体(命令模式)
 *============================================================================*/
​
/**
 * @brief 延迟任务结构体
 */
typedef struct delayed_task {
    uint32_t task_id;               ///< 任务ID
    uint64_t execute_time_us;       ///< 执行时间
    void (*func)(void* arg);        ///< 任务函数
    void* arg;                      ///< 任务参数
    void (*cleanup)(void* arg);     ///< 清理函数
    
    struct delayed_task* next;
} delayed_task_t;
​
/*=============================================================================
 * 事件循环主结构体
 *============================================================================*/
​
/**
 * @brief 事件循环配置
 */
typedef struct {
    uint32_t max_events;            ///< 最大事件数(默认64)
    uint32_t event_queue_size;      ///< 事件队列大小(默认1024)
    int epoll_timeout_ms;           ///< epoll超时(默认-1阻塞)
    bool enable_priority_queue;     ///< 启用优先级队列
    bool enable_stats;              ///< 启用统计
} event_loop_config_t;
​
/**
 * @brief 事件循环上下文(单例模式)
 */
typedef struct event_loop {
    /* epoll相关 */
    int epoll_fd;                   ///< epoll文件描述符
    struct epoll_event* epoll_events;   ///< epoll事件数组
    
    /* 观察者链表(观察者模式) */
    observer_t* observers;          ///< 观察者链表头
    pthread_rwlock_t observer_lock; ///< 观察者读写锁
    
    /* 事件队列(生产者-消费者模式) */
    event_t** priority_queues;      ///< 优先级队列数组(4个优先级)
    uint32_t* queue_sizes;          ///< 各队列当前大小
    uint32_t max_queue_size;        ///< 最大队列大小
    pthread_mutex_t queue_lock;     ///< 队列锁
    pthread_cond_t queue_cond;      ///< 队列条件变量
    
    /* 定时器管理 */
    timer_t* timers;                ///< 定时器链表
    uint32_t next_timer_id;         ///< 下一个定时器ID
    pthread_mutex_t timer_lock;     ///< 定时器锁
    int timer_fd;                   ///< timerfd文件描述符
    
    /* 延迟任务 */
    delayed_task_t* delayed_tasks;  ///< 延迟任务链表
    pthread_mutex_t task_lock;      ///< 任务锁
    
    /* 工作线程池 */
    pthread_t* worker_threads;
    uint32_t worker_count;
    volatile bool running;
    
    /* 统计信息 */
    struct {
        uint64_t total_events;      ///< 总事件数
        uint64_t dropped_events;    ///< 丢弃事件数
        uint64_t max_queue_usage;   ///< 最大队列使用率
        uint64_t avg_latency_us;    ///< 平均处理延迟
        uint64_t timer_fired;       ///< 定时器触发次数
    } stats;
    
    /* 配置 */
    event_loop_config_t config;
    
} event_loop_t;
​
/*=============================================================================
 * 事件循环API
 *============================================================================*/
​
/**
 * @brief 获取全局事件循环实例(单例模式)
 * @param config 配置(首次调用时必须提供)
 * @return 事件循环实例
 */
event_loop_t* event_loop_get_instance(const event_loop_config_t* config);
​
/**
 * @brief 启动事件循环
 * @param loop 事件循环实例
 * @return 成功返回0
 */
int event_loop_start(event_loop_t* loop);
​
/**
 * @brief 停止事件循环
 * @param loop 事件循环实例
 */
void event_loop_stop(event_loop_t* loop);
​
/**
 * @brief 注册观察者(订阅事件)
 * @param loop 事件循环实例
 * @param observer 观察者对象
 * @return 成功返回0
 */
int event_loop_register_observer(event_loop_t* loop, observer_t* observer);
​
/**
 * @brief 注销观察者
 * @param loop 事件循环实例
 * @param observer_id 观察者ID
 * @return 成功返回0
 */
int event_loop_unregister_observer(event_loop_t* loop, uint32_t observer_id);
​
/**
 * @brief 发布事件(异步通知)
 * @param loop 事件循环实例
 * @param event 事件对象(会被拷贝)
 * @return 成功返回0
 * 
 * @note 设计模式: 观察者模式 - 通知所有订阅的观察者
 */
int event_loop_publish(event_loop_t* loop, const event_t* event);
​
/**
 * @brief 添加文件描述符监听(Reactor模式)
 * @param loop 事件循环实例
 * @param fd 文件描述符
 * @param events epoll事件(EPOLLIN|EPOLLOUT等)
 * @param callback 回调函数
 * @param user_data 用户数据
 * @return 成功返回0
 */
int event_loop_add_fd(event_loop_t* loop, int fd, uint32_t events,
                       void (*callback)(int fd, uint32_t events, void* user_data),
                       void* user_data);
​
/**
 * @brief 移除文件描述符监听
 * @param loop 事件循环实例
 * @param fd 文件描述符
 * @return 成功返回0
 */
int event_loop_remove_fd(event_loop_t* loop, int fd);
​
/**
 * @brief 创建定时器
 * @param loop 事件循环实例
 * @param interval_us 间隔时间(微秒)
 * @param type 定时器类型
 * @param callback 回调函数
 * @param user_data 用户数据
 * @return 定时器ID(0表示失败)
 */
uint32_t event_loop_create_timer(event_loop_t* loop, uint64_t interval_us,
                                   timer_type_t type,
                                   void (*callback)(uint32_t timer_id, void* user_data),
                                   void* user_data);
​
/**
 * @brief 删除定时器
 * @param loop 事件循环实例
 * @param timer_id 定时器ID
 * @return 成功返回0
 */
int event_loop_delete_timer(event_loop_t* loop, uint32_t timer_id);
​
/**
 * @brief 添加延迟任务(命令模式)
 * @param loop 事件循环实例
 * @param delay_us 延迟时间(微秒)
 * @param func 任务函数
 * @param arg 参数
 * @param cleanup 清理函数
 * @return 任务ID
 */
uint32_t event_loop_add_delayed_task(event_loop_t* loop, uint64_t delay_us,
                                       void (*func)(void* arg), void* arg,
                                       void (*cleanup)(void* arg));
​
/**
 * @brief 获取事件循环统计信息
 * @param loop 事件循环实例
 * @param stats 输出统计信息
 */
void event_loop_get_stats(event_loop_t* loop, void* stats);
​
#ifdef __cplusplus
}
#endif
​
#endif /* EVENT_LOOP_H */
/**
 * @file event_loop.c
 * @brief 事件循环实现(观察者模式 + Reactor模式)
 */
​
#include "event_loop.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/timerfd.h>
#include <time.h>
​
/*=============================================================================
 * 内部辅助函数
 *============================================================================*/
​
/**
 * @brief 获取当前时间戳(微秒)
 */
static inline uint64_t get_time_us(void)
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (uint64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
}
​
/**
 * @brief 事件拷贝(深拷贝)
 */
static void event_copy(event_t* dest, const event_t* src)
{
    memcpy(dest, src, sizeof(event_t));
    /* 如果有动态数据需要深拷贝,在这里处理 */
}
​
/*=============================================================================
 * 优先级队列实现
 *============================================================================*/
​
/**
 * @brief 获取优先级队列索引
 */
static inline int get_queue_index(event_priority_t priority)
{
    int idx = (int)priority;
    if (idx < 0) idx = 0;
    if (idx > 3) idx = 3;
    return idx;
}
​
/**
 * @brief 入队事件(按优先级)
 */
static int event_queue_push(event_loop_t* loop, const event_t* event)
{
    int idx = get_queue_index(event->priority);
    
    /* 检查队列是否满 */
    if (loop->queue_sizes[idx] >= loop->max_queue_size) {
        /* 队列满,丢弃最低优先级事件 */
        if (idx > 0) {
            /* 尝试降级到低优先级队列 */
            idx--;
            if (loop->queue_sizes[idx] < loop->max_queue_size) {
                goto enqueue;
            }
        }
        loop->stats.dropped_events++;
        return -1;
    }
    
enqueue:
    /* 分配新事件节点 */
    event_t* new_event = (event_t*)malloc(sizeof(event_t));
    if (!new_event) return -2;
    event_copy(new_event, event);
    
    /* 入队(简单FIFO,可优化为按时间戳排序) */
    new_event->next = NULL;
    
    pthread_mutex_lock(&loop->queue_lock);
    
    /* 找到队列尾 */
    event_t** tail = &loop->priority_queues[idx];
    while (*tail) {
        tail = &(*tail)->next;
    }
    *tail = new_event;
    loop->queue_sizes[idx]++;
    
    /* 更新统计 */
    if (loop->queue_sizes[idx] > loop->stats.max_queue_usage) {
        loop->stats.max_queue_usage = loop->queue_sizes[idx];
    }
    
    pthread_cond_signal(&loop->queue_cond);
    pthread_mutex_unlock(&loop->queue_lock);
    
    return 0;
}
​
/**
 * @brief 出队事件(按优先级)
 */
static event_t* event_queue_pop(event_loop_t* loop)
{
    event_t* event = NULL;
    
    pthread_mutex_lock(&loop->queue_lock);
    
    /* 从高优先级到低优先级查找 */
    for (int i = 3; i >= 0; i--) {
        if (loop->priority_queues[i]) {
            event = loop->priority_queues[i];
            loop->priority_queues[i] = event->next;
            loop->queue_sizes[i]--;
            break;
        }
    }
    
    pthread_mutex_unlock(&loop->queue_lock);
    return event;
}
​
/*=============================================================================
 * 定时器管理
 *============================================================================*/
​
/**
 * @brief 更新timerfd
 */
static void update_timerfd(event_loop_t* loop)
{
    uint64_t min_expire = UINT64_MAX;
    timer_t* timer = loop->timers;
    
    /* 找到最近的到期时间 */
    while (timer) {
        if (timer->next_expire_us < min_expire) {
            min_expire = timer->next_expire_us;
        }
        timer = timer->next;
    }
    
    /* 设置timerfd */
    if (min_expire != UINT64_MAX) {
        uint64_t now_us = get_time_us();
        uint64_t expire_ms = 0;
        if (min_expire > now_us) {
            expire_ms = (min_expire - now_us) / 1000;
        }
        
        struct itimerspec its = {
            .it_value = {
                .tv_sec = expire_ms / 1000,
                .tv_nsec = (expire_ms % 1000) * 1000000
            }
        };
        timerfd_settime(loop->timer_fd, 0, &its, NULL);
    }
}
​
/**
 * @brief 处理到期的定时器
 */
static void process_timers(event_loop_t* loop)
{
    uint64_t expirations;
    ssize_t s = read(loop->timer_fd, &expirations, sizeof(uint64_t));
    if (s != sizeof(uint64_t)) return;
    
    uint64_t now_us = get_time_us();
    
    pthread_mutex_lock(&loop->timer_lock);
    
    timer_t* timer = loop->timers;
    timer_t* prev = NULL;
    
    while (timer) {
        if (timer->next_expire_us <= now_us) {
            /* 定时器到期 */
            loop->stats.timer_fired++;
            
            /* 调用回调 */
            if (timer->callback) {
                timer->callback(timer->timer_id, timer->user_data);
            }
            
            /* 更新定时器状态 */
            if (timer->type == TIMER_PERIODIC) {
                /* 周期定时器: 重新调度 */
                timer->fired_count++;
                if (timer->repeat_count == 0 || 
                    timer->fired_count < timer->repeat_count) {
                    timer->next_expire_us = now_us + timer->interval_us;
                    prev = timer;
                    timer = timer->next;
                    continue;
                }
            }
            
            /* 删除定时器(单次或已到期) */
            timer_t* to_delete = timer;
            if (prev) {
                prev->next = timer->next;
                timer = timer->next;
            } else {
                loop->timers = timer->next;
                timer = loop->timers;
            }
            free(to_delete);
        } else {
            prev = timer;
            timer = timer->next;
        }
    }
    
    pthread_mutex_unlock(&loop->timer_lock);
    
    /* 更新timerfd */
    update_timerfd(loop);
}
​
/*=============================================================================
 * 观察者管理(观察者模式核心)
 *============================================================================*/
​
/**
 * @brief 通知所有观察者
 */
static void notify_observers(event_loop_t* loop, const event_t* event)
{
    pthread_rwlock_rdlock(&loop->observer_lock);
    
    observer_t* observer = loop->observers;
    
    /* 按优先级排序(简单插入排序) */
    /* 这里简化处理,实际应维护优先级队列 */
    
    while (observer) {
        /* 检查是否订阅了该事件类型 */
        if (observer->subscribed_events & event->type) {
            uint64_t start_us = get_time_us();
            
            /* 调用观察者处理函数 */
            int ret = observer->on_event(observer, event);
            
            /* 更新延迟统计 */
            uint64_t latency_us = get_time_us() - start_us;
            loop->stats.avg_latency_us = 
                (loop->stats.avg_latency_us * loop->stats.total_events + latency_us) /
                (loop->stats.total_events + 1);
            
            (void)ret; /* 可记录错误 */
        }
        observer = observer->next;
    }
    
    pthread_rwlock_unlock(&loop->observer_lock);
}
​
/*=============================================================================
 * 工作线程函数
 *============================================================================*/
​
/**
 * @brief 工作线程入口
 */
static void* worker_thread_func(void* arg)
{
    event_loop_t* loop = (event_loop_t*)arg;
    
    while (loop->running) {
        /* 等待事件 */
        event_t* event = event_queue_pop(loop);
        
        if (event) {
            /* 处理事件 */
            loop->stats.total_events++;
            notify_observers(loop, event);
            
            /* 释放事件 */
            free(event);
        } else {
            /* 队列空,短暂休眠 */
            usleep(1000);
        }
    }
    
    return NULL;
}
​
/*=============================================================================
 * epoll事件处理(Reactor模式)
 *============================================================================*/
​
/**
 * @brief epoll事件处理结构体
 */
typedef struct fd_handler {
    int fd;
    void (*callback)(int fd, uint32_t events, void* user_data);
    void* user_data;
} fd_handler_t;
​
static fd_handler_t* g_fd_handlers[1024];  /* 简化实现 */
​
/**
 * @brief epoll主循环
 */
static void epoll_loop(event_loop_t* loop)
{
    while (loop->running) {
        int nfds = epoll_wait(loop->epoll_fd, loop->epoll_events, 
                               loop->config.max_events, 
                               loop->config.epoll_timeout_ms);
        
        if (nfds < 0) {
            if (errno == EINTR) continue;
            break;
        }
        
        for (int i = 0; i < nfds; i++) {
            int fd = loop->epoll_events[i].data.fd;
            uint32_t events = loop->epoll_events[i].events;
            
            /* 处理timerfd */
            if (fd == loop->timer_fd) {
                process_timers(loop);
                continue;
            }
            
            /* 查找并调用处理器 */
            if (fd >= 0 && fd < 1024 && g_fd_handlers[fd]) {
                fd_handler_t* handler = g_fd_handlers[fd];
                if (handler->callback) {
                    handler->callback(fd, events, handler->user_data);
                }
            }
        }
    }
}
​
/*=============================================================================
 * 事件循环主API实现
 *============================================================================*/
​
static event_loop_t* g_instance = NULL;
​
event_loop_t* event_loop_get_instance(const event_loop_config_t* config)
{
    if (g_instance) return g_instance;
    
    if (!config) return NULL;
    
    event_loop_t* loop = (event_loop_t*)calloc(1, sizeof(event_loop_t));
    if (!loop) return NULL;
    
    /* 保存配置 */
    memcpy(&loop->config, config, sizeof(event_loop_config_t));
    if (loop->config.max_events == 0) loop->config.max_events = 64;
    if (loop->config.event_queue_size == 0) loop->config.event_queue_size = 1024;
    loop->max_queue_size = loop->config.event_queue_size;
    
    /* 初始化epoll */
    loop->epoll_fd = epoll_create1(0);
    if (loop->epoll_fd < 0) {
        free(loop);
        return NULL;
    }
    
    loop->epoll_events = (struct epoll_event*)calloc(loop->config.max_events, 
                                                       sizeof(struct epoll_event));
    
    /* 初始化优先级队列(4个优先级) */
    loop->priority_queues = (event_t**)calloc(4, sizeof(event_t*));
    loop->queue_sizes = (uint32_t*)calloc(4, sizeof(uint32_t));
    
    /* 初始化锁 */
    pthread_mutex_init(&loop->queue_lock, NULL);
    pthread_cond_init(&loop->queue_cond, NULL);
    pthread_rwlock_init(&loop->observer_lock, NULL);
    pthread_mutex_init(&loop->timer_lock, NULL);
    pthread_mutex_init(&loop->task_lock, NULL);
    
    /* 创建timerfd */
    loop->timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
    if (loop->timer_fd >= 0) {
        /* 添加到epoll */
        struct epoll_event ev = {
            .events = EPOLLIN,
            .data.fd = loop->timer_fd
        };
        epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, loop->timer_fd, &ev);
    }
    
    g_instance = loop;
    return loop;
}
​
int event_loop_start(event_loop_t* loop)
{
    if (!loop) return -1;
    if (loop->running) return 0;
    
    loop->running = true;
    
    /* 创建工作线程 */
    loop->worker_count = 2;  /* 2个工作线程 */
    loop->worker_threads = (pthread_t*)calloc(loop->worker_count, sizeof(pthread_t));
    
    for (uint32_t i = 0; i < loop->worker_count; i++) {
        pthread_create(&loop->worker_threads[i], NULL, worker_thread_func, loop);
    }
    
    /* 主线程运行epoll循环 */
    epoll_loop(loop);
    
    return 0;
}
​
void event_loop_stop(event_loop_t* loop)
{
    if (!loop) return;
    loop->running = false;
    
    /* 等待工作线程结束 */
    for (uint32_t i = 0; i < loop->worker_count; i++) {
        pthread_join(loop->worker_threads[i], NULL);
    }
}
​
int event_loop_register_observer(event_loop_t* loop, observer_t* observer)
{
    if (!loop || !observer) return -1;
    
    pthread_rwlock_wrlock(&loop->observer_lock);
    
    /* 插入到链表头 */
    observer->next = loop->observers;
    loop->observers = observer;
    
    pthread_rwlock_unlock(&loop->observer_lock);
    
    return 0;
}
​
int event_loop_publish(event_loop_t* loop, const event_t* event)
{
    if (!loop || !event) return -1;
    
    /* 设置时间戳(如果未设置) */
    event_t local_event;
    event_copy(&local_event, event);
    if (local_event.timestamp == 0) {
        local_event.timestamp = get_time_us();
    }
    
    return event_queue_push(loop, &local_event);
}
​
int event_loop_add_fd(event_loop_t* loop, int fd, uint32_t events,
                       void (*callback)(int fd, uint32_t events, void* user_data),
                       void* user_data)
{
    if (!loop || fd < 0 || fd >= 1024) return -1;
    
    /* 分配处理器 */
    fd_handler_t* handler = (fd_handler_t*)calloc(1, sizeof(fd_handler_t));
    if (!handler) return -2;
    
    handler->fd = fd;
    handler->callback = callback;
    handler->user_data = user_data;
    g_fd_handlers[fd] = handler;
    
    /* 添加到epoll */
    struct epoll_event ev = {
        .events = events,
        .data.fd = fd
    };
    
    return epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, fd, &ev);
}
​
int event_loop_remove_fd(event_loop_t* loop, int fd)
{
    if (!loop || fd < 0 || fd >= 1024) return -1;
    
    epoll_ctl(loop->epoll_fd, EPOLL_CTL_DEL, fd, NULL);
    
    if (g_fd_handlers[fd]) {
        free(g_fd_handlers[fd]);
        g_fd_handlers[fd] = NULL;
    }
    
    return 0;
}
​
uint32_t event_loop_create_timer(event_loop_t* loop, uint64_t interval_us,
                                   timer_type_t type,
                                   void (*callback)(uint32_t timer_id, void* user_data),
                                   void* user_data)
{
    if (!loop || !callback) return 0;
    
    timer_t* timer = (timer_t*)calloc(1, sizeof(timer_t));
    if (!timer) return 0;
    
    pthread_mutex_lock(&loop->timer_lock);
    
    timer->timer_id = ++loop->next_timer_id;
    timer->type = type;
    timer->interval_us = interval_us;
    timer->next_expire_us = get_time_us() + interval_us;
    timer->callback = callback;
    timer->user_data = user_data;
    
    /* 插入链表 */
    timer->next = loop->timers;
    loop->timers = timer;
    
    pthread_mutex_unlock(&loop->timer_lock);
    
    /* 更新timerfd */
    update_timerfd(loop);
    
    return timer->timer_id;
}
​
/*=============================================================================
 * 示例观察者实现
 *============================================================================*/
​
/**
 * @brief AI结果观察者示例
 */
static int ai_result_observer_on_event(observer_t* self, const event_t* event)
{
    if (event->type == EVENT_AI_RESULT) {
        /* 处理AI结果 */
        printf("[AI Observer] Received AI result: %u objects\n", 
               event->data.ai_event.object_count);
        /* 可以触发RTSP推流、MQTT上报等 */
    }
    return 0;
}
​
/**
 * @brief 创建AI结果观察者
 */
observer_t* create_ai_result_observer(void)
{
    static uint32_t observer_id = 1000;
    
    observer_t* obs = (observer_t*)calloc(1, sizeof(observer_t));
    if (!obs) return NULL;
    
    obs->name = "AIResultObserver";
    obs->id = observer_id++;
    obs->on_event = ai_result_observer_on_event;
    obs->subscribed_events = EVENT_AI_RESULT;
    obs->priority = EVENT_PRIO_HIGH;
    
    return obs;
}

四、内存管理模块

/**
 * @file memory_manager.h
 * @brief 内存管理模块(对象池模式 + 内存池模式)
 * @author System Team
 * 
 * @section 设计模式
 * - **对象池模式(Object Pool)**: 复用帧对象/AI张量对象
 * - **内存池模式(Memory Pool)**: 预分配固定大小内存块
 * - **单例模式(Singleton)**: 全局内存管理器
 * - **策略模式(Strategy)**: 不同场景使用不同分配策略
 */
​
#ifndef MEMORY_MANAGER_H
#define MEMORY_MANAGER_H
​
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
​
#ifdef __cplusplus
extern "C" {
#endif
​
/*=============================================================================
 * 内存块结构体
 *============================================================================*/
​
/**
 * @brief 内存块头部(用于内存池管理)
 */
typedef struct mem_block {
    uint32_t magic;                 ///< 魔数(0x4D454D42)
    uint32_t size;                  ///< 块大小
    bool used;                      ///< 是否使用中
    uint32_t alloc_count;           ///< 分配计数(调试用)
    uint64_t alloc_time_us;         ///< 分配时间戳
    const char* alloc_file;         ///< 分配文件(调试)
    int alloc_line;                 ///< 分配行号(调试)
    struct mem_block* next;         ///< 下一个空闲块
} mem_block_t;
​
/*=============================================================================
 * 内存池结构体
 *============================================================================*/
​
/**
 * @brief 内存池类型
 */
typedef enum {
    MEM_POOL_CMA,           ///< CMA连续内存池(用于DMA/ISP)
    MEM_POOL_DMA,           ///< DMA缓冲区池
    MEM_POOL_SLAB,          ///< SLAB对象缓存(固定大小)
    MEM_POOL_AI_TENSOR,     ///< AI张量内存池
    MEM_POOL_FRAME          ///< 帧数据内存池
} mem_pool_type_t;
​
/**
 * @brief 内存池配置
 */
typedef struct {
    mem_pool_type_t type;       ///< 池类型
    const char* name;           ///< 池名称
    size_t block_size;          ///< 块大小(对于SLAB池)
    size_t block_count;         ///< 块数量
    size_t total_size;          ///< 总大小(对于CMA池)
    uint32_t flags;             ///< 标志位
#define MEM_FLAG_CACHE_ALIGN 0x01   ///< 缓存行对齐(64字节)
#define MEM_FLAG_ZERO_INIT    0x02   ///< 初始化为0
#define MEM_FLAG_NO_MMAP      0x04   ///< 不使用mmap
} mem_pool_cfg_t;
​
/**
 * @brief 内存池统计信息
 */
typedef struct {
    size_t total_bytes;         ///< 总字节数
    size_t used_bytes;          ///< 已用字节数
    size_t peak_bytes;          ///< 峰值字节数
    uint32_t alloc_count;       ///< 分配次数
    uint32_t free_count;        ///< 释放次数
    uint32_t fail_count;        ///< 失败次数
    uint64_t total_alloc_time_us;   ///< 总分配耗时
    uint64_t max_alloc_time_us;     ///< 最大分配耗时
} mem_pool_stat_t;
​
/**
 * @brief 内存池句柄(不透明指针)
 */
typedef struct mem_pool mem_pool_t;
​
/*=============================================================================
 * SLAB缓存(对象池)
 *============================================================================*/
​
/**
 * @brief SLAB缓存配置
 */
typedef struct {
    const char* name;           ///< 缓存名称
    size_t object_size;         ///< 对象大小
    size_t slab_size;           ///< SLAB大小(字节)
    uint32_t align;             ///< 对齐要求
    void (*ctor)(void* obj);    ///< 构造函数
    void (*dtor)(void* obj);    ///< 析构函数
} slab_cache_cfg_t;
​
/**
 * @brief SLAB缓存句柄
 */
typedef struct slab_cache slab_cache_t;
​
/*=============================================================================
 * 内存管理器API
 *============================================================================*/
​
/**
 * @brief 初始化内存管理器(单例模式)
 * @param config 内存池配置数组
 * @param pool_count 配置数量
 * @return 成功返回0
 */
int memory_manager_init(const mem_pool_cfg_t* configs, uint32_t pool_count);
​
/**
 * @brief 从内存池分配内存
 * @param pool_name 内存池名称
 * @param size 需要分配的大小
 * @return 内存指针(失败返回NULL)
 * 
 * @note 设计模式: 对象池模式 - 从预分配池中获取对象
 */
void* memory_pool_alloc(const char* pool_name, size_t size);
​
/**
 * @brief 释放内存回池
 * @param pool_name 内存池名称
 * @param ptr 内存指针
 */
void memory_pool_free(const char* pool_name, void* ptr);
​
/**
 * @brief 获取内存池统计信息
 * @param pool_name 内存池名称
 * @param stat 输出统计信息
 * @return 成功返回0
 */
int memory_pool_get_stat(const char* pool_name, mem_pool_stat_t* stat);
​
/**
 * @brief 创建SLAB缓存(对象池)
 * @param cfg SLAB配置
 * @return SLAB缓存句柄
 */
slab_cache_t* slab_cache_create(const slab_cache_cfg_t* cfg);
​
/**
 * @brief 从SLAB缓存分配对象
 * @param cache SLAB缓存句柄
 * @return 对象指针
 */
void* slab_cache_alloc(slab_cache_t* cache);
​
/**
 * @brief 释放对象回SLAB缓存
 * @param cache SLAB缓存句柄
 * @param obj 对象指针
 */
void slab_cache_free(slab_cache_t* cache, void* obj);
​
/**
 * @brief 销毁SLAB缓存
 * @param cache SLAB缓存句柄
 */
void slab_cache_destroy(slab_cache_t* cache);
​
/**
 * @brief 全局内存调试信息打印
 */
void memory_manager_dump_stats(void);
​
#ifdef __cplusplus
}
#endif
​
#endif /* MEMORY_MANAGER_H */
/**
 * @file memory_manager.c
 * @brief 内存管理实现
 */
​
#include "memory_manager.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <pthread.h>
​
/*=============================================================================
 * 内存池实现
 *============================================================================*/
​
/**
 * @brief 内存池结构体
 */
struct mem_pool {
    char name[64];                  ///< 池名称
    mem_pool_type_t type;           ///< 池类型
    size_t block_size;              ///< 块大小
    size_t block_count;             ///< 块数量
    size_t total_size;              ///< 总大小
    uint32_t flags;                 ///< 标志位
    
    void* base_addr;                ///< 基地址
    mem_block_t* free_list;         ///< 空闲链表
    mem_block_t* blocks;            ///< 块数组
    
    /* 统计信息 */
    mem_pool_stat_t stats;
    
    /* 锁 */
    pthread_mutex_t lock;
    
    /* 下一个池 */
    struct mem_pool* next;
};
​
/* 全局内存池链表 */
static mem_pool_t* g_pools = NULL;
static pthread_mutex_t g_pools_lock = PTHREAD_MUTEX_INITIALIZER;
static bool g_initialized = false;
​
/**
 * @brief 查找内存池
 */
static mem_pool_t* find_pool(const char* name)
{
    mem_pool_t* pool = g_pools;
    while (pool) {
        if (strcmp(pool->name, name) == 0) {
            return pool;
        }
        pool = pool->next;
    }
    return NULL;
}
​
/**
 * @brief 创建CMA连续内存池
 */
static int create_cma_pool(mem_pool_t* pool, const mem_pool_cfg_t* cfg)
{
    /* 使用mmap分配大块连续内存 */
    int fd = open("/dev/mem", O_RDWR);
    if (fd < 0) {
        /* 降级使用匿名mmap */
        pool->base_addr = mmap(NULL, cfg->total_size, 
                                PROT_READ | PROT_WRITE,
                                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    } else {
        /* 从CMA区域分配(简化) */
        pool->base_addr = mmap(NULL, cfg->total_size,
                                PROT_READ | PROT_WRITE,
                                MAP_SHARED, fd, 0);
        close(fd);
    }
    
    if (pool->base_addr == MAP_FAILED) {
        return -1;
    }
    
    pool->total_size = cfg->total_size;
    pool->block_count = 1;  /* CMA池作为一个大块 */
    pool->block_size = cfg->total_size;
    
    return 0;
}
​
/**
 * @brief 创建SLAB内存池
 */
static int create_slab_pool(mem_pool_t* pool, const mem_pool_cfg_t* cfg)
{
    size_t aligned_block_size = cfg->block_size;
    
    /* 对齐到8字节 */
    if (aligned_block_size & 7) {
        aligned_block_size = (aligned_block_size + 7) & ~7;
    }
    
    /* 增加头部大小 */
    size_t block_with_header = aligned_block_size + sizeof(mem_block_t);
    
    /* 总内存大小 */
    pool->total_size = block_with_header * cfg->block_count;
    
    /* 分配内存 */
    pool->base_addr = mmap(NULL, pool->total_size,
                            PROT_READ | PROT_WRITE,
                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    
    if (pool->base_addr == MAP_FAILED) {
        return -1;
    }
    
    pool->block_size = aligned_block_size;
    pool->block_count = cfg->block_count;
    
    /* 初始化空闲链表 */
    pool->blocks = (mem_block_t*)pool->base_addr;
    pool->free_list = NULL;
    
    char* base = (char*)pool->base_addr;
    for (size_t i = 0; i < pool->block_count; i++) {
        mem_block_t* block = (mem_block_t*)(base + i * block_with_header);
        block->magic = 0x4D454D42;
        block->size = pool->block_size;
        block->used = false;
        block->next = pool->free_list;
        pool->free_list = block;
    }
    
    return 0;
}
​
int memory_manager_init(const mem_pool_cfg_t* configs, uint32_t pool_count)
{
    if (g_initialized) return 0;
    
    pthread_mutex_lock(&g_pools_lock);
    
    for (uint32_t i = 0; i < pool_count; i++) {
        const mem_pool_cfg_t* cfg = &configs[i];
        
        mem_pool_t* pool = (mem_pool_t*)calloc(1, sizeof(mem_pool_t));
        if (!pool) continue;
        
        strncpy(pool->name, cfg->name, sizeof(pool->name) - 1);
        pool->type = cfg->type;
        pool->flags = cfg->flags;
        pthread_mutex_init(&pool->lock, NULL);
        
        int ret = 0;
        switch (cfg->type) {
            case MEM_POOL_CMA:
                ret = create_cma_pool(pool, cfg);
                break;
            case MEM_POOL_SLAB:
            case MEM_POOL_FRAME:
            case MEM_POOL_AI_TENSOR:
                ret = create_slab_pool(pool, cfg);
                break;
            default:
                ret = -1;
                break;
        }
        
        if (ret == 0) {
            /* 添加到链表 */
            pool->next = g_pools;
            g_pools = pool;
        } else {
            free(pool);
        }
    }
    
    g_initialized = true;
    pthread_mutex_unlock(&g_pools_lock);
    
    return 0;
}
​
void* memory_pool_alloc(const char* pool_name, size_t size)
{
    mem_pool_t* pool = find_pool(pool_name);
    if (!pool) return NULL;
    
    pthread_mutex_lock(&pool->lock);
    
    mem_block_t* block = pool->free_list;
    
    if (!block) {
        pool->stats.fail_count++;
        pthread_mutex_unlock(&pool->lock);
        return NULL;
    }
    
    /* 从空闲链表移除 */
    pool->free_list = block->next;
    
    /* 标记为已使用 */
    block->used = true;
    block->alloc_count++;
    block->alloc_time_us = 0; /* 可设置时间戳 */
    
    /* 更新统计 */
    pool->stats.alloc_count++;
    pool->stats.used_bytes += block->size;
    if (pool->stats.used_bytes > pool->stats.peak_bytes) {
        pool->stats.peak_bytes = pool->stats.used_bytes;
    }
    
    pthread_mutex_unlock(&pool->lock);
    
    /* 返回数据区域指针 */
    return (void*)((char*)block + sizeof(mem_block_t));
}
​
void memory_pool_free(const char* pool_name, void* ptr)
{
    if (!ptr) return;
    
    mem_pool_t* pool = find_pool(pool_name);
    if (!pool) {
        free(ptr);  /* 降级使用标准free */
        return;
    }
    
    /* 获取块头部 */
    mem_block_t* block = (mem_block_t*)((char*)ptr - sizeof(mem_block_t));
    
    /* 验证魔数 */
    if (block->magic != 0x4D454D42) {
        /* 不是池内存,使用标准free */
        free(ptr);
        return;
    }
    
    pthread_mutex_lock(&pool->lock);
    
    /* 标记为空闲 */
    block->used = false;
    
    /* 回收到空闲链表 */
    block->next = pool->free_list;
    pool->free_list = block;
    
    /* 更新统计 */
    pool->stats.free_count++;
    pool->stats.used_bytes -= block->size;
    
    pthread_mutex_unlock(&pool->lock);
}
​
void memory_manager_dump_stats(void)
{
    printf("\n========== Memory Manager Statistics ==========\n");
    
    mem_pool_t* pool = g_pools;
    while (pool) {
        printf("\nPool: %s\n", pool->name);
        printf("  Type: %d\n", pool->type);
        printf("  Total: %zu bytes\n", pool->total_size);
        printf("  Used: %zu bytes (%.1f%%)\n", 
               pool->stats.used_bytes,
               (float)pool->stats.used_bytes / pool->total_size * 100);
        printf("  Peak: %zu bytes\n", pool->stats.peak_bytes);
        printf("  Allocs: %u, Frees: %u, Fails: %u\n",
               pool->stats.alloc_count,
               pool->stats.free_count,
               pool->stats.fail_count);
        
        pool = pool->next;
    }
    printf("===============================================\n");
}

五、日志管理模块

/**
 * @file logger.h
 * @brief 异步日志模块(生产者-消费者模式)
 * @author System Team
 * 
 * @section 设计模式
 * - **生产者-消费者模式**: 异步日志写入
 * - **单例模式**: 全局日志管理器
 * - **装饰器模式**: 支持多种输出目标(文件/控制台/网络)
 * - **策略模式**: 不同级别不同处理策略
 */
​
#ifndef LOGGER_H
#define LOGGER_H
​
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
​
#ifdef __cplusplus
extern "C" {
#endif
​
/*=============================================================================
 * 日志级别定义
 *============================================================================*/
​
typedef enum {
    LOG_LEVEL_FATAL = 0,    ///< 致命错误(会导致程序退出)
    LOG_LEVEL_ERROR = 1,    ///< 错误
    LOG_LEVEL_WARN  = 2,    ///< 警告
    LOG_LEVEL_INFO  = 3,    ///< 信息
    LOG_LEVEL_DEBUG = 4,    ///< 调试
    LOG_LEVEL_TRACE = 5     ///< 追踪(详细)
} log_level_t;
​
/*=============================================================================
 * 日志输出目标
 *============================================================================*/
​
typedef enum {
    LOG_OUTPUT_CONSOLE = 0x01,   ///< 控制台输出
    LOG_OUTPUT_FILE    = 0x02,   ///< 文件输出
    LOG_OUTPUT_SYSLOG  = 0x04,   ///< syslog输出
    LOG_OUTPUT_NETWORK = 0x08,   ///< 网络输出(UDP)
    LOG_OUTPUT_RINGBUF = 0x10    ///< 环形缓冲区(供调试)
} log_output_t;
​
/*=============================================================================
 * 日志配置
 *============================================================================*/
​
/**
 * @brief 日志配置结构体
 */
typedef struct {
    log_level_t level;              ///< 日志级别
    uint32_t output;                ///< 输出目标(位掩码)
    const char* file_path;          ///< 日志文件路径
    size_t file_max_size;           ///< 文件最大大小(字节,默认10MB)
    uint32_t file_max_count;        ///< 最大文件数(轮转)
    const char* network_host;       ///< 网络主机
    uint16_t network_port;          ///< 网络端口
    size_t ringbuf_size;            ///< 环形缓冲区大小
    bool enable_timestamp;          ///< 启用时间戳
    bool enable_thread_id;          ///< 启用线程ID
    bool enable_file_line;          ///< 启用文件行号
    bool async_mode;                ///< 异步模式(默认true)
    size_t async_queue_size;        ///< 异步队列大小(默认4096)
} logger_config_t;
​
/*=============================================================================
 * 日志API
 *============================================================================*/
​
/**
 * @brief 初始化日志系统(单例模式)
 * @param config 日志配置
 * @return 成功返回0
 */
int logger_init(const logger_config_t* config);
​
/**
 * @brief 反初始化日志系统
 */
void logger_deinit(void);
​
/**
 * @brief 设置日志级别
 * @param level 新级别
 */
void logger_set_level(log_level_t level);
​
/**
 * @brief 核心日志函数
 * @param level 日志级别
 * @param file 文件名
 * @param line 行号
 * @param func 函数名
 * @param fmt 格式化字符串
 * @param ... 可变参数
 */
void logger_log(log_level_t level, const char* file, int line, 
                 const char* func, const char* fmt, ...)
    __attribute__((format(printf, 5, 6)));
​
/**
 * @brief 获取日志环形缓冲区数据(用于调试)
 * @param buf 输出缓冲区
 * @param size 缓冲区大小
 * @return 实际写入大小
 */
size_t logger_get_ringbuf(char* buf, size_t size);
​
/**
 * @brief 强制刷新日志缓冲区
 */
void logger_flush(void);
​
/*=============================================================================
 * 便捷宏定义
 *============================================================================*/
​
#define LOG_FATAL(fmt, ...) \
    logger_log(LOG_LEVEL_FATAL, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
​
#define LOG_ERROR(fmt, ...) \
    logger_log(LOG_LEVEL_ERROR, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
​
#define LOG_WARN(fmt, ...) \
    logger_log(LOG_LEVEL_WARN, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
​
#define LOG_INFO(fmt, ...) \
    logger_log(LOG_LEVEL_INFO, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
​
#define LOG_DEBUG(fmt, ...) \
    logger_log(LOG_LEVEL_DEBUG, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
​
#define LOG_TRACE(fmt, ...) \
    logger_log(LOG_LEVEL_TRACE, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
​
/* 条件日志 */
#define LOG_IF(condition, level, fmt, ...) \
    do { if (condition) logger_log(level, __FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__); } while(0)
​
#ifdef __cplusplus
}
#endif
​
#endif /* LOGGER_H */
/**
 * @file logger.c
 * @brief 异步日志实现
 */
​
#include "logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <stdarg.h>
​
/*=============================================================================
 * 日志条目结构体
 *============================================================================*/
​
/**
 * @brief 日志条目
 */
typedef struct log_entry {
    log_level_t level;              ///< 级别
    char file[32];                  ///< 文件名
    int line;                       ///< 行号
    char func[32];                  ///< 函数名
    uint64_t timestamp_us;          ///< 时间戳(微秒)
    uint32_t thread_id;             ///< 线程ID
    char message[512];              ///< 日志消息
    
    struct log_entry* next;
} log_entry_t;
​
/*=============================================================================
 * 日志上下文
 *============================================================================*/
​
typedef struct {
    logger_config_t config;         ///< 配置
    
    /* 异步队列(生产者-消费者) */
    log_entry_t* queue_head;        ///< 队列头
    log_entry_t* queue_tail;        ///< 队列尾
    size_t queue_size;              ///< 当前队列大小
    pthread_mutex_t queue_lock;     ///< 队列锁
    pthread_cond_t queue_cond;      ///< 队列条件变量
    
    /* 日志线程 */
    pthread_t log_thread;
    volatile bool running;
    
    /* 文件输出 */
    FILE* log_file;
    size_t current_file_size;
    
    /* 环形缓冲区(调试用) */
    char* ringbuf;
    size_t ringbuf_write_pos;
    pthread_mutex_t ringbuf_lock;
    
    /* 网络socket */
    int udp_socket;
    
    /* 统计 */
    uint64_t total_logs;
    uint64_t dropped_logs;
    
} logger_context_t;
​
static logger_context_t* g_ctx = NULL;
static const char* level_names[] = {"FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"};
​
/*=============================================================================
 * 辅助函数
 *============================================================================*/
​
/**
 * @brief 获取当前时间字符串
 */
static void format_time(uint64_t timestamp_us, char* buf, size_t size)
{
    time_t sec = timestamp_us / 1000000;
    struct tm tm;
    localtime_r(&sec, &tm);
    
    uint32_t us = timestamp_us % 1000000;
    snprintf(buf, size, "%04d-%02d-%02d %02d:%02d:%02d.%06u",
             tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
             tm.tm_hour, tm.tm_min, tm.tm_sec, us);
}
​
/**
 * @brief 日志文件轮转
 */
static void rotate_log_file(void)
{
    if (!g_ctx->log_file) return;
    
    fclose(g_ctx->log_file);
    
    /* 重命名旧文件 */
    char old_path[512];
    snprintf(old_path, sizeof(old_path), "%s.1", g_ctx->config.file_path);
    rename(g_ctx->config.file_path, old_path);
    
    /* 打开新文件 */
    g_ctx->log_file = fopen(g_ctx->config.file_path, "a");
    g_ctx->current_file_size = 0;
}
​
/**
 * @brief 写入日志到文件
 */
static void write_to_file(const log_entry_t* entry)
{
    if (!g_ctx->log_file) return;
    
    char time_str[64];
    format_time(entry->timestamp_us, time_str, sizeof(time_str));
    
    int written = fprintf(g_ctx->log_file, "[%s] [%s] [%s:%d] %s\n",
                           time_str,
                           level_names[entry->level],
                           entry->file, entry->line,
                           entry->message);
    
    if (written > 0) {
        g_ctx->current_file_size += written;
    }
    
    fflush(g_ctx->log_file);
    
    /* 检查是否需要轮转 */
    if (g_ctx->current_file_size >= g_ctx->config.file_max_size) {
        rotate_log_file();
    }
}
​
/**
 * @brief 写入日志到控制台
 */
static void write_to_console(const log_entry_t* entry)
{
    char time_str[64];
    format_time(entry->timestamp_us, time_str, sizeof(time_str));
    
    /* 不同级别使用不同颜色(ANSI) */
    const char* color = "";
    const char* reset = "";
    
    if (isatty(STDERR_FILENO)) {
        switch (entry->level) {
            case LOG_LEVEL_FATAL:
            case LOG_LEVEL_ERROR:
                color = "\033[31m"; break;  /* 红色 */
            case LOG_LEVEL_WARN:
                color = "\033[33m"; break;  /* 黄色 */
            case LOG_LEVEL_INFO:
                color = "\033[32m"; break;  /* 绿色 */
            case LOG_LEVEL_DEBUG:
                color = "\033[36m"; break;  /* 青色 */
            default:
                color = "\033[0m"; break;
        }
        reset = "\033[0m";
    }
    
    fprintf(stderr, "%s[%s] [%s] [%s:%d] %s%s\n",
            color, time_str, level_names[entry->level],
            entry->file, entry->line, entry->message, reset);
}
​
/**
 * @brief 写入日志到环形缓冲区(调试)
 */
static void write_to_ringbuf(const log_entry_t* entry)
{
    if (!g_ctx->ringbuf) return;
    
    pthread_mutex_lock(&g_ctx->ringbuf_lock);
    
    char time_str[64];
    format_time(entry->timestamp_us, time_str, sizeof(time_str));
    
    int written = snprintf(g_ctx->ringbuf + g_ctx->ringbuf_write_pos,
                            g_ctx->config.ringbuf_size - g_ctx->ringbuf_write_pos,
                            "[%s] [%s] %s\n",
                            time_str, level_names[entry->level], entry->message);
    
    if (written > 0) {
        g_ctx->ringbuf_write_pos += written;
        if (g_ctx->ringbuf_write_pos >= g_ctx->config.ringbuf_size) {
            g_ctx->ringbuf_write_pos = 0;  /* 循环覆盖 */
        }
    }
    
    pthread_mutex_unlock(&g_ctx->ringbuf_lock);
}
​
/**
 * @brief 日志处理函数(消费者)
 */
static void* log_thread_func(void* arg)
{
    (void)arg;
    
    while (g_ctx->running) {
        pthread_mutex_lock(&g_ctx->queue_lock);
        
        /* 等待日志到来 */
        while (g_ctx->running && !g_ctx->queue_head) {
            struct timespec ts;
            clock_gettime(CLOCK_REALTIME, &ts);
            ts.tv_sec += 1;
            pthread_cond_timedwait(&g_ctx->queue_cond, &g_ctx->queue_lock, &ts);
        }
        
        if (!g_ctx->running && !g_ctx->queue_head) {
            pthread_mutex_unlock(&g_ctx->queue_lock);
            break;
        }
        
        /* 取出队列头 */
        log_entry_t* entry = g_ctx->queue_head;
        g_ctx->queue_head = entry->next;
        if (!g_ctx->queue_head) {
            g_ctx->queue_tail = NULL;
        }
        g_ctx->queue_size--;
        
        pthread_mutex_unlock(&g_ctx->queue_lock);
        
        /* 写入各个输出目标(装饰器模式) */
        if (g_ctx->config.output & LOG_OUTPUT_FILE) {
            write_to_file(entry);
        }
        
        if (g_ctx->config.output & LOG_OUTPUT_CONSOLE) {
            write_to_console(entry);
        }
        
        if (g_ctx->config.output & LOG_OUTPUT_RINGBUF) {
            write_to_ringbuf(entry);
        }
        
        /* 释放条目 */
        free(entry);
        g_ctx->total_logs++;
    }
    
    return NULL;
}
​
/*=============================================================================
 * 公共API实现
 *============================================================================*/
​
int logger_init(const logger_config_t* config)
{
    if (g_ctx) return 0;
    
    g_ctx = (logger_context_t*)calloc(1, sizeof(logger_context_t));
    if (!g_ctx) return -1;
    
    memcpy(&g_ctx->config, config, sizeof(logger_config_t));
    
    /* 设置默认值 */
    if (g_ctx->config.file_max_size == 0) {
        g_ctx->config.file_max_size = 10 * 1024 * 1024;  /* 10MB */
    }
    if (g_ctx->config.async_queue_size == 0) {
        g_ctx->config.async_queue_size = 4096;
    }
    
    /* 初始化锁 */
    pthread_mutex_init(&g_ctx->queue_lock, NULL);
    pthread_cond_init(&g_ctx->queue_cond, NULL);
    pthread_mutex_init(&g_ctx->ringbuf_lock, NULL);
    
    /* 打开日志文件 */
    if ((config->output & LOG_OUTPUT_FILE) && config->file_path) {
        g_ctx->log_file = fopen(config->file_path, "a");
        if (g_ctx->log_file) {
            /* 获取当前文件大小 */
            fseek(g_ctx->log_file, 0, SEEK_END);
            g_ctx->current_file_size = ftell(g_ctx->log_file);
        }
    }
    
    /* 创建环形缓冲区 */
    if (config->output & LOG_OUTPUT_RINGBUF && config->ringbuf_size > 0) {
        g_ctx->ringbuf = (char*)malloc(config->ringbuf_size);
        if (g_ctx->ringbuf) {
            memset(g_ctx->ringbuf, 0, config->ringbuf_size);
        }
    }
    
    /* 启动日志线程 */
    g_ctx->running = true;
    pthread_create(&g_ctx->log_thread, NULL, log_thread_func, NULL);
    
    LOG_INFO("Logger initialized, level=%s", level_names[config->level]);
    
    return 0;
}
​
void logger_deinit(void)
{
    if (!g_ctx) return;
    
    LOG_INFO("Logger shutting down...");
    
    /* 停止日志线程 */
    g_ctx->running = false;
    pthread_cond_signal(&g_ctx->queue_cond);
    pthread_join(g_ctx->log_thread, NULL);
    
    /* 关闭文件 */
    if (g_ctx->log_file) {
        fclose(g_ctx->log_file);
    }
    
    /* 释放资源 */
    if (g_ctx->ringbuf) {
        free(g_ctx->ringbuf);
    }
    
    pthread_mutex_destroy(&g_ctx->queue_lock);
    pthread_cond_destroy(&g_ctx->queue_cond);
    pthread_mutex_destroy(&g_ctx->ringbuf_lock);
    
    free(g_ctx);
    g_ctx = NULL;
}
​
void logger_log(log_level_t level, const char* file, int line,
                 const char* func, const char* fmt, ...)
{
    if (!g_ctx || level > g_ctx->config.level) return;
    
    /* 分配日志条目 */
    log_entry_t* entry = (log_entry_t*)malloc(sizeof(log_entry_t));
    if (!entry) return;
    
    memset(entry, 0, sizeof(log_entry_t));
    
    /* 填充条目 */
    entry->level = level;
    entry->line = line;
    
    /* 提取文件名(去掉路径) */
    const char* filename = strrchr(file, '/');
    if (filename) filename++; else filename = file;
    strncpy(entry->file, filename, sizeof(entry->file) - 1);
    
    strncpy(entry->func, func, sizeof(entry->func) - 1);
    
    /* 时间戳 */
    struct timeval tv;
    gettimeofday(&tv, NULL);
    entry->timestamp_us = (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
    
    /* 线程ID */
    entry->thread_id = (uint32_t)pthread_self();
    
    /* 格式化消息 */
    va_list args;
    va_start(args, fmt);
    vsnprintf(entry->message, sizeof(entry->message), fmt, args);
    va_end(args);
    
    if (g_ctx->config.async_mode) {
        /* 异步模式: 入队 */
        pthread_mutex_lock(&g_ctx->queue_lock);
        
        if (g_ctx->queue_size >= g_ctx->config.async_queue_size) {
            /* 队列满,丢弃最旧的日志 */
            log_entry_t* old = g_ctx->queue_head;
            if (old) {
                g_ctx->queue_head = old->next;
                free(old);
                g_ctx->queue_size--;
                g_ctx->dropped_logs++;
            }
        }
        
        entry->next = NULL;
        if (g_ctx->queue_tail) {
            g_ctx->queue_tail->next = entry;
        } else {
            g_ctx->queue_head = entry;
        }
        g_ctx->queue_tail = entry;
        g_ctx->queue_size++;
        
        pthread_cond_signal(&g_ctx->queue_cond);
        pthread_mutex_unlock(&g_ctx->queue_lock);
    } else {
        /* 同步模式: 直接处理 */
        if (g_ctx->config.output & LOG_OUTPUT_FILE) write_to_file(entry);
        if (g_ctx->config.output & LOG_OUTPUT_CONSOLE) write_to_console(entry);
        if (g_ctx->config.output & LOG_OUTPUT_RINGBUF) write_to_ringbuf(entry);
        free(entry);
    }
}
​
size_t logger_get_ringbuf(char* buf, size_t size)
{
    if (!g_ctx || !g_ctx->ringbuf) return 0;
    
    pthread_mutex_lock(&g_ctx->ringbuf_lock);
    
    size_t copy_size = size - 1;
    if (copy_size > g_ctx->config.ringbuf_size) {
        copy_size = g_ctx->config.ringbuf_size;
    }
    
    /* 从环形缓冲区读取 */
    size_t start = g_ctx->ringbuf_write_pos;
    if (start + copy_size > g_ctx->config.ringbuf_size) {
        size_t first_part = g_ctx->config.ringbuf_size - start;
        memcpy(buf, g_ctx->ringbuf + start, first_part);
        memcpy(buf + first_part, g_ctx->ringbuf, copy_size - first_part);
    } else {
        memcpy(buf, g_ctx->ringbuf + start, copy_size);
    }
    
    buf[copy_size] = '\0';
    
    pthread_mutex_unlock(&g_ctx->ringbuf_lock);
    
    return copy_size;
}
​
void logger_flush(void)
{
    if (!g_ctx) return;
    
    /* 等待队列清空 */
    while (g_ctx->queue_size > 0) {
        usleep(1000);
    }
    
    if (g_ctx->log_file) {
        fflush(g_ctx->log_file);
    }
}
​
void logger_set_level(log_level_t level)
{
    if (g_ctx) {
        LOG_INFO("Log level changed from %s to %s", 
                 level_names[g_ctx->config.level], level_names[level]);
        g_ctx->config.level = level;
    }
}

总结

  1. 双架构IPC模块 (ipc_bus.h/c)

    • 无锁环形队列

    • 共享内存通信

    • 同步/异步命令模式

    • ARM与ARM-None跨核通信

  2. ISP调优模块 (isp_tuning.h/c)

    • 黑电平/镜头阴影/色彩校正/Gamma/去噪/锐化

    • 策略模式场景自适应(室内/室外/夜景)

    • 参数平滑过渡

    • 文件IO与CRC校验

  3. AI流水线模块 (ai_pipeline.h/c)

    • 责任链模式(预处理→推理→后处理→跟踪)

    • 对象池模式(任务复用)

    • YOLO检测 + IOU跟踪

    • NMS后处理

  4. 3A策略模式 (isp_3a.h)

    • AE PID控制/快速策略

    • AWB灰度世界/完美反射

    • AF爬山算法+状态机

  5. 事件循环模块 (event_loop.h/c)

    • 观察者模式事件分发

    • Reactor模式epoll封装

    • 优先级队列

    • 定时器管理

  6. 内存管理模块 (memory_manager.h/c)

    • CMA连续内存池

    • SLAB对象池

    • 内存统计与调试

  7. 日志管理模块 (logger.h/c)

    • 异步生产者-消费者模式

    • 多输出目标(文件/控制台/环形缓冲区)

    • 日志轮转

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐