rtmpdump代码简单分析
来源:互联网 发布:新闻发布系统源码 编辑:程序博客网 时间:2024/04/29 06:31
第一步——握手(Hand Shake)
该文件中HandShake 函数是处理握手的。
第二 步-----建立连接NetConnection 在文件rtmp.cpp 中
RTMP_Connect():
其内部调用了RTMP_Connect0() 和 RTMP_Connect1()。
RTMP_Connect0() 主要是建立Socket连接
RTMP_Connect1() 建立RTMP连接.
第三步-----建立流 NetStream 代码也在rtmp.cpp中
RTMP_ConnectStream
在这个函数中调用了
RTMP_ReadPacket()
RTMP_ClientPacket()
第一个函数的作用是读取通过Socket接收下来的消息(Message)包,但是不做任何处理。第二个函数则是处理消息(Message),并做出响应。这两个函数结合,就可以完成接收消息然后响应消息的步骤。
RTMP_ReadPacket 接收下来的是ChunkRTMP_ClientPacket() 是用来处理消息,根据不同的消息,做不同的调用。
switch (packet->m_packetType)
{
case 0x01:
{
case 0x01:
break;
case 0x02:
break;
case 0x14:
if (HandleInvoke(r, packet->m_body, packet->m_nBodySize) == 1)
bHasMediaPacket = 2;
break;
......
}
消息类型为0x14的消息,即消息类型ID为20的消息,是AMF0编码的命令消息,
依次调用
AMF_Decode(&obj, body, nBodySize, FALSE);
AMFProp_GetString(AMF_GetProp(&obj, NULL, 0), &method);
(AVMATCH(&method, &av__result))
三个命令,
针对不同的method,处理不同的命令。
这些命令有以下这些(不完整)
AVMATCH(&methodInvoked, &av_connect)
AVMATCH(&methodInvoked, &av_createStream)
AVMATCH(&methodInvoked, &av_play)
AVMATCH(&methodInvoked, &av_publish)
AVMATCH(&method, &av_onBWDone)
等等。
第四步------发送消息
消息是如何发送的?- 发送connect命令使用函数SendConnectPacket()
- 发送createstream命令使用RTMP_SendCreateStream()
- 发送realeaseStream命令使用SendReleaseStream()
- 发送publish命令使用SendPublish()
- 发送deleteStream的命令使用SendDeleteStream()
- 发送pause命令使用RTMP_SendPause()
函数命名有两种规律:RTMP_Send***()或者Send***(),其中*号代表命令的名称
发送消息比较类似:
总体的思路是声明一个RTMPPacket类型的结构体,然后设置各种属性值,最后交给RTMP_SendPacket()进行发送。
RTMPPacket类型的结构体定义如下,一个RTMPPacket对应RTMP协议规范里面的一个块(Chunk)。
//Chunk信息
typedef struct RTMPPacket
{
uint8_t m_headerType;//ChunkMsgHeader的类型(4种)
uint8_t m_packetType;//Message type ID(1-7协议控制;8,9音视频;10以后为AMF编码消息)
uint8_t m_hasAbsTimestamp; /* Timestamp 是绝对值还是相对值? */
int m_nChannel; //块流ID
uint32_t m_nTimeStamp; // Timestamp
int32_t m_nInfoField2; /* last 4 bytes in a long header,消息流ID */
uint32_t m_nBodySize; //消息长度
uint32_t m_nBytesRead;
RTMPChunk *m_chunk;
char *m_body;
} RTMPPacket;
RTMP_SendPacket()
各种的RTMPPacket(即各种Chunk)都需要用这个函数进行发送。
这个函数 按照RTMP规范将数据编码成符合规范的块(Chunk),在这里需要注意一个函数:WriteN()。该函数完成了将数据发送出去的功能。
在这个函数里根据协议不同,调用相应的函数
- if (r->Link.protocol & RTMP_FEATURE_HTTP)
- nBytes = HTTP_Post(r, RTMPT_SEND, ptr, n);
- else
- nBytes = RTMPSockBuf_Send(&r->m_sb, ptr, n);
其中 RTMPSockBuf_Send()完成了数据发送的功能
在这个RTMPSockBuf_Send()函数中调用了系统Socket的send()函数完成了数据的发送功能
到此,发送消息能够通过socket发送出去。
第五步------接收消息
RTMPdump中完成视音频数据的接收的函数是:RTMP_Read()。
RTMP_Read()中实际读取数据的函数是Read_1_Packet(),它的功能是从网络上读取一个RTMPPacket的数据,
Read_1_Packet()里面实现从网络中读取视音频数据的函数是RTMP_GetNextMediaPacket()。
RTMP_GetNextMediaPacket 里会调用两个函数:RTMP_ReadPacket()以及RTMP_ClientPacket()。这两个函数中,前一个函数负责从网络上读取数据,后一个负责处理数据。
在RTMP_ReadPacket()函数里完成从Socket中读取数据的函数是ReadN(),
ReadN()中实现从Socket中接收数据的函数是RTMPSockBuf_Fill(),
RTMPSockBuf_Fill()函数中调用了系统Socket的recv()函数接收RTMP连接传输过来的数据。
第六步------处理各种消息
RTMPdump 的函数 RTMP_ClientPacket(), 主要完成了各种消息的处理。
消息ID
功能调用函数
0x01
设置块(Chunk)大小
HandleChangeChunkSize()
0x03
致谢无函数
0x04
用户控制
HandleCtrl
0x05
窗口致谢大小(Window Acknowledgement Size
HandleServerBW()
0x06
设置对等端带宽(Set Peer Bandwidth)
HandleClientBW()
0x08
传输音频0x09
传输视频0x0f--11
传输AMF3编码0x12--14
传输AMF0编码
0 0
- rtmpdump代码简单分析
- rtmpdump源码分析
- rtmpdump源代码分析------HandShake
- RTMPDump(libRTMP) 源代码分析
- RTMPdump源码分析: HandShake(4)
- RTMPdump源码分析: NetConnection(5)
- RTMPdump源码分析: NetStream1(6)
- RTMPdump源码分析: NetStream1(7)
- rtmpdump
- RTMPDump
- Rtmpdump
- rtmpdump 移植记录 与 简单使用
- RTMPdump 源代码分析 1: main()函数
- RTMPdump 源代码分析 1: main()函数
- RTMPdump(libRTMP) 源代码分析大汇总
- RTMPdump 源代码分析 1: main()函数
- RTMPDump源码分析-主要函数调用(0)
- RTMPDump源码分析-main函数(1)
- JAVA使用继承还是组合
- git 配置身份登陆git
- 深度学习
- 蓝牙电话 HFP 剖析(三) --- flow解析
- "三关" + "一关"
- rtmpdump代码简单分析
- Spark执行过程出现outofmemory错误的解决方案
- C语言: gotoxy函数
- Android 4个常用的工具类
- nonce和timestamp在Http安全协议中的作用
- PHP的闭包技术分析
- .bat批处理 搜索当前目录及子目录下的文件
- Web第一部分(1-1)
- mysql建立部分索引