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* usingSource, 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* fUsingSource;
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 exit(1);
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 out.isCurrentlyActive = out.isCurrentlyAwaitingData = False;
00285 }
00286
00287 void MPEG1or2Demux::handleClosure(void* clientData) {
00288 MPEG1or2Demux* demux = (MPEG1or2Demux*)clientData;
00289
00290 demux->fNumPendingReads = 0;
00291
00292
00293
00294
00295
00296 struct {
00297 FramedSource::onCloseFunc* fOnCloseFunc;
00298 void* onCloseClientData;
00299 } savedPending[256];
00300 unsigned i, numPending = 0;
00301 for (i = 0; i < 256; ++i) {
00302 struct OutputDescriptor& out = demux->fOutput[i];
00303 if (out.isCurrentlyAwaitingData) {
00304 if (out.fOnCloseFunc != NULL) {
00305 savedPending[numPending].fOnCloseFunc = out.fOnCloseFunc;
00306 savedPending[numPending].onCloseClientData = out.onCloseClientData;
00307 ++numPending;
00308 }
00309 }
00310 delete out.savedDataHead; out.savedDataHead = out.savedDataTail = NULL;
00311 out.savedDataTotalSize = 0;
00312 out.isPotentiallyReadable = out.isCurrentlyActive = out.isCurrentlyAwaitingData
00313 = False;
00314 }
00315 for (i = 0; i < numPending; ++i) {
00316 (*savedPending[i].fOnCloseFunc)(savedPending[i].onCloseClientData);
00317 }
00318 }
00319
00320
00322
00323 #include <string.h>
00324
00325 MPEGProgramStreamParser::MPEGProgramStreamParser(MPEG1or2Demux* usingSource,
00326 FramedSource* inputSource)
00327 : StreamParser(inputSource, MPEG1or2Demux::handleClosure, usingSource,
00328 &MPEG1or2Demux::continueReadProcessing, usingSource),
00329 fUsingSource(usingSource), fCurrentParseState(PARSING_PACK_HEADER) {
00330 }
00331
00332 MPEGProgramStreamParser::~MPEGProgramStreamParser() {
00333 }
00334
00335 void MPEGProgramStreamParser::setParseState(MPEGParseState parseState) {
00336 fCurrentParseState = parseState;
00337 saveParserState();
00338 }
00339
00340 unsigned char MPEGProgramStreamParser::parse() {
00341 unsigned char acquiredStreamTagId = 0;
00342
00343 try {
00344 do {
00345 switch (fCurrentParseState) {
00346 case PARSING_PACK_HEADER: {
00347 parsePackHeader();
00348 break;
00349 }
00350 case PARSING_SYSTEM_HEADER: {
00351 parseSystemHeader();
00352 break;
00353 }
00354 case PARSING_PES_PACKET: {
00355 acquiredStreamTagId = parsePESPacket();
00356 break;
00357 }
00358 }
00359 } while(acquiredStreamTagId == 0);
00360
00361 return acquiredStreamTagId;
00362 } catch (int ) {
00363 #ifdef DEBUG
00364 fprintf(stderr, "MPEGProgramStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n");
00365 fflush(stderr);
00366 #endif
00367 return 0;
00368 }
00369 }
00370
00371 #define PACK_START_CODE 0x000001BA
00372 #define SYSTEM_HEADER_START_CODE 0x000001BB
00373 #define PACKET_START_CODE_PREFIX 0x00000100
00374
00375 static inline Boolean isPacketStartCode(unsigned code) {
00376 return (code&0xFFFFFF00) == PACKET_START_CODE_PREFIX
00377 && code > SYSTEM_HEADER_START_CODE;
00378 }
00379
00380 void MPEGProgramStreamParser::parsePackHeader() {
00381 #ifdef DEBUG
00382 fprintf(stderr, "parsing pack header\n"); fflush(stderr);
00383 #endif
00384 unsigned first4Bytes;
00385 while (1) {
00386 first4Bytes = test4Bytes();
00387
00388
00389
00390 if (first4Bytes == PACK_START_CODE) {
00391 skipBytes(4);
00392 break;
00393 } else if (first4Bytes == SYSTEM_HEADER_START_CODE) {
00394 #ifdef DEBUG
00395 fprintf(stderr, "found system header instead of pack header\n");
00396 #endif
00397 setParseState(PARSING_SYSTEM_HEADER);
00398 return;
00399 } else if (isPacketStartCode(first4Bytes)) {
00400 #ifdef DEBUG
00401 fprintf(stderr, "found packet start code 0x%02x instead of pack header\n", first4Bytes);
00402 #endif
00403 setParseState(PARSING_PES_PACKET);
00404 return;
00405 }
00406
00407 setParseState(PARSING_PACK_HEADER);
00408 if ((first4Bytes&0xFF) > 1) {
00409 skipBytes(4);
00410 } else {
00411 skipBytes(1);
00412 }
00413 }
00414
00415
00416
00417 unsigned char nextByte = get1Byte();
00418 MPEG1or2Demux::SCR& scr = fUsingSource->fLastSeenSCR;
00419 if ((nextByte&0xF0) == 0x20) {
00420 fUsingSource->fMPEGversion = 1;
00421 scr.highBit = (nextByte&0x08)>>3;
00422 scr.remainingBits = (nextByte&0x06)<<29;
00423 unsigned next4Bytes = get4Bytes();
00424 scr.remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00425 scr.remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00426 scr.extension = 0;
00427 scr.isValid = True;
00428 skipBits(24);
00429
00430 #if defined(DEBUG_TIMESTAMPS) || defined(DEBUG_SCR_TIMESTAMPS)
00431 fprintf(stderr, "pack hdr system_clock_reference_base: 0x%x",
00432 scr.highBit);
00433 fprintf(stderr, "%08x\n", scr.remainingBits);
00434 #endif
00435 } else if ((nextByte&0xC0) == 0x40) {
00436 fUsingSource->fMPEGversion = 2;
00437 scr.highBit = (nextByte&0x20)>>5;
00438 scr.remainingBits = (nextByte&0x18)<<27;
00439 scr.remainingBits |= (nextByte&0x03)<<28;
00440 unsigned next4Bytes = get4Bytes();
00441 scr.remainingBits |= (next4Bytes&0xFFF80000)>>4;
00442 scr.remainingBits |= (next4Bytes&0x0003FFF8)>>3;
00443 scr.extension = (next4Bytes&0x00000003)<<7;
00444 next4Bytes = get4Bytes();
00445 scr.extension |= (next4Bytes&0xFE000000)>>25;
00446 scr.isValid = True;
00447 skipBits(5);
00448
00449 #if defined(DEBUG_TIMESTAMPS) || defined(DEBUG_SCR_TIMESTAMPS)
00450 fprintf(stderr, "pack hdr system_clock_reference_base: 0x%x",
00451 scr.highBit);
00452 fprintf(stderr, "%08x\n", scr.remainingBits);
00453 fprintf(stderr, "pack hdr system_clock_reference_extension: 0x%03x\n",
00454 scr.extension);
00455 #endif
00456 unsigned char pack_stuffing_length = getBits(3);
00457 skipBytes(pack_stuffing_length);
00458 } else {
00459 fUsingSource->envir() << "StreamParser::parsePack() saw strange byte "
00460 << (void*)nextByte
00461 << " following pack_start_code\n";
00462 }
00463
00464
00465 setParseState(PARSING_SYSTEM_HEADER);
00466 }
00467
00468 void MPEGProgramStreamParser::parseSystemHeader() {
00469 #ifdef DEBUG
00470 fprintf(stderr, "parsing system header\n"); fflush(stderr);
00471 #endif
00472 unsigned next4Bytes = test4Bytes();
00473 if (next4Bytes != SYSTEM_HEADER_START_CODE) {
00474
00475 setParseState(PARSING_PES_PACKET);
00476 return;
00477 }
00478
00479 #ifdef DEBUG
00480 fprintf(stderr, "saw system_header_start_code\n"); fflush(stderr);
00481 #endif
00482 skipBytes(4);
00483
00484 unsigned short remaining_header_length = get2Bytes();
00485
00486
00487
00488 if (remaining_header_length < 6) {
00489 fUsingSource->envir() << "StreamParser::parseSystemHeader(): saw strange header_length: "
00490 << remaining_header_length << " < 6\n";
00491 }
00492 skipBytes(remaining_header_length);
00493
00494
00495 setParseState(PARSING_PES_PACKET);
00496 }
00497
00498 #define private_stream_1 0xBD
00499 #define private_stream_2 0xBF
00500
00501
00502 Boolean MPEGProgramStreamParser
00503 ::isSpecialStreamId(unsigned char stream_id) const {
00504 if (stream_id == RAW_PES) return True;
00505
00506 if (fUsingSource->fMPEGversion == 1) {
00507 return stream_id == private_stream_2;
00508 } else {
00509 if (stream_id <= private_stream_2) {
00510 return stream_id != private_stream_1;
00511 } else if ((stream_id&0xF0) == 0xF0) {
00512 unsigned char lower4Bits = stream_id&0x0F;
00513 return lower4Bits <= 2 || lower4Bits == 0x8 || lower4Bits == 0xF;
00514 } else {
00515 return False;
00516 }
00517 }
00518 }
00519
00520 #define READER_NOT_READY 2
00521
00522 unsigned char MPEGProgramStreamParser::parsePESPacket() {
00523 #ifdef DEBUG
00524 fprintf(stderr, "parsing PES packet\n"); fflush(stderr);
00525 #endif
00526 unsigned next4Bytes = test4Bytes();
00527 if (!isPacketStartCode(next4Bytes)) {
00528
00529 setParseState(PARSING_PACK_HEADER);
00530 return 0;
00531 }
00532
00533 #ifdef DEBUG
00534 fprintf(stderr, "saw packet_start_code_prefix\n"); fflush(stderr);
00535 #endif
00536 skipBytes(3);
00537
00538 unsigned char stream_id = get1Byte();
00539 #if defined(DEBUG) || defined(DEBUG_TIMESTAMPS)
00540 unsigned char streamNum = stream_id;
00541 char* streamTypeStr;
00542 if ((stream_id&0xE0) == 0xC0) {
00543 streamTypeStr = "audio";
00544 streamNum = stream_id&~0xE0;
00545 } else if ((stream_id&0xF0) == 0xE0) {
00546 streamTypeStr = "video";
00547 streamNum = stream_id&~0xF0;
00548 } else if (stream_id == 0xbc) {
00549 streamTypeStr = "reserved";
00550 } else if (stream_id == 0xbd) {
00551 streamTypeStr = "private_1";
00552 } else if (stream_id == 0xbe) {
00553 streamTypeStr = "padding";
00554 } else if (stream_id == 0xbf) {
00555 streamTypeStr = "private_2";
00556 } else {
00557 streamTypeStr = "unknown";
00558 }
00559 #endif
00560 #ifdef DEBUG
00561 static unsigned frameCount = 1;
00562 fprintf(stderr, "%d, saw %s stream: 0x%02x\n", frameCount, streamTypeStr, streamNum); fflush(stderr);
00563 #endif
00564
00565 unsigned short PES_packet_length = get2Bytes();
00566 #ifdef DEBUG
00567 fprintf(stderr, "PES_packet_length: %d\n", PES_packet_length); fflush(stderr);
00568 #endif
00569
00570
00571
00572 if (fUsingSource->fOutput[RAW_PES].isPotentiallyReadable) {
00573
00574 stream_id = RAW_PES;
00575 }
00576 unsigned savedParserOffset = curOffset();
00577 #ifdef DEBUG_TIMESTAMPS
00578 unsigned char pts_highBit = 0;
00579 unsigned pts_remainingBits = 0;
00580 unsigned char dts_highBit = 0;
00581 unsigned dts_remainingBits = 0;
00582 #endif
00583 if (fUsingSource->fMPEGversion == 1) {
00584 if (!isSpecialStreamId(stream_id)) {
00585 unsigned char nextByte;
00586 while ((nextByte = get1Byte()) == 0xFF) {
00587 }
00588 if ((nextByte&0xC0) == 0x40) {
00589 skipBytes(1);
00590 nextByte = get1Byte();
00591 }
00592 if ((nextByte&0xF0) == 0x20) {
00593 #ifdef DEBUG_TIMESTAMPS
00594 pts_highBit = (nextByte&0x08)>>3;
00595 pts_remainingBits = (nextByte&0x06)<<29;
00596 unsigned next4Bytes = get4Bytes();
00597 pts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00598 pts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00599 #else
00600 skipBytes(4);
00601 #endif
00602 } else if ((nextByte&0xF0) == 0x30) {
00603 #ifdef DEBUG_TIMESTAMPS
00604 pts_highBit = (nextByte&0x08)>>3;
00605 pts_remainingBits = (nextByte&0x06)<<29;
00606 unsigned next4Bytes = get4Bytes();
00607 pts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00608 pts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00609
00610 nextByte = get1Byte();
00611 dts_highBit = (nextByte&0x08)>>3;
00612 dts_remainingBits = (nextByte&0x06)<<29;
00613 next4Bytes = get4Bytes();
00614 dts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00615 dts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00616 #else
00617 skipBytes(9);
00618 #endif
00619 }
00620 }
00621 } else {
00622 if (!isSpecialStreamId(stream_id)) {
00623
00624 unsigned next3Bytes = getBits(24);
00625 #ifdef DEBUG_TIMESTAMPS
00626 unsigned char PTS_DTS_flags = (next3Bytes&0x00C000)>>14;
00627 #endif
00628 #ifdef undef
00629 unsigned char ESCR_flag = (next3Bytes&0x002000)>>13;
00630 unsigned char ES_rate_flag = (next3Bytes&0x001000)>>12;
00631 unsigned char DSM_trick_mode_flag = (next3Bytes&0x000800)>>11;
00632 #endif
00633 unsigned char PES_header_data_length = (next3Bytes&0x0000FF);
00634 #ifdef DEBUG
00635 fprintf(stderr, "PES_header_data_length: 0x%02x\n", PES_header_data_length); fflush(stderr);
00636 #endif
00637 #ifdef DEBUG_TIMESTAMPS
00638 if (PTS_DTS_flags == 0x2 && PES_header_data_length >= 5) {
00639 unsigned char nextByte = get1Byte();
00640 pts_highBit = (nextByte&0x08)>>3;
00641 pts_remainingBits = (nextByte&0x06)<<29;
00642 unsigned next4Bytes = get4Bytes();
00643 pts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00644 pts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00645
00646 skipBytes(PES_header_data_length-5);
00647 } else if (PTS_DTS_flags == 0x3 && PES_header_data_length >= 10) {
00648 unsigned char nextByte = get1Byte();
00649 pts_highBit = (nextByte&0x08)>>3;
00650 pts_remainingBits = (nextByte&0x06)<<29;
00651 unsigned next4Bytes = get4Bytes();
00652 pts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00653 pts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00654
00655 nextByte = get1Byte();
00656 dts_highBit = (nextByte&0x08)>>3;
00657 dts_remainingBits = (nextByte&0x06)<<29;
00658 next4Bytes = get4Bytes();
00659 dts_remainingBits |= (next4Bytes&0xFFFE0000)>>2;
00660 dts_remainingBits |= (next4Bytes&0x0000FFFE)>>1;
00661
00662 skipBytes(PES_header_data_length-10);
00663 }
00664 #else
00665 skipBytes(PES_header_data_length);
00666 #endif
00667 }
00668 }
00669 #ifdef DEBUG_TIMESTAMPS
00670 fprintf(stderr, "%s stream, ", streamTypeStr);
00671 fprintf(stderr, "packet presentation_time_stamp: 0x%x", pts_highBit);
00672 fprintf(stderr, "%08x\n", pts_remainingBits);
00673 fprintf(stderr, "\t\tpacket decoding_time_stamp: 0x%x", dts_highBit);
00674 fprintf(stderr, "%08x\n", dts_remainingBits);
00675 #endif
00676
00677
00678
00679 unsigned char acquiredStreamIdTag = 0;
00680 unsigned currentParserOffset = curOffset();
00681 unsigned bytesSkipped = currentParserOffset - savedParserOffset;
00682 if (stream_id == RAW_PES) {
00683 restoreSavedParserState();
00684 PES_packet_length += 6;
00685 bytesSkipped = 0;
00686 }
00687 if (PES_packet_length < bytesSkipped) {
00688 fUsingSource->envir() << "StreamParser::parsePESPacket(): saw inconsistent PES_packet_length "
00689 << PES_packet_length << " < "
00690 << bytesSkipped << "\n";
00691 } else {
00692 PES_packet_length -= bytesSkipped;
00693 #ifdef DEBUG
00694 unsigned next4Bytes = test4Bytes();
00695 #endif
00696
00697
00698
00699 MPEG1or2Demux::OutputDescriptor_t& out = fUsingSource->fOutput[stream_id];
00700 if (out.isCurrentlyAwaitingData) {
00701 unsigned numBytesToCopy;
00702 if (PES_packet_length > out.maxSize) {
00703 fUsingSource->envir() << "MPEGProgramStreamParser::parsePESPacket() error: PES_packet_length ("
00704 << PES_packet_length
00705 << ") exceeds max frame size asked for ("
00706 << out.maxSize << ")\n";
00707 numBytesToCopy = out.maxSize;
00708 } else {
00709 numBytesToCopy = PES_packet_length;
00710 }
00711
00712 getBytes(out.to, numBytesToCopy);
00713 out.frameSize = numBytesToCopy;
00714 #ifdef DEBUG
00715 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);
00716 #endif
00717
00718 acquiredStreamIdTag = stream_id;
00719 PES_packet_length -= numBytesToCopy;
00720 } else if (out.isCurrentlyActive) {
00721
00722
00723
00724 #ifdef DEBUG
00725 fprintf(stderr, "%d, currently undeliverable PES data; first 4 bytes: 0x%08x - currently undeliverable!\n", frameCount, next4Bytes); fflush(stderr);
00726 #endif
00727 restoreSavedParserState();
00728 fUsingSource->fHaveUndeliveredData = True;
00729 throw READER_NOT_READY;
00730 } else if (out.isPotentiallyReadable &&
00731 out.savedDataTotalSize + PES_packet_length < 1000000 ) {
00732
00733
00734 unsigned char* buf = new unsigned char[PES_packet_length];
00735 getBytes(buf, PES_packet_length);
00736 MPEG1or2Demux::OutputDescriptor::SavedData* savedData
00737 = new MPEG1or2Demux::OutputDescriptor::SavedData(buf, PES_packet_length);
00738 if (out.savedDataHead == NULL) {
00739 out.savedDataHead = out.savedDataTail = savedData;
00740 } else {
00741 out.savedDataTail->next = savedData;
00742 out.savedDataTail = savedData;
00743 }
00744 out.savedDataTotalSize += PES_packet_length;
00745 PES_packet_length = 0;
00746 }
00747 skipBytes(PES_packet_length);
00748 }
00749
00750
00751 setParseState(PARSING_PES_PACKET);
00752 #ifdef DEBUG
00753 ++frameCount;
00754 #endif
00755 return acquiredStreamIdTag;
00756 }