Nginx RTMP 接收模块分析 (ngx_rtmp_receive.c)

ngx_rtmp_receive.c 是 Nginx RTMP 模块中的接收部分,主要处理 RTMP 协议的消息接收、解析和处理。通过对不同类型的 RTMP 消息进行解析和分发,它为 Nginx RTMP 流媒体服务器提供了接收流数据、用户命令、AMF 数据等功能。以下是这段代码的详细分析。

1. 主要处理函数

1.1 ngx_rtmp_protocol_message_handler

该函数负责处理 RTMP 协议的基础消息,它根据消息类型(h->type)来决定如何处理接收到的数据。以下是常见的消息类型及其处理:

  • NGX_RTMP_MSG_CHUNK_SIZE

    • 设置 RTMP 协议的分块大小(chunk size)。通过 ngx_rtmp_set_chunk_size 函数设置会话的分块大小。

  • NGX_RTMP_MSG_ABORT

    • 处理流的中断消息,但此处没有实现具体的中断逻辑。

  • NGX_RTMP_MSG_ACK

    • 处理 RTMP 的确认消息(ACK)。记录并打印接收到的序列号。

  • NGX_RTMP_MSG_ACK_SIZE

    • 处理确认窗口大小(ACK size)。记录并更新窗口大小。

  • NGX_RTMP_MSG_BANDWIDTH

    • 处理带宽消息。用于控制 RTMP 流的带宽,记录带宽和限制信息。

每个消息类型的处理都是通过对数据进行解析,提取需要的信息(如序列号、带宽、窗口大小等),然后调用相应的处理函数来执行操作。

1.2 ngx_rtmp_user_message_handler

该函数用于处理用户定义的消息类型(用户事件)。根据不同的事件类型(如 NGX_RTMP_USER_STREAM_BEGINNGX_RTMP_USER_STREAM_EOF 等),执行不同的处理逻辑。

  • NGX_RTMP_USER_STREAM_BEGIN:表示流开始,调用 ngx_rtmp_stream_begin 处理流开始事件。

  • NGX_RTMP_USER_STREAM_EOF:表示流结束,调用 ngx_rtmp_stream_eof 处理流结束事件。

  • NGX_RTMP_USER_STREAM_DRY:表示流变干,调用 ngx_rtmp_stream_dry 处理流变干事件。

  • NGX_RTMP_USER_SET_BUFLEN:设置缓冲区大小,更新 s->buflen 并调用 ngx_rtmp_set_buflen 进行处理。

  • NGX_RTMP_USER_RECORDED:表示流已经录制完成,调用 ngx_rtmp_recorded 处理。

该函数的设计允许处理各种 RTMP 用户事件,并将事件委托给相应的处理函数。

1.3 ngx_rtmp_fetch 系列函数

这组函数用于从 ngx_chain_t 中提取数据。ngx_rtmp_fetch 用于提取单个字节,ngx_rtmp_fetch_uint8 用于提取 uint8_t 数据类型,ngx_rtmp_fetch_uint32 用于提取 uint32_t 类型的数据。

这些函数遍历链表 ngx_chain_t,逐个读取数据块中的内容,并将其存储在提供的缓冲区中。它们返回 NGX_OK 表示成功,或者返回 NGX_DONENGX_ERROR 处理不同的情况。

1.4 ngx_rtmp_aggregate_message_handler

该函数处理聚合消息,它允许将多个消息合并为一个消息进行处理。RTMP 协议支持将多个小消息合并成一个较大的消息进行传输,这有助于提高传输效率。

  • 函数首先读取消息头部,提取消息的类型、长度、时间戳等信息。

  • 然后,继续读取后续的消息数据,直到消息完整。

  • 最后,调用 ngx_rtmp_receive_message 函数来处理聚合的消息。

该函数的目的是确保多个合并的消息能够被正确解析和处理。

1.5 ngx_rtmp_amf_message_handler

该函数用于处理 AMF(Action Message Format)消息,它用于 RTMP 协议中的命令和数据交换。

  • ngx_rtmp_amf_read 用于从输入链中读取 AMF 消息并解析。

  • 它会解析 AMF 消息的函数名和事务 ID,并通过哈希查找查找相应的处理函数。

  • 如果找到处理函数,则调用该函数来处理具体的 AMF 命令。

2. RTMP 消息和 AMF 数据

RTMP 协议支持多种消息类型,如命令、音视频数据等,AMF 消息则是用于传输命令、参数等信息。模块中有针对 AMF 消息的专门处理函数,如 ngx_rtmp_amf_message_handler,它能够解析 AMF3 消息格式,并根据不同的命令类型调用对应的处理函数。

  • AMF 消息类型:AMF 消息的类型决定了如何解析消息。不同的命令类型(如调用命令、返回命令、共享对象)会有不同的处理方式。

  • AMF3 解析:AMF3 是 AMF 格式的升级版本,它增加了对复杂对象的支持。在解析 AMF3 消息时,会先读取消息的前缀,然后解析消息的具体内容。

3. 总结

这段代码是 Nginx RTMP 模块中用于接收和处理 RTMP 消息的核心部分。它通过不同的消息类型(协议消息、用户消息、AMF 消息等)来处理和解析从客户端发送来的数据。模块使用链表和缓冲区来高效地接收和处理数据,并根据消息类型执行相应的操作(如流的开始、结束、暂停、设置缓冲区大小等)。重点理解以下几个概念:

  1. RTMP 协议消息:包括分块大小、确认消息、带宽控制等,模块根据不同的消息类型进行不同的处理。

  2. 用户事件和 AMF 消息:RTMP 用户事件和 AMF 消息允许客户端与服务器进行交互,控制流的播放、发布等操作。

  3. 数据读取与提取:通过 ngx_rtmp_fetch 系列函数从数据链表中提取数据,支持多种数据类型(如 uint8_tuint32_t 等)。

这些功能确保了 Nginx RTMP 服务器能够高效处理来自客户端的请求,并支持流的实时播放、发布和控制。