blob: 00c4917a802e02bf9940c405305e565b9a727f6b [file] [log] [blame]
/**********
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 2.1 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-2015 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
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