live
ProxyServerMediaSession.hh
Go to the documentation of this file.
1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2026 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// REMINDER: You should not make major changes to this code.
23// If you want more features, then you should use subclassing, with separate source code files.
24// See: http://live555.com/liveMedia/faq.html#modifying-and-extending
25
26#ifndef _PROXY_SERVER_MEDIA_SESSION_HH
27#define _PROXY_SERVER_MEDIA_SESSION_HH
28
29#ifndef _SERVER_MEDIA_SESSION_HH
30#include "ServerMediaSession.hh"
31#endif
32#ifndef _MEDIA_SESSION_HH
33#include "MediaSession.hh"
34#endif
35#ifndef _RTSP_CLIENT_HH
36#include "RTSPClient.hh"
37#endif
38#ifndef _MEDIA_TRANSCODING_TABLE_HH
40#endif
41
42// A subclass of "RTSPClient", used to refer to the particular "ProxyServerMediaSession" object being used.
43// It is used only within the implementation of "ProxyServerMediaSession", but is defined here, in case developers wish to
44// subclass it.
45
47public:
48 ProxyRTSPClient(class ProxyServerMediaSession& ourServerMediaSession, char const* rtspURL,
49 char const* username, char const* password,
50 portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer);
52
53 void continueAfterDESCRIBE(char const* sdpDescription);
54 void continueAfterLivenessCommand(int resultCode, Boolean serverSupportsGetParameter);
55 void continueAfterSETUP(int resultCode);
56 void continueAfterPLAY(int resultCode);
58
59private:
60 void reset();
61 int connectToServer(int socketNum, portNumBits remotePortNum);
62
64
66 static void sendLivenessCommand(void* clientData);
67 void doReset();
68 static void doReset(void* clientData);
69
71 static void sendDESCRIBE(void* clientData);
73
74 static void subsessionTimeout(void* clientData);
76
77private:
81 char* fOurURL;
86 unsigned fNextDESCRIBEDelay; // in seconds
89};
90
91
92typedef ProxyRTSPClient*
94 char const* rtspURL,
95 char const* username, char const* password,
96 portNumBits tunnelOverHTTPPortNum, int verbosityLevel,
97 int socketNumToServer);
100 char const* rtspURL,
101 char const* username, char const* password,
102 portNumBits tunnelOverHTTPPortNum, int verbosityLevel,
103 int socketNumToServer);
104
106public:
108 GenericMediaServer* ourMediaServer, // Note: We can be used by just one server
109 char const* inputStreamURL, // the "rtsp://" URL of the stream we'll be proxying
110 char const* streamName = NULL,
111 char const* username = NULL, char const* password = NULL,
112 portNumBits tunnelOverHTTPPortNum = 0,
113 // for streaming the *proxied* (i.e., back-end) stream
114 int verbosityLevel = 0,
115 int socketNumToServer = -1,
116 MediaTranscodingTable* transcodingTable = NULL);
117 // Hack: "tunnelOverHTTPPortNum" == 0xFFFF (i.e., all-ones) means: Stream RTP/RTCP-over-TCP, but *not* using HTTP
118 // "verbosityLevel" == 1 means display basic proxy setup info; "verbosityLevel" == 2 means display RTSP client protocol also.
119 // If "socketNumToServer" is >= 0, then it is the socket number of an already-existing TCP connection to the server.
120 // (In this case, "inputStreamURL" must point to the socket's endpoint, so that it can be accessed via the socket.)
121
123
124 char const* url() const;
125
127 // initialized to 0; set to 1 when the back-end "DESCRIBE" completes.
128 // (This can be used as a 'watch variable' in "doEventLoop()".)
130 // This can be used - along with "describeCompletedFlag" - to check whether the back-end "DESCRIBE" completed *successfully*.
131
132protected:
134 char const* inputStreamURL, char const* streamName,
135 char const* username, char const* password,
136 portNumBits tunnelOverHTTPPortNum, int verbosityLevel,
137 int socketNumToServer,
138 MediaTranscodingTable* transcodingTable,
139 createNewProxyRTSPClientFunc* ourCreateNewProxyRTSPClientFunc
141 portNumBits initialPortNum = 6970,
142 Boolean multiplexRTCPWithRTP = False);
143
144 // If you subclass "ProxyRTSPClient", then you will also need to define your own function
145 // - with signature "createNewProxyRTSPClientFunc" (see above) - that creates a new object
146 // of this subclass. You should also subclass "ProxyServerMediaSession" and, in your
147 // subclass's constructor, initialize the parent class (i.e., "ProxyServerMediaSession")
148 // constructor by passing your new function as the "ourCreateNewProxyRTSPClientFunc"
149 // parameter.
150
151 // Subclasses may redefine the following functions, if they want "ProxyServerSubsession"s
152 // to create subclassed "Groupsock" and/or "RTCPInstance" objects:
153 virtual Groupsock* createGroupsock(struct sockaddr_storage const& addr, Port port);
154 virtual RTCPInstance* createRTCP(Groupsock* RTCPgs, unsigned totSessionBW, /* in kbps */
155 unsigned char const* cname, RTPSink* sink);
156
158 // By default, this function always returns True. However, a subclass may redefine this
159 // if it wishes to restrict which subsessions of a stream get proxied - e.g., if it wishes
160 // to proxy only video tracks, but not audio (or other) tracks.
161
162protected:
166
167private:
168 friend class ProxyRTSPClient;
170 void continueAfterDESCRIBE(char const* sdpDescription);
171 void resetDESCRIBEState(); // undoes what was done by "contineAfterDESCRIBE()"
172
173private:
180};
181
182
184
185// The following two classes are used by proxies to convert incoming streams' presentation times into wall-clock-aligned
186// presentation times that are suitable for our "RTPSink"s (for the corresponding outgoing streams).
187// (For multi-subsession (i.e., audio+video) sessions, the outgoing streams' presentation times retain the same relative
188// separation as those of the incoming streams.)
189
191public:
192 void setRTPSink(RTPSink* rtpSink) { fRTPSink = rtpSink; }
193
194private:
197 char const* codecName, PresentationTimeSubsessionNormalizer* next);
198 // called only from within "PresentationTimeSessionNormalizer"
200
201 static void afterGettingFrame(void* clientData, unsigned frameSize,
202 unsigned numTruncatedBytes,
203 struct timeval presentationTime,
204 unsigned durationInMicroseconds);
205 void afterGettingFrame(unsigned frameSize,
206 unsigned numTruncatedBytes,
207 struct timeval presentationTime,
208 unsigned durationInMicroseconds);
209
210private: // redefined virtual functions:
211 virtual void doGetNextFrame();
212
213private:
217 char const* fCodecName;
219};
220
222public:
225
227 createNewPresentationTimeSubsessionNormalizer(FramedSource* inputSource, RTPSource* rtpSource, char const* codecName);
228
229private: // called only from within "~PresentationTimeSubsessionNormalizer":
232 struct timeval& toPT, struct timeval const& fromPT);
234
235private:
237 PresentationTimeSubsessionNormalizer* fMasterSSNormalizer; // used for subsessions that have been RTCP-synced
238
239 struct timeval fPTAdjustment; // Added to (RTCP-synced) subsession presentation times to 'normalize' them with wall-clock time.
240};
241
242#endif
const Boolean False
Definition Boolean.hh:28
unsigned char Boolean
Definition Boolean.hh:25
u_int16_t portNumBits
ProxyRTSPClient * defaultCreateNewProxyRTSPClientFunc(ProxyServerMediaSession &ourServerMediaSession, char const *rtspURL, char const *username, char const *password, portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer)
ProxyRTSPClient * createNewProxyRTSPClientFunc(ProxyServerMediaSession &ourServerMediaSession, char const *rtspURL, char const *username, char const *password, portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer)
#define NULL
void * TaskToken
FramedSource * inputSource() const
FramedFilter(UsageEnvironment &env, FramedSource *inputSource)
FramedSource(UsageEnvironment &env)
Medium(UsageEnvironment &env)
void normalizePresentationTime(PresentationTimeSubsessionNormalizer *ssNormalizer, struct timeval &toPT, struct timeval const &fromPT)
PresentationTimeSubsessionNormalizer * fMasterSSNormalizer
PresentationTimeSessionNormalizer(UsageEnvironment &env)
PresentationTimeSubsessionNormalizer * createNewPresentationTimeSubsessionNormalizer(FramedSource *inputSource, RTPSource *rtpSource, char const *codecName)
void removePresentationTimeSubsessionNormalizer(PresentationTimeSubsessionNormalizer *ssNormalizer)
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
friend class ProxyServerMediaSession
void continueAfterLivenessCommand(int resultCode, Boolean serverSupportsGetParameter)
void scheduleReset()
void continueAfterSETUP(int resultCode)
class ProxyServerMediaSubsession * fSetupQueueTail
void handleSubsessionTimeout()
class ProxyServerMediaSubsession * fSetupQueueHead
void scheduleLivenessCommand()
class PresentationTimeSessionNormalizer * fPresentationTimeSessionNormalizer
createNewProxyRTSPClientFunc * fCreateNewProxyRTSPClientFunc
GenericMediaServer * fOurMediaServer
virtual ~ProxyServerMediaSession()
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)
virtual Boolean allowProxyingForSubsession(MediaSubsession const &mss)
virtual Groupsock * createGroupsock(struct sockaddr_storage const &addr, Port port)
virtual RTCPInstance * createRTCP(Groupsock *RTCPgs, unsigned totSessionBW, unsigned char const *cname, RTPSink *sink)
char const * url() const
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
int socketNum() const
RTSPClient(UsageEnvironment &env, char const *rtspURL, int verbosityLevel, char const *applicationName, portNumBits tunnelOverHTTPPortNum, int socketNumToServer)
char const * streamName() const
ServerMediaSession(UsageEnvironment &env, char const *streamName, char const *info, char const *description, Boolean isSSM, char const *miscSDPLines)