live
ProxyServerMediaSession.hh
Go to the documentation of this file.
1 /**********
2 This library is free software; you can redistribute it and/or modify it under
3 the terms of the GNU Lesser General Public License as published by the
4 Free Software Foundation; either version 3 of the License, or (at your
5 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6 
7 This library is distributed in the hope that it will be useful, but WITHOUT
8 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10 more details.
11 
12 You should have received a copy of the GNU Lesser General Public License
13 along with this library; if not, write to the Free Software Foundation, Inc.,
14 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 **********/
16 // "liveMedia"
17 // Copyright (c) 1996-2021 Live Networks, Inc. All rights reserved.
18 // A subclass of "ServerMediaSession" that can be used to create a (unicast) RTSP servers that acts as a 'proxy' for
19 // another (unicast or multicast) RTSP/RTP stream.
20 // C++ header
21 
22 #ifndef _PROXY_SERVER_MEDIA_SESSION_HH
23 #define _PROXY_SERVER_MEDIA_SESSION_HH
24 
25 #ifndef _SERVER_MEDIA_SESSION_HH
26 #include "ServerMediaSession.hh"
27 #endif
28 #ifndef _MEDIA_SESSION_HH
29 #include "MediaSession.hh"
30 #endif
31 #ifndef _RTSP_CLIENT_HH
32 #include "RTSPClient.hh"
33 #endif
34 #ifndef _MEDIA_TRANSCODING_TABLE_HH
35 #include "MediaTranscodingTable.hh"
36 #endif
37 
38 // A subclass of "RTSPClient", used to refer to the particular "ProxyServerMediaSession" object being used.
39 // It is used only within the implementation of "ProxyServerMediaSession", but is defined here, in case developers wish to
40 // subclass it.
41 
42 class ProxyRTSPClient: public RTSPClient {
43 public:
44  ProxyRTSPClient(class ProxyServerMediaSession& ourServerMediaSession, char const* rtspURL,
45  char const* username, char const* password,
46  portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer);
47  virtual ~ProxyRTSPClient();
48 
49  void continueAfterDESCRIBE(char const* sdpDescription);
50  void continueAfterLivenessCommand(int resultCode, Boolean serverSupportsGetParameter);
51  void continueAfterSETUP(int resultCode);
52  void continueAfterPLAY(int resultCode);
53  void scheduleReset();
54 
55 private:
56  void reset();
57  int connectToServer(int socketNum, portNumBits remotePortNum);
58 
60 
62  static void sendLivenessCommand(void* clientData);
63  void doReset();
64  static void doReset(void* clientData);
65 
67  static void sendDESCRIBE(void* clientData);
68  void sendDESCRIBE();
69 
70  static void subsessionTimeout(void* clientData);
72 
73 private:
77  char* fOurURL;
81  unsigned fNumSetupsDone;
82  unsigned fNextDESCRIBEDelay; // in seconds
85 };
86 
87 
88 typedef ProxyRTSPClient*
90  char const* rtspURL,
91  char const* username, char const* password,
92  portNumBits tunnelOverHTTPPortNum, int verbosityLevel,
93  int socketNumToServer);
96  char const* rtspURL,
97  char const* username, char const* password,
98  portNumBits tunnelOverHTTPPortNum, int verbosityLevel,
99  int socketNumToServer);
100 
102 public:
104  GenericMediaServer* ourMediaServer, // Note: We can be used by just one server
105  char const* inputStreamURL, // the "rtsp://" URL of the stream we'll be proxying
106  char const* streamName = NULL,
107  char const* username = NULL, char const* password = NULL,
108  portNumBits tunnelOverHTTPPortNum = 0,
109  // for streaming the *proxied* (i.e., back-end) stream
110  int verbosityLevel = 0,
111  int socketNumToServer = -1,
112  MediaTranscodingTable* transcodingTable = NULL);
113  // Hack: "tunnelOverHTTPPortNum" == 0xFFFF (i.e., all-ones) means: Stream RTP/RTCP-over-TCP, but *not* using HTTP
114  // "verbosityLevel" == 1 means display basic proxy setup info; "verbosityLevel" == 2 means display RTSP client protocol also.
115  // If "socketNumToServer" is >= 0, then it is the socket number of an already-existing TCP connection to the server.
116  // (In this case, "inputStreamURL" must point to the socket's endpoint, so that it can be accessed via the socket.)
117 
119 
120  char const* url() const;
121 
123  // initialized to 0; set to 1 when the back-end "DESCRIBE" completes.
124  // (This can be used as a 'watch variable' in "doEventLoop()".)
126  // This can be used - along with "describeCompletedFlag" - to check whether the back-end "DESCRIBE" completed *successfully*.
127 
128 protected:
130  char const* inputStreamURL, char const* streamName,
131  char const* username, char const* password,
132  portNumBits tunnelOverHTTPPortNum, int verbosityLevel,
133  int socketNumToServer,
134  MediaTranscodingTable* transcodingTable,
135  createNewProxyRTSPClientFunc* ourCreateNewProxyRTSPClientFunc
137  portNumBits initialPortNum = 6970,
138  Boolean multiplexRTCPWithRTP = False);
139 
140  // If you subclass "ProxyRTSPClient", then you will also need to define your own function
141  // - with signature "createNewProxyRTSPClientFunc" (see above) - that creates a new object
142  // of this subclass. You should also subclass "ProxyServerMediaSession" and, in your
143  // subclass's constructor, initialize the parent class (i.e., "ProxyServerMediaSession")
144  // constructor by passing your new function as the "ourCreateNewProxyRTSPClientFunc"
145  // parameter.
146 
147  // Subclasses may redefine the following functions, if they want "ProxyServerSubsession"s
148  // to create subclassed "Groupsock" and/or "RTCPInstance" objects:
149  virtual Groupsock* createGroupsock(struct sockaddr_storage const& addr, Port port);
150  virtual RTCPInstance* createRTCP(Groupsock* RTCPgs, unsigned totSessionBW, /* in kbps */
151  unsigned char const* cname, RTPSink* sink);
152 
154  // By default, this function always returns True. However, a subclass may redefine this
155  // if it wishes to restrict which subsessions of a stream get proxied - e.g., if it wishes
156  // to proxy only video tracks, but not audio (or other) tracks.
157 
158 protected:
162 
163 private:
164  friend class ProxyRTSPClient;
166  void continueAfterDESCRIBE(char const* sdpDescription);
167  void resetDESCRIBEState(); // undoes what was done by "contineAfterDESCRIBE()"
168 
169 private:
176 };
177 
178 
180 
181 // The following two classes are used by proxies to convert incoming streams' presentation times into wall-clock-aligned
182 // presentation times that are suitable for our "RTPSink"s (for the corresponding outgoing streams).
183 // (For multi-subsession (i.e., audio+video) sessions, the outgoing streams' presentation times retain the same relative
184 // separation as those of the incoming streams.)
185 
187 public:
188  void setRTPSink(RTPSink* rtpSink) { fRTPSink = rtpSink; }
189 
190 private:
193  char const* codecName, PresentationTimeSubsessionNormalizer* next);
194  // called only from within "PresentationTimeSessionNormalizer"
196 
197  static void afterGettingFrame(void* clientData, unsigned frameSize,
198  unsigned numTruncatedBytes,
199  struct timeval presentationTime,
200  unsigned durationInMicroseconds);
201  void afterGettingFrame(unsigned frameSize,
202  unsigned numTruncatedBytes,
203  struct timeval presentationTime,
204  unsigned durationInMicroseconds);
205 
206 private: // redefined virtual functions:
207  virtual void doGetNextFrame();
208 
209 private:
213  char const* fCodecName;
215 };
216 
218 public:
221 
223  createNewPresentationTimeSubsessionNormalizer(FramedSource* inputSource, RTPSource* rtpSource, char const* codecName);
224 
225 private: // called only from within "~PresentationTimeSubsessionNormalizer":
228  struct timeval& toPT, struct timeval const& fromPT);
230 
231 private:
233  PresentationTimeSubsessionNormalizer* fMasterSSNormalizer; // used for subsessions that have been RTCP-synced
234 
235  struct timeval fPTAdjustment; // Added to (RTCP-synced) subsession presentation times to 'normalize' them with wall-clock time.
236 };
237 
238 #endif
const Boolean False
Definition: Boolean.hh:28
unsigned char Boolean
Definition: Boolean.hh:25
u_int16_t portNumBits
Definition: NetAddress.hh:102
ProxyRTSPClient * createNewProxyRTSPClientFunc(ProxyServerMediaSession &ourServerMediaSession, char const *rtspURL, char const *username, char const *password, portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer)
ProxyRTSPClient * defaultCreateNewProxyRTSPClientFunc(ProxyServerMediaSession &ourServerMediaSession, char const *rtspURL, char const *username, char const *password, portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer)
#define NULL
void * TaskToken
FramedSource * inputSource() const
Definition: FramedFilter.hh:30
Definition: Media.hh:50
void normalizePresentationTime(PresentationTimeSubsessionNormalizer *ssNormalizer, struct timeval &toPT, struct timeval const &fromPT)
PresentationTimeSubsessionNormalizer * fMasterSSNormalizer
PresentationTimeSessionNormalizer(UsageEnvironment &env)
void removePresentationTimeSubsessionNormalizer(PresentationTimeSubsessionNormalizer *ssNormalizer)
PresentationTimeSubsessionNormalizer * createNewPresentationTimeSubsessionNormalizer(FramedSource *inputSource, RTPSource *rtpSource, char const *codecName)
PresentationTimeSubsessionNormalizer * fSubsessionNormalizers
void afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime, unsigned durationInMicroseconds)
PresentationTimeSubsessionNormalizer * fNext
PresentationTimeSubsessionNormalizer(PresentationTimeSessionNormalizer &parent, FramedSource *inputSource, RTPSource *rtpSource, char const *codecName, PresentationTimeSubsessionNormalizer *next)
PresentationTimeSessionNormalizer & fParent
static void afterGettingFrame(void *clientData, unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime, unsigned durationInMicroseconds)
void continueAfterPLAY(int resultCode)
Authenticator * fOurAuthenticator
void scheduleDESCRIBECommand()
static void subsessionTimeout(void *clientData)
ProxyRTSPClient(class ProxyServerMediaSession &ourServerMediaSession, char const *rtspURL, char const *username, char const *password, portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer)
static void sendDESCRIBE(void *clientData)
ProxyServerMediaSession & fOurServerMediaSession
static void doReset(void *clientData)
static void sendLivenessCommand(void *clientData)
void continueAfterDESCRIBE(char const *sdpDescription)
virtual ~ProxyRTSPClient()
int connectToServer(int socketNum, portNumBits remotePortNum)
friend class ProxyServerMediaSubsession
void continueAfterLivenessCommand(int resultCode, Boolean serverSupportsGetParameter)
void scheduleReset()
void continueAfterSETUP(int resultCode)
class ProxyServerMediaSubsession * fSetupQueueTail
void handleSubsessionTimeout()
Authenticator * auth()
class ProxyServerMediaSubsession * fSetupQueueHead
void scheduleLivenessCommand()
class PresentationTimeSessionNormalizer * fPresentationTimeSessionNormalizer
virtual Groupsock * createGroupsock(struct sockaddr_storage const &addr, Port port)
createNewProxyRTSPClientFunc * fCreateNewProxyRTSPClientFunc
GenericMediaServer * fOurMediaServer
virtual ~ProxyServerMediaSession()
virtual Boolean allowProxyingForSubsession(MediaSubsession const &mss)
char const * url() const
static ProxyServerMediaSession * createNew(UsageEnvironment &env, GenericMediaServer *ourMediaServer, char const *inputStreamURL, char const *streamName=NULL, char const *username=NULL, char const *password=NULL, portNumBits tunnelOverHTTPPortNum=0, int verbosityLevel=0, int socketNumToServer=-1, MediaTranscodingTable *transcodingTable=NULL)
void continueAfterDESCRIBE(char const *sdpDescription)
MediaTranscodingTable * fTranscodingTable
ProxyServerMediaSession(UsageEnvironment &env, GenericMediaServer *ourMediaServer, char const *inputStreamURL, char const *streamName, char const *username, char const *password, portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer, MediaTranscodingTable *transcodingTable, createNewProxyRTSPClientFunc *ourCreateNewProxyRTSPClientFunc=defaultCreateNewProxyRTSPClientFunc, portNumBits initialPortNum=6970, Boolean multiplexRTCPWithRTP=False)
Boolean describeCompletedSuccessfully() const
virtual RTCPInstance * createRTCP(Groupsock *RTCPgs, unsigned totSessionBW, unsigned char const *cname, RTPSink *sink)
int socketNum() const
Definition: RTSPClient.hh:171
char const * streamName() const