00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "MPEG1or2Demux.hh"
00022 #include "MPEG1or2DemuxedElementaryStream.hh"
00023 #include "StreamParser.hh"
00024 #include <stdlib.h>
00025
00027
00028
00029 enum MPEGParseState {
00030 PARSING_PACK_HEADER,
00031 PARSING_SYSTEM_HEADER,
00032 PARSING_PES_PACKET
00033 };
00034
00035 class MPEGProgramStreamParser: public StreamParser {
00036 public:
00037 MPEGProgramStreamParser(MPEG1or2Demux* usingDemux, FramedSource* inputSource);
00038 virtual ~MPEGProgramStreamParser();
00039
00040 public:
00041 unsigned char parse();
00042
00043
00044
00045 private:
00046 void setParseState(MPEGParseState parseState);
00047
00048 void parsePackHeader();
00049 void parseSystemHeader();
00050 unsigned char parsePESPacket();
00051
00052 Boolean isSpecialStreamId(unsigned char stream_id) const;
00053
00054
00055 private:
00056 MPEG1or2Demux* fUsingDemux;
00057 MPEGParseState fCurrentParseState;
00058 };
00059
00060
00062
00063 class MPEG1or2Demux::OutputDescriptor::SavedData {
00064 public:
00065 SavedData(unsigned char* buf, unsigned size)
00066 : next(NULL), data(buf), dataSize(size), numBytesUsed(0) {
00067 }
00068 virtual ~SavedData() {
00069 delete[] data;
00070 delete next;
00071 }
00072
00073 SavedData* next;
00074 unsigned char* data;
00075 unsigned dataSize, numBytesUsed;
00076 };
00077
00078
00080
00081 MPEG1or2Demux
00082 ::MPEG1or2Demux(UsageEnvironment& env,
00083 FramedSource* inputSource, Boolean reclaimWhenLastESDies)
00084 : Medium(env),
00085 fInputSource(inputSource), fMPEGversion(0),
00086 fNextAudioStreamNumber(0), fNextVideoStreamNumber(0),
00087 fReclaimWhenLastESDies(reclaimWhenLastESDies), fNumOutstandingESs(0),
00088 fNumPendingReads(0), fHaveUndeliveredData(False) {
00089 fParser = new MPEGProgramStreamParser(this, inputSource);
00090 for (unsigned i = 0; i < 256; ++i) {
00091 fOutput[i].savedDataHead = fOutput[i].savedDataTail = NULL;
00092 fOutput[i].isPotentiallyReadable = False;
00093 fOutput[i].isCurrentlyActive = False;
00094 fOutput[i].isCurrentlyAwaitingData = False;
00095 }
00096 }
00097
00098 MPEG1or2Demux::~MPEG1or2Demux() {
00099 delete fParser;
00100 for (unsigned i = 0; i < 256; ++i) delete fOutput[i].savedDataHead;
00101 Medium::close(fInputSource);
00102 }
00103
00104 MPEG1or2Demux* MPEG1or2Demux
00105 ::createNew(UsageEnvironment& env,
00106 FramedSource* inputSource, Boolean reclaimWhenLastESDies) {
00107
00108
00109 return new MPEG1or2Demux(env, inputSource, reclaimWhenLastESDies);
00110 }
00111
00112 MPEG1or2Demux::SCR::SCR()
00113 : highBit(0), remainingBits(0), extension(0), isValid(False) {
00114 }
00115
00116 void MPEG1or2Demux
00117 ::noteElementaryStreamDeletion(MPEG1or2DemuxedElementaryStream* ) {
00118 if (--fNumOutstandingESs == 0 && fReclaimWhenLastESDies) {
00119 Medium::close(this);
00120 }
00121 }
00122
00123 void MPEG1or2Demux::flushInput() {
00124 fParser->flushInput();
00125 }
00126
00127 MPEG1or2DemuxedElementaryStream*
00128 MPEG1or2Demux::newElementaryStream(u_int8_t streamIdTag) {
00129 ++fNumOutstandingESs;
00130 fOutput[streamIdTag].isPotentiallyReadable = True;
00131 return new MPEG1or2DemuxedElementaryStream(envir(), streamIdTag, *this);
00132 }
00133
00134 MPEG1or2DemuxedElementaryStream* MPEG1or2Demux::newAudioStream() {
00135 unsigned char newAudioStreamTag = 0xC0 | (fNextAudioStreamNumber++&~0xE0);
00136
00137 return newElementaryStream(newAudioStreamTag);
00138 }
00139
00140 MPEG1or2DemuxedElementaryStream* MPEG1or2Demux::newVideoStream() {
00141 unsigned char newVideoStreamTag = 0xE0 | (fNextVideoStreamNumber++&~0xF0);
00142
00143 return newElementaryStream(newVideoStreamTag);
00144 }
00145
00146
00147 #define RAW_PES 0xFC
00148
00149 MPEG1or2DemuxedElementaryStream* MPEG1or2Demux::newRawPESStream() {
00150 return newElementaryStream(RAW_PES);
00151 }
00152
00153 void MPEG1or2Demux::registerReadInterest(u_int8_t streamIdTag,
00154 unsigned char* to, unsigned maxSize,
00155 FramedSource::afterGettingFunc* afterGettingFunc,
00156 void* afterGettingClientData,
00157 FramedSource::onCloseFunc* onCloseFunc,
00158 void* onCloseClientData) {
00159 struct OutputDescriptor& out = fOutput[streamIdTag];
00160
00161
00162 if (out.isCurrentlyAwaitingData) {
00163 envir() << "MPEG1or2Demux::registerReadInterest(): attempt to read stream id "
00164 << (void*)streamIdTag << " more than once!\n";
00165 envir().internalError();
00166 }
00167
00168 out.to = to; out.maxSize = maxSize;
00169 out.fAfterGettingFunc = afterGettingFunc;
00170 out.afterGettingClientData = afterGettingClientData;
00171 out.fOnCloseFunc = onCloseFunc;
00172 out.onCloseClientData = onCloseClientData;
00173 out.isCurrentlyActive = True;
00174 out.isCurrentlyAwaitingData = True;
00175
00176
00177 ++fNumPendingReads;
00178 }
00179
00180 Boolean MPEG1or2Demux::useSavedData(u_int8_t streamIdTag,
00181 unsigned char* to, unsigned maxSize,
00182 FramedSource::afterGettingFunc* afterGettingFunc,
00183 void* afterGettingClientData) {
00184 struct OutputDescriptor& out = fOutput[streamIdTag];
00185 if (out.savedDataHead == NULL) return False;
00186
00187 unsigned totNumBytesCopied = 0;
00188 while (maxSize > 0 && out.savedDataHead != NULL) {
00189 OutputDescriptor::SavedData& savedData = *(out.savedDataHead);
00190 unsigned char* from = &savedData.data[savedData.numBytesUsed];
00191 unsigned numBytesToCopy = savedData.dataSize - savedData.numBytesUsed;
00192 if (numBytesToCopy > maxSize) numBytesToCopy = maxSize;
00193 memmove(to, from, numBytesToCopy);
00194 to += numBytesToCopy;
00195 maxSize -= numBytesToCopy;
00196 out.savedDataTotalSize -= numBytesToCopy;
00197 totNumBytesCopied += numBytesToCopy;
00198 savedData.numBytesUsed += numBytesToCopy;
00199 if (savedData.numBytesUsed == savedData.dataSize) {
00200 out.savedDataHead = savedData.next;
00201 if (out.savedDataHead == NULL) out.savedDataTail = NULL;
00202 savedData.next = NULL;
00203 delete &savedData;
00204 }
00205 }
00206
00207 out.isCurrentlyActive = True;
00208 if (afterGettingFunc != NULL) {
00209 struct timeval presentationTime;
00210 presentationTime.tv_sec = 0; presentationTime.tv_usec = 0;
00211 (*afterGettingFunc)(afterGettingClientData, totNumBytesCopied,
00212 0 , presentationTime,
00213 0 );
00214 }
00215 return True;
00216 }
00217
00218 void MPEG1or2Demux
00219 ::continueReadProcessing(void* clientData,
00220 unsigned char* , unsigned ,
00221 struct timeval ) {
00222 MPEG1or2Demux* demux = (MPEG1or2Demux*)clientData;
00223 demux->continueReadProcessing();
00224 }
00225
00226 void MPEG1or2Demux::continueReadProcessing() {
00227 while (fNumPendingReads > 0) {
00228 unsigned char acquiredStreamIdTag = fParser->parse();
00229
00230 if (acquiredStreamIdTag != 0) {
00231
00232 struct OutputDescriptor& newOut = fOutput[acquiredStreamIdTag];
00233 newOut.isCurrentlyAwaitingData = False;
00234
00235
00236
00237
00238
00239
00240 if (newOut.fAfterGettingFunc != NULL) {
00241 (*newOut.fAfterGettingFunc)(newOut.afterGettingClientData,
00242 newOut.frameSize, 0 ,
00243 newOut.presentationTime,
00244 0 );
00245 --fNumPendingReads;
00246 }
00247 } else {
00248
00249
00250
00251
00252
00253 break;
00254 }
00255 }
00256 }
00257
00258 void MPEG1or2Demux::getNextFrame(u_int8_t streamIdTag,
00259 unsigned char* to, unsigned maxSize,
00260 FramedSource::afterGettingFunc* afterGettingFunc,
00261 void* afterGettingClientData,
00262 FramedSource::onCloseFunc* onCloseFunc,
00263 void* onCloseClientData) {
00264
00265 if (useSavedData(streamIdTag, to, maxSize,
00266 afterGettingFunc, afterGettingClientData)) {
00267 return;
00268 }
00269
00270
00271 registerReadInterest(streamIdTag, to, maxSize,
00272 afterGettingFunc, afterGettingClientData,
00273 onCloseFunc, onCloseClientData);
00274
00275
00276 if (fNumPendingReads == 1 || fHaveUndeliveredData) {
00277 fHaveUndeliveredData = 0;
00278 continueReadProcessing();
00279 }
00280 }
00281
00282 void MPEG1or2Demux::stopGettingFrames(u_int8_t streamIdTag) {
00283 struct OutputDescriptor& out = fOutput[streamIdTag];
00284
00285 if (out.isCurrentlyAwaitingData && fNumPendingReads > 0) --fNumPendingReads;
00286
00287 out.isCurrentlyActive = out.isCurrentlyAwaitingData = False;
00288 }
00289
00290 void MPEG1or2Demux::handleClosure(void* clientData) {
00291 MPEG1or2Demux* demux = (MPEG1or2Demux*)clientData;
00292
00293 demux->fNumPendingReads = 0;
00294
00295
00296
00297
00298
00299 struct {
00300 FramedSource::onCloseFunc* fOnCloseFunc;
00301 void* onCloseClientData;
00302 } savedPending[256];
00303 unsigned i, numPending = 0;
00304 for (i = 0; i < 256; ++i) {
00305 struct OutputDescriptor& out = demux->fOutput[i];
00306 if (out.isCurrentlyAwaitingData) {
00307 if (out.fOnCloseFunc != NULL) {
00308 savedPending[numPending].fOnCloseFunc = out.fOnCloseFunc;
00309 savedPending[numPending].onCloseClientData = out.onCloseClientData;
00310 ++numPending;
00311 }
00312 }
00313 delete out.savedDataHead; out.savedDataHead = out.savedDataTail = NULL;
00314 out.savedDataTotalSize = 0;
00315 out.isPotentiallyReadable = out.isCurrentlyActive = out.isCurrentlyAwaitingData
00316 = False;
00317 }
00318 for (i = 0; i < numPending; ++i) {
00319 (*savedPending[i].fOnCloseFunc)(savedPending[i].onCloseClientData);
00320 }
00321 }
00322
00323
00325
00326 #include <string.h>
00327
00328 MPEGProgramStreamParser::MPEGProgramStreamParser(MPEG1or2Demux* usingDemux,
00329 FramedSource* inputSource)
00330 : StreamParser(inputSource, MPEG1or2Demux::handleClosure, usingDemux,
00331 &MPEG1or2Demux::continueReadProcessing, usingDemux),
00332 fUsingDemux(usingDemux), fCurrentParseState(PARSING_PACK_HEADER) {
00333 }
00334
00335 MPEGProgramStreamParser::~MPEGProgramStreamParser() {
00336 }
00337
00338 void MPEGProgramStreamParser::setParseState(MPEGParseState parseState) {
00339 fCurrentParseState = parseState;
00340 saveParserState();
00341 }
00342
00343 unsigned char MPEGProgramStreamParser::parse() {
00344 unsigned char acquiredStreamTagId = 0;
00345
00346 try {
00347 do {
00348 switch (fCurrentParseState) {
00349 case PARSING_PACK_HEADER: {
00350 parsePackHeader();
00351 break;
00352 }
00353 case PARSING_SYSTEM_HEADER: {
00354 parseSystemHeader();
00355 break;
00356 }
00357 case PARSING_PES_PACKET: {
00358 acquiredStreamTagId = parsePESPacket();
00359 break;
00360 }
00361 }
00362 } while(acquiredStreamTagId == 0);
00363
00364 return acquiredStreamTagId;
00365 } catch (int ) {
00366 #ifdef DEBUG
00367 fprintf(stderr, "MPEGProgramStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n");
00368 fflush(stderr);
00369 #endif
00370 return 0;
00371 }
00372 }
00373
00374 #define PACK_START_CODE 0x000001BA
00375 #define SYSTEM_HEADER_START_CODE 0x000001BB
00376 #define PACKET_START_CODE_PREFIX 0x00000100
00377
00378 static inline Boolean isPacketStartCode(unsigned code) {
00379 return (code&0xFFFFFF00) == PACKET_START_CODE_PREFIX
00380 && code > SYSTEM_HEADER_START_CODE;
00381 }
00382
00383 void MPEGProgramStreamParser::parsePackHeader() {
00384 #ifdef DEBUG
00385 fprintf(stderr, "parsing pack header\n"); fflush(stderr);
00386 #endif
00387 unsigned first4Bytes;
00388 while (1) {
00389 first4Bytes = test4Bytes();
00390
00391
00392
00393 if (first4Bytes == PACK_START_CODE) {
00394 skipBytes(4);
00395 break;
00396 } else if (first4Bytes == SYSTEM_HEADER_START_CODE) {
00397 #ifdef DEBUG
00398 fprintf(stderr, "found system header instead of pack header\n");
00399 #endif
00400 setParseState(PARSING_SYSTEM_HEADER);
00401 return;
00402 } else if (isPacketStartCode(first4Bytes)) {
00403 #ifdef DEBUG
00404 fprintf(stderr, "found packet start code 0x%02x instead of pack header\n", first4Bytes);
00405 #endif
00406 setParseState(PARSING_PES_PACKET);
00407 return;
00408 }
00409
00410 setParseState(PARSING_PACK_HEADER);
00411 if ((first4Bytes&0xFF) > 1) {
00412 skipBytes(4);
00413 } else {
00414 skipBytes(1);
00415 }
00416 }
00417
00418
00419
00420 unsigned char nextByte = get1Byte();
00421 MPEG1or2Demux::SCR& scr = fUsingDemux->fLastSeenSCR;
00422 if ((nextByte&0xF0) == 0x20) {
00423 fUsingDemux->fMPEGversion = 1;
00424 scr.highBit = (nextByte&0x08)>>3;
00425 scr.remainingBits = (nextByte&0x06)<<29;
00426 unsigned next4Bytes = get4Bytes();
00427 scr.remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00428 scr.remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00429 scr.extension = 0;
00430 scr.isValid = True;
00431 skipBits(24);
00432
00433 #if defined(DEBUG_TIMESTAMPS) || defined(DEBUG_SCR_TIMESTAMPS)
00434 fprintf(stderr, "pack hdr system_clock_reference_base: 0x%x",
00435 scr.highBit);
00436 fprintf(stderr, "%08x\n", scr.remainingBits);
00437 #endif
00438 } else if ((nextByte&0xC0) == 0x40) {
00439 fUsingDemux->fMPEGversion = 2;
00440 scr.highBit = (nextByte&0x20)>>5;
00441 scr.remainingBits = (nextByte&0x18)<<27;
00442 scr.remainingBits |= (nextByte&0x03)<<28;
00443 unsigned next4Bytes = get4Bytes();
00444 scr.remainingBits |= (next4Bytes&0xFFF80000)>>4;
00445 scr.remainingBits |= (next4Bytes&0x0003FFF8)>>3;
00446 scr.extension = (next4Bytes&0x00000003)<<7;
00447 next4Bytes = get4Bytes();
00448 scr.extension |= (next4Bytes&0xFE000000)>>25;
00449 scr.isValid = True;
00450 skipBits(5);
00451
00452 #if defined(DEBUG_TIMESTAMPS) || defined(DEBUG_SCR_TIMESTAMPS)
00453 fprintf(stderr, "pack hdr system_clock_reference_base: 0x%x",
00454 scr.highBit);
00455 fprintf(stderr, "%08x\n", scr.remainingBits);
00456 fprintf(stderr, "pack hdr system_clock_reference_extension: 0x%03x\n",
00457 scr.extension);
00458 #endif
00459 unsigned char pack_stuffing_length = getBits(3);
00460 skipBytes(pack_stuffing_length);
00461 } else {
00462 fUsingDemux->envir() << "StreamParser::parsePack() saw strange byte "
00463 << (void*)nextByte
00464 << " following pack_start_code\n";
00465 }
00466
00467
00468 setParseState(PARSING_SYSTEM_HEADER);
00469 }
00470
00471 void MPEGProgramStreamParser::parseSystemHeader() {
00472 #ifdef DEBUG
00473 fprintf(stderr, "parsing system header\n"); fflush(stderr);
00474 #endif
00475 unsigned next4Bytes = test4Bytes();
00476 if (next4Bytes != SYSTEM_HEADER_START_CODE) {
00477
00478 setParseState(PARSING_PES_PACKET);
00479 return;
00480 }
00481
00482 #ifdef DEBUG
00483 fprintf(stderr, "saw system_header_start_code\n"); fflush(stderr);
00484 #endif
00485 skipBytes(4);
00486
00487 unsigned short remaining_header_length = get2Bytes();
00488
00489
00490
00491 if (remaining_header_length < 6) {
00492 fUsingDemux->envir() << "StreamParser::parseSystemHeader(): saw strange header_length: "
00493 << remaining_header_length << " < 6\n";
00494 }
00495 skipBytes(remaining_header_length);
00496
00497
00498 setParseState(PARSING_PES_PACKET);
00499 }
00500
00501 #define private_stream_1 0xBD
00502 #define private_stream_2 0xBF
00503
00504
00505 Boolean MPEGProgramStreamParser
00506 ::isSpecialStreamId(unsigned char stream_id) const {
00507 if (stream_id == RAW_PES) return True;
00508
00509 if (fUsingDemux->fMPEGversion == 1) {
00510 return stream_id == private_stream_2;
00511 } else {
00512 if (stream_id <= private_stream_2) {
00513 return stream_id != private_stream_1;
00514 } else if ((stream_id&0xF0) == 0xF0) {
00515 unsigned char lower4Bits = stream_id&0x0F;
00516 return lower4Bits <= 2 || lower4Bits == 0x8 || lower4Bits == 0xF;
00517 } else {
00518 return False;
00519 }
00520 }
00521 }
00522
00523 #define READER_NOT_READY 2
00524
00525 unsigned char MPEGProgramStreamParser::parsePESPacket() {
00526 #ifdef DEBUG
00527 fprintf(stderr, "parsing PES packet\n"); fflush(stderr);
00528 #endif
00529 unsigned next4Bytes = test4Bytes();
00530 if (!isPacketStartCode(next4Bytes)) {
00531
00532 setParseState(PARSING_PACK_HEADER);
00533 return 0;
00534 }
00535
00536 #ifdef DEBUG
00537 fprintf(stderr, "saw packet_start_code_prefix\n"); fflush(stderr);
00538 #endif
00539 skipBytes(3);
00540
00541 unsigned char stream_id = get1Byte();
00542 #if defined(DEBUG) || defined(DEBUG_TIMESTAMPS)
00543 unsigned char streamNum = stream_id;
00544 char const* streamTypeStr;
00545 if ((stream_id&0xE0) == 0xC0) {
00546 streamTypeStr = "audio";
00547 streamNum = stream_id&~0xE0;
00548 } else if ((stream_id&0xF0) == 0xE0) {
00549 streamTypeStr = "video";
00550 streamNum = stream_id&~0xF0;
00551 } else if (stream_id == 0xbc) {
00552 streamTypeStr = "reserved";
00553 } else if (stream_id == 0xbd) {
00554 streamTypeStr = "private_1";
00555 } else if (stream_id == 0xbe) {
00556 streamTypeStr = "padding";
00557 } else if (stream_id == 0xbf) {
00558 streamTypeStr = "private_2";
00559 } else {
00560 streamTypeStr = "unknown";
00561 }
00562 #endif
00563 #ifdef DEBUG
00564 static unsigned frameCount = 1;
00565 fprintf(stderr, "%d, saw %s stream: 0x%02x\n", frameCount, streamTypeStr, streamNum); fflush(stderr);
00566 #endif
00567
00568 unsigned short PES_packet_length = get2Bytes();
00569 #ifdef DEBUG
00570 fprintf(stderr, "PES_packet_length: %d\n", PES_packet_length); fflush(stderr);
00571 #endif
00572
00573
00574
00575 if (fUsingDemux->fOutput[RAW_PES].isPotentiallyReadable) {
00576
00577 stream_id = RAW_PES;
00578 }
00579 unsigned savedParserOffset = curOffset();
00580 #ifdef DEBUG_TIMESTAMPS
00581 unsigned char pts_highBit = 0;
00582 unsigned pts_remainingBits = 0;
00583 unsigned char dts_highBit = 0;
00584 unsigned dts_remainingBits = 0;
00585 #endif
00586 if (fUsingDemux->fMPEGversion == 1) {
00587 if (!isSpecialStreamId(stream_id)) {
00588 unsigned char nextByte;
00589 while ((nextByte = get1Byte()) == 0xFF) {
00590 }
00591 if ((nextByte&0xC0) == 0x40) {
00592 skipBytes(1);
00593 nextByte = get1Byte();
00594 }
00595 if ((nextByte&0xF0) == 0x20) {
00596 #ifdef DEBUG_TIMESTAMPS
00597 pts_highBit = (nextByte&0x08)>>3;
00598 pts_remainingBits = (nextByte&0x06)<<29;
00599 unsigned next4Bytes = get4Bytes();
00600 pts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00601 pts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00602 #else
00603 skipBytes(4);
00604 #endif
00605 } else if ((nextByte&0xF0) == 0x30) {
00606 #ifdef DEBUG_TIMESTAMPS
00607 pts_highBit = (nextByte&0x08)>>3;
00608 pts_remainingBits = (nextByte&0x06)<<29;
00609 unsigned next4Bytes = get4Bytes();
00610 pts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00611 pts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00612
00613 nextByte = get1Byte();
00614 dts_highBit = (nextByte&0x08)>>3;
00615 dts_remainingBits = (nextByte&0x06)<<29;
00616 next4Bytes = get4Bytes();
00617 dts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00618 dts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00619 #else
00620 skipBytes(9);
00621 #endif
00622 }
00623 }
00624 } else {
00625 if (!isSpecialStreamId(stream_id)) {
00626
00627 unsigned next3Bytes = getBits(24);
00628 #ifdef DEBUG_TIMESTAMPS
00629 unsigned char PTS_DTS_flags = (next3Bytes&0x00C000)>>14;
00630 #endif
00631 #ifdef undef
00632 unsigned char ESCR_flag = (next3Bytes&0x002000)>>13;
00633 unsigned char ES_rate_flag = (next3Bytes&0x001000)>>12;
00634 unsigned char DSM_trick_mode_flag = (next3Bytes&0x000800)>>11;
00635 #endif
00636 unsigned char PES_header_data_length = (next3Bytes&0x0000FF);
00637 #ifdef DEBUG
00638 fprintf(stderr, "PES_header_data_length: 0x%02x\n", PES_header_data_length); fflush(stderr);
00639 #endif
00640 #ifdef DEBUG_TIMESTAMPS
00641 if (PTS_DTS_flags == 0x2 && PES_header_data_length >= 5) {
00642 unsigned char nextByte = get1Byte();
00643 pts_highBit = (nextByte&0x08)>>3;
00644 pts_remainingBits = (nextByte&0x06)<<29;
00645 unsigned next4Bytes = get4Bytes();
00646 pts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00647 pts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00648
00649 skipBytes(PES_header_data_length-5);
00650 } else if (PTS_DTS_flags == 0x3 && PES_header_data_length >= 10) {
00651 unsigned char nextByte = get1Byte();
00652 pts_highBit = (nextByte&0x08)>>3;
00653 pts_remainingBits = (nextByte&0x06)<<29;
00654 unsigned next4Bytes = get4Bytes();
00655 pts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00656 pts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00657
00658 nextByte = get1Byte();
00659 dts_highBit = (nextByte&0x08)>>3;
00660 dts_remainingBits = (nextByte&0x06)<<29;
00661 next4Bytes = get4Bytes();
00662 dts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00663 dts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00664
00665 skipBytes(PES_header_data_length-10);
00666 }
00667 #else
00668 skipBytes(PES_header_data_length);
00669 #endif
00670 }
00671 }
00672 #ifdef DEBUG_TIMESTAMPS
00673 fprintf(stderr, "%s stream, ", streamTypeStr);
00674 fprintf(stderr, "packet presentation_time_stamp: 0x%x", pts_highBit);
00675 fprintf(stderr, "%08x\n", pts_remainingBits);
00676 fprintf(stderr, "\t\tpacket decoding_time_stamp: 0x%x", dts_highBit);
00677 fprintf(stderr, "%08x\n", dts_remainingBits);
00678 #endif
00679
00680
00681
00682 unsigned char acquiredStreamIdTag = 0;
00683 unsigned currentParserOffset = curOffset();
00684 unsigned bytesSkipped = currentParserOffset - savedParserOffset;
00685 if (stream_id == RAW_PES) {
00686 restoreSavedParserState();
00687 PES_packet_length += 6;
00688 bytesSkipped = 0;
00689 }
00690 if (PES_packet_length < bytesSkipped) {
00691 fUsingDemux->envir() << "StreamParser::parsePESPacket(): saw inconsistent PES_packet_length "
00692 << PES_packet_length << " < "
00693 << bytesSkipped << "\n";
00694 } else {
00695 PES_packet_length -= bytesSkipped;
00696 #ifdef DEBUG
00697 unsigned next4Bytes = test4Bytes();
00698 #endif
00699
00700
00701
00702 MPEG1or2Demux::OutputDescriptor_t& out = fUsingDemux->fOutput[stream_id];
00703 if (out.isCurrentlyAwaitingData) {
00704 unsigned numBytesToCopy;
00705 if (PES_packet_length > out.maxSize) {
00706 fUsingDemux->envir() << "MPEGProgramStreamParser::parsePESPacket() error: PES_packet_length ("
00707 << PES_packet_length
00708 << ") exceeds max frame size asked for ("
00709 << out.maxSize << ")\n";
00710 numBytesToCopy = out.maxSize;
00711 } else {
00712 numBytesToCopy = PES_packet_length;
00713 }
00714
00715 getBytes(out.to, numBytesToCopy);
00716 out.frameSize = numBytesToCopy;
00717 #ifdef DEBUG
00718 fprintf(stderr, "%d, %d bytes of PES_packet_data (out.maxSize: %d); first 4 bytes: 0x%08x\n", frameCount, numBytesToCopy, out.maxSize, next4Bytes); fflush(stderr);
00719 #endif
00720
00721 acquiredStreamIdTag = stream_id;
00722 PES_packet_length -= numBytesToCopy;
00723 } else if (out.isCurrentlyActive) {
00724
00725
00726
00727 #ifdef DEBUG
00728 fprintf(stderr, "%d, currently undeliverable PES data; first 4 bytes: 0x%08x - currently undeliverable!\n", frameCount, next4Bytes); fflush(stderr);
00729 #endif
00730 restoreSavedParserState();
00731 fUsingDemux->fHaveUndeliveredData = True;
00732 throw READER_NOT_READY;
00733 } else if (out.isPotentiallyReadable &&
00734 out.savedDataTotalSize + PES_packet_length < 1000000 ) {
00735
00736
00737 unsigned char* buf = new unsigned char[PES_packet_length];
00738 getBytes(buf, PES_packet_length);
00739 MPEG1or2Demux::OutputDescriptor::SavedData* savedData
00740 = new MPEG1or2Demux::OutputDescriptor::SavedData(buf, PES_packet_length);
00741 if (out.savedDataHead == NULL) {
00742 out.savedDataHead = out.savedDataTail = savedData;
00743 } else {
00744 out.savedDataTail->next = savedData;
00745 out.savedDataTail = savedData;
00746 }
00747 out.savedDataTotalSize += PES_packet_length;
00748 PES_packet_length = 0;
00749 }
00750 skipBytes(PES_packet_length);
00751 }
00752
00753
00754 setParseState(PARSING_PES_PACKET);
00755 #ifdef DEBUG
00756 ++frameCount;
00757 #endif
00758 return acquiredStreamIdTag;
00759 }