MediaSession.hh 15 KB

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