OnDemandServerMediaSubsession.hh 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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-2019 Live Networks, Inc. All rights reserved.
  16. // A 'ServerMediaSubsession' object that creates new, unicast, "RTPSink"s
  17. // on demand.
  18. // C++ header
  19. #ifndef _ON_DEMAND_SERVER_MEDIA_SUBSESSION_HH
  20. #define _ON_DEMAND_SERVER_MEDIA_SUBSESSION_HH
  21. #ifndef _SERVER_MEDIA_SESSION_HH
  22. #include "ServerMediaSession.hh"
  23. #endif
  24. #ifndef _RTP_SINK_HH
  25. #include "RTPSink.hh"
  26. #endif
  27. #ifndef _BASIC_UDP_SINK_HH
  28. #include "BasicUDPSink.hh"
  29. #endif
  30. #ifndef _RTCP_HH
  31. #include "RTCP.hh"
  32. #endif
  33. class OnDemandServerMediaSubsession: public ServerMediaSubsession {
  34. protected: // we're a virtual base class
  35. OnDemandServerMediaSubsession(UsageEnvironment& env, Boolean reuseFirstSource,
  36. portNumBits initialPortNum = 6970,
  37. Boolean multiplexRTCPWithRTP = False);
  38. virtual ~OnDemandServerMediaSubsession();
  39. protected: // redefined virtual functions
  40. virtual char const* sdpLines();
  41. virtual void getStreamParameters(unsigned clientSessionId,
  42. netAddressBits clientAddress,
  43. Port const& clientRTPPort,
  44. Port const& clientRTCPPort,
  45. int tcpSocketNum,
  46. unsigned char rtpChannelId,
  47. unsigned char rtcpChannelId,
  48. netAddressBits& destinationAddress,
  49. u_int8_t& destinationTTL,
  50. Boolean& isMulticast,
  51. Port& serverRTPPort,
  52. Port& serverRTCPPort,
  53. void*& streamToken);
  54. virtual void startStream(unsigned clientSessionId, void* streamToken,
  55. TaskFunc* rtcpRRHandler,
  56. void* rtcpRRHandlerClientData,
  57. unsigned short& rtpSeqNum,
  58. unsigned& rtpTimestamp,
  59. ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler,
  60. void* serverRequestAlternativeByteHandlerClientData);
  61. virtual void pauseStream(unsigned clientSessionId, void* streamToken);
  62. virtual void seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, double streamDuration, u_int64_t& numBytes);
  63. virtual void seekStream(unsigned clientSessionId, void* streamToken, char*& absStart, char*& absEnd);
  64. virtual void nullSeekStream(unsigned clientSessionId, void* streamToken,
  65. double streamEndTime, u_int64_t& numBytes);
  66. virtual void setStreamScale(unsigned clientSessionId, void* streamToken, float scale);
  67. virtual float getCurrentNPT(void* streamToken);
  68. virtual FramedSource* getStreamSource(void* streamToken);
  69. virtual void getRTPSinkandRTCP(void* streamToken,
  70. RTPSink const*& rtpSink, RTCPInstance const*& rtcp);
  71. virtual void deleteStream(unsigned clientSessionId, void*& streamToken);
  72. protected: // new virtual functions, possibly redefined by subclasses
  73. virtual char const* getAuxSDPLine(RTPSink* rtpSink,
  74. FramedSource* inputSource);
  75. virtual void seekStreamSource(FramedSource* inputSource, double& seekNPT, double streamDuration, u_int64_t& numBytes);
  76. // This routine is used to seek by relative (i.e., NPT) time.
  77. // "streamDuration", if >0.0, specifies how much data to stream, past "seekNPT". (If <=0.0, all remaining data is streamed.)
  78. // "numBytes" returns the size (in bytes) of the data to be streamed, or 0 if unknown or unlimited.
  79. virtual void seekStreamSource(FramedSource* inputSource, char*& absStart, char*& absEnd);
  80. // This routine is used to seek by 'absolute' time.
  81. // "absStart" should be a string of the form "YYYYMMDDTHHMMSSZ" or "YYYYMMDDTHHMMSS.<frac>Z".
  82. // "absEnd" should be either NULL (for no end time), or a string of the same form as "absStart".
  83. // These strings may be modified in-place, or can be reassigned to a newly-allocated value (after delete[]ing the original).
  84. virtual void setStreamSourceScale(FramedSource* inputSource, float scale);
  85. virtual void setStreamSourceDuration(FramedSource* inputSource, double streamDuration, u_int64_t& numBytes);
  86. virtual void closeStreamSource(FramedSource* inputSource);
  87. protected: // new virtual functions, defined by all subclasses
  88. virtual FramedSource* createNewStreamSource(unsigned clientSessionId,
  89. unsigned& estBitrate) = 0;
  90. // "estBitrate" is the stream's estimated bitrate, in kbps
  91. virtual RTPSink* createNewRTPSink(Groupsock* rtpGroupsock,
  92. unsigned char rtpPayloadTypeIfDynamic,
  93. FramedSource* inputSource) = 0;
  94. protected: // new virtual functions, may be redefined by a subclass:
  95. virtual Groupsock* createGroupsock(struct in_addr const& addr, Port port);
  96. virtual RTCPInstance* createRTCP(Groupsock* RTCPgs, unsigned totSessionBW, /* in kbps */
  97. unsigned char const* cname, RTPSink* sink);
  98. public:
  99. void multiplexRTCPWithRTP() { fMultiplexRTCPWithRTP = True; }
  100. // An alternative to passing the "multiplexRTCPWithRTP" parameter as True in the constructor
  101. void setRTCPAppPacketHandler(RTCPAppHandlerFunc* handler, void* clientData);
  102. // Sets a handler to be called if a RTCP "APP" packet arrives from any future client.
  103. // (Any current clients are not affected; any "APP" packets from them will continue to be
  104. // handled by whatever handler existed when the client sent its first RTSP "PLAY" command.)
  105. // (Call with (NULL, NULL) to remove an existing handler - for future clients only)
  106. void sendRTCPAppPacket(u_int8_t subtype, char const* name,
  107. u_int8_t* appDependentData, unsigned appDependentDataSize);
  108. // Sends a custom RTCP "APP" packet to the most recent client (if "reuseFirstSource" was False),
  109. // or to all current clients (if "reuseFirstSource" was True).
  110. // The parameters correspond to their
  111. // respective fields as described in the RTP/RTCP definition (RFC 3550).
  112. // Note that only the low-order 5 bits of "subtype" are used, and only the first 4 bytes
  113. // of "name" are used. (If "name" has fewer than 4 bytes, or is NULL,
  114. // then the remaining bytes are '\0'.)
  115. private:
  116. void setSDPLinesFromRTPSink(RTPSink* rtpSink, FramedSource* inputSource,
  117. unsigned estBitrate);
  118. // used to implement "sdpLines()"
  119. protected:
  120. char* fSDPLines;
  121. HashTable* fDestinationsHashTable; // indexed by client session id
  122. private:
  123. Boolean fReuseFirstSource;
  124. portNumBits fInitialPortNum;
  125. Boolean fMultiplexRTCPWithRTP;
  126. void* fLastStreamToken;
  127. char fCNAME[100]; // for RTCP
  128. RTCPAppHandlerFunc* fAppHandlerTask;
  129. void* fAppHandlerClientData;
  130. friend class StreamState;
  131. };
  132. // A class that represents the state of an ongoing stream. This is used only internally, in the implementation of
  133. // "OnDemandServerMediaSubsession", but we expose the definition here, in case subclasses of "OnDemandServerMediaSubsession"
  134. // want to access it.
  135. class Destinations {
  136. public:
  137. Destinations(struct in_addr const& destAddr,
  138. Port const& rtpDestPort,
  139. Port const& rtcpDestPort)
  140. : isTCP(False), addr(destAddr), rtpPort(rtpDestPort), rtcpPort(rtcpDestPort) {
  141. }
  142. Destinations(int tcpSockNum, unsigned char rtpChanId, unsigned char rtcpChanId)
  143. : isTCP(True), rtpPort(0) /*dummy*/, rtcpPort(0) /*dummy*/,
  144. tcpSocketNum(tcpSockNum), rtpChannelId(rtpChanId), rtcpChannelId(rtcpChanId) {
  145. }
  146. public:
  147. Boolean isTCP;
  148. struct in_addr addr;
  149. Port rtpPort;
  150. Port rtcpPort;
  151. int tcpSocketNum;
  152. unsigned char rtpChannelId, rtcpChannelId;
  153. };
  154. class StreamState {
  155. public:
  156. StreamState(OnDemandServerMediaSubsession& master,
  157. Port const& serverRTPPort, Port const& serverRTCPPort,
  158. RTPSink* rtpSink, BasicUDPSink* udpSink,
  159. unsigned totalBW, FramedSource* mediaSource,
  160. Groupsock* rtpGS, Groupsock* rtcpGS);
  161. virtual ~StreamState();
  162. void startPlaying(Destinations* destinations, unsigned clientSessionId,
  163. TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData,
  164. ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler,
  165. void* serverRequestAlternativeByteHandlerClientData);
  166. void pause();
  167. void sendRTCPAppPacket(u_int8_t subtype, char const* name,
  168. u_int8_t* appDependentData, unsigned appDependentDataSize);
  169. void endPlaying(Destinations* destinations, unsigned clientSessionId);
  170. void reclaim();
  171. unsigned& referenceCount() { return fReferenceCount; }
  172. Port const& serverRTPPort() const { return fServerRTPPort; }
  173. Port const& serverRTCPPort() const { return fServerRTCPPort; }
  174. RTPSink* rtpSink() const { return fRTPSink; }
  175. RTCPInstance* rtcpInstance() const { return fRTCPInstance; }
  176. float streamDuration() const { return fStreamDuration; }
  177. FramedSource* mediaSource() const { return fMediaSource; }
  178. float& startNPT() { return fStartNPT; }
  179. private:
  180. OnDemandServerMediaSubsession& fMaster;
  181. Boolean fAreCurrentlyPlaying;
  182. unsigned fReferenceCount;
  183. Port fServerRTPPort, fServerRTCPPort;
  184. RTPSink* fRTPSink;
  185. BasicUDPSink* fUDPSink;
  186. float fStreamDuration;
  187. unsigned fTotalBW;
  188. RTCPInstance* fRTCPInstance;
  189. FramedSource* fMediaSource;
  190. float fStartNPT; // initial 'normal play time'; reset after each seek
  191. Groupsock* fRTPgs;
  192. Groupsock* fRTCPgs;
  193. };
  194. #endif