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-2024 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
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
43public:
44 ProxyRTSPClient(class ProxyServerMediaSession& ourServerMediaSession, char const* rtspURL,
45 char const* username, char const* password,
46 portNumBits tunnelOverHTTPPortNum, int verbosityLevel, int socketNumToServer);
48
49 void continueAfterDESCRIBE(char const* sdpDescription);
50 void continueAfterLivenessCommand(int resultCode, Boolean serverSupportsGetParameter);
51 void continueAfterSETUP(int resultCode);
52 void continueAfterPLAY(int resultCode);
54
55private:
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);
69
70 static void subsessionTimeout(void* clientData);
72
73private:
77 char* fOurURL;
82 unsigned fNextDESCRIBEDelay; // in seconds
85};
86
87
88typedef 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
102public:
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
128protected:
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
158protected:
162
163private:
164 friend class ProxyRTSPClient;
166 void continueAfterDESCRIBE(char const* sdpDescription);
167 void resetDESCRIBEState(); // undoes what was done by "contineAfterDESCRIBE()"
168
169private:
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
187public:
188 void setRTPSink(RTPSink* rtpSink) { fRTPSink = rtpSink; }
189
190private:
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
206private: // redefined virtual functions:
207 virtual void doGetNextFrame();
208
209private:
213 char const* fCodecName;
215};
216
218public:
221
223 createNewPresentationTimeSubsessionNormalizer(FramedSource* inputSource, RTPSource* rtpSource, char const* codecName);
224
225private: // called only from within "~PresentationTimeSubsessionNormalizer":
228 struct timeval& toPT, struct timeval const& fromPT);
230
231private:
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 * 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
Definition: FramedFilter.hh:30
Definition: Media.hh:50
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()
Authenticator * auth()
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()
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
Definition: RTSPClient.hh:176
char const * streamName() const