commit 1300b62958483013e286b6e09518b10683ca0970 Author: kingecg Date: Thu Sep 25 21:07:30 2025 +0800 first doc diff --git a/doc/ARCHITECTURE.md b/doc/ARCHITECTURE.md new file mode 100644 index 0000000..190c115 --- /dev/null +++ b/doc/ARCHITECTURE.md @@ -0,0 +1,82 @@ +# ZLMediaKit 架构文档 + +## 1. 项目概述 +ZLMediaKit 是一个高性能流媒体服务器框架,支持 RTMP/RTSP/WebRTC/SRT 等多种协议,采用 C++11 编写,具有跨平台、高并发、低延迟等特点。 + +## 2. 核心模块架构 + +### 2.1 基础设施层 +- **`3rdpart/ZLToolKit`** + - 网络库基础:提供 [Socket](3rdpart/ZLToolKit/src/network/Socket.h)、[EventPoller](3rdpart/ZLToolKit/src/poller/EventPoller.h) 等核心组件 + - 内存管理:[ObjectPool](3rdpart/ZLToolKit/src/util/ObjectPool.h) 对象池实现 + +- **`src/Common`** + - 配置系统:[config.cpp](src/Common/config.cpp) 实现 `MediaServer` 配置项管理 + - 工具集:[Util.cpp](src/Common/Util.cpp) 提供时间处理、Base64 编码等通用功能 + - 日志系统:[Logger.cpp](src/Common/Logger.cpp) 实现多级日志输出 + +### 2.2 协议处理层 + +#### RTMP 协议栈 +- **`src/Rtmp`** + - 协议解析:[RtmpProtocol.cpp](src/Rtmp/RtmpProtocol.cpp) 实现 AMF0 解析 + - 会话管理:[RtmpSession.cpp](src/Rtmp/RtmpSession.cpp) 处理推流/拉流会话 + - 转发服务:[RtmpMuxer.cpp](src/Rtmp/RtmpMuxer.cpp) 实现流媒体转发 + +#### RTSP 协议栈 +- **`src/Rtsp`** + - 信令处理:[RtspSession.cpp](src/Rtsp/RtspSession.cpp) 实现 SETUP/PLAY/TEARDOWN 等方法 + - 传输层:[RtpProcess.cpp](src/Rtsp/RtpProcess.cpp) 处理 RTP/RTCP 传输 + +#### WebRTC 协议栈 +- **`webrtc` 目录** + - 信令交互:[WebRtcSignalingSession.cpp](webrtc/WebRtcSignalingSession.cpp) + - 媒体传输:[DtlsTransport.cpp](webrtc/DtlsTransport.cpp) 和 [SrtpSession.cpp](webrtc/SrtpSession.cpp) + - ICE 处理:[IceTransport.cpp](webrtc/IceTransport.cpp) + +#### SRT 协议支持 +- **`srt` 目录** + - 核心传输:[SrtTransport.cpp](srt/SrtTransport.cpp) + - 会话管理:[SrtSession.cpp](srt/SrtSession.cpp) + - 重传机制:[NackContext.cpp](srt/NackContext.cpp) + +### 2.3 媒体处理层 + +#### 编解码模块 +- **`ext-codec` 目录** + - 视频编解码:[H264.cpp](ext-codec/H264.cpp) 和 [H265.cpp](ext-codec/H265.cpp) + - 音频编解码:[AAC.cpp](ext-codec/AAC.cpp) 和 [G711.cpp](ext-codec/G711.cpp) + - 封装处理:[H264Rtmp.cpp](ext-codec/H264Rtmp.cpp) 实现 RTMP 封装 + +- **`src/Codec` 目录** + - 软件编解码:[SoftDecoder.cpp](src/Codec/SoftDecoder.cpp) + - 硬件加速:[Hardware.cpp](src/Codec/Hardware.cpp) + +#### 流媒体处理 +- **`src/Player`** + - 播放器核心:[PlayerBase.cpp](src/Player/PlayerBase.cpp) + - 协议适配:[RtspPlayer.cpp](src/Player/RtspPlayer.cpp) + +- **`src/Pusher`** + - 推流器实现:[RtmpPusher.cpp](src/Pusher/RtmpPusher.cpp) + - 协议转换:[FlvMuxer.cpp](src/Pusher/FlvMuxer.cpp) + +### 2.4 服务管理层 + +- **`server` 目录** + - 主服务入口:[main.cpp](server/main.cpp) + - Web API:[WebApi.cpp](server/WebApi.cpp) 实现 RESTful 接口 + - 事件回调:[WebHook.cpp](server/WebHook.cpp) 处理业务事件 + +- **`api` 目录** + - 接口定义:[include/api-api.h](api/include/api-api.h) + - 测试用例:[tests/test_httpApi.cpp](api/tests/test_httpApi.cpp) + +## 3. 扩展能力 +- **`player` 目录**:SDL 音频输出 ([SDLAudioDevice.cpp](player/SDLAudioDevice.cpp)) 和 YUV 渲染 +- **`FFmpegSource.cpp`**:基于 FFmpeg 的媒体源处理 +- **`docker` 支持**:通过 [build_docker_images.sh](docker/build_docker_images.sh) 构建容器镜像 + +## 4. 测试体系 +- **`tests` 目录**:协议测试 ([test_rtmp.cpp](tests/test_rtmp.cpp)) 和性能测试 ([test_bench.cpp](tests/test_bench.cpp)) +- **`postman` 集合**:[ZLMediaKit.postman_collection.json](postman/ZLMediaKit.postman_collection.json) 提供 API 测试用例 \ No newline at end of file diff --git a/doc/FRAME_DESIGN.md b/doc/FRAME_DESIGN.md new file mode 100644 index 0000000..a55970b --- /dev/null +++ b/doc/FRAME_DESIGN.md @@ -0,0 +1,162 @@ +# Frame 模块设计与实现 + +## 1. 模块概述 +`Frame.h`/`Frame.cpp` 是 ZLMediaKit 中处理媒体帧的核心模块,提供统一的帧数据抽象、时间戳管理、编解码信息转换和帧合并功能。该模块通过面向对象设计实现协议无关的媒体帧处理,支撑 RTMP/RTSP/WebRTC 等多种协议的媒体传输。 + +## 2. 核心数据结构 + +### 2.1 媒体类型定义 + +#### 2.1.1 轨道类型([TrackType](src/Extension/Frame.h#L20-L28)) +```cpp +enum { + TrackInvalid = -1, + TrackVideo = 0, // 视频轨道 + TrackAudio, // 音频轨道 + TrackTitle, // 字幕轨道 + TrackApplication // 应用数据轨道 +}; +``` +- **功能**:区分媒体数据的逻辑类型 +- **使用场景**:流媒体会话建立时标识数据类型 + +#### 2.1.2 编解码标识([CodecId](src/Extension/Frame.h#L54-L78)) +```cpp +#define CODEC_MAP(XX) \ + XX(CodecH264, TrackVideo, 0, "H264", PSI_STREAM_H264, MOV_OBJECT_H264) \ + // ... 其他编解码定义 + +typedef enum { + CodecInvalid = -1, + CODEC_MAP(XX) + CodecMax +} CodecId; +``` +- **特点**: + - 通过宏定义统一管理编解码参数 + - 包含协议标识(mpeg_id)、容器标识(mp4_id)等扩展信息 +- **关键函数**: + - `[getTrackType(CodecId)](src/Extension/Frame.cpp#L15-L23)`:获取轨道类型 + - `[getMovIdByCodec()](src/Extension/Frame.cpp#L35-L43)`:获取 MP4 容器标识 + - `[getMpegIdByCodec()](src/Extension/Frame.cpp#L70-L78)`:获取 MPEG-TS 标识 + +### 2.2 帧抽象基类([Frame](src/Extension/Frame.h#L137-L177)) +```cpp +class Frame : public toolkit::Buffer, public CodecInfo { + virtual uint64_t dts() const = 0; // 解码时间戳 + virtual uint64_t pts() const; // 显示时间戳 + virtual size_t prefixSize() const = 0; // 帧前缀长度 + virtual bool keyFrame() const = 0; // 是否关键帧 + virtual bool configFrame() const = 0; // 是否配置帧(sps/pps) + virtual bool cacheAble() const; // 是否可缓存 +}; +``` +- **设计要点**: + - 继承自 `Buffer` 实现内存管理 + - 通过 `CodecInfo` 关联编解码信息 + - 所有方法均为虚函数支持多态操作 +- **典型派生类**: + +| 类名 | 作用 | 实现文件 | +|------|------|----------| +| `[FrameImp](src/Extension/Frame.h#L191-L220)` | 基础帧实现 | Frame.h | +| `[FrameFromPtr](src/Extension/Frame.h#L233-L263)` | 指针包装帧(不可缓存) | Frame.h | +| `[FrameCacheAble](src/Extension/Frame.h#L336-L367)` | 可缓存帧包装 | Frame.h | +| `[FrameStamp](src/Extension/Frame.h#L381-L407)` | 时间戳覆盖实现 | Frame.h | + +## 3. 核心处理工具 + +### 3.1 帧合并器([FrameMerger](src/Extension/Frame.cpp#L235-L338)) +```cpp +class FrameMerger { + enum { none, h264_prefix, mp4_nal_size }; + bool inputFrame(const Frame::Ptr &frame, onOutput cb, BufferLikeString *buffer = nullptr); + void flush(); +}; +``` +- **核心功能**: + - 合并时间戳相同的帧(如 AAC 复合帧) + - 支持三种输出模式: + - `none`:原始数据拼接(用于 PS 流) + - `h264_prefix`:添加 `00 00 00 01` 前缀 + - `mp4_nal_size`:添加 4 字节 NALU 长度 +- **工作流程**: + ```mermaid + graph TD + A[输入帧] --> B{是否需要合并?} + B -->|是| C[缓存帧] + B -->|否| D[直接输出] + C --> E{是否触发flush?} + E -->|是| F[合并输出] + E -->|否| C + ``` + +### 3.2 帧分发器([FrameDispatcher](src/Extension/Frame.h#L465-L526)) +```cpp +class FrameDispatcher : public FrameWriterInterface { + FrameWriterInterface* addDelegate(FrameWriterInterface::Ptr delegate); + bool inputFrame(const Frame::Ptr &frame) override; +}; +``` +- **设计特点**: + - 代理模式实现多路帧分发 + - 线程安全的递归锁保护 + - 自动统计 GOP 信息(`_gop_size`, `_gop_interval_ms`) +- **典型应用场景**: + - 同时推送到 RTMP 服务器和 HLS 切片 + - 媒体流录制与实时分析并行处理 + +## 4. 关键方法解析 + +### 4.1 帧缓存转换([getCacheAbleFrame](src/Extension/Frame.cpp#L9-L13)) +```cpp +Frame::Ptr Frame::getCacheAbleFrame(const Frame::Ptr &frame){ + if(frame->cacheAble()) return frame; + return std::make_shared(frame); +} +``` +- **解决痛点**:原始帧可能指向临时内存(如网络包缓冲区),通过 `FrameCacheAble` 复制数据确保生命周期 +- **性能优化**:仅当 `cacheAble()=false` 时进行深拷贝 + +### 4.2 时间戳修正([FrameStamp](src/Extension/Frame.cpp#L27-L33)) +```cpp +FrameStamp::FrameStamp(Frame::Ptr frame, Stamp &stamp, int modify_stamp) { + stamp.revise(frame->dts(), frame->pts(), _dts, _pts, + modify_stamp == ProtocolOption::kModifyStampSystem); +} +``` +- **时间戳模式**: + - `kModifyStampSystem`:使用系统绝对时间戳 + - `kModifyStampRelative`:保持相对时间戳 +- **应用场景**: + - 播放器同步控制 + - WebRTC 中的 RTP 时间戳转换 + +## 5. 使用示例 + +### 5.1 创建可缓存帧 +```cpp +// 从网络包创建原始帧(不可缓存) +auto raw_frame = std::make_shared( + CodecH264, ptr, size, dts, pts, 4, is_key); + +// 转换为可缓存帧(自动深拷贝) +Frame::Ptr cache_frame = Frame::getCacheAbleFrame(raw_frame); +``` + +### 5.2 合并 H.264 帧 +```cpp +FrameMerger merger(FrameMerger::h264_prefix); +merger.inputFrame(frame1, [](uint64_t dts, uint64_t pts, Buffer::Ptr buffer, bool key) { + // 处理合并后的完整帧 + rtmp_muxer->inputFrame(buffer, dts, pts, key); +}); +merger.inputFrame(frame2); +merger.flush(); // 强制输出剩余缓存 +``` + +## 6. 设计哲学 +1. **零拷贝优先**:通过 `FrameInternal` 等类避免不必要的内存复制 +2. **协议无关性**:帧操作不依赖具体传输协议 +3. **资源精确控制**:通过 `cacheAble()` 明确内存生命周期 +4. **扩展性设计**:宏定义 `CODEC_MAP` 支持便捷添加新编解码器 \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..411b23e --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.kingecg.top/kingecg/goZLMediaKit + +go 1.23.1