00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "DynamicRTSPServer.hh"
00022 #include <liveMedia.hh>
00023 #include <string.h>
00024
00025 DynamicRTSPServer*
00026 DynamicRTSPServer::createNew(UsageEnvironment& env, Port ourPort,
00027 UserAuthenticationDatabase* authDatabase,
00028 unsigned reclamationTestSeconds) {
00029 int ourSocket = setUpOurSocket(env, ourPort);
00030 if (ourSocket == -1) return NULL;
00031
00032 return new DynamicRTSPServer(env, ourSocket, ourPort, authDatabase, reclamationTestSeconds);
00033 }
00034
00035 DynamicRTSPServer::DynamicRTSPServer(UsageEnvironment& env, int ourSocket,
00036 Port ourPort,
00037 UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds)
00038 : RTSPServerSupportingHTTPStreaming(env, ourSocket, ourPort, authDatabase, reclamationTestSeconds) {
00039 }
00040
00041 DynamicRTSPServer::~DynamicRTSPServer() {
00042 }
00043
00044 static ServerMediaSession* createNewSMS(UsageEnvironment& env,
00045 char const* fileName, FILE* fid);
00046
00047 ServerMediaSession*
00048 DynamicRTSPServer::lookupServerMediaSession(char const* streamName) {
00049
00050 FILE* fid = fopen(streamName, "rb");
00051 Boolean fileExists = fid != NULL;
00052
00053
00054 ServerMediaSession* sms = RTSPServer::lookupServerMediaSession(streamName);
00055 Boolean smsExists = sms != NULL;
00056
00057
00058 if (!fileExists) {
00059 if (smsExists) {
00060
00061 removeServerMediaSession(sms);
00062 }
00063 return NULL;
00064 } else {
00065 if (!smsExists) {
00066
00067 sms = createNewSMS(envir(), streamName, fid);
00068 addServerMediaSession(sms);
00069 }
00070 fclose(fid);
00071 return sms;
00072 }
00073 }
00074
00075
00076 static char newMatroskaDemuxWatchVariable;
00077 static MatroskaFileServerDemux* demux;
00078 static void onMatroskaDemuxCreation(MatroskaFileServerDemux* newDemux, void* ) {
00079 demux = newDemux;
00080 newMatroskaDemuxWatchVariable = 1;
00081 }
00082
00083
00084 #define NEW_SMS(description) do {\
00085 char const* descStr = description\
00086 ", streamed by the LIVE555 Media Server";\
00087 sms = ServerMediaSession::createNew(env, fileName, fileName, descStr);\
00088 } while(0)
00089
00090 static ServerMediaSession* createNewSMS(UsageEnvironment& env,
00091 char const* fileName, FILE* ) {
00092
00093 char const* extension = strrchr(fileName, '.');
00094 if (extension == NULL) return NULL;
00095
00096 ServerMediaSession* sms = NULL;
00097 Boolean const reuseSource = False;
00098 if (strcmp(extension, ".aac") == 0) {
00099
00100 NEW_SMS("AAC Audio");
00101 sms->addSubsession(ADTSAudioFileServerMediaSubsession::createNew(env, fileName, reuseSource));
00102 } else if (strcmp(extension, ".amr") == 0) {
00103
00104 NEW_SMS("AMR Audio");
00105 sms->addSubsession(AMRAudioFileServerMediaSubsession::createNew(env, fileName, reuseSource));
00106 } else if (strcmp(extension, ".ac3") == 0) {
00107
00108 NEW_SMS("AC-3 Audio");
00109 sms->addSubsession(AC3AudioFileServerMediaSubsession::createNew(env, fileName, reuseSource));
00110 } else if (strcmp(extension, ".m4e") == 0) {
00111
00112 NEW_SMS("MPEG-4 Video");
00113 sms->addSubsession(MPEG4VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
00114 } else if (strcmp(extension, ".264") == 0) {
00115
00116 NEW_SMS("H.264 Video");
00117 OutPacketBuffer::maxSize = 100000;
00118 sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
00119 } else if (strcmp(extension, ".mp3") == 0) {
00120
00121 NEW_SMS("MPEG-1 or 2 Audio");
00122
00123
00124
00125
00126
00127
00128 Boolean useADUs = False;
00129 Interleaving* interleaving = NULL;
00130 #ifdef STREAM_USING_ADUS
00131 useADUs = True;
00132 #ifdef INTERLEAVE_ADUS
00133 unsigned char interleaveCycle[] = {0,2,1,3};
00134 unsigned const interleaveCycleSize
00135 = (sizeof interleaveCycle)/(sizeof (unsigned char));
00136 interleaving = new Interleaving(interleaveCycleSize, interleaveCycle);
00137 #endif
00138 #endif
00139 sms->addSubsession(MP3AudioFileServerMediaSubsession::createNew(env, fileName, reuseSource, useADUs, interleaving));
00140 } else if (strcmp(extension, ".mpg") == 0) {
00141
00142 NEW_SMS("MPEG-1 or 2 Program Stream");
00143 MPEG1or2FileServerDemux* demux
00144 = MPEG1or2FileServerDemux::createNew(env, fileName, reuseSource);
00145 sms->addSubsession(demux->newVideoServerMediaSubsession());
00146 sms->addSubsession(demux->newAudioServerMediaSubsession());
00147 } else if (strcmp(extension, ".ts") == 0) {
00148
00149
00150 unsigned indexFileNameLen = strlen(fileName) + 2;
00151 char* indexFileName = new char[indexFileNameLen];
00152 sprintf(indexFileName, "%sx", fileName);
00153 NEW_SMS("MPEG Transport Stream");
00154 sms->addSubsession(MPEG2TransportFileServerMediaSubsession::createNew(env, fileName, indexFileName, reuseSource));
00155 delete[] indexFileName;
00156 } else if (strcmp(extension, ".wav") == 0) {
00157
00158 NEW_SMS("WAV Audio Stream");
00159
00160
00161 Boolean convertToULaw = False;
00162 sms->addSubsession(WAVAudioFileServerMediaSubsession::createNew(env, fileName, reuseSource, convertToULaw));
00163 } else if (strcmp(extension, ".dv") == 0) {
00164
00165
00166 OutPacketBuffer::maxSize = 300000;
00167
00168 NEW_SMS("DV Video");
00169 sms->addSubsession(DVVideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
00170 } else if (strcmp(extension, ".mkv") == 0 || strcmp(extension, ".webm") == 0) {
00171
00172 NEW_SMS("Matroska video+audio+(optional)subtitles");
00173
00174
00175 newMatroskaDemuxWatchVariable = 0;
00176 MatroskaFileServerDemux::createNew(env, fileName, onMatroskaDemuxCreation, NULL);
00177 env.taskScheduler().doEventLoop(&newMatroskaDemuxWatchVariable);
00178
00179 ServerMediaSubsession* smss;
00180 while ((smss = demux->newServerMediaSubsession()) != NULL) {
00181 sms->addSubsession(smss);
00182 }
00183 }
00184
00185 return sms;
00186 }