Commit f1277c8d authored by tgs's avatar tgs

Upload uccp调研.txt

parent dd6653e1
1. 项目本质
UCCP 基于 Intel OWT (Open WebRTC Toolkit) 改造,是一个分布式实时媒体处理平台。
- 主线 Apache 2.0 license + OWT 的 SFU+MCU 混合架构
- Node.js 控制层 + C++ 媒体层 + AI 插件层
- 原本服务于"体育赛事 AI 增强 + 云制作(UCCP = Unified Cloud Content Production)+ PUGC 直播"
2. 顶层目录结构
uccp_server/
├── source/
│ ├── agent/ ← Node.js 业务进程池(10+ 种 agent)
│ ├── core/ ← C++ 媒体处理引擎(owt_base)
│ ├── management_api/ ← REST API (3000 端口)
│ ├── management_console/ ← Web 控制台 (3300)
│ ├── portal/ ← Socket.IO 信令 (8080)
│ ├── cluster_manager/ ← 集群调度
│ ├── delegation/ ← PUGC/UCCP 任务委托
│ ├── sip_portal/ ← SIP 网关
│ ├── process_monitor/ ← 健康检查
│ ├── rabbitMQManagement/ ← MQ 管理
│ ├── data_access/ ← Mongo 访问层
│ └── common/ ← 公共工具
├── build/libdeps/ ← FFmpeg/OpenCV/CUDA 等 3rd-party .so
├── scripts/ doc/ cert/ docker/ services/ test/
3. 技术栈
┌───────────┬────────────────────────────────────────────────────────────────────────────┐
│ 层 │ 技术 │
├───────────┼────────────────────────────────────────────────────────────────────────────┤
│ 业务/控制 │ Node.js + Express + Socket.IO + amqplib + mongoose + log4js │
├───────────┼────────────────────────────────────────────────────────────────────────────┤
│ 媒体核心 │ C++ + OWT + FFmpeg + NVENC/NVDEC + OpenCV+CUDA │
├───────────┼────────────────────────────────────────────────────────────────────────────┤
│ 通信 │ RabbitMQ (服务间 RPC) + ZeroMQ (高性能 IPC) + Socket.IO (信令) + HTTP REST │
├───────────┼────────────────────────────────────────────────────────────────────────────┤
│ 存储 │ MongoDB(房间/服务/用户)+ RabbitMQ(消息) │
├───────────┼────────────────────────────────────────────────────────────────────────────┤
│ AI │ dlopen 加载的 plugin .so + Triton/Fssrv 等外部推理服务 │
└───────────┴────────────────────────────────────────────────────────────────────────────┘
4. 部署形态
多进程分布式:一个完整 uccp 部署有 10+ 类独立进程,全靠 RabbitMQ 串起来:
┌────────────────────┬─────────────────────────────────┐
│ 进程 │ 端口/角色 │
├────────────────────┼─────────────────────────────────┤
│ management_api │ 3000 REST │
├────────────────────┼─────────────────────────────────┤
│ management_console │ 3300 Web UI │
├────────────────────┼─────────────────────────────────┤
│ portal │ 8080 Socket.IO 信令 │
├────────────────────┼─────────────────────────────────┤
│ cluster_manager │ 调度,监听 MQ │
├────────────────────┼─────────────────────────────────┤
│ conference agent │ 会议房间控制 │
├────────────────────┼─────────────────────────────────┤
│ video agent │ 视频混流/转码 │
├────────────────────┼─────────────────────────────────┤
│ audio agent │ 音频混流 │
├────────────────────┼─────────────────────────────────┤
│ webrtc agent │ WebRTC 接入 │
├────────────────────┼─────────────────────────────────┤
│ streaming agent │ 直播拉流/推流(篮球点亮走这条) │
├────────────────────┼─────────────────────────────────┤
│ recording agent │ 录制 │
├────────────────────┼─────────────────────────────────┤
│ sip agent │ SIP 网关 │
├────────────────────┼─────────────────────────────────┤
│ process_monitor │ 看门狗 │
└────────────────────┴─────────────────────────────────┘
5. 功能模块清单(这才是关键!篮球点亮只是冰山一角)
按类别分:
核心媒体处理
- 视频混流(VideoMixer)—— 多路画面合成
- 视频转码(VideoTranscoder)—— 编码格式转换
- 音频混流(AudioMixer)
- WebRTC 接入(SFU)
- 录制服务
- SIP 网关
AI 增强(都在 source/core/owt_base/AI*.cpp)
- ?? 篮球轨迹点亮(AILightBasketballStar.cpp)← 我们关心的就这一个
- ?.足球轨迹点亮.(AILighFootballStar.cpp) ← .
- ??.冰.轨迹点亮(AILightFHockeyStar.cpp)
- ?? OCR 比分识别(AILightStarOcrInference.cpp)
- ?? 广告植入(AIadvertsInference.cpp)
- ?? 通用 AI 推理框架(AIInference.h)
云制作业务
- PUGC 直播任务(pugcLiveTaskController.js)
- PUGC VOD 任务(pugcVodTaskController.js)
- UCCP 云制作任务(uccpTaskController.js)
- UCCP 混流(uccp_mix/)
- 数字人控制(digitalHumanController.js)
- 虚拟场景(planeController.js)
- 语料库(corpusController.js)
6. 大架构图
┌─────────────────────────────────────────────────────────────────┐
│ 用户接入层 │
│ Web Console │ REST API │ Socket.IO Portal │ SIP 客户端 │
│ :3300 │ :3000 │ :8080 │ │
└───────┬───────────────┬──────────────┬─────────────┬────────────┘
│ │ │ │
└───────────────┴──────┬───────┴─────────────┘
│ HTTP/WS/SIP
┌─────────────────────────────────────────────────────────────────┐
│ 控制层(Node.js) │
│ cluster_manager ?──? delegation ?──? process_monitor │
│ │ │ │ │
│ └──────────────────┴──────────────────┘ │
│ │ │
└────────────────────────────────┼────────────────────────────────┘
│ RabbitMQ (RPC + 事件)
┌─────────────────────────────────────────────────────────────────┐
│ 业务 Agent 进程池(Node.js,可水平扩展) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────┐│
│ │conference│ │ video │ │ audio │ │ webrtc │ │sip ││
│ │ agent │ │ agent │ │ agent │ │ agent │ │agent ││
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └───────┘│
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │analytics │ │streaming │ │recording │ │ quic │ ... │
│ │ agent │ │ agent ?──┼ 篮球点亮 │ │ agent │ │
│ └──────────┘ └──────────┘ │ 走这里 │ └──────────┘ │
│ └──────────┘ │
└────────────────────────────────┬────────────────────────────────┘
│ N-API 加载 C++ addon
┌─────────────────────────────────────────────────────────────────┐
│ 媒体处理层(C++,OWT 框架) │
│ │
│ 输入端 核心处理 输出端 │
│ ┌─────────┐ ┌──────────────┐ ┌─────────┐ │
│ │LiveStrm │ ────? │ FFNvFrame │ ────? │FFNvFrame│ │
│ │ In │ 解封装 │ Decoder │ GPU │Encoder │ │
│ │(FFmpeg) │ │ (NVDEC) │ NV12 │(NVENC) │ │
│ └─────────┘ └──────┬───────┘ └────┬────┘ │
│ │ │ │
│ ▼ AI 介入 ▼ │
│ ┌──────────────┐ ┌──────────┐ │
│ │FrameProcesser│ ────? │SeiGenera-│ │
│ │ │ AI JSON│ tor │ │
│ │ ┌────────┐ │ 附帧上 │ SEI NALU│ │
│ │ │AI*Star │ │ └──────────┘ │
│ │ │(同步) │ │ │
│ │ └───┬────┘ │ │
│ └──────┼───────┘ │
│ │ dlopen │
└──────────────────────────────┼───────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ AI Plugin 层(.so 动态库,按业务加载) │
│ libpluginSDKBasketballTraj.so libpluginSDKFootballTraj.so │
│ libpluginSDKHockeyTraj.so libpluginSDKOCR.so │
│ │ │ │
│ ▼ gRPC ▼ gRPC │
└─────────┼──────────────────────────┼────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ 外部推理服务:Triton (2403/2401/2402/2064) + Fssrv + │
│ ball_detect gRPC :6099 (migu_basketball_yolo) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 基础设施 │
│ RabbitMQ ?── 服务间 RPC MongoDB ── 房间/会话/用户状态 │
└─────────────────────────────────────────────────────────────────┘
● 下面是基于代码考古整理的 uccp 流处理完整分析。
1. 入口和会话管理
┌──────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ 项 │ 位置 │
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 主进程 │ source/agent/index.js(Node.js 守护进程) │
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ C++ 拉流包装 │ source/agent/addons/avstreamLib/AVStreamInWrap.cc:309 ?? new owt_base::LiveStreamIn(...) │
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 会话生命周期管理 │ VideoFrameTranscoderImpl (VideoFrameTranscoderImpl.h:51),setInput() → addOutput() → ... → removeOutput() → unsetInput() │
├──────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 配置 │ source/agent/video/agent.toml + JS 层 Options 透传到 C++ │
└──────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
2. 拉流 & 解码
- 拉流:LiveStreamIn.cpp:1143 avformat_open_input();LiveStreamIn.cpp:2639 av_read_frame() ?? 就是 FFmpeg
- 拉流线程:LiveStreamIn.cpp:1029 boost::thread(&LiveStreamIn::receiveLoop, this)
- 解码器:两个并存
- FFNvFrameDecoder ?? NVDEC(走 FFmpeg h264_cuvid + AV_PIX_FMT_CUDA),现役
- NvcuvidFrameDecoder ?? 直接走 NVIDIA nvcuvid SDK,已被 #if 0 注释掉
- 切换点:VideoFrameDecoderAdapter.cpp:65-76
- 输出:NvFrame,内含 cv::cuda::GpuMat data,NV12 GPU 内存
3. AI 推理串接
- 同步调用链:FFNvFrameDecoder::onFrame → FrameProcesser::onFrame → AILightBasketballStar::process(没有独立 AI 线程)
- AI 输入:boost::shared_ptr<NvLightStarFrame>,内含 NvVideoFrame->data(GpuMat)
- Plugin 调用序列:
- AILightBasketballStar.cpp:38-39 dlopen("./lib/libpluginSDKBasketballTraj.so")
- AILightBasketballStar.cpp:45 dlsym("createMiguPluginClientInstance")
- AILightBasketballStar.cpp:381 client->process(ai_input, processOutput)
- AI 结果传递:NvFrame::addAIMetaData(json) 把 JSON 挂在帧对象上,跟着帧走到编码器
4. 编码 & SEI 注入
- 编码器:FFNvFrameEncoder(FFNvFrameEncoder.h:41),输入 NvFrame(GPU NV12)
- AI 元数据取出:FFNvFrameEncoder.cpp:1018 inFrame->getAIMetaData(aiMetaData)
- SEI 注入点:FFNvFrameEncoder.cpp:1071-1079,把 JSON 拼到 outFrame.additionalInfo.video.seiData
- SEI UUID:"mg-sei-user-data" (SeiGenerator.cpp:23)
- JSON 包装:AILightBasketballStar.cpp:407 {"name":"HighLightStar","parameters":<plugin_out>,"frameIndex":N}
5. 输出推流
- LiveStreamOut 继承 AVStreamOut,avformat_write_header() / av_interleaved_write_frame()
- 协议:RTMP / UDP / SRT
- 延时参数:AVStreamOutWrap.cc:331 requireDelayPlay / delayPlayTime,在 MediaFrameQueue 里生效
6. 线程模型(每会话)
┌────────────────────────────┬───────────────────────┐
│ 线程 │ 职责 │
├────────────────────────────┼───────────────────────┤
│ LiveStreamIn::m_thread │ 网络 read + 解封装 │
├────────────────────────────┼───────────────────────┤
│ FFNvFrameDecoder 内部 │ NVDEC 解码 │
├────────────────────────────┼───────────────────────┤
│ (无独立 AI 线程) │ AI 在解码线程里同步跑 │
├────────────────────────────┼───────────────────────┤
│ FFNvFrameEncoder::m_thread │ GPU 编码 + SEI │
├────────────────────────────┼───────────────────────┤
│ LiveStreamOut 内部 │ 网络 write │
└────────────────────────────┴───────────────────────┘
同步原语:boost::mutex + boost::condition_variable;队列:FramePacketBuffer / JitterBuffer(满了丢帧)。
7. 流处理流程图
┌────────────────────────────────────┐
│ Node.js agent (index.js) │
│ 透传 Options → C++ │
└──────────────┬─────────────────────┘
│ new LiveStreamIn
?
┌──────────────────────────────────────────────────────────┐
│ LiveStreamIn (uccp_server/.../LiveStreamIn.cpp) │
│ │
│ avformat_open_input [:1143] ← RTMP/UDP/SRT/RTSP │
│ │ │
│ ? │
│ av_read_frame [:2639] ← AVPacket │
│ │ │
│ ? │
│ deliverVideoFrame [:3352] ← FramePacketBuffer │
│ │ │
│ ? │
│ deliverFrame(onFrame) [:3437] ← FrameDestination │
└────────┼─────────────────────────────────────────────────┘
?
┌──────────────────────────────────────────────────────────┐
│ VideoFrameDecoderAdapter::onFrame [:135] │
│ │ │
│ ? │
│ FFNvFrameDecoder ← h264_cuvid + AV_PIX_FMT_CUDA │
│ (NvcuvidFrameDecoder 已被 #if 0 注释掉) │
│ │ │
│ ? GPU 内存 NV12 │
│ NvFrame { cv::cuda::GpuMat data; list<string> AIMeta; }│
└────────┼─────────────────────────────────────────────────┘
│ FrameDestination::onFrame(NvFrame)
?
┌──────────────────────────────────────────────────────────┐
│ FrameProcesser::onFrame │
│ │ │
│ ? SendNvFrame │
│ AILightBasketballStar::process [:214] │
│ │ │
│ │ ai_input.image.addr[0] = frame->data.data │ ← GPU 直传
│ │ ai_input.image.pitch[0]= frame->data.step │
│ │ │
│ ? │
│ dlopen libpluginSDKBasketballTraj.so │
│ client->process(ai_input, output) [:381] │
│ │ │
│ ? JSON │
│ NvFrame::addAIMetaData(json) ← 元数据跟着帧走 │
└────────┼─────────────────────────────────────────────────┘
?
┌──────────────────────────────────────────────────────────┐
│ FFNvFrameEncoder::onFrame [:655] │
│ │ │
│ ? NvFrame → AVFrame (CUDA frame) │
│ Encode (h264_nvenc) │
│ │ │
│ ? AVPacket │
│ getAIMetaData [:1018] ← 取出帧上挂的 JSON │
│ │ │
│ ? │
│ SeiGenerator::generateSEI (UUID="mg-sei-user-data") │
│ │ │
│ ? │
│ outFrame.additionalInfo.video.seiData [:1079] │
│ │ │
│ ? │
│ deliverFrame [:1099] │
└────────┼─────────────────────────────────────────────────┘
?
┌──────────────────────────────────────────────────────────┐
│ LiveStreamOut / AVStreamOut │
│ │
│ av_interleaved_write_frame() → RTMP/UDP/SRT │
│ │
│ delayPlayTime / requireDelayPlay 在 MediaFrameQueue 生效│
└──────────────────────────────────────────────────────────┘
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment