美文网首页
Live555 源代码分析(四)

Live555 源代码分析(四)

作者: RonZheng2010 | 来源:发表于2020-09-22 23:18 被阅读0次

1 Media Session

1.1 ServerMediaSession

ServerMediaSession是媒体流的抽象。它可以包括多个子媒体流,也就是ServerMediaSubsession实例。

  • 成员fStreamName是客户端请求的媒体源名字。
  • 成员fSubsessionsHead指向子媒体流的链表。
  • 成员fSubsessionCounter是对通道编号(也就是ServerMediaSubsession实例)的计数,从1开始。
  • ServerMediaSubsession的成员fTrackNumber保存它的通道编号。ServerMediaSession::addSubsession()会设置这个值。

1.2 ServerMediaSubsession

ServerMediaSubsession实现媒体流接口。

  • 成员fTrackNumber是通道编号,
  • 成员函数trackId()得到通道编号字符串。如通道编号为1,则trackId()就是”track1”。这个值将打包在RTCP应答中,返回给客户端。
  • 成员函数sdpLines()构建sdp描述字符串。
  • getStreamParameter()构建媒体流。
  • startStream()、seekStream()、pauseStream()、deleteStream()分别启动、定位、暂停、和停止媒体流。

ServerMediaSubsession定义如下虚拟函数,以便它的派生类定制自己的行为。

  • createNewStreamSource()创建数据源,这是一个FramedSource实例。
  • createGroupsock()创建发布数据的UDP socket组,这是一个Groupsock实例。
  • createNewRTPSink()创建操作数据源的入口,这是一个RTPSink实例。
  • createRTCP()创建RTCPInstance实例。

OnDemandServerMediaSubsession是客户端可以交互的媒体流。客户端开始接收媒体流后,可以启动、暂停、定位、停止媒体流。

PassiveServerMediaSubsession的媒体流,客户端可以加入、退出流,不能控制它。

1.3 OnDemandServerMediaSubsession

对于OnDemandServerMediaSubsession,

  • 成员fDestinationHashTable中,这是一个Destinations的Hash表,保存目标地址信息,key值是client session id。
  • 创建媒体流(包括FramedSource、RTPSink等)之后,OnDemandServerMediaSubsession把管理它的工作委托给StreamState。

对于StreamState,

  • 成员函数startPlaying()、pause()、和endPlaying()分别负责开始播放,暂停、结束播放。
  • 成员函数sendRTCPAppPacket()发送指定数据包,这是跟媒体流有关的信息。

关于Destinations,

  • 地址可以是TCP地址,也可以是UDP地址。成员isTCP指明这一点。
  • 如果是TCP地址,则成员tcpSocketNum指明socket句柄,rtpChannelId和rtcpChannelId指明TCP连接的channel编号
  • 如果是UDP地址,则成员addr指明组播地址,成员rtpPort和rtcpPort指明组播地址的端口号。

1.4 MP3AudioFileServerMediaSubsession

FileServerMediaSubsession只是增加成员fFileName。这是媒体源的文件名。

MP3AudioFileServerMediaSubsession定义了MP3音频媒体源。

MP3AudioFileServerMediaSubsession::createNew()创建它的实例。

  • 调用HashTable::create()创建成员fDestinationsHashTable。它存放一组目标地址。
  • 调用gethostname()得到本地主机名。构造RTCP包时需要用到这个名字。

这里说明MP3AudioFileServerMediaSubsession对虚拟函数的定制。

虚拟函数createNewStreamSource()实现如下。

  • 调用MP3FileSource::createNew(),创建MP3FileSource实例。这里使用的文件名是FileServerMediaSubsession的成员fFileName。
  • 调用createNewStreamSourceCommon()。 其中基于MP3FileSource创建ADUFromMP3Source实例,基于后者又创建MP3FromADUSource实例。

最后得到如下图所示的链。MP3AudioServerMediaSubsession看到的是MP3FromADUSource。

虚拟函数createNewRTPSink()的实现如下。

  • 创建MPEG1or2AudioRTPSink实例。

虚拟函数seekStreamSource()实现如下。

  • 调用getBaseStreams(),从FramedSource链中得到链末端的FramedSoure,这里是基于文件的MP3FileSource。
  • 调用MP3FileSource::seekWithinFile()定位。

1.5 创建、启动、停止媒体流

以MP3AudioServerMediaSubsession说明。

成员函数getStreamParameters()负责创建流。

  • 调用MP3AudioServerMediaSubsession::createNewStreamSource()创建媒体源。
  • 调用MP3AudioFileServerMediaSubsession::createNewRTPSink()创建RTPSink实例。
  • 调用createGroupsock()创建Groupsock实例。
  • 调用全局函数increaseSendBufferTo()设置Groupsock的socket的发送缓存大小。
  • 基于前面创建的FramedSource、RTPSink、Groupsock实例,创建StreamState实例。
  • 创建Destination实例保存地址信息。对于TCP是socket和channel,对于UDP,是组播地址和端口号。
  • 将Destination实例加入成员fDestinationHashTable。

seekStream()负责在流中定位。

  • 将工作委托给MP3AudioFileServerMediaSubsession::seekStreamSource()。

startStream()启动流。

  • 调用HashTable::lookup(),根据client session id在成员fDestinationsHashTable中找到对应Destinations实例,其中包括目标地址信息,如若干组组播地址及端口等。
  • 调用StreamState::startPlaying(),参数是这个Destinations实例。
    • 调用OnDemandServerMediaSubsession::createRTCP()创建RTCPInstance实例。
    • 调用RTCPInstance::setAppHandler()和RTCPInstance::setSpecificRRHandler(),设置回调函数,以便接收数据。
    • 用成员fRTPSink实例,调用MediaSink::startPlaying()。

相关文章

网友评论

      本文标题:Live555 源代码分析(四)

      本文链接:https://www.haomeiwen.com/subject/mujpyktx.html