00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "MPEG2TransportStreamFromESSource.hh"
00023
00024 #define MAX_INPUT_ES_FRAME_SIZE 50000
00025 #define SIMPLE_PES_HEADER_SIZE 14
00026 #define LOW_WATER_MARK 1000 // <= MAX_INPUT_ES_FRAME_SIZE
00027 #define INPUT_BUFFER_SIZE (SIMPLE_PES_HEADER_SIZE + 2*MAX_INPUT_ES_FRAME_SIZE)
00028
00030
00031 class InputESSourceRecord {
00032 public:
00033 InputESSourceRecord(MPEG2TransportStreamFromESSource& parent,
00034 FramedSource* inputSource,
00035 u_int8_t streamId, int mpegVersion,
00036 InputESSourceRecord* next);
00037 virtual ~InputESSourceRecord();
00038
00039 InputESSourceRecord* next() const { return fNext; }
00040 FramedSource* inputSource() const { return fInputSource; }
00041
00042 void askForNewData();
00043 Boolean deliverBufferToClient();
00044
00045 unsigned char* buffer() const { return fInputBuffer; }
00046 void reset() {
00047
00048 fInputBufferBytesAvailable = 0;
00049 fInputBufferInUse = False;
00050 }
00051
00052 private:
00053 static void afterGettingFrame(void* clientData, unsigned frameSize,
00054 unsigned numTruncatedBytes,
00055 struct timeval presentationTime,
00056 unsigned durationInMicroseconds);
00057 void afterGettingFrame1(unsigned frameSize,
00058 unsigned numTruncatedBytes,
00059 struct timeval presentationTime);
00060
00061 private:
00062 InputESSourceRecord* fNext;
00063 MPEG2TransportStreamFromESSource& fParent;
00064 FramedSource* fInputSource;
00065 u_int8_t fStreamId;
00066 int fMPEGVersion;
00067 unsigned char* fInputBuffer;
00068 unsigned fInputBufferBytesAvailable;
00069 Boolean fInputBufferInUse;
00070 MPEG1or2Demux::SCR fSCR;
00071 };
00072
00073
00075
00076 MPEG2TransportStreamFromESSource* MPEG2TransportStreamFromESSource
00077 ::createNew(UsageEnvironment& env) {
00078 return new MPEG2TransportStreamFromESSource(env);
00079 }
00080
00081 void MPEG2TransportStreamFromESSource
00082 ::addNewVideoSource(FramedSource* inputSource, int mpegVersion) {
00083 u_int8_t streamId = 0xE0 | (fVideoSourceCounter++&0x0F);
00084 addNewInputSource(inputSource, streamId, mpegVersion);
00085 fHaveVideoStreams = True;
00086 }
00087
00088 void MPEG2TransportStreamFromESSource
00089 ::addNewAudioSource(FramedSource* inputSource, int mpegVersion) {
00090 u_int8_t streamId = 0xC0 | (fAudioSourceCounter++&0x0F);
00091 addNewInputSource(inputSource, streamId, mpegVersion);
00092 }
00093
00094 MPEG2TransportStreamFromESSource
00095 ::MPEG2TransportStreamFromESSource(UsageEnvironment& env)
00096 : MPEG2TransportStreamMultiplexor(env),
00097 fInputSources(NULL), fVideoSourceCounter(0), fAudioSourceCounter(0) {
00098 fHaveVideoStreams = False;
00099 }
00100
00101 MPEG2TransportStreamFromESSource::~MPEG2TransportStreamFromESSource() {
00102 delete fInputSources;
00103 }
00104
00105 void MPEG2TransportStreamFromESSource::doStopGettingFrames() {
00106
00107 for (InputESSourceRecord* sourceRec = fInputSources; sourceRec != NULL;
00108 sourceRec = sourceRec->next()) {
00109 sourceRec->inputSource()->stopGettingFrames();
00110 }
00111 }
00112
00113 void MPEG2TransportStreamFromESSource
00114 ::awaitNewBuffer(unsigned char* oldBuffer) {
00115 InputESSourceRecord* sourceRec;
00116
00117 if (oldBuffer != NULL) {
00118 for (sourceRec = fInputSources; sourceRec != NULL;
00119 sourceRec = sourceRec->next()) {
00120 if (sourceRec->buffer() == oldBuffer) {
00121 sourceRec->reset();
00122 break;
00123 }
00124 }
00125 }
00126
00127 if (isCurrentlyAwaitingData()) {
00128
00129 for (sourceRec = fInputSources; sourceRec != NULL;
00130 sourceRec = sourceRec->next()) {
00131 if (sourceRec->deliverBufferToClient()) break;
00132 }
00133 }
00134
00135
00136 for (sourceRec = fInputSources; sourceRec != NULL;
00137 sourceRec = sourceRec->next()) {
00138 sourceRec->askForNewData();
00139 }
00140
00141 }
00142
00143 void MPEG2TransportStreamFromESSource
00144 ::addNewInputSource(FramedSource* inputSource,
00145 u_int8_t streamId, int mpegVersion) {
00146 if (inputSource == NULL) return;
00147 fInputSources = new InputESSourceRecord(*this, inputSource, streamId,
00148 mpegVersion, fInputSources);
00149 }
00150
00151
00153
00154 InputESSourceRecord
00155 ::InputESSourceRecord(MPEG2TransportStreamFromESSource& parent,
00156 FramedSource* inputSource,
00157 u_int8_t streamId, int mpegVersion,
00158 InputESSourceRecord* next)
00159 : fNext(next), fParent(parent), fInputSource(inputSource),
00160 fStreamId(streamId), fMPEGVersion(mpegVersion) {
00161 fInputBuffer = new unsigned char[INPUT_BUFFER_SIZE];
00162 reset();
00163 }
00164
00165 InputESSourceRecord::~InputESSourceRecord() {
00166 Medium::close(fInputSource);
00167 delete[] fInputBuffer;
00168 delete fNext;
00169 }
00170
00171 void InputESSourceRecord::askForNewData() {
00172 if (fInputBufferInUse) return;
00173
00174 if (fInputBufferBytesAvailable == 0) {
00175
00176 fInputBuffer[0] = 0; fInputBuffer[1] = 0; fInputBuffer[2] = 1;
00177 fInputBuffer[3] = fStreamId;
00178 fInputBuffer[4] = 0; fInputBuffer[5] = 0;
00179 fInputBuffer[6] = 0x80;
00180 fInputBuffer[7] = 0x80;
00181 fInputBuffer[8] = 5;
00182
00183 fInputBufferBytesAvailable = SIMPLE_PES_HEADER_SIZE;
00184 }
00185 if (fInputBufferBytesAvailable < LOW_WATER_MARK &&
00186 !fInputSource->isCurrentlyAwaitingData()) {
00187
00188 fInputSource->getNextFrame(&fInputBuffer[fInputBufferBytesAvailable],
00189 INPUT_BUFFER_SIZE-fInputBufferBytesAvailable,
00190 afterGettingFrame, this,
00191 FramedSource::handleClosure, &fParent);
00192 }
00193 }
00194
00195 Boolean InputESSourceRecord::deliverBufferToClient() {
00196 if (fInputBufferInUse || fInputBufferBytesAvailable < LOW_WATER_MARK) return False;
00197
00198
00199 unsigned PES_packet_length = fInputBufferBytesAvailable - 6;
00200 if (PES_packet_length > 0xFFFF) {
00201
00202 PES_packet_length = 0;
00203 }
00204 fInputBuffer[4] = PES_packet_length>>8;
00205 fInputBuffer[5] = PES_packet_length;
00206
00207
00208 fInputBuffer[9] = 0x20|(fSCR.highBit<<3)|(fSCR.remainingBits>>29)|0x01;
00209 fInputBuffer[10] = fSCR.remainingBits>>22;
00210 fInputBuffer[11] = (fSCR.remainingBits>>14)|0x01;
00211 fInputBuffer[12] = fSCR.remainingBits>>7;
00212 fInputBuffer[13] = (fSCR.remainingBits<<1)|0x01;
00213
00214 fInputBufferInUse = True;
00215
00216
00217 fParent.handleNewBuffer(fInputBuffer, fInputBufferBytesAvailable,
00218 fMPEGVersion, fSCR);
00219
00220 return True;
00221 }
00222
00223 void InputESSourceRecord
00224 ::afterGettingFrame(void* clientData, unsigned frameSize,
00225 unsigned numTruncatedBytes,
00226 struct timeval presentationTime,
00227 unsigned ) {
00228 InputESSourceRecord* source = (InputESSourceRecord*)clientData;
00229 source->afterGettingFrame1(frameSize, numTruncatedBytes, presentationTime);
00230 }
00231 void InputESSourceRecord
00232 ::afterGettingFrame1(unsigned frameSize, unsigned numTruncatedBytes,
00233 struct timeval presentationTime) {
00234 if (numTruncatedBytes > 0) {
00235 fParent.envir() << "MPEG2TransportStreamFromESSource: input buffer too small; increase \"MAX_INPUT_ES_FRAME_SIZE\" in \"MPEG2TransportStreamFromESSource\" by at least "
00236 << numTruncatedBytes << " bytes!\n";
00237 }
00238
00239 if (fInputBufferBytesAvailable == SIMPLE_PES_HEADER_SIZE) {
00240
00241 fSCR.highBit
00242 = ((presentationTime.tv_sec*45000 + (presentationTime.tv_usec*9)/200)&
00243 0x80000000) != 0;
00244 fSCR.remainingBits
00245 = presentationTime.tv_sec*90000 + (presentationTime.tv_usec*9)/100;
00246 fSCR.extension = (presentationTime.tv_usec*9)%100;
00247 #ifdef DEBUG_SCR
00248 fprintf(stderr, "PES header: stream_id 0x%02x, pts: %u.%06u => SCR 0x%x%08x:%03x\n", fStreamId, (unsigned)presentationTime.tv_sec, (unsigned)presentationTime.tv_usec, fSCR.highBit, fSCR.remainingBits, fSCR.extension);
00249 #endif
00250 }
00251
00252 fInputBufferBytesAvailable += frameSize;
00253
00254 fParent.fPresentationTime = presentationTime;
00255
00256
00257 fParent.awaitNewBuffer(NULL);
00258 }