日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

live555 源码分析:RTSPServer 组件结构

發(fā)布時(shí)間:2024/4/11 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 live555 源码分析:RTSPServer 组件结构 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前面幾篇文章分析了 live555 中 RTSP 的處理邏輯,RTSP 處理有關(guān)組件的處理邏輯有點(diǎn)復(fù)雜,本文就再來(lái)梳理一下它們之間的關(guān)系。

live555 中 RTSP 處理有關(guān)組件關(guān)系如下圖:

事件和執(zhí)行流程的源頭在 TaskScheduler。GenericMediaServer 對(duì)象在創(chuàng)建的時(shí)候,會(huì)向 TaskScheduler 注冊(cè)一個(gè) server socket 及處理該 socket 上的事件的處理程序 GenericMediaServer::incomingConnectionHandler(void* instance, int /*mask*/)。

當(dāng)有客戶(hù)端連接服務(wù)器時(shí),觸發(fā) server socket 上的事件處理器執(zhí)行。此時(shí)會(huì)基于客戶(hù)端 socket 創(chuàng)建 ClientConnection 對(duì)象,及 RTSPClientConnection。 RTSPClientConnection 對(duì)象在創(chuàng)建過(guò)程中,會(huì)將該客戶(hù)端 socket 及
ClientConnection 中處理該 socket 上的事件的處理程序 GenericMediaServer::ClientConnection::incomingRequestHandler(void* instance, int /*mask*/) 注冊(cè)給 TaskScheduler。

在客戶(hù)端發(fā)送的 RTSP 請(qǐng)求數(shù)據(jù)到達(dá)之后,GenericMediaServer::ClientConnection 會(huì)讀取這些數(shù)據(jù),并交給 RTSPServer::RTSPClientConnection::handleRequestBytes(int newBytesRead) 處理。

RTSPServer::RTSPClientConnection 解析 RTSP 請(qǐng)求,并處理 OPTIONS、DESCRIBE 和 “SETUP 等無(wú)需流媒體會(huì)話(huà)建立即可處理的請(qǐng)求。

RTSPServer::RTSPClientConnection 在處理 SETUP 請(qǐng)求時(shí),會(huì)創(chuàng)建流媒體會(huì)話(huà)的 RTSPServer::RTSPClientSession,具體的會(huì)話(huà)建立過(guò)程都會(huì)被委托給后者處理。

需要會(huì)話(huà)建立之后才能處理的請(qǐng)求,也會(huì)被交給 RTSPServer::RTSPClientSession 處理。

這里來(lái)看一下 RTSPServer::RTSPClientConnection 的完整定義:

class RTSPServer: public GenericMediaServer { . . . . . . public: // should be protected, but some old compilers complain otherwise// The state of a TCP connection used by a RTSP client:class RTSPClientSession; // forwardclass RTSPClientConnection: public GenericMediaServer::ClientConnection {public:// A data structure that's used to implement the "REGISTER" command:class ParamsForREGISTER {public:ParamsForREGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,RTSPClientConnection* ourConnection, char const* url, char const* urlSuffix,Boolean reuseConnection, Boolean deliverViaTCP, char const* proxyURLSuffix);virtual ~ParamsForREGISTER();private:friend class RTSPClientConnection;char const* fCmd;RTSPClientConnection* fOurConnection;char* fURL;char* fURLSuffix;Boolean fReuseConnection, fDeliverViaTCP;char* fProxyURLSuffix;};protected: // redefined virtual functions:virtual void handleRequestBytes(int newBytesRead);protected:RTSPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in clientAddr);virtual ~RTSPClientConnection();friend class RTSPServer;friend class RTSPClientSession;// Make the handler functions for each command virtual, to allow subclasses to reimplement them, if necessary:virtual void handleCmd_OPTIONS();// You probably won't need to subclass/reimplement this function; reimplement "RTSPServer::allowedCommandNames()" instead.virtual void handleCmd_GET_PARAMETER(char const* fullRequestStr); // when operating on the entire servervirtual void handleCmd_SET_PARAMETER(char const* fullRequestStr); // when operating on the entire servervirtual void handleCmd_DESCRIBE(char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr);virtual void handleCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,char const* url, char const* urlSuffix, char const* fullRequestStr,Boolean reuseConnection, Boolean deliverViaTCP, char const* proxyURLSuffix);// You probably won't need to subclass/reimplement this function;// reimplement "RTSPServer::weImplementREGISTER()" and "RTSPServer::implementCmd_REGISTER()" instead.virtual void handleCmd_bad();virtual void handleCmd_notSupported();virtual void handleCmd_notFound();virtual void handleCmd_sessionNotFound();virtual void handleCmd_unsupportedTransport();// Support for optional RTSP-over-HTTP tunneling:virtual Boolean parseHTTPRequestString(char* resultCmdName, unsigned resultCmdNameMaxSize,char* urlSuffix, unsigned urlSuffixMaxSize,char* sessionCookie, unsigned sessionCookieMaxSize,char* acceptStr, unsigned acceptStrMaxSize);virtual void handleHTTPCmd_notSupported();virtual void handleHTTPCmd_notFound();virtual void handleHTTPCmd_OPTIONS();virtual void handleHTTPCmd_TunnelingGET(char const* sessionCookie);virtual Boolean handleHTTPCmd_TunnelingPOST(char const* sessionCookie, unsigned char const* extraData, unsigned extraDataSize);virtual void handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* fullRequestStr);protected:void resetRequestBuffer();void closeSocketsRTSP();static void handleAlternativeRequestByte(void*, u_int8_t requestByte);void handleAlternativeRequestByte1(u_int8_t requestByte);Boolean authenticationOK(char const* cmdName, char const* urlSuffix, char const* fullRequestStr);void changeClientInputSocket(int newSocketNum, unsigned char const* extraData, unsigned extraDataSize);// used to implement RTSP-over-HTTP tunnelingstatic void continueHandlingREGISTER(ParamsForREGISTER* params);virtual void continueHandlingREGISTER1(ParamsForREGISTER* params);// Shortcuts for setting up a RTSP response (prior to sending it):void setRTSPResponse(char const* responseStr);void setRTSPResponse(char const* responseStr, u_int32_t sessionId);void setRTSPResponse(char const* responseStr, char const* contentStr);void setRTSPResponse(char const* responseStr, u_int32_t sessionId, char const* contentStr);RTSPServer& fOurRTSPServer; // same as ::fOurServerint& fClientInputSocket; // aliased to ::fOurSocketint fClientOutputSocket;Boolean fIsActive;unsigned char* fLastCRLF;unsigned fRecursionCount;char const* fCurrentCSeq;Authenticator fCurrentAuthenticator; // used if access control is neededchar* fOurSessionCookie; // used for optional RTSP-over-HTTP tunnelingunsigned fBase64RemainderCount; // used for optional RTSP-over-HTTP tunneling (possible values: 0,1,2,3)};

RTSPServer::RTSPClientConnection 繼承自 GenericMediaServer::ClientConnection:

class GenericMediaServer: public Medium { . . . . . . public: // should be protected, but some old compilers complain otherwise// The state of a TCP connection used by a client:class ClientConnection {protected:ClientConnection(GenericMediaServer& ourServer, int clientSocket, struct sockaddr_in clientAddr);virtual ~ClientConnection();UsageEnvironment& envir() { return fOurServer.envir(); }void closeSockets();static void incomingRequestHandler(void*, int /*mask*/);void incomingRequestHandler();virtual void handleRequestBytes(int newBytesRead) = 0;void resetRequestBuffer();protected:friend class GenericMediaServer;friend class ClientSession;friend class RTSPServer; // needed to make some broken Windows compilers work; remove this in the future when we end support for WindowsGenericMediaServer& fOurServer;int fOurSocket;struct sockaddr_in fClientAddr;unsigned char fRequestBuffer[REQUEST_BUFFER_SIZE];unsigned char fResponseBuffer[RESPONSE_BUFFER_SIZE];unsigned fRequestBytesAlreadySeen, fRequestBufferBytesLeft;};

從它們的定義,不難理解它們的職責(zé)主要在于處理網(wǎng)絡(luò) I/O,處理 RTSP 請(qǐng)求,并建立會(huì)話(huà)。

再來(lái)看 RTSPServer::RTSPClientSession 的定義:

class RTSPServer: public GenericMediaServer { . . . . . .// The state of an individual client session (using one or more sequential TCP connections) handled by a RTSP server:class RTSPClientSession: public GenericMediaServer::ClientSession {protected:RTSPClientSession(RTSPServer& ourServer, u_int32_t sessionId);virtual ~RTSPClientSession();friend class RTSPServer;friend class RTSPClientConnection;// Make the handler functions for each command virtual, to allow subclasses to redefine them:virtual void handleCmd_SETUP(RTSPClientConnection* ourClientConnection,char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr);virtual void handleCmd_withinSession(RTSPClientConnection* ourClientConnection,char const* cmdName,char const* urlPreSuffix, char const* urlSuffix,char const* fullRequestStr);virtual void handleCmd_TEARDOWN(RTSPClientConnection* ourClientConnection,ServerMediaSubsession* subsession);virtual void handleCmd_PLAY(RTSPClientConnection* ourClientConnection,ServerMediaSubsession* subsession, char const* fullRequestStr);virtual void handleCmd_PAUSE(RTSPClientConnection* ourClientConnection,ServerMediaSubsession* subsession);virtual void handleCmd_GET_PARAMETER(RTSPClientConnection* ourClientConnection,ServerMediaSubsession* subsession, char const* fullRequestStr);virtual void handleCmd_SET_PARAMETER(RTSPClientConnection* ourClientConnection,ServerMediaSubsession* subsession, char const* fullRequestStr);protected:void deleteStreamByTrack(unsigned trackNum);void reclaimStreamStates();Boolean isMulticast() const { return fIsMulticast; }// Shortcuts for setting up a RTSP response (prior to sending it):void setRTSPResponse(RTSPClientConnection* ourClientConnection, char const* responseStr) { ourClientConnection->setRTSPResponse(responseStr); }void setRTSPResponse(RTSPClientConnection* ourClientConnection, char const* responseStr, u_int32_t sessionId) { ourClientConnection->setRTSPResponse(responseStr, sessionId); }void setRTSPResponse(RTSPClientConnection* ourClientConnection, char const* responseStr, char const* contentStr) { ourClientConnection->setRTSPResponse(responseStr, contentStr); }void setRTSPResponse(RTSPClientConnection* ourClientConnection, char const* responseStr, u_int32_t sessionId, char const* contentStr) { ourClientConnection->setRTSPResponse(responseStr, sessionId, contentStr); }protected:RTSPServer& fOurRTSPServer; // same as ::fOurServerBoolean fIsMulticast, fStreamAfterSETUP;unsigned char fTCPStreamIdCount; // used for (optional) RTP/TCPBoolean usesTCPTransport() const { return fTCPStreamIdCount > 0; }unsigned fNumStreamStates;struct streamState {ServerMediaSubsession* subsession;int tcpSocketNum;void* streamToken;} * fStreamStates;};

RTSPServer::RTSPClientSession 繼承自 GenericMediaServer::ClientSession:

// The state of an individual client session (using one or more sequential TCP connections) handled by a server:class ClientSession {protected:ClientSession(GenericMediaServer& ourServer, u_int32_t sessionId);virtual ~ClientSession();UsageEnvironment& envir() { return fOurServer.envir(); }void noteLiveness();static void noteClientLiveness(ClientSession* clientSession);static void livenessTimeoutTask(ClientSession* clientSession);protected:friend class GenericMediaServer;friend class ClientConnection;GenericMediaServer& fOurServer;u_int32_t fOurSessionId;ServerMediaSession* fOurServerMediaSession;TaskToken fLivenessCheckTask;};

不難理解 RTSPServer::RTSPClientSession 用于封裝整個(gè)流媒體會(huì)話(huà),處理那些要求流媒體會(huì)話(huà)已經(jīng)建立的 RTSP 請(qǐng)求,如 PLAY 等。

具體的流媒體數(shù)據(jù)的交互,如音視頻文件/數(shù)據(jù)的解析,RTP/RTCP 數(shù)據(jù)的打包及收發(fā)等,則依賴(lài)于 ServerMediaSession 和 ServerMediaSubsession。

Done。

live555 源碼分析系列文章

live555 源碼分析:簡(jiǎn)介
live555 源碼分析:基礎(chǔ)設(shè)施
live555 源碼分析:MediaSever
Wireshark 抓包分析 RTSP/RTP/RTCP 基本工作過(guò)程
live555 源碼分析:RTSPServer
live555 源碼分析:DESCRIBE 的處理
live555 源碼分析:SETUP 的處理
live555 源碼分析:PLAY 的處理
live555 源碼分析:RTSPServer 組件結(jié)構(gòu)

總結(jié)

以上是生活随笔為你收集整理的live555 源码分析:RTSPServer 组件结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。