From 2ae0446917184b36996823e9dbf452dba82e8994 Mon Sep 17 00:00:00 2001
From: xuxiuxi <xuxiuxi@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期五, 21 四月 2017 12:31:44 +0800
Subject: [PATCH] 

---
 VisitFace/RtspNativeCodec/app/libs/live555/include/liveMedia/RTSPClient.hh |  394 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 394 insertions(+), 0 deletions(-)

diff --git a/VisitFace/RtspNativeCodec/app/libs/live555/include/liveMedia/RTSPClient.hh b/VisitFace/RtspNativeCodec/app/libs/live555/include/liveMedia/RTSPClient.hh
new file mode 100644
index 0000000..53e0130
--- /dev/null
+++ b/VisitFace/RtspNativeCodec/app/libs/live555/include/liveMedia/RTSPClient.hh
@@ -0,0 +1,394 @@
+/**********
+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 generic RTSP client - for a single "rtsp://" URL
+// C++ header
+
+#ifndef _RTSP_CLIENT_HH
+#define _RTSP_CLIENT_HH
+
+#ifndef _MEDIA_SESSION_HH
+#include "MediaSession.hh"
+#endif
+#ifndef _NET_ADDRESS_HH
+#include "NetAddress.hh"
+#endif
+#ifndef _DIGEST_AUTHENTICATION_HH
+#include "DigestAuthentication.hh"
+#endif
+#ifndef OMIT_REGISTER_HANDLING
+#ifndef _RTSP_SERVER_HH
+#include "RTSPServer.hh" // For the optional "HandlerForREGISTERCommand" mini-server
+#endif
+#endif
+
+class RTSPClient: public Medium {
+public:
+  static RTSPClient* createNew(UsageEnvironment& env, char const* rtspURL,
+			       int verbosityLevel = 0,
+			       char const* applicationName = NULL,
+			       portNumBits tunnelOverHTTPPortNum = 0,
+			       int socketNumToServer = -1);
+  // If "tunnelOverHTTPPortNum" is non-zero, we tunnel RTSP (and RTP)
+  //     over a HTTP connection with the given port number, using the technique
+  //     described in Apple's document <http://developer.apple.com/documentation/QuickTime/QTSS/Concepts/chapter_2_section_14.html>
+  // If "socketNumToServer" is >= 0, then it is the socket number of an already-existing TCP connection to the server.
+  //     (In this case, "rtspURL" must point to the socket's endpoint, so that it can be accessed via the socket.)
+
+  typedef void (responseHandler)(RTSPClient* rtspClient,
+				 int resultCode, char* resultString);
+      // A function that is called in response to a RTSP command.  The parameters are as follows:
+      //     "rtspClient": The "RTSPClient" object on which the original command was issued.
+      //     "resultCode": If zero, then the command completed successfully.  If non-zero, then the command did not complete
+      //         successfully, and "resultCode" indicates the error, as follows:
+      //             A positive "resultCode" is a RTSP error code (for example, 404 means "not found")
+      //             A negative "resultCode" indicates a socket/network error; 0-"resultCode" is the standard "errno" code.
+      //     "resultString": A ('\0'-terminated) string returned along with the response, or else NULL.
+      //         In particular:
+      //             "resultString" for a successful "DESCRIBE" command will be the media session's SDP description.
+      //             "resultString" for a successful "OPTIONS" command will be a list of allowed commands.
+      //         Note that this string can be present (i.e., not NULL) even if "resultCode" is non-zero - i.e., an error message.
+      //         Also, "resultString" can be NULL, even if "resultCode" is zero (e.g., if the RTSP command succeeded, but without
+      //             including an appropriate result header).
+      //         Note also that this string is dynamically allocated, and must be freed by the handler (or the caller)
+      //             - using "delete[]".
+
+  unsigned sendDescribeCommand(responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues a RTSP "DESCRIBE" command, then returns the "CSeq" sequence number that was used in the command.
+      // The (programmer-supplied) "responseHandler" function is called later to handle the response
+      //     (or is called immediately - with an error code - if the command cannot be sent).
+      // "authenticator" (optional) is used for access control.  If you have username and password strings, you can use this by
+      //     passing an actual parameter that you created by creating an "Authenticator(username, password) object".
+      //     (Note that if you supply a non-NULL "authenticator" parameter, you need do this only for the first command you send.)
+
+  unsigned sendOptionsCommand(responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues a RTSP "OPTIONS" command, then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  unsigned sendAnnounceCommand(char const* sdpDescription, responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues a RTSP "ANNOUNCE" command (with "sdpDescription" as parameter),
+      //     then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  unsigned sendSetupCommand(MediaSubsession& subsession, responseHandler* responseHandler,
+			    Boolean streamOutgoing = False,
+			    Boolean streamUsingTCP = False,
+			    Boolean forceMulticastOnUnspecified = False,
+			    Authenticator* authenticator = NULL);
+      // Issues a RTSP "SETUP" command, then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  unsigned sendPlayCommand(MediaSession& session, responseHandler* responseHandler,
+			   double start = 0.0f, double end = -1.0f, float scale = 1.0f,
+			   Authenticator* authenticator = NULL);
+      // Issues an aggregate RTSP "PLAY" command on "session", then returns the "CSeq" sequence number that was used in the command.
+      // (Note: start=-1 means 'resume'; end=-1 means 'play to end')
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+  unsigned sendPlayCommand(MediaSubsession& subsession, responseHandler* responseHandler,
+			   double start = 0.0f, double end = -1.0f, float scale = 1.0f,
+			   Authenticator* authenticator = NULL);
+      // Issues a RTSP "PLAY" command on "subsession", then returns the "CSeq" sequence number that was used in the command.
+      // (Note: start=-1 means 'resume'; end=-1 means 'play to end')
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  // Alternative forms of "sendPlayCommand()", used to send "PLAY" commands that include an 'absolute' time range:
+  // (The "absStartTime" string (and "absEndTime" string, if present) *must* be of the form
+  //  "YYYYMMDDTHHMMSSZ" or "YYYYMMDDTHHMMSS.<frac>Z")
+  unsigned sendPlayCommand(MediaSession& session, responseHandler* responseHandler,
+			   char const* absStartTime, char const* absEndTime = NULL, float scale = 1.0f,
+			   Authenticator* authenticator = NULL);
+  unsigned sendPlayCommand(MediaSubsession& subsession, responseHandler* responseHandler,
+			   char const* absStartTime, char const* absEndTime = NULL, float scale = 1.0f,
+			   Authenticator* authenticator = NULL);
+
+  unsigned sendPauseCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues an aggregate RTSP "PAUSE" command on "session", then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+  unsigned sendPauseCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues a RTSP "PAUSE" command on "subsession", then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  unsigned sendRecordCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues an aggregate RTSP "RECORD" command on "session", then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+  unsigned sendRecordCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues a RTSP "RECORD" command on "subsession", then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  unsigned sendTeardownCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues an aggregate RTSP "TEARDOWN" command on "session", then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+  unsigned sendTeardownCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
+      // Issues a RTSP "TEARDOWN" command on "subsession", then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  unsigned sendSetParameterCommand(MediaSession& session, responseHandler* responseHandler,
+				   char const* parameterName, char const* parameterValue,
+				   Authenticator* authenticator = NULL);
+      // Issues an aggregate RTSP "SET_PARAMETER" command on "session", then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  unsigned sendGetParameterCommand(MediaSession& session, responseHandler* responseHandler, char const* parameterName,
+				   Authenticator* authenticator = NULL);
+      // Issues an aggregate RTSP "GET_PARAMETER" command on "session", then returns the "CSeq" sequence number that was used in the command.
+      // (The "responseHandler" and "authenticator" parameters are as described for "sendDescribeCommand".)
+
+  void sendDummyUDPPackets(MediaSession& session, unsigned numDummyPackets = 2);
+  void sendDummyUDPPackets(MediaSubsession& subsession, unsigned numDummyPackets = 2);
+      // Sends short 'dummy' (i.e., non-RTP or RTCP) UDP packets towards the server, to increase
+      // the likelihood of RTP/RTCP packets from the server reaching us if we're behind a NAT.
+      // (If we requested RTP-over-TCP streaming, then these functions have no effect.)
+      // Our implementation automatically does this just prior to sending each "PLAY" command;
+      // You should not call these functions yourself unless you know what you're doing.
+
+  void setSpeed(MediaSession& session, float speed = 1.0f);
+      // Set (recorded) media download speed to given value to support faster download using 'Speed:'
+      // option on 'PLAY' command.
+
+  Boolean changeResponseHandler(unsigned cseq, responseHandler* newResponseHandler);
+      // Changes the response handler for the previously-performed command (whose operation returned "cseq").
+      // (To turn off any response handling for the command, use a "newResponseHandler" value of NULL.  This might be done as part
+      //  of an implementation of a 'timeout handler' on the command, for example.)
+      // This function returns True iff "cseq" was for a valid previously-performed command (whose response is still unhandled).
+
+  int socketNum() const { return fInputSocketNum; }
+
+  static Boolean lookupByName(UsageEnvironment& env,
+			      char const* sourceName,
+			      RTSPClient*& resultClient);
+
+  static Boolean parseRTSPURL(UsageEnvironment& env, char const* url,
+			      char*& username, char*& password, NetAddress& address, portNumBits& portNum, char const** urlSuffix = NULL);
+      // Parses "url" as "rtsp://[<username>[:<password>]@]<server-address-or-name>[:<port>][/<stream-name>]"
+      // (Note that the returned "username" and "password" are either NULL, or heap-allocated strings that the caller must later delete[].)
+
+  void setUserAgentString(char const* userAgentName);
+      // sets an alternative string to be used in RTSP "User-Agent:" headers
+
+  void disallowBasicAuthentication() { fAllowBasicAuthentication = False; }
+      // call this if you don't want the server to request 'Basic' authentication
+      // (which would cause the client to send usernames and passwords over the net).
+
+  unsigned sessionTimeoutParameter() const { return fSessionTimeoutParameter; }
+
+  char const* url() const { return fBaseURL; }
+
+  static unsigned responseBufferSize;
+
+public: // Some compilers complain if this is "private:"
+  // The state of a request-in-progress:
+  class RequestRecord {
+  public:
+    RequestRecord(unsigned cseq, char const* commandName, responseHandler* handler,
+		  MediaSession* session = NULL, MediaSubsession* subsession = NULL, u_int32_t booleanFlags = 0,
+		  double start = 0.0f, double end = -1.0f, float scale = 1.0f, char const* contentStr = NULL);
+    RequestRecord(unsigned cseq, responseHandler* handler,
+		  char const* absStartTime, char const* absEndTime = NULL, float scale = 1.0f,
+		  MediaSession* session = NULL, MediaSubsession* subsession = NULL);
+        // alternative constructor for creating "PLAY" requests that include 'absolute' time values
+    virtual ~RequestRecord();
+
+    RequestRecord*& next() { return fNext; }
+    unsigned& cseq() { return fCSeq; }
+    char const* commandName() const { return fCommandName; }
+    MediaSession* session() const { return fSession; }
+    MediaSubsession* subsession() const { return fSubsession; }
+    u_int32_t booleanFlags() const { return fBooleanFlags; }
+    double start() const { return fStart; }
+    double end() const { return fEnd; }
+    char const* absStartTime() const { return fAbsStartTime; }
+    char const* absEndTime() const { return fAbsEndTime; }
+    float scale() const { return fScale; }
+    char* contentStr() const { return fContentStr; }
+    responseHandler*& handler() { return fHandler; }
+
+  private:
+    RequestRecord* fNext;
+    unsigned fCSeq;
+    char const* fCommandName;
+    MediaSession* fSession;
+    MediaSubsession* fSubsession;
+    u_int32_t fBooleanFlags;
+    double fStart, fEnd;
+    char *fAbsStartTime, *fAbsEndTime; // used for optional 'absolute' (i.e., "time=") range specifications
+    float fScale;
+    char* fContentStr;
+    responseHandler* fHandler;
+  };
+
+protected:
+  RTSPClient(UsageEnvironment& env, char const* rtspURL,
+	     int verbosityLevel, char const* applicationName, portNumBits tunnelOverHTTPPortNum, int socketNumToServer);
+      // called only by createNew();
+  virtual ~RTSPClient();
+
+  void reset();
+  void setBaseURL(char const* url);
+  int grabSocket(); // allows a subclass to reuse our input socket, so that it won't get closed when we're deleted
+  virtual unsigned sendRequest(RequestRecord* request);
+  virtual Boolean setRequestFields(RequestRecord* request,
+				   char*& cmdURL, Boolean& cmdURLWasAllocated,
+				   char const*& protocolStr,
+				   char*& extraHeaders, Boolean& extraHeadersWereAllocated);
+      // used to implement "sendRequest()"; subclasses may reimplement this (e.g., when implementing a new command name)
+  virtual int connectToServer(int socketNum, portNumBits remotePortNum); // used to implement "openConnection()"; result values: -1: failure; 0: pending; 1: success
+
+private: // redefined virtual functions
+  virtual Boolean isRTSPClient() const;
+
+private:
+  class RequestQueue {
+  public:
+    RequestQueue();
+    RequestQueue(RequestQueue& origQueue); // moves the queue contents to the new queue
+    virtual ~RequestQueue();
+
+    void enqueue(RequestRecord* request); // "request" must not be NULL
+    RequestRecord* dequeue();
+    void putAtHead(RequestRecord* request); // "request" must not be NULL
+    RequestRecord* findByCSeq(unsigned cseq);
+    Boolean isEmpty() const { return fHead == NULL; }
+    void reset();
+
+  private:
+    RequestRecord* fHead;
+    RequestRecord* fTail;
+  };
+
+  void resetTCPSockets();
+  void resetResponseBuffer();
+  int openConnection(); // result values: -1: failure; 0: pending; 1: success
+  char* createAuthenticatorString(char const* cmd, char const* url);
+  char* createBlocksizeString(Boolean streamUsingTCP);
+  void handleRequestError(RequestRecord* request);
+  Boolean parseResponseCode(char const* line, unsigned& responseCode, char const*& responseString);
+  void handleIncomingRequest();
+  static Boolean checkForHeader(char const* line, char const* headerName, unsigned headerNameLength, char const*& headerParams);
+  Boolean parseTransportParams(char const* paramsStr,
+			       char*& serverAddressStr, portNumBits& serverPortNum,
+			       unsigned char& rtpChannelId, unsigned char& rtcpChannelId);
+  Boolean parseScaleParam(char const* paramStr, float& scale);
+  Boolean parseSpeedParam(char const* paramStr, float& speed);
+  Boolean parseRTPInfoParams(char const*& paramStr, u_int16_t& seqNum, u_int32_t& timestamp);
+  Boolean handleSETUPResponse(MediaSubsession& subsession, char const* sessionParamsStr, char const* transportParamsStr,
+			      Boolean streamUsingTCP);
+  Boolean handlePLAYResponse(MediaSession& session, MediaSubsession& subsession,
+                             char const* scaleParamsStr, const char* speedParamsStr,
+			     char const* rangeParamsStr, char const* rtpInfoParamsStr);
+  Boolean handleTEARDOWNResponse(MediaSession& session, MediaSubsession& subsession);
+  Boolean handleGET_PARAMETERResponse(char const* parameterName, char*& resultValueString, char* resultValueStringEnd);
+  Boolean handleAuthenticationFailure(char const* wwwAuthenticateParamsStr);
+  Boolean resendCommand(RequestRecord* request);
+  char const* sessionURL(MediaSession const& session) const;
+  static void handleAlternativeRequestByte(void*, u_int8_t requestByte);
+  void handleAlternativeRequestByte1(u_int8_t requestByte);
+  void constructSubsessionURL(MediaSubsession const& subsession,
+			      char const*& prefix,
+			      char const*& separator,
+			      char const*& suffix);
+
+  // Support for tunneling RTSP-over-HTTP:
+  Boolean setupHTTPTunneling1(); // send the HTTP "GET"
+  static void responseHandlerForHTTP_GET(RTSPClient* rtspClient, int responseCode, char* responseString);
+  void responseHandlerForHTTP_GET1(int responseCode, char* responseString);
+  Boolean setupHTTPTunneling2(); // send the HTTP "POST"
+
+  // Support for asynchronous connections to the server:
+  static void connectionHandler(void*, int /*mask*/);
+  void connectionHandler1();
+
+  // Support for handling data sent back by a server:
+  static void incomingDataHandler(void*, int /*mask*/);
+  void incomingDataHandler1();
+  void handleResponseBytes(int newBytesRead);
+
+public:
+  u_int16_t desiredMaxIncomingPacketSize;
+    // If set to a value >0, then a "Blocksize:" header with this value (minus an allowance for
+    // IP, UDP, and RTP headers) will be sent with each "SETUP" request.
+
+protected:
+  int fVerbosityLevel;
+  unsigned fCSeq; // sequence number, used in consecutive requests
+  Authenticator fCurrentAuthenticator;
+  Boolean fAllowBasicAuthentication;
+  netAddressBits fServerAddress;
+
+private:
+  portNumBits fTunnelOverHTTPPortNum;
+  char* fUserAgentHeaderStr;
+  unsigned fUserAgentHeaderStrLen;
+  int fInputSocketNum, fOutputSocketNum;
+  char* fBaseURL;
+  unsigned char fTCPStreamIdCount; // used for (optional) RTP/TCP
+  char* fLastSessionId;
+  unsigned fSessionTimeoutParameter; // optionally set in response "Session:" headers
+  char* fResponseBuffer;
+  unsigned fResponseBytesAlreadySeen, fResponseBufferBytesLeft;
+  RequestQueue fRequestsAwaitingConnection, fRequestsAwaitingHTTPTunneling, fRequestsAwaitingResponse;
+
+  // Support for tunneling RTSP-over-HTTP:
+  char fSessionCookie[33];
+  unsigned fSessionCookieCounter;
+  Boolean fHTTPTunnelingConnectionIsPending;
+};
+
+
+#ifndef OMIT_REGISTER_HANDLING
+////////// HandlerServerForREGISTERCommand /////////
+
+// A simple server that creates a new "RTSPClient" object whenever a "REGISTER" request arrives (specifying the "rtsp://" URL
+// of a stream).  The new "RTSPClient" object will be created with the specified URL, and passed to the provided handler function.
+
+typedef void onRTSPClientCreationFunc(RTSPClient* newRTSPClient, Boolean requestStreamingOverTCP);
+
+class HandlerServerForREGISTERCommand: public RTSPServer {
+public:
+  static HandlerServerForREGISTERCommand* createNew(UsageEnvironment& env, onRTSPClientCreationFunc* creationFunc,
+						    Port ourPort = 0, UserAuthenticationDatabase* authDatabase = NULL,
+						    int verbosityLevel = 0, char const* applicationName = NULL);
+      // If ourPort.num() == 0, we'll choose the port number ourself.  (Use the following function to get it.)
+  portNumBits serverPortNum() const { return ntohs(fServerPort.num()); }
+
+protected:
+  HandlerServerForREGISTERCommand(UsageEnvironment& env, onRTSPClientCreationFunc* creationFunc, int ourSocket, Port ourPort,
+				  UserAuthenticationDatabase* authDatabase, int verbosityLevel, char const* applicationName);
+      // called only by createNew();
+  virtual ~HandlerServerForREGISTERCommand();
+
+  virtual RTSPClient* createNewRTSPClient(char const* rtspURL, int verbosityLevel, char const* applicationName,
+					  int socketNumToServer);
+      // This function - by default - creates a (base) "RTSPClient" object.  If you want to create a subclass
+      // of "RTSPClient" instead, then subclass this class, and redefine this virtual function.
+
+protected: // redefined virtual functions
+  virtual char const* allowedCommandNames(); // "OPTIONS", "REGISTER", and (perhaps) "DEREGISTER" only
+  virtual Boolean weImplementREGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,
+				      char const* proxyURLSuffix, char*& responseStr);
+      // redefined to return True (for cmd=="REGISTER")
+  virtual void implementCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,
+				     char const* url, char const* urlSuffix, int socketToRemoteServer,
+				     Boolean deliverViaTCP, char const* proxyURLSuffix);
+
+private:
+  onRTSPClientCreationFunc* fCreationFunc;
+  int fVerbosityLevel;
+  char* fApplicationName;
+};
+#endif
+
+#endif

--
Gitblit v1.8.0