博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
live555源码简介
阅读量:6039 次
发布时间:2019-06-20

本文共 7923 字,大约阅读时间需要 26 分钟。

live555开发库源代码包括6个部分:UsageEnviromentBasicUsageEnviromentgroupsockliveMediatestProgsmediaServer

UsageEnviroment

UsageEnviroment目录中声明一些虚类class UsageEnviromentclass HashTableclass TaskScheduler,这些类中包括各种纯虚函数,这些虚函数定义出这些类的整体轮廓。这些类的某些子类,如果想要实例化的,必须描绘出这些轮廓,即实现这些函数。

class UsageEnviroment是程序运行环境的抽象描述,通过包含TaskScheduler& fScheduler的私有变量,表示网络功能、异步事件处理等。

class TaskScheduler是定义如何设置RTSPServer端的网络功能、异步事件处理。

class HashTable是定义类似于字典的功能。

BasicUsageEnviroment

BasicUsageEnviroment目录中,主要是对UsageEnviroment目录中的class UsageEnviromentclass TaskScheduler各个部分的逐步实现,在实现的过程中逐步引入相应的成员数据。

groupsock

groupsock目录主要是对基本的socket封装,在liveMedia目录中涉及网络的部分会有使用。

liveMedia

liveMeida目录是整个live555开发库的核心部分。

class Medim class _Tables class MediaLookupTable

class Medimclass _TablesMedia.hh文件中定义,在Media.cpp文件中实现,class MediaLookupTableMedia.cpp文件中定义和实现。

liveMeida目录中最基础的类是class MediumliveMedia目录下很多class类型都是class Media的子类。class _Tablesclass MediaLookupTable主要是实现对Medium的管理。

#define mediumNameMaxLen 30class Medium {public:  static Boolean lookupByName(UsageEnvironment& env,                  char const* mediumName,                  Medium*& resultMedium);  static void close(UsageEnvironment& env, char const* mediumName);  static void close(Medium* medium); // alternative close() method using ptrs      // (has no effect if medium == NULL)  UsageEnvironment& envir() const {return fEnviron;}  char const* name() const {return fMediumName;}  // Test for specific types of media:  virtual Boolean isSource() const;  virtual Boolean isSink() const;  virtual Boolean isRTCPInstance() const;  virtual Boolean isRTSPClient() const;  virtual Boolean isRTSPServer() const;  virtual Boolean isMediaSession() const;  virtual Boolean isServerMediaSession() const;protected:  friend class MediaLookupTable;  Medium(UsageEnvironment& env); // abstract base class  virtual ~Medium(); // instances are deleted using close() only  TaskToken& nextTask() {    return fNextTask;  }private:  UsageEnvironment& fEnviron;  char fMediumName[mediumNameMaxLen];  TaskToken fNextTask;};// A data structure for looking up a Medium by its string name.// (It is used only to implement "Medium", but we make it visible here, in case developers want to use it to iterate over//  the whole set of "Medium" objects that we've created.)class MediaLookupTable {public:  static MediaLookupTable* ourMedia(UsageEnvironment& env);  HashTable const& getTable() { return *fTable; }protected:  MediaLookupTable(UsageEnvironment& env);  virtual ~MediaLookupTable();private:  friend class Medium;  Medium* lookup(char const* name) const;  // Returns NULL if none already exists  void addNew(Medium* medium, char* mediumName);  void remove(char const* name);  void generateNewName(char* mediumName, unsigned maxLen);private:  UsageEnvironment& fEnv;  HashTable* fTable;  unsigned fNameGenerator;};// The structure pointed to by the "liveMediaPriv" UsageEnvironment field:class _Tables {public:  static _Tables* getOurTables(UsageEnvironment& env, Boolean createIfNotPresent = True);      // returns a pointer to a "_Tables" structure (creating it if necessary)  void reclaimIfPossible();      // used to delete ourselves when we're no longer used  MediaLookupTable* mediaTable;  void* socketTable;protected:  _Tables(UsageEnvironment& env);  virtual ~_Tables();private:  UsageEnvironment& fEnv;};

class Medium 某种媒体

class _Tables 查找表,包括void *mediaTableclass MediaLookupTable类型
class MedaLookupTable 通过HashTabel实现的Medium的查找表,包括所有在UsageEnviroment中创建的Medium实体。

上面三种类型是通过class UsageEnviroment类型中的void *liveMediaPriv成员变量联系起来。其中liveMediaPriv实际上是_Tables*类型,而在_Tables类型中有void *mediaTable成员变量,mediaTableMediaLookupTable*类型的。如果我们知道UsageEnviroment& env,给出key值,即Medium的名称,我们就可以查找相关的Medium

class RTSPServer class RTSPServer::class RTSPClientSession

class RTSPServerclass Medium的子类,是对RTSPServer的抽象描述。RTSPServer主要功能包括:

[ 1 ] RTSPServer可以接收客户端TCP连接请求,在接收客户端TCP连接请求后会创建class RTSPServer::class RTSPClientSession类。class RTSPClientSession是真正负责与客户端进行RTSP消息的接收、解包、打包、发送,是RTSP协议在RTSPServer端的具体实现。

接收客户端请求的Socket和端口号,在创建RTSPServer实例时,会调用如下接口:

static int setUpOurSocket(UsageEnvironment& env, Port& ourPort);

创建RTSPServer端的非阻塞的监听Socket,并且调用listen,监听网络数据。如果后续有请求消息到达,RTSPServer进行处理。这里需要特别提出RTSPServer处理网络数据采用的是Select模型。例如,在创建RTSPServer实例时源代码如下:

RTSPServer::RTSPServer(UsageEnvironment& env,                     int ourSocket, Port ourPort,                     UserAuthenticationDatabase* authDatabase,                     unsigned reclamationTestSeconds)  : Medium(env),          fRTSPServerSocket(ourSocket), fRTSPServerPort(ourPort),          fHTTPServerSocket(-1), fHTTPServerPort(0), fClientSessionsForHTTPTunneling(NULL),          fAuthDB(authDatabase), fReclamationTestSeconds(reclamationTestSeconds),          fServerMediaSessions(HashTable::create(STRING_HASH_KEYS)) {      #ifdef USE_SIGNALS        // Ignore the SIGPIPE signal, so that clients on the same host that are killed        // don't also kill us:        signal(SIGPIPE, SIG_IGN);      #endif              // Arrange to handle connections from others:        env.taskScheduler().turnOnBackgroundReadHandling(fRTSPServerSocket,                                 (TaskScheduler::BackgroundHandlerProc*)&incomingConnectionHandlerRTSP, this);  }

通过调用TaskScheduler::turnOnBackgroundReadHandling(),开启监听SOCKET fRTSOServerSocketREAD功能,设置回调函数。

static void incomingConnectionHandlerRTSP(void*, int /*mask*/);        //RTSPServer接收到

TaskScheduler::doEventLoop( )循环中

void BasicTaskScheduler0::doEventLoop(char* watchVariable) {      // Repeatedly loop, handling readble sockets and timed events:      while (1) {          if (watchVariable != NULL && *watchVariable != 0) break;          SingleStep();      }  }

会调用TaskScheduler::SingleStep()函数,在SingleStep()函数中,我们会处理网络数据的发送和接收(select模型)、异步事件的处理、触发事件的处理。在TaskScheduler::SingleStep()函数中调用select函数,发现监听SOCKET fRTSOServerSocket有数据需要去读,会调用如下接口:

static void incomingConnectionHandlerRTSP(void*, int /*mask*/);        //RTSPServer接收到

调用accept()函数,创建RTSPServer端与特定的Client通信的SOCKET,获取Client的地址,之后实例化class RTSPServer::class RTSPClientSession

RTSPServer::RTSPClientSession      ::RTSPClientSession(RTSPServer& ourServer, unsigned sessionId, int clientSocket, struct sockaddr_in clientAddr)        : fOurServer(ourServer), fOurSessionId(sessionId),          fOurServerMediaSession(NULL),          fClientInputSocket(clientSocket), fClientOutputSocket(clientSocket), fClientAddr(clientAddr),          fSessionCookie(NULL), fLivenessCheckTask(NULL),          fIsMulticast(False), fSessionIsActive(True), fStreamAfterSETUP(False),          fTCPStreamIdCount(0), fNumStreamStates(0), fStreamStates(NULL) {        // Arrange to handle incoming requests:        resetRequestBuffer();                                                             envir().taskScheduler().turnOnBackgroundReadHandling(fClientInputSocket,           (TaskScheduler::BackgroundHandlerProc*)&incomingRequestHandler, this);  //打开int fClientInputSocket的READ功能,接收Client的RTSP消息,设置处理函数。        noteLiveness();  }

赋值:

int fRTSPServerSocket;       //接收客户端TCP连接请求的SOCKET  Port fRTSPServerPort;        //接收客户端TCP请求的端口

[ 2 ] 增加,查找,删除RTSPServer支持的ServerMediaSession集合。

void addServerMediaSession(ServerMediaSession* serverMediaSession);  virtual ServerMediaSession* lookupServerMediaSession(char const* streamName);  void removeServerMediaSession(ServerMediaSession* serverMediaSession);  void removeServerMediaSession(char const* streamName);

ServerMediaSession集合的相关数据保存在HashTable中,在创建RTSPServernew HashTable

HashTable* fServerMediaSessions;          //服务器端ServerMediaSession的查找表,(Medium名称,指向ServerMediaSession的地址)

[ 3 ] 用户验证。

UserAuthenticationDatabase* fAuthDB

[ 4 ] TCP打洞。

实现在RTSPServer.hh源文件。

class RTSPServer::class RTSPClientSession是对RTSP协议在Server端的描述,主要功能是:接收客户端RTSP的Request消息、解析RTSP Request消息、封装Server端的RTSP Reply消息、发送Server端的RTSP Reply消息。

static void incomingRequestHandler(void*, int /*mask*/);   //class RTSPServer::class RTSPClientSession的整体工作流程。

参考资料

转载地址:http://lpghx.baihongyu.com/

你可能感兴趣的文章
Shell命令-文件压缩解压缩之gzip、zip
查看>>
个人总结
查看>>
uva 673 Parentheses Balance
查看>>
Bzoj 2252: [2010Beijing wc]矩阵距离 广搜
查看>>
css 禁止选中文本
查看>>
bzoj2165
查看>>
算术运算表达式正则及分析
查看>>
Oracle 12c 多租户 手工创建 pdb 与 手工删除 pdb
查看>>
shell初涉
查看>>
[浪子学编程][MS Enterprise Library]ObjectBuilder之创建策略祥解(二)
查看>>
windows添加和删除服务
查看>>
关于云栖,有点无语的几个地方,管理能不能管?
查看>>
Windows线程的同步与互斥
查看>>
C#进阶系列——MEF实现设计上的“松耦合”(四):构造函数注入
查看>>
AngularJs ng-change事件/指令(转)
查看>>
linux系统下安装两个或多个tomcat
查看>>
ProtoBuffer 简单例子
查看>>
iOS多线程开发系列之(一)NSThread
查看>>
微信小程序初体验(上)- 腾讯ISUX社交用户体验设计成员出品
查看>>
SAP WM Physical Inventory Method ST & PZ
查看>>