LIVE555学习笔记1 - 理解源码结构

引言

LIVE555的安装就不多赘述了,一搜一大把。但是它选择编译平台的思路很独特,我这里想简单介绍一下。

我们在给不同平台编译的时候,主要的区别就是编译链的区别,LIVE555给每个不同的平台各做了一份config文件,里面放的是目标平台的CC、CPP、C_FLAGS、CPP_FLAGS等等信息,然后用genMakefile脚本来组合生成目标Makefile。

这个思路被我用在了项目里,我的工程中定义了很多条件编译选项,因为要针对不同的需求给相应的功能。在了解了LIVE555这个方法后,我把C_FLAGS单独拿出来管理,用脚本生成我要的Makefile。

以下言归正传,这一篇先讲讲LIVE555的主要模块。

一、主要模块

LIVE555的源码结构还是很清晰的,每个模块是一个文件夹。除了主目录下用来区分平台编译的各种config文件,剩下8个文件夹。

主要的模块只有4个:BasicUsageEnvironment,UsageEnvironment,groupsock,liveMedia。

上手开发主要关注的是 liveMedia 模块,音视频数据的处理都在这里做。另外的三个模块,字面意思看是跟系统、网络socket相关的部分,还不是很理解,不在此误人子弟。

mediaServer是LIVE555提供的RTSP直播服务器,更准确的说,是一个点播服务器。而我理解的直播,是摄像头视频的实时直播或者是录屏画面的实时直播。

proxyServer字面就是代理服务器,我也没多研究。testProgs和WindowsAudioInputDevice直接跳过没看。

二、liveMedia和mediaServer

理解源码从mediaServer开始,这个模块是一个完整的示例程序,从如何启动RTSP服务,到如何调用liveMedia相应的类。自己上手开发的时候也是按这个顺序来垒代码。

mediaServer简单带过,看源码能懂。主要头疼的是这个liveMedia,这也是我小标题里把它放在前面的原因。

从liveMedia这个模块里我深深感受到了C++继承与派生的强大之处。首先要做的是理清基类和派生类之间的关系。

雷霄骅的一篇博客对LIVE555的源码进行了分析,我取了其中对继承关系的梳理。传送门:https://blog.csdn.net/leixiaohua1020/article/details/12235615

获取数据的类的继承关系:

Medium <- ServerMediaSession

Medium <- ServerMediaSubsession <- OnDemandServerMediaSubsession <-MPEG1or2DemuxedServerMediaSubsession

Medium <- MediaSource <- FramedSouse <- FramedFileSource <- ByteStreamFileSource

Medium <- MediaSource <- FramedSouse <- MPEG1or2DemuxedElementaryStream

Medium <- MPEG1or2FileServerDemux

Medium <- MPEG1or2Demux

Medium <- MediaSource <- FramedSouse <- MPEG1or2DemuxedElementaryStream

Medium <- MediaSource <- FramedSouse <- FramedFilter <- MPEGVideoStreamFramer <-MPEG1or2VideoStreamFramer

Medium <- MediaSink <- RTPSink <- MultiFramedRTPSink <- VideoRTPSink <-MPEG1or2VideoRTPSink

 RTP数据包发送的类的继承关系:

MPEGVideoStreamFramer: A filter that breaks up an MPEG video elementary stream into headers

and frames

MPEG1or2VideoStreamFramer: A filter that breaks up an MPEG 1 or 2 video elementary stream

into frames for: Video_Sequence_Header, GOP_Header, Picture_Header

MPEG1or2DemuxedElementaryStream: A MPEG 1 or 2 Elementary Stream, demultiplexed from

a Program Stream

MPEG1or2Demux: Demultiplexer for a MPEG 1 or 2 Program Stream

ByteStreamFileSource: A file source that is a plain byte stream (rather than frames)

MPEGProgramStreamParser: Class for parsing MPEG program stream

StreamParser: Abstract class for parsing a byte stream

StreamState: A class that represents the state of an ongoing stream

以上的目的是先对liveMedia的代码有个大概了解。

三、以H264点播为例

LIVE555是基于文件的,这也是我一直说它本质是“点播”的原因。大家最终的目的是快速上手开发,所以挑重要的讲。

首先,LIVE555用Subsession的方式来管理不同格式的流媒体。要播放H264格式,那就调用H264VideoFileServerMediaSubsession,在其createNewStreamSource()里再调用H264使用的数据处理类ByteStreamFileSource,组包处理类H264VideoStreamFramer。

如果我们做开发,首先处理的问题应该是我们自己的数据从哪儿来?要怎么给LIVE555?真正跟我们的音视频数据接触的,就是Source,我们初期也只要关注这里,在ByteStreamFileSource::doGetNextFrame()每一次的循环调用里把数据正确的给到LIVE555。阅读一下ByteStreamFileSource.cpp,这里是具体数据调取的具体实现,每次从文件读一点放入缓存,直到读完为止。其他不需要关心的地方都在他的父类里,父类又是一层层继承而来,每一层都有各自关心的功能,没必要初学就杠上去。

理解了ByteStreamFileSource的工作,可以自己仿照他写一个。毕竟做开发的时候多半要自己写Source,否则也破坏源码的结构。写完了自己的Source,你需要再写一个自己的Subsession,目的是调用你自己的Source。Framer、Parser、Sink不需要自己写,这三个要处理的数据都是标准格式(比如H264),LIVE555基本覆盖了所有的音视频格式。

其实数据真正的使用者是Sink,它问StreamFramer要数据,StreamFramer::continueReadProcessing()调用StreamParser,Parser再从Source去调数据,然后层层处理最终返回给Sink。这个过程真的复杂,给大家一篇博客去深入研究:https://blog.csdn.net/niu_gao/article/details/7212181

你可能感兴趣的:(LIVE555)