云计算百科
云计算领域专业知识百科平台

第二讲:从零实现RTSP服务器系列,基于UDP的H.264 RTP传输

从零实现RTSP服务器系列(二):基于UDP的H.264 RTP传输

📚 核心知识回顾

1. RTP协议报文结构

// RTP头部定义(12字节)
struct RTPHeader {
uint8_t cc : 4; // CSRC计数器
uint8_t extension : 1; // 扩展标志
uint8_t padding : 1; // 填充标志
uint8_t version : 2; // 版本号(固定2)

uint8_t payloadType : 7; // 负载类型(H.264=96)
uint8_t marker : 1; // 标记位

uint16_t seq; // 序列号
uint32_t timestamp; // 时间戳(90000Hz时钟)
uint32_t ssrc; // 同步信源标识
};

2. H.264关键概念

术语说明示例值
NALU 网络抽象层单元 0x00000001
SPS 序列参数集 profile=100
PPS 图像参数集 pic_parameter_set_id=0
IDR帧 即时解码刷新帧 NALU Type=5
FU-A 分片单元类型A FU Indicator=28
常见本地文件的H264码流的Nalu类型表
十六进制十进制Nalu Type
0x67 103 7
0x68 104 8
0x06 6 6
0x65 101 5
0x61 97 1
0x41 65 1
0x01 1 1
0x09 9 9

🛠️ 实战开发步骤

1. 生成H.264测试文件

ffmpeg -i input.mp4 -c:v copy -bsf:v h264_mp4toannexb output.h264

ffmpeg -i test.mp4 -codec copy -bsf: h264_mp4toannexb -f h264 test.h264

2. RTP分片打包逻辑

// H.264分片打包示例
void send_rtp_packet(const uint8_t* data, int size) {
// FU Indicator结构
uint8_t fu_indicator = (nalu_type & 0xE0) | 28;

// FU Header结构
uint8_t fu_header = nalu_type & 0x1F;
if (is_first_packet) fu_header |= 0x80; // S标记
if (is_last_packet) fu_header |= 0x40; // E标记

// 构造RTP包
RTPPacket packet;
memcpy(packet.payload, &fu_indicator, 1);
memcpy(packet.payload+1, &fu_header, 1);
memcpy(packet.payload+2, data, size-2);

sendto(rtp_socket, &packet, sizeof(packet), 0, …);
}

3. 关键时序控制

// 视频帧发送间隔控制(25fps)
const int FRAME_INTERVAL = 40; // ms
auto last_send_time = std::chrono::steady_clock::now();

while (true) {
auto now = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now – last_send_time);

if (elapsed.count() >= FRAME_INTERVAL) {
send_rtp_frame();
last_send_time = now;
}
}

📊 RTP包结构示例

偏移量字段值说明
0x00 Version 0x80 RTP版本2,无扩展
0x01 Payload Type 0x60 H.264负载类型
0x02 Sequence 0x1234 递增序列号
0x04 Timestamp 0xABCDEF 90000Hz时钟基准
0x08 SSRC 0xDEADBEEF 同步信源标识
0x0C FU Indicator 0x7C F=0, NRI=3, Type=28
0x0D FU Header 0x85 S=1, E=0, Type=5
0x0E Payload Data H.264分片数据

⚠️ 开发注意事项

  • MTU限制:UDP包建议不超过1400字节
  • 时间戳同步:使用90000Hz时钟基准
  • 关键帧处理:IDR帧需要完整发送SPS/PPS
  • 网络字节序:所有整数字段需转换
  • 丢包处理:需实现简单重传机制(后续课程讲解)
  • 🚀 效果验证

    # 使用FFplay验证流媒体
    ffplay -rtsp_transport udp rtsp://localhost:554/live

    📚 学习资源推荐

  • RFC3550 – RTP协议规范(https://tools.ietf.org/html/rfc3550)
  • H.264编码白皮书(https://www.itu.int/rec/T-REC-H.264)
  • Live555开源项目(http://www.live555.com/)
  • 下期预告:第三讲《基于UDP的AAC音频传输实现》即将发布!

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 第二讲:从零实现RTSP服务器系列,基于UDP的H.264 RTP传输
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!