00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "MatroskaFileServerDemux.hh"
00022 #include "MP3AudioMatroskaFileServerMediaSubsession.hh"
00023 #include "AACAudioMatroskaFileServerMediaSubsession.hh"
00024 #include "AC3AudioMatroskaFileServerMediaSubsession.hh"
00025 #include "VorbisAudioMatroskaFileServerMediaSubsession.hh"
00026 #include "H264VideoMatroskaFileServerMediaSubsession.hh"
00027 #include "VP8VideoMatroskaFileServerMediaSubsession.hh"
00028 #include "T140TextMatroskaFileServerMediaSubsession.hh"
00029
00030 void MatroskaFileServerDemux
00031 ::createNew(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData) {
00032 (void)new MatroskaFileServerDemux(env, fileName, onCreation, onCreationClientData);
00033 }
00034
00035 ServerMediaSubsession* MatroskaFileServerDemux::newServerMediaSubsession() {
00036 ServerMediaSubsession* result;
00037
00038 for (result = NULL; result == NULL && fNextTrackTypeToCheck != MATROSKA_TRACK_TYPE_OTHER; fNextTrackTypeToCheck <<= 1) {
00039 unsigned trackNumber = 0;
00040 if (fNextTrackTypeToCheck == MATROSKA_TRACK_TYPE_VIDEO) trackNumber = fOurMatroskaFile->chosenVideoTrackNumber();
00041 else if (fNextTrackTypeToCheck == MATROSKA_TRACK_TYPE_AUDIO) trackNumber = fOurMatroskaFile->chosenAudioTrackNumber();
00042 else if (fNextTrackTypeToCheck == MATROSKA_TRACK_TYPE_SUBTITLE) trackNumber = fOurMatroskaFile->chosenSubtitleTrackNumber();
00043
00044 result = newServerMediaSubsession(trackNumber);
00045 }
00046
00047 return result;
00048 }
00049
00050 ServerMediaSubsession* MatroskaFileServerDemux::newServerMediaSubsession(unsigned trackNumber) {
00051 MatroskaTrack* track = fOurMatroskaFile->lookup(trackNumber);
00052 if (track == NULL) return NULL;
00053
00054
00055 ServerMediaSubsession* result = NULL;
00056 if (strncmp(track->codecID, "A_MPEG", 6) == 0) {
00057 track->mimeType = "audio/MPEG";
00058 result = MP3AudioMatroskaFileServerMediaSubsession::createNew(*this, track->trackNumber, False, NULL);
00059 } else if (strncmp(track->codecID, "A_AAC", 5) == 0) {
00060 track->mimeType = "audio/AAC";
00061 result = AACAudioMatroskaFileServerMediaSubsession::createNew(*this, track->trackNumber);
00062 } else if (strncmp(track->codecID, "A_AC3", 5) == 0) {
00063 track->mimeType = "audio/AC3";
00064 result = AC3AudioMatroskaFileServerMediaSubsession::createNew(*this, track->trackNumber);
00065 } else if (strncmp(track->codecID, "A_VORBIS", 8) == 0) {
00066 track->mimeType = "audio/VORBIS";
00067 result = VorbisAudioMatroskaFileServerMediaSubsession::createNew(*this, track->trackNumber);
00068 } else if (strcmp(track->codecID, "V_MPEG4/ISO/AVC") == 0) {
00069 track->mimeType = "video/H264";
00070 result = H264VideoMatroskaFileServerMediaSubsession::createNew(*this, track->trackNumber);
00071 } else if (strncmp(track->codecID, "V_VP8", 5) == 0) {
00072 track->mimeType = "video/VP8";
00073 result = VP8VideoMatroskaFileServerMediaSubsession::createNew(*this, track->trackNumber);
00074 } else if (strncmp(track->codecID, "S_TEXT", 6) == 0) {
00075 track->mimeType = "text/T140";
00076 result = T140TextMatroskaFileServerMediaSubsession::createNew(*this, track->trackNumber);
00077 }
00078
00079 if (result != NULL) {
00080 #ifdef DEBUG
00081 fprintf(stderr, "Created 'ServerMediaSubsession' object for track #%d: %s (%s)\n", track->trackNumber, track->codecID, track->mimeType);
00082 #endif
00083 }
00084
00085 return result;
00086 }
00087
00088 FramedSource* MatroskaFileServerDemux::newDemuxedTrack(unsigned clientSessionId, unsigned trackNumber) {
00089 MatroskaDemux* demuxToUse = NULL;
00090
00091 if (clientSessionId != 0 && clientSessionId == fLastClientSessionId) {
00092 demuxToUse = fLastCreatedDemux;
00093
00094
00095
00096
00097
00098
00099 }
00100
00101 if (demuxToUse == NULL) demuxToUse = fOurMatroskaFile->newDemux();
00102
00103 fLastClientSessionId = clientSessionId;
00104 fLastCreatedDemux = demuxToUse;
00105
00106 return demuxToUse->newDemuxedTrack(trackNumber);
00107 }
00108
00109 MatroskaFileServerDemux
00110 ::MatroskaFileServerDemux(UsageEnvironment& env, char const* fileName, onCreationFunc* onCreation, void* onCreationClientData)
00111 : Medium(env),
00112 fFileName(fileName), fOnCreation(onCreation), fOnCreationClientData(onCreationClientData),
00113 fNextTrackTypeToCheck(0x1), fLastClientSessionId(0), fLastCreatedDemux(NULL) {
00114 MatroskaFile::createNew(env, fileName, onMatroskaFileCreation, this);
00115 }
00116
00117 MatroskaFileServerDemux::~MatroskaFileServerDemux() {
00118 Medium::close(fOurMatroskaFile);
00119 }
00120
00121 void MatroskaFileServerDemux::onMatroskaFileCreation(MatroskaFile* newFile, void* clientData) {
00122 ((MatroskaFileServerDemux*)clientData)->onMatroskaFileCreation(newFile);
00123 }
00124
00125 void MatroskaFileServerDemux::onMatroskaFileCreation(MatroskaFile* newFile) {
00126 fOurMatroskaFile = newFile;
00127
00128
00129 if (fOnCreation != NULL) (*fOnCreation)(this, fOnCreationClientData);
00130 }