先直接看图 这是ffmpeg向流媒体服务器推流时候的堆栈 引入C++ 11之后 堆栈会显得特别繁复冗余 看起来 也没有 以前没有C++11之前那样 简单明了
太复杂了 标记下 很多函数名字被我改了 因为原来的看起来 同名函数太多了
C++11 和lambada 匿名函数 让看堆栈 成了地狱模式
断点断在 DemuxInputRtp 这个函数 这个是我改了名字的 之前是叫inputRtp 叫这个名字的函数太多了,所以给重新改了个名字 这样 看起来 会清晰一点
从eventpoller里面的 RunLoop函数开始 慢慢开始看
cb这个标黄的316行这里
之后会走到 这个ReadData函数
ReadData函数 中 不管UDP还是TCP都是通过recvfrom这个函数 从内核接收网络数据
正常流程会走到 _on_read这个回调
这个回调是在tcpserver onAcceptConnection中设置的 如下图
一般流程会走到onRecv那个回调去
这个onRecv回调就是创建tcpserver的时候 根据不同的类型 比如HttpSession RtspSession 在其对应cpp文件中 去实现这个虚函数
我的工程中 没有全部按照官方的代码 走 很多地方 为了便捷 就服用了httpsession中的部分代码
所以 我的代码中会走到HttpSession的onRecv中 这个ProcessData函数也是我重新命名了
再看ProcessData函数 他会给收到的数据 组装或者拆分成对应的 head和 content数据
之后会调用 onRecvHeader或者 onContentRecv函数 这两个函数不同协议实现方式不一样
如下图
对于RTSP协议来说 如下图 会区分成是rtsp交互的sdp数据 还是媒体rtp数据 如下图
rtsp协议的各种方法 媒体描述信息都是在onWholeRtspPacket那个函数里面处理的
这里我们只关心媒体数据 代码中已经给出注释 rtcp先不管 所以我们会走到handleOneRtp这个函数里
PushRtpData也是我改名字了的函数 最后 会走到 sortPacket这里
这个cb设置的有两个地方
实现体就是 推流的走到这个onWrite函数
至此 终于走到我们打断点的地方了
这里根据不同的媒体类型 会调用不同的inputRtp函数 我们这里是 H264
这里的decodeRtp函数中会将Rtp包重新组装成H264 packet包
分别是上面标黄的三个函数
在mergeFu 和 singleFrame函数中 会调用outputFrame函数如下图
outputFrame函数又调用了基类的inputFrame函数 之后通过obtainFrame函数开辟一个新的Frame
_delegates的定义如下
这个map是在addDeletegate中添加的
再看下谁调用了这个addDelegate函数即可 是在rtspdemuxer类中
刚刚那里的inputFrame自然就是调用了如下的代码
然后走到RtspMediaSourceMuxer 的inputFrame函数中
这里终于走到encoder了 之前一直是decoder demuxer
这里是 muxer encoder
不管是那个packRtp都会走到 RtpCodec::inputRtp
将rtp数据写进环形队列
最终会走到 大概应该是将这个数据填充到ringbuffer里面
文章来源:https://www.toymoban.com/news/detail-419690.html
暂时先分析到这文章来源地址https://www.toymoban.com/news/detail-419690.html
到了这里,关于ZLMediaKit流媒体服务器 RTSP推流时候的堆栈的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!