| /********** |
| This library is free software; you can redistribute it and/or modify it under |
| the terms of the GNU Lesser General Public License as published by the |
| Free Software Foundation; either version 3 of the License, or (at your |
| option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.) |
| |
| This library is distributed in the hope that it will be useful, but WITHOUT |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for |
| more details. |
| |
| You should have received a copy of the GNU Lesser General Public License |
| along with this library; if not, write to the Free Software Foundation, Inc., |
| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| **********/ |
| // "liveMedia" |
| // Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved. |
| // A data structure that represents a session that consists of |
| // potentially multiple (audio and/or video) sub-sessions |
| // (This data structure is used for media *streamers* - i.e., servers. |
| // For media receivers, use "MediaSession" instead.) |
| // C++ header |
| |
| #ifndef _SERVER_MEDIA_SESSION_HH |
| #define _SERVER_MEDIA_SESSION_HH |
| |
| #ifndef _RTCP_HH |
| #include "RTCP.hh" |
| #endif |
| |
| class ServerMediaSubsession; // forward |
| |
| class ServerMediaSession: public Medium { |
| public: |
| static ServerMediaSession* createNew(UsageEnvironment& env, |
| char const* streamName = NULL, |
| char const* info = NULL, |
| char const* description = NULL, |
| Boolean isSSM = False, |
| char const* miscSDPLines = NULL); |
| |
| static Boolean lookupByName(UsageEnvironment& env, |
| char const* mediumName, |
| ServerMediaSession*& resultSession); |
| |
| char* generateSDPDescription(); // based on the entire session |
| // Note: The caller is responsible for freeing the returned string |
| |
| char const* streamName() const { return fStreamName; } |
| |
| Boolean addSubsession(ServerMediaSubsession* subsession); |
| unsigned numSubsessions() const { return fSubsessionCounter; } |
| |
| void testScaleFactor(float& scale); // sets "scale" to the actual supported scale |
| float duration() const; |
| // a result == 0 means an unbounded session (the default) |
| // a result < 0 means: subsession durations differ; the result is -(the largest). |
| // a result > 0 means: this is the duration of a bounded session |
| |
| virtual void noteLiveness(); |
| // called whenever a client - accessing this media - notes liveness. |
| // The default implementation does nothing, but subclasses can redefine this - e.g., if you |
| // want to remove long-unused "ServerMediaSession"s from the server. |
| |
| unsigned referenceCount() const { return fReferenceCount; } |
| void incrementReferenceCount() { ++fReferenceCount; } |
| void decrementReferenceCount() { if (fReferenceCount > 0) --fReferenceCount; } |
| Boolean& deleteWhenUnreferenced() { return fDeleteWhenUnreferenced; } |
| |
| void deleteAllSubsessions(); |
| // Removes and deletes all subsessions added by "addSubsession()", returning us to an 'empty' state |
| // Note: If you have already added this "ServerMediaSession" to a "RTSPServer" then, before calling this function, |
| // you must first close any client connections that use it, |
| // by calling "RTSPServer::closeAllClientSessionsForServerMediaSession()". |
| |
| protected: |
| ServerMediaSession(UsageEnvironment& env, char const* streamName, |
| char const* info, char const* description, |
| Boolean isSSM, char const* miscSDPLines); |
| // called only by "createNew()" |
| |
| virtual ~ServerMediaSession(); |
| |
| private: // redefined virtual functions |
| virtual Boolean isServerMediaSession() const; |
| |
| private: |
| Boolean fIsSSM; |
| |
| // Linkage fields: |
| friend class ServerMediaSubsessionIterator; |
| ServerMediaSubsession* fSubsessionsHead; |
| ServerMediaSubsession* fSubsessionsTail; |
| unsigned fSubsessionCounter; |
| |
| char* fStreamName; |
| char* fInfoSDPString; |
| char* fDescriptionSDPString; |
| char* fMiscSDPLines; |
| struct timeval fCreationTime; |
| unsigned fReferenceCount; |
| Boolean fDeleteWhenUnreferenced; |
| }; |
| |
| |
| class ServerMediaSubsessionIterator { |
| public: |
| ServerMediaSubsessionIterator(ServerMediaSession& session); |
| virtual ~ServerMediaSubsessionIterator(); |
| |
| ServerMediaSubsession* next(); // NULL if none |
| void reset(); |
| |
| private: |
| ServerMediaSession& fOurSession; |
| ServerMediaSubsession* fNextPtr; |
| }; |
| |
| |
| class ServerMediaSubsession: public Medium { |
| public: |
| unsigned trackNumber() const { return fTrackNumber; } |
| char const* trackId(); |
| virtual char const* sdpLines() = 0; |
| virtual void getStreamParameters(unsigned clientSessionId, // in |
| netAddressBits clientAddress, // in |
| Port const& clientRTPPort, // in |
| Port const& clientRTCPPort, // in |
| int tcpSocketNum, // in (-1 means use UDP, not TCP) |
| unsigned char rtpChannelId, // in (used if TCP) |
| unsigned char rtcpChannelId, // in (used if TCP) |
| netAddressBits& destinationAddress, // in out |
| u_int8_t& destinationTTL, // in out |
| Boolean& isMulticast, // out |
| Port& serverRTPPort, // out |
| Port& serverRTCPPort, // out |
| void*& streamToken // out |
| ) = 0; |
| virtual void startStream(unsigned clientSessionId, void* streamToken, |
| TaskFunc* rtcpRRHandler, |
| void* rtcpRRHandlerClientData, |
| unsigned short& rtpSeqNum, |
| unsigned& rtpTimestamp, |
| ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, |
| void* serverRequestAlternativeByteHandlerClientData) = 0; |
| virtual void pauseStream(unsigned clientSessionId, void* streamToken); |
| virtual void seekStream(unsigned clientSessionId, void* streamToken, double& seekNPT, |
| double streamDuration, u_int64_t& numBytes); |
| // This routine is used to seek by relative (i.e., NPT) time. |
| // "streamDuration", if >0.0, specifies how much data to stream, past "seekNPT". (If <=0.0, all remaining data is streamed.) |
| // "numBytes" returns the size (in bytes) of the data to be streamed, or 0 if unknown or unlimited. |
| virtual void seekStream(unsigned clientSessionId, void* streamToken, char*& absStart, char*& absEnd); |
| // This routine is used to seek by 'absolute' time. |
| // "absStart" should be a string of the form "YYYYMMDDTHHMMSSZ" or "YYYYMMDDTHHMMSS.<frac>Z". |
| // "absEnd" should be either NULL (for no end time), or a string of the same form as "absStart". |
| // These strings may be modified in-place, or can be reassigned to a newly-allocated value (after delete[]ing the original). |
| virtual void nullSeekStream(unsigned clientSessionId, void* streamToken, |
| double streamEndTime, u_int64_t& numBytes); |
| // Called whenever we're handling a "PLAY" command without a specified start time. |
| virtual void setStreamScale(unsigned clientSessionId, void* streamToken, float scale); |
| virtual float getCurrentNPT(void* streamToken); |
| virtual FramedSource* getStreamSource(void* streamToken); |
| virtual void getRTPSinkandRTCP(void* streamToken, |
| RTPSink const*& rtpSink, RTCPInstance const*& rtcp) = 0; |
| // Returns pointers to the "RTPSink" and "RTCPInstance" objects for "streamToken". |
| // (This can be useful if you want to get the associated 'Groupsock' objects, for example.) |
| // You must not delete these objects, or start/stop playing them; instead, that is done |
| // using the "startStream()" and "deleteStream()" functions. |
| virtual void deleteStream(unsigned clientSessionId, void*& streamToken); |
| |
| virtual void testScaleFactor(float& scale); // sets "scale" to the actual supported scale |
| virtual float duration() const; |
| // returns 0 for an unbounded session (the default) |
| // returns > 0 for a bounded session |
| virtual void getAbsoluteTimeRange(char*& absStartTime, char*& absEndTime) const; |
| // Subclasses can reimplement this iff they support seeking by 'absolute' time. |
| |
| // The following may be called by (e.g.) SIP servers, for which the |
| // address and port number fields in SDP descriptions need to be non-zero: |
| void setServerAddressAndPortForSDP(netAddressBits addressBits, |
| portNumBits portBits); |
| |
| protected: // we're a virtual base class |
| ServerMediaSubsession(UsageEnvironment& env); |
| virtual ~ServerMediaSubsession(); |
| |
| char const* rangeSDPLine() const; |
| // returns a string to be delete[]d |
| |
| ServerMediaSession* fParentSession; |
| netAddressBits fServerAddressForSDP; |
| portNumBits fPortNumForSDP; |
| |
| private: |
| friend class ServerMediaSession; |
| friend class ServerMediaSubsessionIterator; |
| ServerMediaSubsession* fNext; |
| |
| unsigned fTrackNumber; // within an enclosing ServerMediaSession |
| char const* fTrackId; |
| }; |
| |
| #endif |