LiveMedia收发RTP数据包1

最近的项目需要用Live555架设流媒体服务器,谷歌百度了两天,总算有点进展,小结一下。

目前主流的流媒体服务器有:

1.Helix Server,功能最强大,收费。

2.Darwin Server,稳定,暂无接触。

3.Live555,开源免费,据说性能有瓶颈。

Live555的核心在Live Media,Live Media的核心在Source和Sink。服务器大致的服务流程是调用Sink的continuePlaying()来向客户发送流媒体数据,而continuePlaying()内调用了Source类的getNextFrame()函数,来获取帧数据。简单来说,Source类主要用于获取要发送的数据,而Sink类主要用于发送数据。

一  几个重要的类

1.RTPInterface类

  该类的主要作用是从一个Socket读取数据到一个buffer中,是数据的源头所在。

  注意到它最重要的一个函数是:Boolean handleRead (unsigned char *buffer, unsigned bufferMaxSize, unsigned &bytesRead, struct sockaddr_in &fromAddress, Boolean &packetReadWasIncomplete),它将fromAddress中的数据读入到buffer中。

2.BufferedPacket类

  该类用于存储媒体数据的RTP包内容,它的子类具体到媒体类型,如H264BufferedPacket类。值得注意的有两点:

  1)构造函数BufferedPacket()中申请了MAX_PACKET_SIZE(10000)大小的unsigned char数组。

  2)一个重要函数是

  Boolean fillInData (RTPInterface &rtpInterface, Boolean &packetReadWasIncomplete)

  {  

    rtpInterface.handleRead(&fBuf);

  }

  实现了将rtpInterface指向的数据存入fBuf中的功能。

4.ReorderingPacketBuffer类

该类用于存放多个BufferedPacket对象(可能是对象指针链表,有待考察),作为Source类中组织多个BufferedPacket对象的场所。

二  Source类的继承关系

Medium<-MediaSource<-FramedSource<-RTPSource<-MultiFramedRTPSource<-H264<-VideoRTPSource

其中,我们要重点关注的类是下面几个:

FramedSource,RTPSource,MultiFramedRTPSource。

1.FramedSource类

class FramedSource

{

       void getNextFrame (unsigned char *to,......)

  {

    ......

    doGetNextFrame();

  }

       virtual void doGetNextFrame ()=0;

}

2.RTPSource类

该类并未实现doGetNextFrame()函数,因而getNextFrame()与doGetNextFrame()与FramedSource类中定义完全相同。需要注意该类相比父类FramedSource,其protected成员多了一个RTPInterface fRTPInterface。

3.MultiFramedRTPSource类

非常重要的类,实现了doGetNextFrame()函数。

class MultiFramedRTPSource

{

public:

       void getNextFrame (unsigned char *to,......)

  {

    ......

    doGetNextFrame();

  }

       void doGetNextFrame ()

  {

    ......

    fRTPInterface.startNetworkReading();

              doGetNextFrame1()

              {

                     BufferedPacket* nextPacket = fReorderingBuffer->getNextCompletedPacket();

              };

             

  }

       void networkReadHandler1 ()

  {

    ......

              do

              {

                      bPacket->fillInData(fRTPInterface);

                      fReorderingBuffer->storePacket(bPacket);

              }while(0);

  }

protected:

       RTPInterface fRTPInterface;

private:

       ReorderingPacketBuffer *fReorderingBuffer;

}

三  RTP包的接收以及发送流程

       了解了以上几个类以及重要的函数,大概的RTP包处理流程推断如下:某个Sink类调用continuePlaying()函数,而continuePlaying()函数中调用Source类(以MultiFramedRTPSource为例,因为它以实现doGetFrame()函数)的getNextFrame()函数以得到发送数据,而getNextFrame()是通过调用doGetNextFrame(),继而是doGetNextFrame1(),最终在doNextFrame1中由语句fReorderingBuffer->getNextCompletedPacket()将存放在fReorderingBuffer中的数据取出交给Sink类来发送。

       那么,fReorderingBuffer中的数据是从何而来呢?推测是通过MultiFramedRTPSource类的networkReadHandler1()函数不断从fRTPInterface所指向的socket读入, 最终执行语句fReorderingBuffer->storePacket(bPacket);实现。

posted @ 2011-10-19 21:11  浓得化不开  阅读(2478)  评论(0编辑  收藏  举报