liveMedia/PassiveServerMediaSubsession.cpp

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-2008 Live Networks, Inc.  All rights reserved.
00018 // A 'ServerMediaSubsession' object that represents an existing
00019 // 'RTPSink', rather than one that creates new 'RTPSink's on demand.
00020 // Implementation
00021 
00022 #include "PassiveServerMediaSubsession.hh"
00023 #include <GroupsockHelper.hh>
00024 
00026 
00027 PassiveServerMediaSubsession*
00028 PassiveServerMediaSubsession::createNew(RTPSink& rtpSink,
00029                                         RTCPInstance* rtcpInstance) {
00030   return new PassiveServerMediaSubsession(rtpSink, rtcpInstance);
00031 }
00032 
00033 PassiveServerMediaSubsession
00034 ::PassiveServerMediaSubsession(RTPSink& rtpSink, RTCPInstance* rtcpInstance)
00035   : ServerMediaSubsession(rtpSink.envir()),
00036     fRTPSink(rtpSink), fRTCPInstance(rtcpInstance), fSDPLines(NULL) {
00037 }
00038 
00039 char const*
00040 PassiveServerMediaSubsession::sdpLines() {
00041   if (fSDPLines == NULL ) {
00042     // Construct a set of SDP lines that describe this subsession:
00043     // Use the components from "rtpSink":
00044     Groupsock const& gs = fRTPSink.groupsockBeingUsed();
00045     struct in_addr const& ipAddress = gs.groupAddress();
00046     unsigned short portNum = ntohs(gs.port().num());
00047     unsigned char ttl = gs.ttl();
00048     unsigned char rtpPayloadType = fRTPSink.rtpPayloadType();
00049     char const* mediaType = fRTPSink.sdpMediaType();
00050     char* rtpmapLine = fRTPSink.rtpmapLine();
00051     char const* rangeLine = rangeSDPLine();
00052     char const* auxSDPLine = fRTPSink.auxSDPLine();
00053     if (auxSDPLine == NULL) auxSDPLine = "";
00054 
00055     char* const ipAddressStr = strDup(our_inet_ntoa(ipAddress));
00056 
00057     char const* const sdpFmt =
00058       "m=%s %d RTP/AVP %d\r\n"
00059       "c=IN IP4 %s/%d\r\n"
00060       "%s"
00061       "%s"
00062       "%s"
00063       "a=control:%s\r\n";
00064     unsigned sdpFmtSize = strlen(sdpFmt)
00065       + strlen(mediaType) + 5 /* max short len */ + 3 /* max char len */
00066       + strlen(ipAddressStr) + 3 /* max char len */
00067       + strlen(rtpmapLine)
00068       + strlen(rangeLine)
00069       + strlen(auxSDPLine)
00070       + strlen(trackId());
00071     char* sdpLines = new char[sdpFmtSize];
00072     sprintf(sdpLines, sdpFmt,
00073             mediaType, // m= <media>
00074             portNum, // m= <port>
00075             rtpPayloadType, // m= <fmt list>
00076             ipAddressStr, // c= <connection address>
00077             ttl, // c= TTL
00078             rtpmapLine, // a=rtpmap:... (if present)
00079             rangeLine, // a=range:... (if present)
00080             auxSDPLine, // optional extra SDP line
00081             trackId()); // a=control:<track-id>
00082     delete[] ipAddressStr; delete[] (char*)rangeLine; delete[] rtpmapLine;
00083 
00084     fSDPLines = strDup(sdpLines);
00085     delete[] sdpLines;
00086   }
00087 
00088   return fSDPLines;
00089 }
00090 
00091 void PassiveServerMediaSubsession
00092 ::getStreamParameters(unsigned /*clientSessionId*/,
00093                       netAddressBits /*clientAddress*/,
00094                       Port const& /*clientRTPPort*/,
00095                       Port const& /*clientRTCPPort*/,
00096                       int /*tcpSocketNum*/,
00097                       unsigned char /*rtpChannelId*/,
00098                       unsigned char /*rtcpChannelId*/,
00099                       netAddressBits& destinationAddress,
00100                       u_int8_t& destinationTTL,
00101                       Boolean& isMulticast,
00102                       Port& serverRTPPort,
00103                       Port& serverRTCPPort,
00104                       void*& streamToken) {
00105   isMulticast = True;
00106   Groupsock& gs = fRTPSink.groupsockBeingUsed();
00107   if (destinationTTL == 255) destinationTTL = gs.ttl();
00108   if (destinationAddress == 0) { // normal case
00109     destinationAddress = gs.groupAddress().s_addr;
00110   } else { // use the client-specified destination address instead:
00111     struct in_addr destinationAddr; destinationAddr.s_addr = destinationAddress;
00112     gs.changeDestinationParameters(destinationAddr, 0, destinationTTL);
00113     if (fRTCPInstance != NULL) {
00114       Groupsock* rtcpGS = fRTCPInstance->RTCPgs();
00115       rtcpGS->changeDestinationParameters(destinationAddr, 0, destinationTTL);
00116     }
00117   }
00118   serverRTPPort = gs.port();
00119   if (fRTCPInstance != NULL) {
00120     Groupsock* rtcpGS = fRTCPInstance->RTCPgs();
00121     serverRTCPPort = rtcpGS->port();
00122   }
00123   streamToken = NULL; // not used
00124 }
00125 
00126 void PassiveServerMediaSubsession::startStream(unsigned /*clientSessionId*/,
00127                                                void* /*streamToken*/,
00128                                                TaskFunc* /*rtcpRRHandler*/,
00129                                                void* /*rtcpRRHandlerClientData*/,
00130                                                unsigned short& rtpSeqNum,
00131                                                unsigned& rtpTimestamp) {
00132   // Note: We don't set a RTCP RR handler, because (i) we're called potentially
00133   // many times on the same "RTCPInstance", and (ii) the "RTCPInstance" remains
00134   // in existence after "deleteStream()" is called.
00135   rtpSeqNum = fRTPSink.currentSeqNo();
00136   rtpTimestamp = fRTPSink.presetNextTimestamp();
00137 }
00138 
00139 PassiveServerMediaSubsession::~PassiveServerMediaSubsession() {
00140   delete[] fSDPLines;
00141 }

Generated on Tue Oct 7 15:38:09 2008 for live by  doxygen 1.5.2