00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "VorbisAudioMatroskaFileServerMediaSubsession.hh"
00023 #include "VorbisAudioRTPSink.hh"
00024 #include "MatroskaDemuxedTrack.hh"
00025
00026 VorbisAudioMatroskaFileServerMediaSubsession* VorbisAudioMatroskaFileServerMediaSubsession
00027 ::createNew(MatroskaFileServerDemux& demux, unsigned trackNumber) {
00028 return new VorbisAudioMatroskaFileServerMediaSubsession(demux, trackNumber);
00029 }
00030
00031 #define getPrivByte(b) if (n == 0) break; else do {b = *p++; --n;} while (0)
00032
00033 VorbisAudioMatroskaFileServerMediaSubsession
00034 ::VorbisAudioMatroskaFileServerMediaSubsession(MatroskaFileServerDemux& demux, unsigned trackNumber)
00035 : FileServerMediaSubsession(demux.envir(), demux.fileName(), False),
00036 fOurDemux(demux), fTrackNumber(trackNumber),
00037 fIdentificationHeader(NULL), fIdentificationHeaderSize(0),
00038 fCommentHeader(NULL), fCommentHeaderSize(0),
00039 fSetupHeader(NULL), fSetupHeaderSize(0),
00040 fEstBitrate(96) {
00041 MatroskaTrack* track = fOurDemux.lookup(fTrackNumber);
00042
00043
00044
00045 do {
00046 u_int8_t* p = track->codecPrivate;
00047 unsigned n = track->codecPrivateSize;
00048 if (n == 0 || p == NULL) break;
00049
00050 u_int8_t numHeaders;
00051 getPrivByte(numHeaders);
00052 unsigned headerSize[3];
00053
00054
00055 unsigned sizesSum = 0;
00056 Boolean success = True;
00057 unsigned i;
00058 for (i = 0; i < numHeaders && i < 3; ++i) {
00059 unsigned len = 0;
00060 u_int8_t c;
00061
00062 do {
00063 success = False;
00064 getPrivByte(c);
00065 success = True;
00066
00067 len += c;
00068 } while (c == 255);
00069 if (!success || len == 0) break;
00070
00071 headerSize[i] = len;
00072 sizesSum += len;
00073 }
00074 if (!success) break;
00075
00076
00077 if (numHeaders < 3) {
00078 int finalHeaderSize = n - sizesSum;
00079 if (finalHeaderSize <= 0) break;
00080
00081 headerSize[numHeaders] = (unsigned)finalHeaderSize;
00082 ++numHeaders;
00083 } else {
00084 numHeaders = 3;
00085 }
00086
00087
00088 for (i = 0; i < numHeaders; ++i) {
00089 success = False;
00090 unsigned newHeaderSize = headerSize[i];
00091 u_int8_t* newHeader = new u_int8_t[newHeaderSize];
00092 if (newHeader == NULL) break;
00093
00094 u_int8_t* hdr = newHeader;
00095 while (newHeaderSize-- > 0) {
00096 success = False;
00097 getPrivByte(*hdr++);
00098 success = True;
00099 }
00100 if (!success) {
00101 delete[] newHeader;
00102 break;
00103 }
00104
00105 u_int8_t headerType = newHeader[0];
00106 if (headerType == 1) {
00107 delete[] fIdentificationHeader; fIdentificationHeader = newHeader;
00108 fIdentificationHeaderSize = headerSize[i];
00109
00110 if (fIdentificationHeaderSize >= 28) {
00111
00112 u_int32_t val;
00113 u_int8_t* p;
00114
00115 p = &fIdentificationHeader[16];
00116 val = ((p[3]*256 + p[2])*256 + p[1])*256 + p[0];
00117 int bitrate_maximum = (int)val;
00118 if (bitrate_maximum < 0) bitrate_maximum = 0;
00119
00120 p = &fIdentificationHeader[20];
00121 val = ((p[3]*256 + p[2])*256 + p[1])*256 + p[0];
00122 int bitrate_nominal = (int)val;
00123 if (bitrate_nominal < 0) bitrate_nominal = 0;
00124
00125 p = &fIdentificationHeader[24];
00126 val = ((p[3]*256 + p[2])*256 + p[1])*256 + p[0];
00127 int bitrate_minimum = (int)val;
00128 if (bitrate_minimum < 0) bitrate_minimum = 0;
00129
00130 int bitrate
00131 = bitrate_nominal>0 ? bitrate_nominal : bitrate_maximum>0 ? bitrate_maximum : bitrate_minimum>0 ? bitrate_minimum : 0;
00132 if (bitrate > 0) fEstBitrate = ((unsigned)bitrate)/1000;
00133 }
00134 } else if (headerType == 3) {
00135 delete[] fCommentHeader; fCommentHeader = newHeader;
00136 fCommentHeaderSize = headerSize[i];
00137 } else if (headerType == 5) {
00138 delete[] fSetupHeader; fSetupHeader = newHeader;
00139 fSetupHeaderSize = headerSize[i];
00140 } else {
00141 delete[] newHeader;
00142 }
00143 }
00144 if (!success) break;
00145 } while (0);
00146 }
00147
00148 VorbisAudioMatroskaFileServerMediaSubsession
00149 ::~VorbisAudioMatroskaFileServerMediaSubsession() {
00150 delete[] fIdentificationHeader;
00151 delete[] fCommentHeader;
00152 delete[] fSetupHeader;
00153 }
00154
00155 float VorbisAudioMatroskaFileServerMediaSubsession::duration() const { return fOurDemux.fileDuration(); }
00156
00157 void VorbisAudioMatroskaFileServerMediaSubsession
00158 ::seekStreamSource(FramedSource* inputSource, double& seekNPT, double , u_int64_t& ) {
00159 ((MatroskaDemuxedTrack*)inputSource)->seekToTime(seekNPT);
00160 }
00161
00162 FramedSource* VorbisAudioMatroskaFileServerMediaSubsession
00163 ::createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate) {
00164 estBitrate = fEstBitrate;
00165
00166 return fOurDemux.newDemuxedTrack(clientSessionId, fTrackNumber);
00167 }
00168
00169 RTPSink* VorbisAudioMatroskaFileServerMediaSubsession
00170 ::createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* ) {
00171 MatroskaTrack* track = fOurDemux.lookup(fTrackNumber);
00172 return VorbisAudioRTPSink::createNew(envir(), rtpGroupsock,
00173 rtpPayloadTypeIfDynamic, track->samplingFrequency, track->numChannels,
00174 fIdentificationHeader, fIdentificationHeaderSize,
00175 fCommentHeader, fCommentHeaderSize,
00176 fSetupHeader, fSetupHeaderSize);
00177 }