live
MediaSession.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-2019 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 *receivers* - i.e., clients.
21 // For media streamers, use "ServerMediaSession" instead.)
22 // C++ header
23 
24 /* NOTE: To support receiving your own custom RTP payload format, you must first define a new
25  subclass of "MultiFramedRTPSource" (or "BasicUDPSource") that implements it.
26  Then define your own subclass of "MediaSession" and "MediaSubsession", as follows:
27  - In your subclass of "MediaSession" (named, for example, "myMediaSession"):
28  - Define and implement your own static member function
29  static myMediaSession* createNew(UsageEnvironment& env, char const* sdpDescription);
30  and call this - instead of "MediaSession::createNew()" - in your application,
31  when you create a new "MediaSession" object.
32  - Reimplement the "createNewMediaSubsession()" virtual function, as follows:
33  MediaSubsession* myMediaSession::createNewMediaSubsession() { return new myMediaSubsession(*this); }
34  - In your subclass of "MediaSubsession" (named, for example, "myMediaSubsession"):
35  - Reimplement the "createSourceObjects()" virtual function, perhaps similar to this:
36  Boolean myMediaSubsession::createSourceObjects(int useSpecialRTPoffset) {
37  if (strcmp(fCodecName, "X-MY-RTP-PAYLOAD-FORMAT") == 0) {
38  // This subsession uses our custom RTP payload format:
39  fReadSource = fRTPSource = myRTPPayloadFormatRTPSource::createNew( <parameters> );
40  return True;
41  } else {
42  // This subsession uses some other RTP payload format - perhaps one that we already implement:
43  return ::createSourceObjects(useSpecialRTPoffset);
44  }
45  }
46 */
47 
48 #ifndef _MEDIA_SESSION_HH
49 #define _MEDIA_SESSION_HH
50 
51 #ifndef _RTCP_HH
52 #include "RTCP.hh"
53 #endif
54 #ifndef _FRAMED_FILTER_HH
55 #include "FramedFilter.hh"
56 #endif
57 
58 class MediaSubsession; // forward
59 
60 class MediaSession: public Medium {
61 public:
63  char const* sdpDescription);
64 
65  static Boolean lookupByName(UsageEnvironment& env, char const* sourceName,
66  MediaSession*& resultSession);
67 
69 
71  char const* CNAME() const { return fCNAME; }
72  struct in_addr const& sourceFilterAddr() const { return fSourceFilterAddr; }
73  float& scale() { return fScale; }
74  float& speed() { return fSpeed; }
75  char* mediaSessionType() const { return fMediaSessionType; }
76  char* sessionName() const { return fSessionName; }
77  char* sessionDescription() const { return fSessionDescription; }
78  char const* controlPath() const { return fControlPath; }
79 
80  double& playStartTime() { return fMaxPlayStartTime; }
81  double& playEndTime() { return fMaxPlayEndTime; }
82  char* absStartTime() const;
83  char* absEndTime() const;
84  // Used only to set the local fields:
85  char*& _absStartTime() { return fAbsStartTime; }
86  char*& _absEndTime() { return fAbsEndTime; }
87 
88  Boolean initiateByMediaType(char const* mimeType,
89  MediaSubsession*& resultSubsession,
90  int useSpecialRTPoffset = -1);
91  // Initiates the first subsession with the specified MIME type
92  // Returns the resulting subsession, or 'multi source' (not both)
93 
94 protected: // redefined virtual functions
95  virtual Boolean isMediaSession() const;
96 
97 protected:
99  // called only by createNew();
100  virtual ~MediaSession();
101 
103 
104  Boolean initializeWithSDP(char const* sdpDescription);
105  Boolean parseSDPLine(char const* input, char const*& nextLine);
106  Boolean parseSDPLine_s(char const* sdpLine);
107  Boolean parseSDPLine_i(char const* sdpLine);
108  Boolean parseSDPLine_c(char const* sdpLine);
109  Boolean parseSDPAttribute_type(char const* sdpLine);
110  Boolean parseSDPAttribute_control(char const* sdpLine);
111  Boolean parseSDPAttribute_range(char const* sdpLine);
112  Boolean parseSDPAttribute_source_filter(char const* sdpLine);
113 
114  static char* lookupPayloadFormat(unsigned char rtpPayloadType,
115  unsigned& rtpTimestampFrequency,
116  unsigned& numChannels);
117  static unsigned guessRTPTimestampFrequency(char const* mediumName,
118  char const* codecName);
119 
120 protected:
122  char* fCNAME; // used for RTCP
123 
124  // Linkage fields:
127 
128  // Fields set from a SDP description:
133  char* fAbsEndTime;
134  struct in_addr fSourceFilterAddr; // used for SSM
135  float fScale; // set from a RTSP "Scale:" header
136  float fSpeed;
137  char* fMediaSessionType; // holds a=type value
138  char* fSessionName; // holds s=<session name> value
139  char* fSessionDescription; // holds i=<session description> value
140  char* fControlPath; // holds optional a=control: string
141 };
142 
143 
145 public:
146  MediaSubsessionIterator(MediaSession const& session);
147  virtual ~MediaSubsessionIterator();
148 
149  MediaSubsession* next(); // NULL if none
150  void reset();
151 
152 private:
155 };
156 
157 
159 public:
161  MediaSession const& parentSession() const { return fParent; }
162 
163  unsigned short clientPortNum() const { return fClientPortNum; }
164  unsigned char rtpPayloadFormat() const { return fRTPPayloadFormat; }
165  char const* savedSDPLines() const { return fSavedSDPLines; }
166  char const* mediumName() const { return fMediumName; }
167  char const* codecName() const { return fCodecName; }
168  char const* protocolName() const { return fProtocolName; }
169  char const* controlPath() const { return fControlPath; }
170  Boolean isSSM() const { return fSourceFilterAddr.s_addr != 0; }
171 
172  unsigned short videoWidth() const { return fVideoWidth; }
173  unsigned short videoHeight() const { return fVideoHeight; }
174  unsigned videoFPS() const { return fVideoFPS; }
175  unsigned numChannels() const { return fNumChannels; }
176  float& scale() { return fScale; }
177  float& speed() { return fSpeed; }
178 
181  unsigned rtpTimestampFrequency() const { return fRTPTimestampFrequency; }
184  // This is the source that client sinks read from. It is usually
185  // (but not necessarily) the same as "rtpSource()"
186  void addFilter(FramedFilter* filter);
187  // Changes "readSource()" to "filter" (which must have just been created with "readSource()" as its input)
188 
189  double playStartTime() const;
190  double playEndTime() const;
191  char* absStartTime() const;
192  char* absEndTime() const;
193  // Used only to set the local fields:
194  double& _playStartTime() { return fPlayStartTime; }
195  double& _playEndTime() { return fPlayEndTime; }
196  char*& _absStartTime() { return fAbsStartTime; }
197  char*& _absEndTime() { return fAbsEndTime; }
198 
199  Boolean initiate(int useSpecialRTPoffset = -1);
200  // Creates a "RTPSource" for this subsession. (Has no effect if it's
201  // already been created.) Returns True iff this succeeds.
202  void deInitiate(); // Destroys any previously created RTPSource
203  Boolean setClientPortNum(unsigned short portNum);
204  // Sets the preferred client port number that any "RTPSource" for
205  // this subsession would use. (By default, the client port number
206  // is gotten from the original SDP description, or - if the SDP
207  // description does not specfy a client port number - an ephemeral
208  // (even) port number is chosen.) This routine must *not* be
209  // called after initiate().
210  void receiveRawMP3ADUs() { fReceiveRawMP3ADUs = True; } // optional hack for audio/MPA-ROBUST; must not be called after initiate()
211  void receiveRawJPEGFrames() { fReceiveRawJPEGFrames = True; } // optional hack for video/JPEG; must not be called after initiate()
213  char const* connectionEndpointName() const {
215  }
216 
217  // 'Bandwidth' parameter, set in the "b=" SDP line:
218  unsigned bandwidth() const { return fBandwidth; }
219 
220  // General SDP attribute accessor functions:
221  char const* attrVal_str(char const* attrName) const;
222  // returns "" if attribute doesn't exist (and has no default value), or is not a string
223  char const* attrVal_strToLower(char const* attrName) const;
224  // returns "" if attribute doesn't exist (and has no default value), or is not a string
225  unsigned attrVal_int(char const* attrName) const;
226  // also returns 0 if attribute doesn't exist (and has no default value)
227  unsigned attrVal_unsigned(char const* attrName) const { return (unsigned)attrVal_int(attrName); }
228  Boolean attrVal_bool(char const* attrName) const { return attrVal_int(attrName) != 0; }
229 
230  // Old, now-deprecated SDP attribute accessor functions, kept here for backwards-compatibility:
231  char const* fmtp_config() const;
232  char const* fmtp_configuration() const { return fmtp_config(); }
233  char const* fmtp_spropparametersets() const { return attrVal_str("sprop-parameter-sets"); }
234  char const* fmtp_spropvps() const { return attrVal_str("sprop-vps"); }
235  char const* fmtp_spropsps() const { return attrVal_str("sprop-sps"); }
236  char const* fmtp_sproppps() const { return attrVal_str("sprop-pps"); }
237 
239  // Converts "fConnectionEndpointName" to an address (or 0 if unknown)
240  void setDestinations(netAddressBits defaultDestAddress);
241  // Uses "fConnectionEndpointName" and "serverPortNum" to set
242  // the destination address and port of the RTP and RTCP objects.
243  // This is typically called by RTSP clients after doing "SETUP".
244 
245  char const* sessionId() const { return fSessionId; }
246  void setSessionId(char const* sessionId);
247 
248  // Public fields that external callers can use to keep state.
249  // (They are responsible for all storage management on these fields)
250  unsigned short serverPortNum; // in host byte order (used by RTSP)
251  unsigned char rtpChannelId, rtcpChannelId; // used by RTSP (for RTP/TCP)
252  MediaSink* sink; // callers can use this to keep track of who's playing us
253  void* miscPtr; // callers can use this for whatever they want
254 
255  // Parameters set from a RTSP "RTP-Info:" header:
256  struct {
257  u_int16_t seqNum;
258  u_int32_t timestamp;
259  Boolean infoIsNew; // not part of the RTSP header; instead, set whenever this struct is filled in
260  } rtpInfo;
261 
262  double getNormalPlayTime(struct timeval const& presentationTime);
263  // Computes the stream's "Normal Play Time" (NPT) from the given "presentationTime".
264  // (For the definition of "Normal Play Time", see RFC 2326, section 3.6.)
265  // This function is useful only if the "rtpInfo" structure was previously filled in
266  // (e.g., by a "RTP-Info:" header in a RTSP response).
267  // Also, for this function to work properly, the RTP stream's presentation times must (eventually) be
268  // synchronized via RTCP.
269  // (Note: If this function returns a negative number, then the result should be ignored by the caller.)
270 
271 protected:
272  friend class MediaSession;
274  MediaSubsession(MediaSession& parent);
275  virtual ~MediaSubsession();
276 
279 
280  void setAttribute(char const* name, char const* value = NULL, Boolean valueIsHexadecimal = False);
281 
282  Boolean parseSDPLine_c(char const* sdpLine);
283  Boolean parseSDPLine_b(char const* sdpLine);
284  Boolean parseSDPAttribute_rtpmap(char const* sdpLine);
285  Boolean parseSDPAttribute_rtcpmux(char const* sdpLine);
286  Boolean parseSDPAttribute_control(char const* sdpLine);
287  Boolean parseSDPAttribute_range(char const* sdpLine);
288  Boolean parseSDPAttribute_fmtp(char const* sdpLine);
289  Boolean parseSDPAttribute_source_filter(char const* sdpLine);
290  Boolean parseSDPAttribute_x_dimensions(char const* sdpLine);
291  Boolean parseSDPAttribute_framerate(char const* sdpLine);
292 
293  virtual Boolean createSourceObjects(int useSpecialRTPoffset);
294  // create "fRTPSource" and "fReadSource" member objects, after we've been initialized via SDP
295 
296 protected:
297  // Linkage fields:
300 
301  // Fields set from a SDP description:
302  char* fConnectionEndpointName; // may also be set by RTSP SETUP response
303  unsigned short fClientPortNum; // in host byte order
304  // This field is also set by initiate()
305  unsigned char fRTPPayloadFormat;
307  char* fMediumName;
308  char* fCodecName;
312  char* fControlPath; // holds optional a=control: string
313  struct in_addr fSourceFilterAddr; // used for SSM
314  unsigned fBandwidth; // in kilobits-per-second, from b= line
315 
317  double fPlayEndTime;
319  char* fAbsEndTime;
320  unsigned short fVideoWidth, fVideoHeight;
321  // screen dimensions (set by an optional a=x-dimensions: <w>,<h> line)
322  unsigned fVideoFPS;
323  // frame rate (set by an optional "a=framerate: <fps>" or "a=x-framerate: <fps>" line)
324  unsigned fNumChannels;
325  // optionally set by "a=rtpmap:" lines for audio sessions. Default: 1
326  float fScale; // set from a RTSP "Scale:" header
327  float fSpeed;
328  double fNPT_PTS_Offset; // set by "getNormalPlayTime()"; add this to a PTS to get NPT
329  HashTable* fAttributeTable; // for "a=fmtp:" attributes. (Later an array by payload type #####)
330 
331  // Fields set or used by initiate():
332  Groupsock* fRTPSocket; Groupsock* fRTCPSocket; // works even for unicast
336 
337  // Other fields:
338  char* fSessionId; // used by RTSP
339 };
340 
341 #endif
unsigned char Boolean
Definition: Boolean.hh:25
void setAttribute(char const *name, char const *value=NULL, Boolean valueIsHexadecimal=False)
unsigned short fVideoWidth
RTCPInstance * rtcpInstance()
char const * connectionEndpointName() const
char * fAbsEndTime
virtual MediaSubsession * createNewMediaSubsession()
double & _playStartTime()
u_int32_t netAddressBits
Definition: NetAddress.hh:39
const Boolean False
Definition: Boolean.hh:28
MediaSession(UsageEnvironment &env)
void receiveRawMP3ADUs()
unsigned attrVal_int(char const *attrName) const
Boolean initializeWithSDP(char const *sdpDescription)
unsigned short fClientPortNum
MediaSubsession * fNext
char * connectionEndpointName() const
Definition: MediaSession.hh:70
double & _playEndTime()
MediaSubsession * next()
virtual ~MediaSession()
void receiveRawJPEGFrames()
char * fSessionName
void setSessionId(char const *sessionId)
#define NULL
Boolean parseSDPLine_c(char const *sdpLine)
unsigned numChannels() const
unsigned char fRTPPayloadFormat
char const * fmtp_spropparametersets() const
Boolean rtcpIsMuxed() const
char const * fmtp_sproppps() const
MediaSink * sink
void setNext(MediaSubsession *next)
double playStartTime() const
unsigned short videoHeight() const
double fMaxPlayStartTime
MediaSession const & parentSession() const
Boolean fReceiveRawJPEGFrames
UsageEnvironment & envir() const
Definition: Media.hh:59
char const * mediumName() const
MediaSubsessionIterator(MediaSession const &session)
Groupsock * fRTCPSocket
unsigned bandwidth() const
Boolean parseSDPAttribute_rtpmap(char const *sdpLine)
char * fAbsStartTime
u_int16_t seqNum
Boolean parseSDPLine_c(char const *sdpLine)
char * absStartTime() const
char * sessionName() const
Definition: MediaSession.hh:76
float & scale()
Definition: MediaSession.hh:73
Boolean initiate(int useSpecialRTPoffset=-1)
unsigned fNumChannels
struct in_addr fSourceFilterAddr
virtual Boolean createSourceObjects(int useSpecialRTPoffset)
double fMaxPlayEndTime
static Boolean lookupByName(UsageEnvironment &env, char const *sourceName, MediaSession *&resultSession)
char *& connectionEndpointName()
Boolean fReceiveRawMP3ADUs
char *& _absStartTime()
Definition: MediaSession.hh:85
char const * codecName() const
Boolean parseSDPAttribute_range(char const *sdpLine)
char *& _absStartTime()
Boolean parseSDPLine_i(char const *sdpLine)
FramedSource * readSource()
MediaSubsession * fNextPtr
char const * fmtp_config() const
MediaSession & parentSession()
MediaSubsession * fSubsessionsTail
static MediaSession * createNew(UsageEnvironment &env, char const *sdpDescription)
char const * protocolName() const
u_int32_t timestamp
char const * attrVal_strToLower(char const *attrName) const
RTPSource * fRTPSource
Boolean parseSDPAttribute_control(char const *sdpLine)
char const * controlPath() const
Definition: MediaSession.hh:78
Boolean fMultiplexRTCPWithRTP
char * absEndTime() const
double & playStartTime()
Definition: MediaSession.hh:80
char const * CNAME() const
Definition: MediaSession.hh:71
Boolean parseSDPAttribute_x_dimensions(char const *sdpLine)
Definition: Media.hh:50
Boolean hasSubsessions() const
Definition: MediaSession.hh:68
UsageEnvironment & env()
struct in_addr fSourceFilterAddr
char * absEndTime() const
unsigned short serverPortNum
char *& _absEndTime()
double playEndTime() const
float & speed()
Definition: MediaSession.hh:74
unsigned char rtpChannelId
char *& _absEndTime()
Definition: MediaSession.hh:86
char * sessionDescription() const
Definition: MediaSession.hh:77
char const * controlPath() const
void setDestinations(netAddressBits defaultDestAddress)
double fNPT_PTS_Offset
RTPSource * rtpSource()
double & playEndTime()
Definition: MediaSession.hh:81
Boolean parseSDPAttribute_range(char const *sdpLine)
unsigned fBandwidth
virtual Boolean isMediaSession() const
char * fConnectionEndpointName
char * fMediaSessionType
char * mediaSessionType() const
Definition: MediaSession.hh:75
Groupsock * fRTPSocket
char * fControlPath
Boolean parseSDPAttribute_type(char const *sdpLine)
Boolean parseSDPAttribute_rtcpmux(char const *sdpLine)
unsigned attrVal_unsigned(char const *attrName) const
unsigned char rtcpChannelId
void addFilter(FramedFilter *filter)
unsigned rtpTimestampFrequency() const
unsigned short videoWidth() const
unsigned char rtpPayloadFormat() const
Boolean parseSDPAttribute_source_filter(char const *sdpLine)
Boolean setClientPortNum(unsigned short portNum)
MediaSession const & fOurSession
char const * fmtp_spropsps() const
struct MediaSubsession::@0 rtpInfo
Boolean attrVal_bool(char const *attrName) const
MediaSession & fParent
char const * savedSDPLines() const
char const * attrVal_str(char const *attrName) const
HashTable * fAttributeTable
char * fSessionDescription
char const * fmtp_configuration() const
Boolean parseSDPAttribute_fmtp(char const *sdpLine)
unsigned fRTPTimestampFrequency
Boolean parseSDPAttribute_control(char const *sdpLine)
FramedSource * fReadSource
double getNormalPlayTime(struct timeval const &presentationTime)
virtual ~MediaSubsessionIterator()
MediaSubsession * fSubsessionsHead
Boolean parseSDPAttribute_source_filter(char const *sdpLine)
const Boolean True
Definition: Boolean.hh:31
Boolean isSSM() const
Boolean parseSDPLine_s(char const *sdpLine)
struct in_addr const & sourceFilterAddr() const
Definition: MediaSession.hh:72
Boolean parseSDPAttribute_framerate(char const *sdpLine)
char * fConnectionEndpointName
static unsigned guessRTPTimestampFrequency(char const *mediumName, char const *codecName)
unsigned videoFPS() const
char * absStartTime() const
unsigned fVideoFPS
static char * lookupPayloadFormat(unsigned char rtpPayloadType, unsigned &rtpTimestampFrequency, unsigned &numChannels)
Boolean parseSDPLine(char const *input, char const *&nextLine)
Boolean parseSDPLine_b(char const *sdpLine)
Boolean initiateByMediaType(char const *mimeType, MediaSubsession *&resultSubsession, int useSpecialRTPoffset=-1)
unsigned short fVideoHeight
char const * fmtp_spropvps() const
unsigned short clientPortNum() const
virtual ~MediaSubsession()
netAddressBits connectionEndpointAddress() const
RTCPInstance * fRTCPInstance
MediaSubsession(MediaSession &parent)
char const * sessionId() const