liveMedia/include/MediaSession.hh

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // "liveMedia"
00017 // Copyright (c) 1996-2013 Live Networks, Inc.  All rights reserved.
00018 // A data structure that represents a session that consists of
00019 // potentially multiple (audio and/or video) sub-sessions
00020 // (This data structure is used for media *receivers* - i.e., clients.
00021 //  For media streamers, use "ServerMediaSession" instead.)
00022 // C++ header
00023 
00024 /* NOTE: To support receiving your own custom RTP payload format, you must first define a new subclass of "MultiFramedRTPSource"
00025    (or "BasicUDPSource") that implements it.  Then define your own subclass of "MediaSession" and "MediaSubsession", as follows:
00026    - In your subclass of "MediaSession" (named, for example, "myMediaSession"):
00027        - Define and implement your own static member function
00028            static myMediaSession* createNew(UsageEnvironment& env, char const* sdpDescription);
00029          and call this - instead of "MediaSession::createNew()" - in your application, when you create a new "MediaSession" object.
00030        - Reimplement the "createNewMediaSubsession()" virtual function, as follows:
00031            MediaSubsession* myMediaSession::createNewMediaSubsession() { return new myMediaSubsession(*this); }
00032    - In your subclass of "MediaSubsession" (named, for example, "myMediaSubsession"):
00033        - Reimplement the "createSourceObjects()" virtual function, perhaps similar to this:
00034            Boolean myMediaSubsession::createSourceObjects(int useSpecialRTPoffset) {
00035              if (strcmp(fCodecName, "X-MY-RTP-PAYLOAD-FORMAT") == 0) {
00036                // This subsession uses our custom RTP payload format:
00037                fReadSource = fRTPSource = myRTPPayloadFormatRTPSource::createNew( <parameters> );
00038                return True;
00039              } else {
00040                // This subsession uses some other RTP payload format - perhaps one that we already implement:
00041                return ::createSourceObjects(useSpecialRTPoffset);
00042              }
00043            }  
00044 */
00045 
00046 #ifndef _MEDIA_SESSION_HH
00047 #define _MEDIA_SESSION_HH
00048 
00049 #ifndef _RTCP_HH
00050 #include "RTCP.hh"
00051 #endif
00052 #ifndef _FRAMED_FILTER_HH
00053 #include "FramedFilter.hh"
00054 #endif
00055 
00056 class MediaSubsession; // forward
00057 
00058 class MediaSession: public Medium {
00059 public:
00060   static MediaSession* createNew(UsageEnvironment& env,
00061                                  char const* sdpDescription);
00062 
00063   static Boolean lookupByName(UsageEnvironment& env, char const* sourceName,
00064                               MediaSession*& resultSession);
00065 
00066   Boolean hasSubsessions() const { return fSubsessionsHead != NULL; }
00067 
00068   char* connectionEndpointName() const { return fConnectionEndpointName; }
00069   char const* CNAME() const { return fCNAME; }
00070   struct in_addr const& sourceFilterAddr() const { return fSourceFilterAddr; }
00071   float& scale() { return fScale; }
00072   char* mediaSessionType() const { return fMediaSessionType; }
00073   char* sessionName() const { return fSessionName; }
00074   char* sessionDescription() const { return fSessionDescription; }
00075   char const* controlPath() const { return fControlPath; }
00076 
00077   double& playStartTime() { return fMaxPlayStartTime; }
00078   double& playEndTime() { return fMaxPlayEndTime; }
00079   char* absStartTime() const;
00080   char* absEndTime() const;
00081   // Used only to set the local fields:
00082   char*& _absStartTime() { return fAbsStartTime; }
00083   char*& _absEndTime() { return fAbsEndTime; }
00084 
00085   Boolean initiateByMediaType(char const* mimeType,
00086                               MediaSubsession*& resultSubsession,
00087                               int useSpecialRTPoffset = -1);
00088       // Initiates the first subsession with the specified MIME type
00089       // Returns the resulting subsession, or 'multi source' (not both)
00090 
00091 protected: // redefined virtual functions
00092   virtual Boolean isMediaSession() const;
00093 
00094 protected:
00095   MediaSession(UsageEnvironment& env);
00096       // called only by createNew();
00097   virtual ~MediaSession();
00098 
00099   virtual MediaSubsession* createNewMediaSubsession();
00100 
00101   Boolean initializeWithSDP(char const* sdpDescription);
00102   Boolean parseSDPLine(char const* input, char const*& nextLine);
00103   Boolean parseSDPLine_s(char const* sdpLine);
00104   Boolean parseSDPLine_i(char const* sdpLine);
00105   Boolean parseSDPLine_c(char const* sdpLine);
00106   Boolean parseSDPAttribute_type(char const* sdpLine);
00107   Boolean parseSDPAttribute_control(char const* sdpLine);
00108   Boolean parseSDPAttribute_range(char const* sdpLine);
00109   Boolean parseSDPAttribute_source_filter(char const* sdpLine);
00110 
00111   static char* lookupPayloadFormat(unsigned char rtpPayloadType,
00112                                    unsigned& rtpTimestampFrequency,
00113                                    unsigned& numChannels);
00114   static unsigned guessRTPTimestampFrequency(char const* mediumName,
00115                                              char const* codecName);
00116 
00117 protected:
00118   friend class MediaSubsessionIterator;
00119   char* fCNAME; // used for RTCP
00120 
00121   // Linkage fields:
00122   MediaSubsession* fSubsessionsHead;
00123   MediaSubsession* fSubsessionsTail;
00124 
00125   // Fields set from a SDP description:
00126   char* fConnectionEndpointName;
00127   double fMaxPlayStartTime;
00128   double fMaxPlayEndTime;
00129   char* fAbsStartTime;
00130   char* fAbsEndTime;
00131   struct in_addr fSourceFilterAddr; // used for SSM
00132   float fScale; // set from a RTSP "Scale:" header
00133   char* fMediaSessionType; // holds a=type value
00134   char* fSessionName; // holds s=<session name> value
00135   char* fSessionDescription; // holds i=<session description> value
00136   char* fControlPath; // holds optional a=control: string
00137 };
00138 
00139 
00140 class MediaSubsessionIterator {
00141 public:
00142   MediaSubsessionIterator(MediaSession const& session);
00143   virtual ~MediaSubsessionIterator();
00144 
00145   MediaSubsession* next(); // NULL if none
00146   void reset();
00147 
00148 private:
00149   MediaSession const& fOurSession;
00150   MediaSubsession* fNextPtr;
00151 };
00152 
00153 
00154 class MediaSubsession {
00155 public:
00156   MediaSession& parentSession() { return fParent; }
00157   MediaSession const& parentSession() const { return fParent; }
00158 
00159   unsigned short clientPortNum() const { return fClientPortNum; }
00160   unsigned char rtpPayloadFormat() const { return fRTPPayloadFormat; }
00161   char const* savedSDPLines() const { return fSavedSDPLines; }
00162   char const* mediumName() const { return fMediumName; }
00163   char const* codecName() const { return fCodecName; }
00164   char const* protocolName() const { return fProtocolName; }
00165   char const* controlPath() const { return fControlPath; }
00166   Boolean isSSM() const { return fSourceFilterAddr.s_addr != 0; }
00167 
00168   unsigned short videoWidth() const { return fVideoWidth; }
00169   unsigned short videoHeight() const { return fVideoHeight; }
00170   unsigned videoFPS() const { return fVideoFPS; }
00171   unsigned numChannels() const { return fNumChannels; }
00172   float& scale() { return fScale; }
00173 
00174   RTPSource* rtpSource() { return fRTPSource; }
00175   RTCPInstance* rtcpInstance() { return fRTCPInstance; }
00176   unsigned rtpTimestampFrequency() const { return fRTPTimestampFrequency; }
00177   FramedSource* readSource() { return fReadSource; }
00178     // This is the source that client sinks read from.  It is usually
00179     // (but not necessarily) the same as "rtpSource()"
00180   void addFilter(FramedFilter* filter);
00181     // Changes "readSource()" to "filter" (which must have just been created with "readSource()" as its input)
00182 
00183   double playStartTime() const;
00184   double playEndTime() const;
00185   char* absStartTime() const;
00186   char* absEndTime() const;
00187   // Used only to set the local fields:
00188   double& _playStartTime() { return fPlayStartTime; }
00189   double& _playEndTime() { return fPlayEndTime; }
00190   char*& _absStartTime() { return fAbsStartTime; }
00191   char*& _absEndTime() { return fAbsEndTime; }
00192 
00193   Boolean initiate(int useSpecialRTPoffset = -1);
00194       // Creates a "RTPSource" for this subsession. (Has no effect if it's
00195       // already been created.)  Returns True iff this succeeds.
00196   void deInitiate(); // Destroys any previously created RTPSource
00197   Boolean setClientPortNum(unsigned short portNum);
00198       // Sets the preferred client port number that any "RTPSource" for
00199       // this subsession would use.  (By default, the client port number
00200       // is gotten from the original SDP description, or - if the SDP
00201       // description does not specfy a client port number - an ephemeral
00202       // (even) port number is chosen.)  This routine must *not* be
00203       // called after initiate().
00204   void receiveRawMP3ADUs() { fReceiveRawMP3ADUs = True; } // optional hack for audio/MPA-ROBUST; must not be called after Initiate()
00205   void receiveRawJPEGFrames() { fReceiveRawJPEGFrames = True; } // optional hack for video/JPEG; must not be called after Initiate()
00206   char*& connectionEndpointName() { return fConnectionEndpointName; }
00207   char const* connectionEndpointName() const {
00208     return fConnectionEndpointName;
00209   }
00210 
00211   // 'Bandwidth' parameter, set in the "b=" SDP line:
00212   unsigned bandwidth() const { return fBandwidth; }
00213 
00214   // Various parameters set in "a=fmtp:" SDP lines:
00215   unsigned fmtp_auxiliarydatasizelength() const { return fAuxiliarydatasizelength; }
00216   unsigned fmtp_constantduration() const { return fConstantduration; }
00217   unsigned fmtp_constantsize() const { return fConstantsize; }
00218   unsigned fmtp_crc() const { return fCRC; }
00219   unsigned fmtp_ctsdeltalength() const { return fCtsdeltalength; }
00220   unsigned fmtp_de_interleavebuffersize() const { return fDe_interleavebuffersize; }
00221   unsigned fmtp_dtsdeltalength() const { return fDtsdeltalength; }
00222   unsigned fmtp_indexdeltalength() const { return fIndexdeltalength; }
00223   unsigned fmtp_indexlength() const { return fIndexlength; }
00224   unsigned fmtp_interleaving() const { return fInterleaving; }
00225   unsigned fmtp_maxdisplacement() const { return fMaxdisplacement; }
00226   unsigned fmtp_objecttype() const { return fObjecttype; }
00227   unsigned fmtp_octetalign() const { return fOctetalign; }
00228   unsigned fmtp_profile_level_id() const { return fProfile_level_id; }
00229   unsigned fmtp_robustsorting() const { return fRobustsorting; }
00230   unsigned fmtp_sizelength() const { return fSizelength; }
00231   unsigned fmtp_streamstateindication() const { return fStreamstateindication; }
00232   unsigned fmtp_streamtype() const { return fStreamtype; }
00233   Boolean fmtp_cpresent() const { return fCpresent; }
00234   Boolean fmtp_randomaccessindication() const { return fRandomaccessindication; }
00235   char const* fmtp_config() const { return fConfig; }
00236   char const* fmtp_configuration() const { return fmtp_config(); }
00237   char const* fmtp_mode() const { return fMode; }
00238   char const* fmtp_spropparametersets() const { return fSpropParameterSets; }
00239   char const* fmtp_emphasis() const { return fEmphasis; }
00240   char const* fmtp_channelorder() const { return fChannelOrder; }
00241 
00242   netAddressBits connectionEndpointAddress() const;
00243       // Converts "fConnectionEndpointName" to an address (or 0 if unknown)
00244   void setDestinations(netAddressBits defaultDestAddress);
00245       // Uses "fConnectionEndpointName" and "serverPortNum" to set
00246       // the destination address and port of the RTP and RTCP objects.
00247       // This is typically called by RTSP clients after doing "SETUP".
00248 
00249   char const* sessionId() const { return fSessionId; }
00250   void setSessionId(char const* sessionId);
00251 
00252   // Public fields that external callers can use to keep state.
00253   // (They are responsible for all storage management on these fields)
00254   unsigned short serverPortNum; // in host byte order (used by RTSP)
00255   unsigned char rtpChannelId, rtcpChannelId; // used by RTSP (for RTP/TCP)
00256   MediaSink* sink; // callers can use this to keep track of who's playing us
00257   void* miscPtr; // callers can use this for whatever they want
00258 
00259   // Parameters set from a RTSP "RTP-Info:" header:
00260   struct {
00261     u_int16_t seqNum;
00262     u_int32_t timestamp;
00263     Boolean infoIsNew; // not part of the RTSP header; instead, set whenever this struct is filled in
00264   } rtpInfo;
00265 
00266   double getNormalPlayTime(struct timeval const& presentationTime);
00267   // Computes the stream's "Normal Play Time" (NPT) from the given "presentationTime".
00268   // (For the definition of "Normal Play Time", see RFC 2326, section 3.6.)
00269   // This function is useful only if the "rtpInfo" structure was previously filled in
00270   // (e.g., by a "RTP-Info:" header in a RTSP response).
00271   // Also, for this function to work properly, the RTP stream's presentation times must (eventually) be
00272   // synchronized via RTCP.
00273   // (Note: If this function returns a negative number, then the result should be ignored by the caller.)
00274 
00275 protected:
00276   friend class MediaSession;
00277   friend class MediaSubsessionIterator;
00278   MediaSubsession(MediaSession& parent);
00279   virtual ~MediaSubsession();
00280 
00281   UsageEnvironment& env() { return fParent.envir(); }
00282   void setNext(MediaSubsession* next) { fNext = next; }
00283 
00284   Boolean parseSDPLine_c(char const* sdpLine);
00285   Boolean parseSDPLine_b(char const* sdpLine);
00286   Boolean parseSDPAttribute_rtpmap(char const* sdpLine);
00287   Boolean parseSDPAttribute_control(char const* sdpLine);
00288   Boolean parseSDPAttribute_range(char const* sdpLine);
00289   Boolean parseSDPAttribute_fmtp(char const* sdpLine);
00290   Boolean parseSDPAttribute_source_filter(char const* sdpLine);
00291   Boolean parseSDPAttribute_x_dimensions(char const* sdpLine);
00292   Boolean parseSDPAttribute_framerate(char const* sdpLine);
00293 
00294   virtual Boolean createSourceObjects(int useSpecialRTPoffset);
00295     // create "fRTPSource" and "fReadSource" member objects, after we've been initialized via SDP
00296 
00297 protected:
00298   // Linkage fields:
00299   MediaSession& fParent;
00300   MediaSubsession* fNext;
00301 
00302   // Fields set from a SDP description:
00303   char* fConnectionEndpointName; // may also be set by RTSP SETUP response
00304   unsigned short fClientPortNum; // in host byte order
00305       // This field is also set by initiate()
00306   unsigned char fRTPPayloadFormat;
00307   char* fSavedSDPLines;
00308   char* fMediumName;
00309   char* fCodecName;
00310   char* fProtocolName;
00311   unsigned fRTPTimestampFrequency;
00312   char* fControlPath; // holds optional a=control: string
00313   struct in_addr fSourceFilterAddr; // used for SSM
00314   unsigned fBandwidth; // in kilobits-per-second, from b= line
00315 
00316   // Parameters set by "a=fmtp:" SDP lines:
00317   unsigned fAuxiliarydatasizelength, fConstantduration, fConstantsize;
00318   unsigned fCRC, fCtsdeltalength, fDe_interleavebuffersize, fDtsdeltalength;
00319   unsigned fIndexdeltalength, fIndexlength, fInterleaving;
00320   unsigned fMaxdisplacement, fObjecttype;
00321   unsigned fOctetalign, fProfile_level_id, fRobustsorting;
00322   unsigned fSizelength, fStreamstateindication, fStreamtype;
00323   Boolean fCpresent, fRandomaccessindication;
00324   char *fConfig, *fMode, *fSpropParameterSets, *fEmphasis, *fChannelOrder;
00325 
00326   double fPlayStartTime;
00327   double fPlayEndTime;
00328   char* fAbsStartTime;
00329   char* fAbsEndTime;
00330   unsigned short fVideoWidth, fVideoHeight;
00331      // screen dimensions (set by an optional a=x-dimensions: <w>,<h> line)
00332   unsigned fVideoFPS;
00333      // frame rate (set by an optional "a=framerate: <fps>" or "a=x-framerate: <fps>" line)
00334   unsigned fNumChannels;
00335      // optionally set by "a=rtpmap:" lines for audio sessions.  Default: 1
00336   float fScale; // set from a RTSP "Scale:" header
00337   double fNPT_PTS_Offset; // set by "getNormalPlayTime()"; add this to a PTS to get NPT
00338 
00339   // Fields set or used by initiate():
00340   Groupsock* fRTPSocket; Groupsock* fRTCPSocket; // works even for unicast
00341   RTPSource* fRTPSource; RTCPInstance* fRTCPInstance;
00342   FramedSource* fReadSource;
00343   Boolean fReceiveRawMP3ADUs, fReceiveRawJPEGFrames;
00344 
00345   // Other fields:
00346   char* fSessionId; // used by RTSP
00347 };
00348 
00349 #endif

Generated on Mon Apr 29 13:28:01 2013 for live by  doxygen 1.5.2