00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "H264VideoMatroskaFileServerMediaSubsession.hh"
00023 #include "H264VideoStreamDiscreteFramer.hh"
00024 #include "MatroskaDemuxedTrack.hh"
00025
00026 H264VideoMatroskaFileServerMediaSubsession* H264VideoMatroskaFileServerMediaSubsession
00027 ::createNew(MatroskaFileServerDemux& demux, unsigned trackNumber) {
00028 return new H264VideoMatroskaFileServerMediaSubsession(demux, trackNumber);
00029 }
00030
00031 #define checkPtr if (ptr >= limit) return;
00032 #define numBytesRemaining (unsigned)(limit - ptr)
00033
00034 H264VideoMatroskaFileServerMediaSubsession
00035 ::H264VideoMatroskaFileServerMediaSubsession(MatroskaFileServerDemux& demux, unsigned trackNumber)
00036 : H264VideoFileServerMediaSubsession(demux.envir(), demux.fileName(), False),
00037 fOurDemux(demux), fTrackNumber(trackNumber),
00038 fSPSSize(0), fSPS(NULL), fPPSSize(0), fPPS(NULL) {
00039
00040
00041 MatroskaTrack* track = fOurDemux.lookup(fTrackNumber);
00042 if (track->codecPrivateSize >= 5) track->subframeSizeSize = (track->codecPrivate[4])&0x3 + 1;
00043
00044 unsigned numSPSandPPSBytes;
00045 u_int8_t* SPSandPPSBytes;
00046 if (track->codecPrivateSize >= 6) {
00047 numSPSandPPSBytes = track->codecPrivateSize - 5;
00048 track->codecPrivate[5] &=~ 0xE0;
00049 SPSandPPSBytes = &track->codecPrivate[5];
00050 } else {
00051 numSPSandPPSBytes = 0;
00052 SPSandPPSBytes = NULL;
00053 }
00054
00055
00056 do {
00057 if (numSPSandPPSBytes == 0 || SPSandPPSBytes == NULL) break;
00058 u_int8_t* ptr = SPSandPPSBytes;
00059 u_int8_t* limit = &SPSandPPSBytes[numSPSandPPSBytes];
00060
00061 unsigned numSPSs = *ptr++; checkPtr;
00062 unsigned i;
00063 for (i = 0; i < numSPSs; ++i) {
00064 unsigned spsSize = (*ptr++)<<8; checkPtr;
00065 spsSize |= *ptr++; checkPtr;
00066
00067 if (spsSize > numBytesRemaining) return;
00068 if (i == 0) {
00069 fSPSSize = spsSize;
00070 fSPS = new u_int8_t[spsSize];
00071 memmove(fSPS, ptr, spsSize);
00072 }
00073 ptr += spsSize;
00074 }
00075
00076 unsigned numPPSs = *ptr++; checkPtr;
00077 for (i = 0; i < numPPSs; ++i) {
00078 unsigned ppsSize = (*ptr++)<<8; checkPtr;
00079 ppsSize |= *ptr++; checkPtr;
00080
00081 if (ppsSize > numBytesRemaining) return;
00082 if (i == 0) {
00083 fPPSSize = ppsSize;
00084 fPPS = new u_int8_t[ppsSize];
00085 memmove(fPPS, ptr, ppsSize);
00086 }
00087 ptr += ppsSize;
00088 }
00089 } while (0);
00090 }
00091
00092 H264VideoMatroskaFileServerMediaSubsession
00093 ::~H264VideoMatroskaFileServerMediaSubsession() {
00094 delete[] fSPS;
00095 delete[] fPPS;
00096 }
00097
00098 float H264VideoMatroskaFileServerMediaSubsession::duration() const { return fOurDemux.fileDuration(); }
00099
00100 void H264VideoMatroskaFileServerMediaSubsession
00101 ::seekStreamSource(FramedSource* inputSource, double& seekNPT, double , u_int64_t& ) {
00102
00103 H264VideoStreamFramer* framer = (H264VideoStreamFramer*)inputSource;
00104
00105 MatroskaDemuxedTrack* demuxedTrack = (MatroskaDemuxedTrack*)(framer->inputSource());
00106 demuxedTrack->seekToTime(seekNPT);
00107 }
00108
00109 FramedSource* H264VideoMatroskaFileServerMediaSubsession
00110 ::createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate) {
00111
00112 OutPacketBuffer::maxSize = 300000;
00113 estBitrate = 500;
00114
00115
00116 FramedSource* baseH264VideoSource = fOurDemux.newDemuxedTrack(clientSessionId, fTrackNumber);
00117 if (baseH264VideoSource == NULL) return NULL;
00118
00119
00120 H264VideoStreamFramer* framer = H264VideoStreamDiscreteFramer::createNew(envir(), baseH264VideoSource);
00121 framer->setSPSandPPS(fSPS, fSPSSize, fPPS, fPPSSize);
00122
00123 return framer;
00124 }