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-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
31class ServerMediaSubsession; // forward
32
33class ServerMediaSession: public Medium {
34public:
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
76protected:
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
84private: // redefined virtual functions
85 virtual Boolean isServerMediaSession() const;
86
87private:
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
106class ServerMediaSubsessionIterator {
107public:
108 ServerMediaSubsessionIterator(ServerMediaSession& session);
109 virtual ~ServerMediaSubsessionIterator();
110
111 ServerMediaSubsession* next(); // NULL if none
112 void reset();
113
114private:
115 ServerMediaSession& fOurSession;
116 ServerMediaSubsession* fNextPtr;
117};
118
119
120class ServerMediaSubsession: public Medium {
121public:
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
183protected: // 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
194private:
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