From 9e5babf9db52e64bdae60137be7696e56241fca6 Mon Sep 17 00:00:00 2001 From: xingzilong <xingzilong@454eff88-639b-444f-9e54-f578c98de674> Date: 星期五, 18 八月 2017 18:12:17 +0800 Subject: [PATCH] H264 NALU解析 并在RTSPServer判断 --- VisitFace/RtspNativeCodec/app/libs/live555/include/liveMedia/RTSPServer.hh | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 348 insertions(+), 0 deletions(-) diff --git a/VisitFace/RtspNativeCodec/app/libs/live555/include/liveMedia/RTSPServer.hh b/VisitFace/RtspNativeCodec/app/libs/live555/include/liveMedia/RTSPServer.hh new file mode 100644 index 0000000..e20ebc6 --- /dev/null +++ b/VisitFace/RtspNativeCodec/app/libs/live555/include/liveMedia/RTSPServer.hh @@ -0,0 +1,348 @@ +/********** +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) + +This library is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +**********/ +// "liveMedia" +// Copyright (c) 1996-2017 Live Networks, Inc. All rights reserved. +// A RTSP server +// C++ header + +#ifndef _RTSP_SERVER_HH +#define _RTSP_SERVER_HH + +#ifndef _GENERIC_MEDIA_SERVER_HH +#include "GenericMediaServer.hh" +#endif +#ifndef _DIGEST_AUTHENTICATION_HH +#include "DigestAuthentication.hh" +#endif + +class RTSPServer: public GenericMediaServer { +public: + static RTSPServer* createNew(UsageEnvironment& env, Port ourPort = 554, + UserAuthenticationDatabase* authDatabase = NULL, + unsigned reclamationSeconds = 65); + // If ourPort.num() == 0, we'll choose the port number + // Note: The caller is responsible for reclaiming "authDatabase" + // If "reclamationSeconds" > 0, then the "RTSPClientSession" state for + // each client will get reclaimed (and the corresponding RTP stream(s) + // torn down) if no RTSP commands - or RTCP "RR" packets - from the + // client are received in at least "reclamationSeconds" seconds. + + static Boolean lookupByName(UsageEnvironment& env, char const* name, + RTSPServer*& resultServer); + + typedef void (responseHandlerForREGISTER)(RTSPServer* rtspServer, unsigned requestId, int resultCode, char* resultString); + unsigned registerStream(ServerMediaSession* serverMediaSession, + char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum, + responseHandlerForREGISTER* responseHandler, + char const* username = NULL, char const* password = NULL, + Boolean receiveOurStreamViaTCP = False, + char const* proxyURLSuffix = NULL); + // 'Register' the stream represented by "serverMediaSession" with the given remote client (specifed by name and port number). + // This is done using our custom "REGISTER" RTSP command. + // The function returns a unique number that can be used to identify the request; this number is also passed to "responseHandler". + // When a response is received from the remote client (or the "REGISTER" request fails), the specified response handler + // (if non-NULL) is called. (Note that the "resultString" passed to the handler was dynamically allocated, + // and should be delete[]d by the handler after use.) + // If "receiveOurStreamViaTCP" is True, then we're requesting that the remote client access our stream using RTP/RTCP-over-TCP. + // (Otherwise, the remote client may choose regular RTP/RTCP-over-UDP streaming.) + // "proxyURLSuffix" (optional) is used only when the remote client is also a proxy server. + // It tells the proxy server the suffix that it should use in its "rtsp://" URL (when front-end clients access the stream) + + typedef void (responseHandlerForDEREGISTER)(RTSPServer* rtspServer, unsigned requestId, int resultCode, char* resultString); + unsigned deregisterStream(ServerMediaSession* serverMediaSession, + char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum, + responseHandlerForDEREGISTER* responseHandler, + char const* username = NULL, char const* password = NULL, + char const* proxyURLSuffix = NULL); + // Used to turn off a previous "registerStream()" - using our custom "DEREGISTER" RTSP command. + + char* rtspURL(ServerMediaSession const* serverMediaSession, int clientSocket = -1) const; + // returns a "rtsp://" URL that could be used to access the + // specified session (which must already have been added to + // us using "addServerMediaSession()". + // This string is dynamically allocated; caller should delete[] + // (If "clientSocket" is non-negative, then it is used (by calling "getsockname()") to determine + // the IP address to be used in the URL.) + char* rtspURLPrefix(int clientSocket = -1) const; + // like "rtspURL()", except that it returns just the common prefix used by + // each session's "rtsp://" URL. + // This string is dynamically allocated; caller should delete[] + + UserAuthenticationDatabase* setAuthenticationDatabase(UserAuthenticationDatabase* newDB); + // Changes the server's authentication database to "newDB", returning a pointer to the old database (if there was one). + // "newDB" may be NULL (you can use this to disable authentication at runtime, if desired). + + void disableStreamingRTPOverTCP() { + fAllowStreamingRTPOverTCP = False; + } + + Boolean setUpTunnelingOverHTTP(Port httpPort); + // (Attempts to) enable RTSP-over-HTTP tunneling on the specified port. + // Returns True iff the specified port can be used in this way (i.e., it's not already being used for a separate HTTP server). + // Note: RTSP-over-HTTP tunneling is described in + // http://mirror.informatimago.com/next/developer.apple.com/quicktime/icefloe/dispatch028.html + // and http://images.apple.com/br/quicktime/pdf/QTSS_Modules.pdf + portNumBits httpServerPortNum() const; // in host byte order. (Returns 0 if not present.) + +protected: + RTSPServer(UsageEnvironment& env, + int ourSocket, Port ourPort, + UserAuthenticationDatabase* authDatabase, + unsigned reclamationSeconds); + // called only by createNew(); + virtual ~RTSPServer(); + + virtual char const* allowedCommandNames(); // used to implement "RTSPClientConnection::handleCmd_OPTIONS()" + virtual Boolean weImplementREGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/, + char const* proxyURLSuffix, char*& responseStr); + // used to implement "RTSPClientConnection::handleCmd_REGISTER()" + // Note: "responseStr" is dynamically allocated (or NULL), and should be delete[]d after the call + virtual void implementCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/, + char const* url, char const* urlSuffix, int socketToRemoteServer, + Boolean deliverViaTCP, char const* proxyURLSuffix); + // used to implement "RTSPClientConnection::handleCmd_REGISTER()" + + virtual UserAuthenticationDatabase* getAuthenticationDatabaseForCommand(char const* cmdName); + virtual Boolean specialClientAccessCheck(int clientSocket, struct sockaddr_in& clientAddr, + char const* urlSuffix); + // a hook that allows subclassed servers to do server-specific access checking + // on each client (e.g., based on client IP address), without using digest authentication. + virtual Boolean specialClientUserAccessCheck(int clientSocket, struct sockaddr_in& clientAddr, + char const* urlSuffix, char const *username); + // another hook that allows subclassed servers to do server-specific access checking + // - this time after normal digest authentication has already taken place (and would otherwise allow access). + // (This test can only be used to further restrict access, not to grant additional access.) + +private: // redefined virtual functions + virtual Boolean isRTSPServer() const; + +public: // should be protected, but some old compilers complain otherwise + // The state of a TCP connection used by a RTSP client: + class RTSPClientSession; // forward + class 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 server + virtual void handleCmd_SET_PARAMETER(char const* fullRequestStr); // when operating on the entire server + virtual 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 tunneling + static 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 ::fOurServer + int& fClientInputSocket; // aliased to ::fOurSocket + int fClientOutputSocket; + Boolean fIsActive; + unsigned char* fLastCRLF; + unsigned fRecursionCount; + char const* fCurrentCSeq; + Authenticator fCurrentAuthenticator; // used if access control is needed + char* fOurSessionCookie; // used for optional RTSP-over-HTTP tunneling + unsigned fBase64RemainderCount; // used for optional RTSP-over-HTTP tunneling (possible values: 0,1,2,3) + }; + + // 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 ::fOurServer + Boolean fIsMulticast, fStreamAfterSETUP; + unsigned char fTCPStreamIdCount; // used for (optional) RTP/TCP + Boolean usesTCPTransport() const { return fTCPStreamIdCount > 0; } + unsigned fNumStreamStates; + struct streamState { + ServerMediaSubsession* subsession; + int tcpSocketNum; + void* streamToken; + } * fStreamStates; + }; + +protected: // redefined virtual functions + // If you subclass "RTSPClientConnection", then you must also redefine this virtual function in order + // to create new objects of your subclass: + virtual ClientConnection* createNewClientConnection(int clientSocket, struct sockaddr_in clientAddr); + +protected: + // If you subclass "RTSPClientSession", then you must also redefine this virtual function in order + // to create new objects of your subclass: + virtual ClientSession* createNewClientSession(u_int32_t sessionId); + +private: + static void incomingConnectionHandlerHTTP(void*, int /*mask*/); + void incomingConnectionHandlerHTTP(); + + void noteTCPStreamingOnSocket(int socketNum, RTSPClientSession* clientSession, unsigned trackNum); + void unnoteTCPStreamingOnSocket(int socketNum, RTSPClientSession* clientSession, unsigned trackNum); + void stopTCPStreamingOnSocket(int socketNum); + +private: + friend class RTSPClientConnection; + friend class RTSPClientSession; + friend class RegisterRequestRecord; + friend class DeregisterRequestRecord; + int fHTTPServerSocket; // for optional RTSP-over-HTTP tunneling + Port fHTTPServerPort; // ditto + HashTable* fClientConnectionsForHTTPTunneling; // maps client-supplied 'session cookie' strings to "RTSPClientConnection"s + // (used only for optional RTSP-over-HTTP tunneling) + HashTable* fTCPStreamingDatabase; + // maps TCP socket numbers to ids of sessions that are streaming over it (RTP/RTCP-over-TCP) + HashTable* fPendingRegisterOrDeregisterRequests; + unsigned fRegisterOrDeregisterRequestCounter; + UserAuthenticationDatabase* fAuthDB; + Boolean fAllowStreamingRTPOverTCP; // by default, True +}; + + +////////// A subclass of "RTSPServer" that implements the "REGISTER" command to set up proxying on the specified URL ////////// + +class RTSPServerWithREGISTERProxying: public RTSPServer { +public: + static RTSPServerWithREGISTERProxying* createNew(UsageEnvironment& env, Port ourPort = 554, + UserAuthenticationDatabase* authDatabase = NULL, + UserAuthenticationDatabase* authDatabaseForREGISTER = NULL, + unsigned reclamationSeconds = 65, + Boolean streamRTPOverTCP = False, + int verbosityLevelForProxying = 0); + +protected: + RTSPServerWithREGISTERProxying(UsageEnvironment& env, int ourSocket, Port ourPort, + UserAuthenticationDatabase* authDatabase, UserAuthenticationDatabase* authDatabaseForREGISTER, + unsigned reclamationSeconds, + Boolean streamRTPOverTCP, int verbosityLevelForProxying); + // called only by createNew(); + virtual ~RTSPServerWithREGISTERProxying(); + +protected: // redefined virtual functions + virtual char const* allowedCommandNames(); + virtual Boolean weImplementREGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/, + char const* proxyURLSuffix, char*& responseStr); + virtual void implementCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/, + char const* url, char const* urlSuffix, int socketToRemoteServer, + Boolean deliverViaTCP, char const* proxyURLSuffix); + virtual UserAuthenticationDatabase* getAuthenticationDatabaseForCommand(char const* cmdName); + +private: + Boolean fStreamRTPOverTCP; + int fVerbosityLevelForProxying; + unsigned fRegisteredProxyCounter; + char* fAllowedCommandNames; + UserAuthenticationDatabase* fAuthDBForREGISTER; +}; + + +// A special version of "parseTransportHeader()", used just for parsing the "Transport:" header +// in an incoming "REGISTER" command: +void parseTransportHeaderForREGISTER(char const* buf, // in + Boolean &reuseConnection, // out + Boolean& deliverViaTCP, // out + char*& proxyURLSuffix); // out + +#endif -- Gitblit v1.8.0