00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "liveMedia.hh"
00023 #include "Locale.hh"
00024 #ifdef SUPPORT_REAL_RTSP
00025 #include "../RealRTSP/include/RealRTSP.hh"
00026 #endif
00027 #include "GroupsockHelper.hh"
00028 #include <ctype.h>
00029
00031
00032 MediaSession* MediaSession::createNew(UsageEnvironment& env,
00033 char const* sdpDescription) {
00034 MediaSession* newSession = new MediaSession(env);
00035 if (newSession != NULL) {
00036 if (!newSession->initializeWithSDP(sdpDescription)) {
00037 delete newSession;
00038 return NULL;
00039 }
00040 }
00041
00042 return newSession;
00043 }
00044
00045 Boolean MediaSession::lookupByName(UsageEnvironment& env,
00046 char const* instanceName,
00047 MediaSession*& resultSession) {
00048 resultSession = NULL;
00049
00050 Medium* medium;
00051 if (!Medium::lookupByName(env, instanceName, medium)) return False;
00052
00053 if (!medium->isMediaSession()) {
00054 env.setResultMsg(instanceName, " is not a 'MediaSession' object");
00055 return False;
00056 }
00057
00058 resultSession = (MediaSession*)medium;
00059 return True;
00060 }
00061
00062 MediaSession::MediaSession(UsageEnvironment& env)
00063 : Medium(env),
00064 fSubsessionsHead(NULL), fSubsessionsTail(NULL),
00065 fConnectionEndpointName(NULL), fMaxPlayStartTime(0.0f), fMaxPlayEndTime(0.0f),
00066 fScale(1.0f), fMediaSessionType(NULL), fSessionName(NULL), fSessionDescription(NULL),
00067 fControlPath(NULL) {
00068 #ifdef SUPPORT_REAL_RTSP
00069 RealInitSDPAttributes(this);
00070 #endif
00071 fSourceFilterAddr.s_addr = 0;
00072
00073
00074 const unsigned maxCNAMElen = 100;
00075 char CNAME[maxCNAMElen+1];
00076 #ifndef CRIS
00077 gethostname((char*)CNAME, maxCNAMElen);
00078 #else
00079
00080 sprintf(CNAME, "unknown host %d", (unsigned)(our_random()*0x7FFFFFFF));
00081 #endif
00082 CNAME[maxCNAMElen] = '\0';
00083 fCNAME = strDup(CNAME);
00084 }
00085
00086 MediaSession::~MediaSession() {
00087 delete fSubsessionsHead;
00088 delete[] fCNAME;
00089 delete[] fConnectionEndpointName;
00090 delete[] fMediaSessionType;
00091 delete[] fSessionName;
00092 delete[] fSessionDescription;
00093 delete[] fControlPath;
00094 #ifdef SUPPORT_REAL_RTSP
00095 RealReclaimSDPAttributes(this);
00096 #endif
00097 }
00098
00099 Boolean MediaSession::isMediaSession() const {
00100 return True;
00101 }
00102
00103 Boolean MediaSession::initializeWithSDP(char const* sdpDescription) {
00104 if (sdpDescription == NULL) return False;
00105
00106
00107 char const* sdpLine = sdpDescription;
00108 char const* nextSDPLine;
00109 while (1) {
00110 if (!parseSDPLine(sdpLine, nextSDPLine)) return False;
00111
00112
00113
00114 if (sdpLine[0] == 'm') break;
00115 sdpLine = nextSDPLine;
00116 if (sdpLine == NULL) break;
00117
00118
00119 if (parseSDPLine_s(sdpLine)) continue;
00120 if (parseSDPLine_i(sdpLine)) continue;
00121 if (parseSDPLine_c(sdpLine)) continue;
00122 if (parseSDPAttribute_control(sdpLine)) continue;
00123 if (parseSDPAttribute_range(sdpLine)) continue;
00124 if (parseSDPAttribute_type(sdpLine)) continue;
00125 if (parseSDPAttribute_source_filter(sdpLine)) continue;
00126 #ifdef SUPPORT_REAL_RTSP
00127 if (RealParseSDPAttributes(this, sdpLine)) continue;
00128 #endif
00129 }
00130
00131 while (sdpLine != NULL) {
00132
00133 MediaSubsession* subsession = new MediaSubsession(*this);
00134 if (subsession == NULL) {
00135 envir().setResultMsg("Unable to create new MediaSubsession");
00136 return False;
00137 }
00138
00139
00140
00141
00142 char* mediumName = strDupSize(sdpLine);
00143 char* protocolName = NULL;
00144 unsigned payloadFormat;
00145 if ((sscanf(sdpLine, "m=%s %hu RTP/AVP %u",
00146 mediumName, &subsession->fClientPortNum, &payloadFormat) == 3 ||
00147 sscanf(sdpLine, "m=%s %hu/%*u RTP/AVP %u",
00148 mediumName, &subsession->fClientPortNum, &payloadFormat) == 3)
00149 && payloadFormat <= 127) {
00150 protocolName = "RTP";
00151 } else if ((sscanf(sdpLine, "m=%s %hu UDP %u",
00152 mediumName, &subsession->fClientPortNum, &payloadFormat) == 3 ||
00153 sscanf(sdpLine, "m=%s %hu udp %u",
00154 mediumName, &subsession->fClientPortNum, &payloadFormat) == 3 ||
00155 sscanf(sdpLine, "m=%s %hu RAW/RAW/UDP %u",
00156 mediumName, &subsession->fClientPortNum, &payloadFormat) == 3)
00157 && payloadFormat <= 127) {
00158
00159 protocolName = "UDP";
00160 } else {
00161
00162 char* sdpLineStr;
00163 if (nextSDPLine == NULL) {
00164 sdpLineStr = (char*)sdpLine;
00165 } else {
00166 sdpLineStr = strDup(sdpLine);
00167 sdpLineStr[nextSDPLine-sdpLine] = '\0';
00168 }
00169 envir() << "Bad SDP \"m=\" line: " << sdpLineStr << "\n";
00170 if (sdpLineStr != (char*)sdpLine) delete[] sdpLineStr;
00171
00172 delete[] mediumName;
00173 delete subsession;
00174
00175
00176 while (1) {
00177 sdpLine = nextSDPLine;
00178 if (sdpLine == NULL) break;
00179 if (!parseSDPLine(sdpLine, nextSDPLine)) return False;
00180
00181 if (sdpLine[0] == 'm') break;
00182 }
00183 continue;
00184 }
00185
00186
00187 if (fSubsessionsTail == NULL) {
00188 fSubsessionsHead = fSubsessionsTail = subsession;
00189 } else {
00190 fSubsessionsTail->setNext(subsession);
00191 fSubsessionsTail = subsession;
00192 }
00193
00194 subsession->serverPortNum = subsession->fClientPortNum;
00195
00196 char const* mStart = sdpLine;
00197 subsession->fSavedSDPLines = strDup(mStart);
00198
00199 subsession->fMediumName = strDup(mediumName);
00200 delete[] mediumName;
00201 subsession->fProtocolName = strDup(protocolName);
00202 subsession->fRTPPayloadFormat = payloadFormat;
00203
00204
00205 while (1) {
00206 sdpLine = nextSDPLine;
00207 if (sdpLine == NULL) break;
00208 if (!parseSDPLine(sdpLine, nextSDPLine)) return False;
00209
00210 if (sdpLine[0] == 'm') break;
00211
00212
00213 if (subsession->parseSDPLine_c(sdpLine)) continue;
00214 if (subsession->parseSDPAttribute_rtpmap(sdpLine)) continue;
00215 if (subsession->parseSDPAttribute_control(sdpLine)) continue;
00216 if (subsession->parseSDPAttribute_range(sdpLine)) continue;
00217 if (subsession->parseSDPAttribute_fmtp(sdpLine)) continue;
00218 if (subsession->parseSDPAttribute_source_filter(sdpLine)) continue;
00219 if (subsession->parseSDPAttribute_x_dimensions(sdpLine)) continue;
00220 if (subsession->parseSDPAttribute_framerate(sdpLine)) continue;
00221 #ifdef SUPPORT_REAL_RTSP
00222 if (RealParseSDPAttributes(subsession, sdpLine)) continue;
00223 #endif
00224
00225
00226 }
00227 if (sdpLine != NULL) subsession->fSavedSDPLines[sdpLine-mStart] = '\0';
00228
00229
00230
00231 if (subsession->fCodecName == NULL) {
00232 subsession->fCodecName
00233 = lookupPayloadFormat(subsession->fRTPPayloadFormat,
00234 subsession->fRTPTimestampFrequency,
00235 subsession->fNumChannels);
00236 if (subsession->fCodecName == NULL) {
00237 char typeStr[20];
00238 sprintf(typeStr, "%d", subsession->fRTPPayloadFormat);
00239 envir().setResultMsg("Unknown codec name for RTP payload type ",
00240 typeStr);
00241 return False;
00242 }
00243 }
00244
00245
00246
00247
00248
00249 if (subsession->fRTPTimestampFrequency == 0) {
00250 subsession->fRTPTimestampFrequency
00251 = guessRTPTimestampFrequency(subsession->fMediumName,
00252 subsession->fCodecName);
00253 }
00254 }
00255
00256 return True;
00257 }
00258
00259 Boolean MediaSession::parseSDPLine(char const* inputLine,
00260 char const*& nextLine){
00261
00262 nextLine = NULL;
00263 for (char const* ptr = inputLine; *ptr != '\0'; ++ptr) {
00264 if (*ptr == '\r' || *ptr == '\n') {
00265
00266 ++ptr;
00267 while (*ptr == '\r' || *ptr == '\n') ++ptr;
00268 nextLine = ptr;
00269 if (nextLine[0] == '\0') nextLine = NULL;
00270 break;
00271 }
00272 }
00273
00274
00275
00276 if (inputLine[0] == '\r' || inputLine[0] == '\n') return True;
00277 if (strlen(inputLine) < 2 || inputLine[1] != '='
00278 || inputLine[0] < 'a' || inputLine[0] > 'z') {
00279 envir().setResultMsg("Invalid SDP line: ", inputLine);
00280 return False;
00281 }
00282
00283 return True;
00284 }
00285
00286 static char* parseCLine(char const* sdpLine) {
00287 char* resultStr = NULL;
00288 char* buffer = strDupSize(sdpLine);
00289 if (sscanf(sdpLine, "c=IN IP4 %[^/ ]", buffer) == 1) {
00290
00291 resultStr = strDup(buffer);
00292 }
00293 delete[] buffer;
00294
00295 return resultStr;
00296 }
00297
00298 Boolean MediaSession::parseSDPLine_s(char const* sdpLine) {
00299
00300 char* buffer = strDupSize(sdpLine);
00301 Boolean parseSuccess = False;
00302
00303 if (sscanf(sdpLine, "s=%[^\r\n]", buffer) == 1) {
00304 delete[] fSessionName; fSessionName = strDup(buffer);
00305 parseSuccess = True;
00306 }
00307 delete[] buffer;
00308
00309 return parseSuccess;
00310 }
00311
00312 Boolean MediaSession::parseSDPLine_i(char const* sdpLine) {
00313
00314 char* buffer = strDupSize(sdpLine);
00315 Boolean parseSuccess = False;
00316
00317 if (sscanf(sdpLine, "i=%[^\r\n]", buffer) == 1) {
00318 delete[] fSessionDescription; fSessionDescription = strDup(buffer);
00319 parseSuccess = True;
00320 }
00321 delete[] buffer;
00322
00323 return parseSuccess;
00324 }
00325
00326 Boolean MediaSession::parseSDPLine_c(char const* sdpLine) {
00327
00328
00329
00330 char* connectionEndpointName = parseCLine(sdpLine);
00331 if (connectionEndpointName != NULL) {
00332 delete[] fConnectionEndpointName;
00333 fConnectionEndpointName = connectionEndpointName;
00334 return True;
00335 }
00336
00337 return False;
00338 }
00339
00340 Boolean MediaSession::parseSDPAttribute_type(char const* sdpLine) {
00341
00342 Boolean parseSuccess = False;
00343
00344 char* buffer = strDupSize(sdpLine);
00345 if (sscanf(sdpLine, "a=type: %[^ ]", buffer) == 1) {
00346 delete[] fMediaSessionType;
00347 fMediaSessionType = strDup(buffer);
00348 parseSuccess = True;
00349 }
00350 delete[] buffer;
00351
00352 return parseSuccess;
00353 }
00354
00355 static Boolean parseRangeAttribute(char const* sdpLine, float& startTime, float& endTime) {
00356 return sscanf(sdpLine, "a=range: npt = %g - %g", &startTime, &endTime) == 2;
00357 }
00358
00359 Boolean MediaSession::parseSDPAttribute_control(char const* sdpLine) {
00360
00361 Boolean parseSuccess = False;
00362
00363 char* controlPath = strDupSize(sdpLine);
00364 if (sscanf(sdpLine, "a=control: %s", controlPath) == 1) {
00365 parseSuccess = True;
00366 delete[] fControlPath; fControlPath = strDup(controlPath);
00367 }
00368 delete[] controlPath;
00369
00370 return parseSuccess;
00371 }
00372
00373 Boolean MediaSession::parseSDPAttribute_range(char const* sdpLine) {
00374
00375
00376 Boolean parseSuccess = False;
00377
00378 float playStartTime;
00379 float playEndTime;
00380 if (parseRangeAttribute(sdpLine, playStartTime, playEndTime)) {
00381 parseSuccess = True;
00382 if (playStartTime > fMaxPlayStartTime) {
00383 fMaxPlayStartTime = playStartTime;
00384 }
00385 if (playEndTime > fMaxPlayEndTime) {
00386 fMaxPlayEndTime = playEndTime;
00387 }
00388 }
00389
00390 return parseSuccess;
00391 }
00392
00393 static Boolean parseSourceFilterAttribute(char const* sdpLine,
00394 struct in_addr& sourceAddr) {
00395
00396
00397
00398
00399 Boolean result = False;
00400 char* sourceName = strDupSize(sdpLine);
00401 do {
00402 if (sscanf(sdpLine, "a=source-filter: incl IN IP4 %*s %s",
00403 sourceName) != 1) break;
00404
00405
00406 NetAddressList addresses(sourceName);
00407 if (addresses.numAddresses() == 0) break;
00408
00409 netAddressBits sourceAddrBits
00410 = *(netAddressBits*)(addresses.firstAddress()->data());
00411 if (sourceAddrBits == 0) break;
00412
00413 sourceAddr.s_addr = sourceAddrBits;
00414 result = True;
00415 } while (0);
00416
00417 delete[] sourceName;
00418 return result;
00419 }
00420
00421 Boolean MediaSession
00422 ::parseSDPAttribute_source_filter(char const* sdpLine) {
00423 return parseSourceFilterAttribute(sdpLine, fSourceFilterAddr);
00424 }
00425
00426 char* MediaSession::lookupPayloadFormat(unsigned char rtpPayloadType,
00427 unsigned& freq, unsigned& nCh) {
00428
00429
00430 char* temp = NULL;
00431 switch (rtpPayloadType) {
00432 case 0: {temp = "PCMU"; freq = 8000; nCh = 1; break;}
00433 case 2: {temp = "G726-32"; freq = 8000; nCh = 1; break;}
00434 case 3: {temp = "GSM"; freq = 8000; nCh = 1; break;}
00435 case 4: {temp = "G723"; freq = 8000; nCh = 1; break;}
00436 case 5: {temp = "DVI4"; freq = 8000; nCh = 1; break;}
00437 case 6: {temp = "DVI4"; freq = 16000; nCh = 1; break;}
00438 case 7: {temp = "LPC"; freq = 8000; nCh = 1; break;}
00439 case 8: {temp = "PCMA"; freq = 8000; nCh = 1; break;}
00440 case 9: {temp = "G722"; freq = 8000; nCh = 1; break;}
00441 case 10: {temp = "L16"; freq = 44100; nCh = 2; break;}
00442 case 11: {temp = "L16"; freq = 44100; nCh = 1; break;}
00443 case 12: {temp = "QCELP"; freq = 8000; nCh = 1; break;}
00444 case 14: {temp = "MPA"; freq = 90000; nCh = 1; break;}
00445
00446 case 15: {temp = "G728"; freq = 8000; nCh = 1; break;}
00447 case 16: {temp = "DVI4"; freq = 11025; nCh = 1; break;}
00448 case 17: {temp = "DVI4"; freq = 22050; nCh = 1; break;}
00449 case 18: {temp = "G729"; freq = 8000; nCh = 1; break;}
00450 case 25: {temp = "CELB"; freq = 90000; nCh = 1; break;}
00451 case 26: {temp = "JPEG"; freq = 90000; nCh = 1; break;}
00452 case 28: {temp = "NV"; freq = 90000; nCh = 1; break;}
00453 case 31: {temp = "H261"; freq = 90000; nCh = 1; break;}
00454 case 32: {temp = "MPV"; freq = 90000; nCh = 1; break;}
00455 case 33: {temp = "MP2T"; freq = 90000; nCh = 1; break;}
00456 case 34: {temp = "H263"; freq = 90000; nCh = 1; break;}
00457 };
00458
00459 return strDup(temp);
00460 }
00461
00462 unsigned MediaSession::guessRTPTimestampFrequency(char const* mediumName,
00463 char const* codecName) {
00464
00465
00466
00467
00468 if (strcmp(codecName, "L16") == 0) return 44100;
00469 if (strcmp(codecName, "MPA") == 0
00470 || strcmp(codecName, "MPA-ROBUST") == 0
00471 || strcmp(codecName, "X-MP3-DRAFT-00")) return 90000;
00472
00473
00474 if (strcmp(mediumName, "video") == 0) return 90000;
00475 return 8000;
00476 }
00477
00478 Boolean MediaSession
00479 ::initiateByMediaType(char const* mimeType,
00480 MediaSubsession*& resultSubsession,
00481 int useSpecialRTPoffset) {
00482
00483 resultSubsession = NULL;
00484 MediaSubsessionIterator iter(*this);
00485 MediaSubsession* subsession;
00486 while ((subsession = iter.next()) != NULL) {
00487 Boolean wasAlreadyInitiated = subsession->readSource() != NULL;
00488 if (!wasAlreadyInitiated) {
00489
00490 if (!subsession->initiate(useSpecialRTPoffset)) return False;
00491 }
00492
00493
00494 if (strcmp(subsession->readSource()->MIMEtype(), mimeType) != 0) {
00495 if (!wasAlreadyInitiated) subsession->deInitiate();
00496 continue;
00497 }
00498
00499 resultSubsession = subsession;
00500 break;
00501 }
00502
00503 if (resultSubsession == NULL) {
00504 envir().setResultMsg("Session has no usable media subsession");
00505 return False;
00506 }
00507
00508 return True;
00509 }
00510
00511
00513
00514 MediaSubsessionIterator::MediaSubsessionIterator(MediaSession& session)
00515 : fOurSession(session) {
00516 reset();
00517 }
00518
00519 MediaSubsessionIterator::~MediaSubsessionIterator() {
00520 }
00521
00522 MediaSubsession* MediaSubsessionIterator::next() {
00523 MediaSubsession* result = fNextPtr;
00524
00525 if (fNextPtr != NULL) fNextPtr = fNextPtr->fNext;
00526
00527 return result;
00528 }
00529
00530 void MediaSubsessionIterator::reset() {
00531 fNextPtr = fOurSession.fSubsessionsHead;
00532 }
00533
00535
00536 MediaSubsession::MediaSubsession(MediaSession& parent)
00537 : sessionId(NULL), serverPortNum(0), sink(NULL), miscPtr(NULL),
00538 fParent(parent), fNext(NULL),
00539 fConnectionEndpointName(NULL),
00540 fClientPortNum(0), fRTPPayloadFormat(0xFF),
00541 fSavedSDPLines(NULL), fMediumName(NULL), fCodecName(NULL), fProtocolName(NULL),
00542 fRTPTimestampFrequency(0), fControlPath(NULL),
00543 fSourceFilterAddr(parent.sourceFilterAddr()),
00544 fAuxiliarydatasizelength(0), fConstantduration(0), fConstantsize(0),
00545 fCRC(0), fCtsdeltalength(0), fDe_interleavebuffersize(0), fDtsdeltalength(0),
00546 fIndexdeltalength(0), fIndexlength(0), fInterleaving(0), fMaxdisplacement(0),
00547 fObjecttype(0), fOctetalign(0), fProfile_level_id(0), fRobustsorting(0),
00548 fSizelength(0), fStreamstateindication(0), fStreamtype(0),
00549 fCpresent(False), fRandomaccessindication(False),
00550 fConfig(NULL), fMode(NULL), fSpropParameterSets(NULL),
00551 fPlayStartTime(0.0), fPlayEndTime(0.0),
00552 fVideoWidth(0), fVideoHeight(0), fVideoFPS(0), fNumChannels(1), fScale(1.0f), fNPT_PTS_Offset(0.0f),
00553 fRTPSocket(NULL), fRTCPSocket(NULL),
00554 fRTPSource(NULL), fRTCPInstance(NULL), fReadSource(NULL) {
00555 rtpInfo.seqNum = 0; rtpInfo.timestamp = 0; rtpInfo.infoIsNew = False;
00556 #ifdef SUPPORT_REAL_RTSP
00557 RealInitSDPAttributes(this);
00558 #endif
00559 }
00560
00561 MediaSubsession::~MediaSubsession() {
00562 deInitiate();
00563
00564 delete[] fConnectionEndpointName; delete[] fSavedSDPLines;
00565 delete[] fMediumName; delete[] fCodecName; delete[] fProtocolName;
00566 delete[] fControlPath; delete[] fConfig; delete[] fMode; delete[] fSpropParameterSets;
00567
00568 delete fNext;
00569 #ifdef SUPPORT_REAL_RTSP
00570 RealReclaimSDPAttributes(this);
00571 #endif
00572 }
00573
00574 float MediaSubsession::playStartTime() const {
00575 if (fPlayStartTime > 0) return fPlayStartTime;
00576
00577 return fParent.playStartTime();
00578 }
00579
00580 float MediaSubsession::playEndTime() const {
00581 if (fPlayEndTime > 0) return fPlayEndTime;
00582
00583 return fParent.playEndTime();
00584 }
00585
00586 Boolean MediaSubsession::initiate(int useSpecialRTPoffset) {
00587 if (fReadSource != NULL) return True;
00588
00589 do {
00590 if (fCodecName == NULL) {
00591 env().setResultMsg("Codec is unspecified");
00592 break;
00593 }
00594
00595
00596
00597 Groupsock* oldGroupsock = NULL;
00598 Boolean success = False;
00599 struct in_addr tempAddr;
00600 tempAddr.s_addr = connectionEndpointAddress();
00601
00602 while (1) {
00603 unsigned short rtpPortNum = fClientPortNum&~1;
00604 if (isSSM()) {
00605 fRTPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr,
00606 rtpPortNum);
00607 } else {
00608 fRTPSocket = new Groupsock(env(), tempAddr, rtpPortNum, 255);
00609 }
00610 if (fRTPSocket == NULL) {
00611 env().setResultMsg("Failed to create RTP socket");
00612 break;
00613 }
00614
00615
00616 Port clientPort(0);
00617 if (!getSourcePort(env(), fRTPSocket->socketNum(), clientPort)) {
00618 break;
00619 }
00620 fClientPortNum = ntohs(clientPort.num());
00621
00622
00623 if ((fClientPortNum&1) == 0) {
00624 success = True;
00625 break;
00626 }
00627
00628 delete oldGroupsock;
00629 oldGroupsock = fRTPSocket;
00630 fClientPortNum = 0;
00631 }
00632 delete oldGroupsock;
00633 if (!success) break;
00634
00635
00636 unsigned short const rtcpPortNum = fClientPortNum|1;
00637 if (isSSM()) {
00638 fRTCPSocket = new Groupsock(env(), tempAddr, fSourceFilterAddr,
00639 rtcpPortNum);
00640
00641 if (fRTCPSocket != NULL) {
00642 fRTCPSocket->changeDestinationParameters(fSourceFilterAddr,0,~0);
00643 }
00644 } else {
00645 fRTCPSocket = new Groupsock(env(), tempAddr, rtcpPortNum, 255);
00646 }
00647 if (fRTCPSocket == NULL) {
00648 char tmpBuf[100];
00649 sprintf(tmpBuf, "Failed to create RTCP socket (port %d)",
00650 rtcpPortNum);
00651 env().setResultMsg(tmpBuf);
00652 break;
00653 }
00654
00655
00656 if (strcmp(fProtocolName, "UDP") == 0) {
00657
00658 fReadSource = BasicUDPSource::createNew(env(), fRTPSocket);
00659 fRTPSource = NULL;
00660
00661 if (strcmp(fCodecName, "MP2T") == 0) {
00662 fReadSource = MPEG2TransportStreamFramer::createNew(env(), fReadSource);
00663
00664 }
00665 } else {
00666
00667
00668
00669
00670 Boolean createSimpleRTPSource = False;
00671 Boolean doNormalMBitRule = False;
00672 if (strcmp(fCodecName, "QCELP") == 0) {
00673 fReadSource =
00674 QCELPAudioRTPSource::createNew(env(), fRTPSocket, fRTPSource,
00675 fRTPPayloadFormat,
00676 fRTPTimestampFrequency);
00677
00678 } else if (strcmp(fCodecName, "AMR") == 0) {
00679 fReadSource =
00680 AMRAudioRTPSource::createNew(env(), fRTPSocket, fRTPSource,
00681 fRTPPayloadFormat, 0 ,
00682 fNumChannels, fOctetalign, fInterleaving,
00683 fRobustsorting, fCRC);
00684
00685 } else if (strcmp(fCodecName, "AMR-WB") == 0) {
00686 fReadSource =
00687 AMRAudioRTPSource::createNew(env(), fRTPSocket, fRTPSource,
00688 fRTPPayloadFormat, 1 ,
00689 fNumChannels, fOctetalign, fInterleaving,
00690 fRobustsorting, fCRC);
00691
00692 } else if (strcmp(fCodecName, "MPA") == 0) {
00693 fReadSource = fRTPSource
00694 = MPEG1or2AudioRTPSource::createNew(env(), fRTPSocket,
00695 fRTPPayloadFormat,
00696 fRTPTimestampFrequency);
00697 } else if (strcmp(fCodecName, "MPA-ROBUST") == 0) {
00698 fRTPSource
00699 = MP3ADURTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
00700 fRTPTimestampFrequency);
00701 if (fRTPSource == NULL) break;
00702
00703
00704 MP3ADUdeinterleaver* deinterleaver
00705 = MP3ADUdeinterleaver::createNew(env(), fRTPSource);
00706 if (deinterleaver == NULL) break;
00707
00708
00709 fReadSource = MP3FromADUSource::createNew(env(), deinterleaver);
00710 } else if (strcmp(fCodecName, "X-MP3-DRAFT-00") == 0) {
00711
00712
00713 fRTPSource
00714 = SimpleRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
00715 fRTPTimestampFrequency,
00716 "audio/MPA-ROBUST" );
00717 if (fRTPSource == NULL) break;
00718
00719
00720 fReadSource = MP3FromADUSource::createNew(env(), fRTPSource,
00721 False );
00722 } else if (strcmp(fCodecName, "MP4A-LATM") == 0) {
00723 fReadSource = fRTPSource
00724 = MPEG4LATMAudioRTPSource::createNew(env(), fRTPSocket,
00725 fRTPPayloadFormat,
00726 fRTPTimestampFrequency);
00727 } else if (strcmp(fCodecName, "AC3") == 0) {
00728 fReadSource = fRTPSource
00729 = AC3AudioRTPSource::createNew(env(), fRTPSocket,
00730 fRTPPayloadFormat,
00731 fRTPTimestampFrequency);
00732 } else if (strcmp(fCodecName, "MP4V-ES") == 0) {
00733 fReadSource = fRTPSource
00734 = MPEG4ESVideoRTPSource::createNew(env(), fRTPSocket,
00735 fRTPPayloadFormat,
00736 fRTPTimestampFrequency);
00737 } else if (strcmp(fCodecName, "MPEG4-GENERIC") == 0) {
00738 fReadSource = fRTPSource
00739 = MPEG4GenericRTPSource::createNew(env(), fRTPSocket,
00740 fRTPPayloadFormat,
00741 fRTPTimestampFrequency,
00742 fMediumName, fMode,
00743 fSizelength, fIndexlength,
00744 fIndexdeltalength);
00745 } else if (strcmp(fCodecName, "MPV") == 0) {
00746 fReadSource = fRTPSource
00747 = MPEG1or2VideoRTPSource::createNew(env(), fRTPSocket,
00748 fRTPPayloadFormat,
00749 fRTPTimestampFrequency);
00750 } else if (strcmp(fCodecName, "MP2T") == 0) {
00751 fRTPSource = SimpleRTPSource::createNew(env(), fRTPSocket, fRTPPayloadFormat,
00752 fRTPTimestampFrequency, "video/MP2T",
00753 0, False);
00754 fReadSource = MPEG2TransportStreamFramer::createNew(env(), fRTPSource);
00755
00756 } else if (strcmp(fCodecName, "H261") == 0) {
00757 fReadSource = fRTPSource
00758 = H261VideoRTPSource::createNew(env(), fRTPSocket,
00759 fRTPPayloadFormat,
00760 fRTPTimestampFrequency);
00761 } else if (strcmp(fCodecName, "H263-1998") == 0 ||
00762 strcmp(fCodecName, "H263-2000") == 0) {
00763 fReadSource = fRTPSource
00764 = H263plusVideoRTPSource::createNew(env(), fRTPSocket,
00765 fRTPPayloadFormat,
00766 fRTPTimestampFrequency);
00767 } else if (strcmp(fCodecName, "H264") == 0) {
00768 fReadSource = fRTPSource
00769 = H264VideoRTPSource::createNew(env(), fRTPSocket,
00770 fRTPPayloadFormat,
00771 fRTPTimestampFrequency);
00772 } else if (strcmp(fCodecName, "JPEG") == 0) {
00773 fReadSource = fRTPSource
00774 = JPEGVideoRTPSource::createNew(env(), fRTPSocket,
00775 fRTPPayloadFormat,
00776 fRTPTimestampFrequency,
00777 videoWidth(),
00778 videoHeight());
00779 } else if (strcmp(fCodecName, "X-QT") == 0
00780 || strcmp(fCodecName, "X-QUICKTIME") == 0) {
00781
00782
00783 char* mimeType
00784 = new char[strlen(mediumName()) + strlen(codecName()) + 2] ;
00785 sprintf(mimeType, "%s/%s", mediumName(), codecName());
00786 fReadSource = fRTPSource
00787 = QuickTimeGenericRTPSource::createNew(env(), fRTPSocket,
00788 fRTPPayloadFormat,
00789 fRTPTimestampFrequency,
00790 mimeType);
00791 delete[] mimeType;
00792 #ifdef SUPPORT_REAL_RTSP
00793 } else if (strcmp(fCodecName, "X-PN-REALAUDIO") == 0 ||
00794 strcmp(fCodecName, "X-PN-MULTIRATE-REALAUDIO-LIVE") == 0 ||
00795 strcmp(fCodecName, "X-PN-REALVIDEO") == 0 ||
00796 strcmp(fCodecName, "X-PN-MULTIRATE-REALVIDEO-LIVE") == 0) {
00797
00798 fReadSource = RealRDTSource::createNew(