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);实现。 |
|