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-2020 Live Networks, Inc. All rights reserved. |
18 | // A data structure that represents a session that consists of |
19 | // potentially multiple (audio and/or video) sub-sessions |
20 | // (This data structure is used for media *streamers* - i.e., servers. |
21 | // For media receivers, use "MediaSession" instead.) |
22 | // C++ header |
23 | |
24 | #ifndef _SERVER_MEDIA_SESSION_HH |
25 | #define _SERVER_MEDIA_SESSION_HH |
26 | |
27 | #ifndef _RTCP_HH |
28 | #include "RTCP.hh" |
29 | #endif |
30 | |
31 | class ServerMediaSubsession; // forward |
32 | |
33 | class ServerMediaSession: public Medium { |
34 | public: |
35 | static ServerMediaSession* createNew(UsageEnvironment& env, |
36 | char const* streamName = NULL, |
37 | char const* info = NULL, |
38 | char const* description = NULL, |
39 | Boolean isSSM = False, |
40 | char const* miscSDPLines = NULL); |
41 | |
42 | static Boolean lookupByName(UsageEnvironment& env, |
43 | char const* mediumName, |
44 | ServerMediaSession*& resultSession); |
45 | |
46 | char* generateSDPDescription(); // based on the entire session |
47 | // Note: The caller is responsible for freeing the returned string |
48 | |
49 | char const* streamName() const { return fStreamName; } |
50 | |
51 | Boolean addSubsession(ServerMediaSubsession* subsession); |
52 | unsigned numSubsessions() const { return fSubsessionCounter; } |
53 | |
54 | void testScaleFactor(float& scale); // sets "scale" to the actual supported scale |
55 | float duration() const; |
56 | // a result == 0 means an unbounded session (the default) |
57 | // a result < 0 means: subsession durations differ; the result is -(the largest). |
58 | // a result > 0 means: this is the duration of a bounded session |
59 | |
60 | virtual void noteLiveness(); |
61 | // called whenever a client - accessing this media - notes liveness. |
62 | // The default implementation does nothing, but subclasses can redefine this - e.g., if you |
63 | // want to remove long-unused "ServerMediaSession"s from the server. |
64 | |
65 | unsigned referenceCount() const { return fReferenceCount; } |
66 | void incrementReferenceCount() { ++fReferenceCount; } |
67 | void decrementReferenceCount() { if (fReferenceCount > 0) --fReferenceCount; } |
68 | Boolean& deleteWhenUnreferenced() { return fDeleteWhenUnreferenced; } |
69 | |
70 | void deleteAllSubsessions(); |
71 | // Removes and deletes all subsessions added by "addSubsession()", returning us to an 'empty' state |
72 | // Note: If you have already added this "ServerMediaSession" to a "RTSPServer" then, before calling this function, |
73 | // you must first close any client connections that use it, |
74 | // by calling "RTSPServer::closeAllClientSessionsForServerMediaSession()". |
75 | |
76 | protected: |
77 | ServerMediaSession(UsageEnvironment& env, char const* streamName, |
78 | char const* info, char const* description, |
79 | Boolean isSSM, char const* miscSDPLines); |
80 | // called only by "createNew()" |
81 | |
82 | virtual ~ServerMediaSession(); |
83 | |
84 | private: // redefined virtual functions |
85 | virtual Boolean isServerMediaSession() const; |
86 | |
87 | private: |
88 | Boolean fIsSSM; |
89 | |
90 | // Linkage fields: |
91 | friend class ServerMediaSubsessionIterator; |
92 | ServerMediaSubsession* fSubsessionsHead; |
93 | ServerMediaSubsession* fSubsessionsTail; |
94 | unsigned fSubsessionCounter; |
95 | |
96 | char* fStreamName; |
97 | char* fInfoSDPString; |
98 | char* fDescriptionSDPString; |
99 | char* fMiscSDPLines; |
100 | struct timeval fCreationTime; |
101 | unsigned fReferenceCount; |
102 | Boolean fDeleteWhenUnreferenced; |
103 | }; |
104 | |
105 | |
106 | class ServerMediaSubsessionIterator { |
107 | public: |
108 | ServerMediaSubsessionIterator(ServerMediaSession& session); |
109 | virtual ~ServerMediaSubsessionIterator(); |
110 | |
111 | ServerMediaSubsession* next(); // NULL if none |
112 | void reset(); |
113 | |
114 | private: |
115 | ServerMediaSession& fOurSession; |
116 | ServerMediaSubsession* fNextPtr; |
117 | }; |
118 | |
119 | |
120 | class ServerMediaSubsession: public Medium { |
121 | public: |
122 | unsigned trackNumber() const { return fTrackNumber; } |
123 | char const* trackId(); |
124 | virtual char const* sdpLines() = 0; |
125 | virtual void getStreamParameters(unsigned clientSessionId, // in |
126 | netAddressBits clientAddress, // in |
127 | Port const& clientRTPPort, // in |
128 | Port const& clientRTCPPort, // in |
129 | int tcpSocketNum, // in (-1 means use UDP, not TCP) |
130 | unsigned char rtpChannelId, // in (used if TCP) |
131 | unsigned char rtcpChannelId, // in (used if TCP) |
132 | netAddressBits& destinationAddress, // in out |
133 | u_int8_t& destinationTTL, // in out |
134 | Boolean& isMulticast, // out |
135 | Port& serverRTPPort, // out |
136 | Port& serverRTCPPort, // out |
137 | void*& streamToken // out |
138 | ) = 0; |
139 | virtual void startStream(unsigned clientSessionId, void* streamToken, |
140 | TaskFunc* rtcpRRHandler, |
141 | void* rtcpRRHandlerClientData, |
142 | unsigned short& rtpSeqNum, |
143 | unsigned& rtpTimestamp, |
144 | ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, |
145 | void* serverRequestAlternativeByteHandlerClientData) = 0; |
146 | virtual void pauseStream(unsigned clientSessionId, void* streamToken); |
147 | virtual void seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, |
148 | double streamDuration, u_int64_t& numBytes); |
149 | // This routine is used to seek by relative (i.e., NPT) time. |
150 | // "streamDuration", if >0.0, specifies how much data to stream, past "seekNPT". (If <=0.0, all remaining data is streamed.) |
151 | // "numBytes" returns the size (in bytes) of the data to be streamed, or 0 if unknown or unlimited. |
152 | virtual void seekStream(unsigned clientSessionId, void* streamToken, char*& absStart, char*& absEnd); |
153 | // This routine is used to seek by 'absolute' time. |
154 | // "absStart" should be a string of the form "YYYYMMDDTHHMMSSZ" or "YYYYMMDDTHHMMSS.<frac>Z". |
155 | // "absEnd" should be either NULL (for no end time), or a string of the same form as "absStart". |
156 | // These strings may be modified in-place, or can be reassigned to a newly-allocated value (after delete[]ing the original). |
157 | virtual void nullSeekStream(unsigned clientSessionId, void* streamToken, |
158 | double streamEndTime, u_int64_t& numBytes); |
159 | // Called whenever we're handling a "PLAY" command without a specified start time. |
160 | virtual void setStreamScale(unsigned clientSessionId, void* streamToken, float scale); |
161 | virtual float getCurrentNPT(void* streamToken); |
162 | virtual FramedSource* getStreamSource(void* streamToken); |
163 | virtual void getRTPSinkandRTCP(void* streamToken, |
164 | RTPSink const*& rtpSink, RTCPInstance const*& rtcp) = 0; |
165 | // Returns pointers to the "RTPSink" and "RTCPInstance" objects for "streamToken". |
166 | // (This can be useful if you want to get the associated 'Groupsock' objects, for example.) |
167 | // You must not delete these objects, or start/stop playing them; instead, that is done |
168 | // using the "startStream()" and "deleteStream()" functions. |
169 | virtual void deleteStream(unsigned clientSessionId, void*& streamToken); |
170 | |
171 | virtual void testScaleFactor(float& scale); // sets "scale" to the actual supported scale |
172 | virtual float duration() const; |
173 | // returns 0 for an unbounded session (the default) |
174 | // returns > 0 for a bounded session |
175 | virtual void getAbsoluteTimeRange(char*& absStartTime, char*& absEndTime) const; |
176 | // Subclasses can reimplement this iff they support seeking by 'absolute' time. |
177 | |
178 | // The following may be called by (e.g.) SIP servers, for which the |
179 | // address and port number fields in SDP descriptions need to be non-zero: |
180 | void setServerAddressAndPortForSDP(netAddressBits addressBits, |
181 | portNumBits portBits); |
182 | |
183 | protected: // we're a virtual base class |
184 | ServerMediaSubsession(UsageEnvironment& env); |
185 | virtual ~ServerMediaSubsession(); |
186 | |
187 | char const* rangeSDPLine() const; |
188 | // returns a string to be delete[]d |
189 | |
190 | ServerMediaSession* fParentSession; |
191 | netAddressBits fServerAddressForSDP; |
192 | portNumBits fPortNumForSDP; |
193 | |
194 | private: |
195 | friend class ServerMediaSession; |
196 | friend class ServerMediaSubsessionIterator; |
197 | ServerMediaSubsession* fNext; |
198 | |
199 | unsigned fTrackNumber; // within an enclosing ServerMediaSession |
200 | char const* fTrackId; |
201 | }; |
202 | |
203 | #endif |
204 | |