/********** 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 .) 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-2024 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 LIVEMEDIA_API 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(int addressFamily); // 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 server then, before calling this function, // you must first close any client connections that use it, // by calling "GenericMediaServer::closeAllClientSessionsForServerMediaSession()". Boolean streamingUsesSRTP; // by default, False Boolean streamingIsEncrypted; // by default, False 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 LIVEMEDIA_API ServerMediaSubsessionIterator { public: ServerMediaSubsessionIterator(ServerMediaSession& session); virtual ~ServerMediaSubsessionIterator(); ServerMediaSubsession* next(); // NULL if none void reset(); private: ServerMediaSession& fOurSession; ServerMediaSubsession* fNextPtr; }; class LIVEMEDIA_API ServerMediaSubsession: public Medium { public: unsigned trackNumber() const { return fTrackNumber; } char const* trackId(); virtual char const* sdpLines(int addressFamily) = 0; virtual void getStreamParameters(unsigned clientSessionId, // in struct sockaddr_storage const& 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) TLSState* tlsState, // in (used if TCP) struct sockaddr_storage& 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.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*& rtpSink, RTCPInstance*& 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. 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; private: friend class ServerMediaSession; friend class ServerMediaSubsessionIterator; ServerMediaSubsession* fNext; unsigned fTrackNumber; // within an enclosing ServerMediaSession char const* fTrackId; }; #endif