00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 fSDPLines(NULL), fRTPSink(rtpSink), fRTCPInstance(rtcpInstance) {
00037 fClientRTCPSourceRecords = HashTable::create(ONE_WORD_HASH_KEYS);
00038 }
00039
00040 class RTCPSourceRecord {
00041 public:
00042 RTCPSourceRecord(netAddressBits addr, Port const& port)
00043 : addr(addr), port(port) {
00044 }
00045
00046 netAddressBits addr;
00047 Port port;
00048 };
00049
00050 PassiveServerMediaSubsession::~PassiveServerMediaSubsession() {
00051 delete[] fSDPLines;
00052
00053
00054 while (1) {
00055 RTCPSourceRecord* source = (RTCPSourceRecord*)(fClientRTCPSourceRecords->RemoveNext());
00056 if (source == NULL) break;
00057 delete source;
00058 }
00059
00060 delete fClientRTCPSourceRecords;
00061 }
00062
00063 char const*
00064 PassiveServerMediaSubsession::sdpLines() {
00065 if (fSDPLines == NULL ) {
00066
00067
00068 Groupsock const& gs = fRTPSink.groupsockBeingUsed();
00069 AddressString groupAddressStr(gs.groupAddress());
00070 unsigned short portNum = ntohs(gs.port().num());
00071 unsigned char ttl = gs.ttl();
00072 unsigned char rtpPayloadType = fRTPSink.rtpPayloadType();
00073 char const* mediaType = fRTPSink.sdpMediaType();
00074 unsigned estBitrate
00075 = fRTCPInstance == NULL ? 50 : fRTCPInstance->totSessionBW();
00076 char* rtpmapLine = fRTPSink.rtpmapLine();
00077 char const* rangeLine = rangeSDPLine();
00078 char const* auxSDPLine = fRTPSink.auxSDPLine();
00079 if (auxSDPLine == NULL) auxSDPLine = "";
00080
00081 char const* const sdpFmt =
00082 "m=%s %d RTP/AVP %d\r\n"
00083 "c=IN IP4 %s/%d\r\n"
00084 "b=AS:%u\r\n"
00085 "%s"
00086 "%s"
00087 "%s"
00088 "a=control:%s\r\n";
00089 unsigned sdpFmtSize = strlen(sdpFmt)
00090 + strlen(mediaType) + 5 + 3
00091 + strlen(groupAddressStr.val()) + 3
00092 + 20
00093 + strlen(rtpmapLine)
00094 + strlen(rangeLine)
00095 + strlen(auxSDPLine)
00096 + strlen(trackId());
00097 char* sdpLines = new char[sdpFmtSize];
00098 sprintf(sdpLines, sdpFmt,
00099 mediaType,
00100 portNum,
00101 rtpPayloadType,
00102 groupAddressStr.val(),
00103 ttl,
00104 estBitrate,
00105 rtpmapLine,
00106 rangeLine,
00107 auxSDPLine,
00108 trackId());
00109 delete[] (char*)rangeLine; delete[] rtpmapLine;
00110
00111 fSDPLines = strDup(sdpLines);
00112 delete[] sdpLines;
00113 }
00114
00115 return fSDPLines;
00116 }
00117
00118 void PassiveServerMediaSubsession
00119 ::getStreamParameters(unsigned clientSessionId,
00120 netAddressBits clientAddress,
00121 Port const& ,
00122 Port const& clientRTCPPort,
00123 int ,
00124 unsigned char ,
00125 unsigned char ,
00126 netAddressBits& destinationAddress,
00127 u_int8_t& destinationTTL,
00128 Boolean& isMulticast,
00129 Port& serverRTPPort,
00130 Port& serverRTCPPort,
00131 void*& streamToken) {
00132 isMulticast = True;
00133 Groupsock& gs = fRTPSink.groupsockBeingUsed();
00134 if (destinationTTL == 255) destinationTTL = gs.ttl();
00135 if (destinationAddress == 0) {
00136 destinationAddress = gs.groupAddress().s_addr;
00137 } else {
00138 struct in_addr destinationAddr; destinationAddr.s_addr = destinationAddress;
00139 gs.changeDestinationParameters(destinationAddr, 0, destinationTTL);
00140 if (fRTCPInstance != NULL) {
00141 Groupsock* rtcpGS = fRTCPInstance->RTCPgs();
00142 rtcpGS->changeDestinationParameters(destinationAddr, 0, destinationTTL);
00143 }
00144 }
00145 serverRTPPort = gs.port();
00146 if (fRTCPInstance != NULL) {
00147 Groupsock* rtcpGS = fRTCPInstance->RTCPgs();
00148 serverRTCPPort = rtcpGS->port();
00149 }
00150 streamToken = NULL;
00151
00152
00153 RTCPSourceRecord* source = new RTCPSourceRecord(clientAddress, clientRTCPPort);
00154 fClientRTCPSourceRecords->Add((char const*)clientSessionId, source);
00155 }
00156
00157 void PassiveServerMediaSubsession::startStream(unsigned clientSessionId,
00158 void* ,
00159 TaskFunc* rtcpRRHandler,
00160 void* rtcpRRHandlerClientData,
00161 unsigned short& rtpSeqNum,
00162 unsigned& rtpTimestamp,
00163 ServerRequestAlternativeByteHandler* ,
00164 void* ) {
00165 rtpSeqNum = fRTPSink.currentSeqNo();
00166 rtpTimestamp = fRTPSink.presetNextTimestamp();
00167
00168
00169
00170 unsigned streamBitrate = fRTCPInstance == NULL ? 50 : fRTCPInstance->totSessionBW();
00171 unsigned rtpBufSize = streamBitrate * 25 / 2;
00172 if (rtpBufSize < 50 * 1024) rtpBufSize = 50 * 1024;
00173 increaseSendBufferTo(envir(), fRTPSink.groupsockBeingUsed().socketNum(), rtpBufSize);
00174
00175
00176 if (fRTCPInstance != NULL) {
00177 RTCPSourceRecord* source = (RTCPSourceRecord*)(fClientRTCPSourceRecords->Lookup((char const*)clientSessionId));
00178 if (source != NULL) {
00179 fRTCPInstance->setSpecificRRHandler(source->addr, source->port,
00180 rtcpRRHandler, rtcpRRHandlerClientData);
00181 }
00182 }
00183 }
00184
00185 void PassiveServerMediaSubsession::deleteStream(unsigned clientSessionId, void*& ) {
00186
00187 RTCPSourceRecord* source = (RTCPSourceRecord*)(fClientRTCPSourceRecords->Lookup((char const*)clientSessionId));
00188 if (source != NULL) {
00189 if (fRTCPInstance != NULL) {
00190 fRTCPInstance->unsetSpecificRRHandler(source->addr, source->port);
00191 }
00192
00193 fClientRTCPSourceRecords->Remove((char const*)clientSessionId);
00194 delete source;
00195 }
00196 }