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 100000
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 doStopGettingFrames();
00103 delete fInputSources;
00104 }
00105
00106 void MPEG2TransportStreamFromESSource::doStopGettingFrames() {
00107
00108 for (InputESSourceRecord* sourceRec = fInputSources; sourceRec != NULL;
00109 sourceRec = sourceRec->next()) {
00110 sourceRec->inputSource()->stopGettingFrames();
00111 }
00112 }
00113
00114 void MPEG2TransportStreamFromESSource
00115 ::awaitNewBuffer(unsigned char* oldBuffer) {
00116 InputESSourceRecord* sourceRec;
00117
00118 if (oldBuffer != NULL) {
00119 for (sourceRec = fInputSources; sourceRec != NULL;
00120 sourceRec = sourceRec->next()) {
00121 if (sourceRec->buffer() == oldBuffer) {
00122 sourceRec->reset();
00123 break;
00124 }
00125 }
00126 }
00127
00128 if (isCurrentlyAwaitingData()) {
00129
00130 for (sourceRec = fInputSources; sourceRec != NULL;
00131 sourceRec = sourceRec->next()) {
00132 if (sourceRec->deliverBufferToClient()) break;
00133 }
00134 }
00135
00136
00137 for (sourceRec = fInputSources; sourceRec != NULL;
00138 sourceRec = sourceRec->next()) {
00139 sourceRec->askForNewData();
00140 }
00141
00142 }
00143
00144 void MPEG2TransportStreamFromESSource
00145 ::addNewInputSource(FramedSource* inputSource,
00146 u_int8_t streamId, int mpegVersion) {
00147 if (inputSource == NULL) return;
00148 fInputSources = new InputESSourceRecord(*this, inputSource, streamId,
00149 mpegVersion, fInputSources);
00150 }
00151
00152
00154
00155 InputESSourceRecord
00156 ::InputESSourceRecord(MPEG2TransportStreamFromESSource& parent,
00157 FramedSource* inputSource,
00158 u_int8_t streamId, int mpegVersion,
00159 InputESSourceRecord* next)
00160 : fNext(next), fParent(parent), fInputSource(inputSource),
00161 fStreamId(streamId), fMPEGVersion(mpegVersion) {
00162 fInputBuffer = new unsigned char[INPUT_BUFFER_SIZE];
00163 reset();
00164 }
00165
00166 InputESSourceRecord::~InputESSourceRecord() {
00167 Medium::close(fInputSource);
00168 delete[] fInputBuffer;
00169 delete fNext;
00170 }
00171
00172 void InputESSourceRecord::askForNewData() {
00173 if (fInputBufferInUse) return;
00174
00175 if (fInputBufferBytesAvailable == 0) {
00176
00177 fInputBuffer[0] = 0; fInputBuffer[1] = 0; fInputBuffer[2] = 1;
00178 fInputBuffer[3] = fStreamId;
00179 fInputBuffer[4] = 0; fInputBuffer[5] = 0;
00180 fInputBuffer[6] = 0x80;
00181 fInputBuffer[7] = 0x80;
00182 fInputBuffer[8] = 5;
00183
00184 fInputBufferBytesAvailable = SIMPLE_PES_HEADER_SIZE;
00185 }
00186 if (fInputBufferBytesAvailable < LOW_WATER_MARK &&
00187 !fInputSource->isCurrentlyAwaitingData()) {
00188
00189 fInputSource->getNextFrame(&fInputBuffer[fInputBufferBytesAvailable],
00190 INPUT_BUFFER_SIZE-fInputBufferBytesAvailable,
00191 afterGettingFrame, this,
00192 FramedSource::handleClosure, &fParent);
00193 }
00194 }
00195
00196 Boolean InputESSourceRecord::deliverBufferToClient() {
00197 if (fInputBufferInUse || fInputBufferBytesAvailable < LOW_WATER_MARK) return False;
00198
00199
00200 unsigned PES_packet_length = fInputBufferBytesAvailable - 6;
00201 if (PES_packet_length > 0xFFFF) {
00202
00203 PES_packet_length = 0;
00204 }
00205 fInputBuffer[4] = PES_packet_length>>8;
00206 fInputBuffer[5] = PES_packet_length;
00207
00208
00209 fInputBuffer[9] = 0x20|(fSCR.highBit<<3)|(fSCR.remainingBits>>29)|0x01;
00210 fInputBuffer[10] = fSCR.remainingBits>>22;
00211 fInputBuffer[11] = (fSCR.remainingBits>>14)|0x01;
00212 fInputBuffer[12] = fSCR.remainingBits>>7;
00213 fInputBuffer[13] = (fSCR.remainingBits<<1)|0x01;
00214
00215 fInputBufferInUse = True;
00216
00217
00218 fParent.handleNewBuffer(fInputBuffer, fInputBufferBytesAvailable,
00219 fMPEGVersion, fSCR);
00220
00221 return True;
00222 }
00223
00224 void InputESSourceRecord
00225 ::afterGettingFrame(void* clientData, unsigned frameSize,
00226 unsigned numTruncatedBytes,
00227 struct timeval presentationTime,
00228 unsigned ) {
00229 InputESSourceRecord* source = (InputESSourceRecord*)clientData;
00230 source->afterGettingFrame1(frameSize, numTruncatedBytes, presentationTime);
00231 }
00232 void InputESSourceRecord
00233 ::afterGettingFrame1(unsigned frameSize, unsigned numTruncatedBytes,
00234 struct timeval presentationTime) {
00235 if (numTruncatedBytes > 0) {
00236 fParent.envir() << "MPEG2TransportStreamFromESSource: input buffer too small; increase \"MAX_INPUT_ES_FRAME_SIZE\" in \"MPEG2TransportStreamFromESSource\" by at least "
00237 << numTruncatedBytes << " bytes!\n";
00238 }
00239
00240 if (fInputBufferBytesAvailable == SIMPLE_PES_HEADER_SIZE) {
00241
00242 fSCR.highBit
00243 = ((presentationTime.tv_sec*45000 + (presentationTime.tv_usec*9)/200)&
00244 0x80000000) != 0;
00245 fSCR.remainingBits
00246 = presentationTime.tv_sec*90000 + (presentationTime.tv_usec*9)/100;
00247 fSCR.extension = (presentationTime.tv_usec*9)%100;
00248 #ifdef DEBUG_SCR
00249 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);
00250 #endif
00251 }
00252
00253 fInputBufferBytesAvailable += frameSize;
00254
00255 fParent.fPresentationTime = presentationTime;
00256
00257
00258 fParent.awaitNewBuffer(NULL);
00259 }