ZLMediaKit的转流流程(二)

在前面提到的转流流程还有一个细节:

  • 推流端和拉流端如果协议相同,则没有组视频帧的过程,而是直接转发。
  • 如果不相同,则有视频组帧,再打包的过程。

直接转发

这里以Rtmp推流端为例子。
RtmpSession中,有一个_push_src的成员变量,它是RtmpMediaSourceImp类型,作为一个Rtmp的源。
RtmpMediaSourceImp中有MultiMediaSourceMuxer成员变量_muxer,它是一个各种协议的muxer类,将视频帧按不同的协议进行拆包。可以看看这篇文章。

在文件RtmpMediaSourceImp.cppsetProtocolOption方法中,创建对象_muxer时,关闭了rtmp的muxer。如下代码:

//关闭rtmp的muxer
_option.enable_rtmp = false;
//创建MultiMediaSourceMuxer对象
_muxer = std::make_shared<MultiMediaSourceMuxer>(_tuple, _demuxer->getDuration(), _option);

作为源的RtmpMediaSource对象会注册到全局MediaSource中(MediaSource可以看看这篇文章),作为rtmp的源。
**如果有rtmp的拉流端则会直接使用这个源,以RtmpMediaSource_ring成员作为转流结构,而它类型定义如下:

using RingDataType = std::shared_ptr<toolkit::List<RtmpPacket::Ptr> >;
using RingType = toolkit::RingBuffer<RingDataType>;

可以看到这个RingBuffer中的类型就是RtmpPacket。可见是没有组帧(视频)的过程是直接转发。RTSP也是如此流程。

以视频帧转发

当转流需要MultiMediaSourceMuxer中的suorce作为源时,此时就涉及到了组帧,拆包的过程了。这里的核心就是MultiMediaSourceMuxer。下面是它的类图

ZLMediaKit的转流流程(二)_第1张图片
视频帧的转发的被抽象为一个FrameDispathcer类,它有一个std::map类型的成员变量,存放的就是Frame的消费者。
Frame通过inputFrame方法,将Frame转发至各个FrameWriteInterface类型的消费者中。MultiMediaSourceMuxer就是FrameWriteInterface类型。

RtmpDemux,RtspDemux中,通过信令协商产生了对应的音视频的Track,视频对应的Track为H265TrackH264Track,它们都是具体的FrameDispathcer类型,数据将由它们转发。下面Frame的牛转图。

ZLMediaKit的转流流程(二)_第2张图片
在以Rtsp为源的情况下,RtspDemuxer::inputRtp方法传入的是rtp包,经过H264RtpDecoder后就将rtp包组成了视频帧。视频帧再通过FrameDispatcher体系,最终到达MultiMediaSourceMuxer中各个类型的source,视频帧又被拆分为各协议对应的包。

你可能感兴趣的:(ZLMediaKit源码分析,c++,音视频,架构)